1<?php
2/**
3 * Zend Framework (http://framework.zend.com/)
4 *
5 * @link      http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license   http://framework.zend.com/license/new-bsd New BSD License
8 */
9
10namespace Zend\Form\Element;
11
12use Traversable;
13use Zend\Captcha as ZendCaptcha;
14use Zend\Form\Element;
15use Zend\Form\Exception;
16use Zend\InputFilter\InputProviderInterface;
17
18class Captcha extends Element implements InputProviderInterface
19{
20    /**
21     * @var \Zend\Captcha\AdapterInterface
22     */
23    protected $captcha;
24
25    /**
26     * Accepted options for Captcha:
27     * - captcha: a valid Zend\Captcha\AdapterInterface
28     *
29     * @param array|Traversable $options
30     * @return Captcha
31     */
32    public function setOptions($options)
33    {
34        parent::setOptions($options);
35
36        if (isset($this->options['captcha'])) {
37            $this->setCaptcha($this->options['captcha']);
38        }
39
40        return $this;
41    }
42
43    /**
44     * Set captcha
45     *
46     * @param  array|ZendCaptcha\AdapterInterface $captcha
47     * @throws Exception\InvalidArgumentException
48     * @return Captcha
49     */
50    public function setCaptcha($captcha)
51    {
52        if (is_array($captcha) || $captcha instanceof Traversable) {
53            $captcha = ZendCaptcha\Factory::factory($captcha);
54        } elseif (!$captcha instanceof ZendCaptcha\AdapterInterface) {
55            throw new Exception\InvalidArgumentException(sprintf(
56                '%s expects either a Zend\Captcha\AdapterInterface or specification to pass to Zend\Captcha\Factory; received "%s"',
57                __METHOD__,
58                (is_object($captcha) ? get_class($captcha) : gettype($captcha))
59            ));
60        }
61        $this->captcha = $captcha;
62
63        return $this;
64    }
65
66    /**
67     * Retrieve captcha (if any)
68     *
69     * @return null|ZendCaptcha\AdapterInterface
70     */
71    public function getCaptcha()
72    {
73        return $this->captcha;
74    }
75
76    /**
77     * Provide default input rules for this element
78     *
79     * Attaches the captcha as a validator.
80     *
81     * @return array
82     */
83    public function getInputSpecification()
84    {
85        $spec = array(
86            'name' => $this->getName(),
87            'required' => true,
88            'filters' => array(
89                array('name' => 'Zend\Filter\StringTrim'),
90            ),
91        );
92
93        // Test that we have a captcha before adding it to the spec
94        $captcha = $this->getCaptcha();
95        if ($captcha instanceof ZendCaptcha\AdapterInterface) {
96            $spec['validators'] = array($captcha);
97        }
98
99        return $spec;
100    }
101}
102