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\View\Helper;
11
12use Zend\Form\ElementInterface;
13use Zend\Form\Exception;
14use Zend\Form\LabelAwareInterface;
15
16class FormLabel extends AbstractHelper
17{
18    const APPEND  = 'append';
19    const PREPEND = 'prepend';
20
21    /**
22     * Attributes valid for the label tag
23     *
24     * @var array
25     */
26    protected $validTagAttributes = array(
27        'for'  => true,
28        'form' => true,
29    );
30
31    /**
32     * Generate a form label, optionally with content
33     *
34     * Always generates a "for" statement, as we cannot assume the form input
35     * will be provided in the $labelContent.
36     *
37     * @param  ElementInterface $element
38     * @param  null|string      $labelContent
39     * @param  string           $position
40     * @throws Exception\DomainException
41     * @return string|FormLabel
42     */
43    public function __invoke(ElementInterface $element = null, $labelContent = null, $position = null)
44    {
45        if (!$element) {
46            return $this;
47        }
48
49        $openTag = $this->openTag($element);
50        $label   = '';
51        if ($labelContent === null || $position !== null) {
52            $label = $element->getLabel();
53            if (empty($label)) {
54                throw new Exception\DomainException(
55                    sprintf(
56                        '%s expects either label content as the second argument, ' .
57                        'or that the element provided has a label attribute; neither found',
58                        __METHOD__
59                    )
60                );
61            }
62
63            if (null !== ($translator = $this->getTranslator())) {
64                $label = $translator->translate($label, $this->getTranslatorTextDomain());
65            }
66
67            if (! $element instanceof LabelAwareInterface || ! $element->getLabelOption('disable_html_escape')) {
68                $escapeHtmlHelper = $this->getEscapeHtmlHelper();
69                $label = $escapeHtmlHelper($label);
70            }
71        }
72
73        if ($label && $labelContent) {
74            switch ($position) {
75                case self::APPEND:
76                    $labelContent .= $label;
77                    break;
78                case self::PREPEND:
79                default:
80                    $labelContent = $label . $labelContent;
81                    break;
82            }
83        }
84
85        if ($label && null === $labelContent) {
86            $labelContent = $label;
87        }
88
89        return $openTag . $labelContent . $this->closeTag();
90    }
91
92    /**
93     * Generate an opening label tag
94     *
95     * @param  null|array|ElementInterface $attributesOrElement
96     * @throws Exception\InvalidArgumentException
97     * @throws Exception\DomainException
98     * @return string
99     */
100    public function openTag($attributesOrElement = null)
101    {
102        if (null === $attributesOrElement) {
103            return '<label>';
104        }
105
106        if (is_array($attributesOrElement)) {
107            $attributes = $this->createAttributesString($attributesOrElement);
108            return sprintf('<label %s>', $attributes);
109        }
110
111        if (!$attributesOrElement instanceof ElementInterface) {
112            throw new Exception\InvalidArgumentException(sprintf(
113                '%s expects an array or Zend\Form\ElementInterface instance; received "%s"',
114                __METHOD__,
115                (is_object($attributesOrElement) ? get_class($attributesOrElement) : gettype($attributesOrElement))
116            ));
117        }
118
119        $id = $this->getId($attributesOrElement);
120        if (null === $id) {
121            throw new Exception\DomainException(sprintf(
122                '%s expects the Element provided to have either a name or an id present; neither found',
123                __METHOD__
124            ));
125        }
126
127        $labelAttributes = array();
128        if ($attributesOrElement instanceof LabelAwareInterface) {
129            $labelAttributes = $attributesOrElement->getLabelAttributes();
130        }
131
132        $attributes = array('for' => $id);
133
134        if (!empty($labelAttributes)) {
135            $attributes = array_merge($labelAttributes, $attributes);
136        }
137
138        $attributes = $this->createAttributesString($attributes);
139        return sprintf('<label %s>', $attributes);
140    }
141
142    /**
143     * Return a closing label tag
144     *
145     * @return string
146     */
147    public function closeTag()
148    {
149        return '</label>';
150    }
151}
152