Passed
Push — main ( d45a63...f487df )
by Stefan
02:34
created

FormStarRate::onParentSet()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 2
eloc 2
c 1
b 0
f 1
nc 2
nop 0
dl 0
loc 4
rs 10
1
<?php
2
declare(strict_types=1);
3
4
namespace SKien\Formgenerator;
5
6
/**
7
 * Element for rating input with stars.
8
 *
9
 * This element can be used to select rating between 1 ... n stars. It is based
10
 * on radio-input, CSS and uses UTF-8 Symbols for the stars - no Javascript
11
 * and images are needed!
12
 *
13
 * The count and titles of the stars can be set
14
 * - in the configuration
15
 * - by calling the `setTitles()` method
16
 * - within the XML definition
17
 *
18
 * default is 5 Stars (*'terrible', 'not good', 'average', 'good', 'great'*)
19
 *
20
 * The submmited value is an integer between 1 ... n (representing the count of stars)
21
 *
22
 * @SKienImage FormStarRate.png
23
 *
24
 * @package Formgenerator
25
 * @author Stefanius <[email protected]>
26
 * @copyright MIT License - see the LICENSE file for details
27
 */
28
class FormStarRate extends FormInput
29
{
30
    /** default count of stars */
31
    protected const STAR_COUNT = 5;
32
    /** default titles for the stars */
33
    protected const STAR_TITELS = ['terrible', 'not good', 'average', 'good', 'great'];
34
35
    /** @var array titles for the stars (from 0 ... n-1) */
36
    protected ?array $aTitles = null;
37
38
    /**
39
     * Create a star rating element.
40
     * @param string $strName   name AND id of the element
41
     * @param int $wFlags    (default: 0)
42
     */
43
    public function __construct(string $strName, int $wFlags = 0)
44
    {
45
        $this->oFlags = new FormFlags($wFlags);
46
        $this->strName = $strName;
47
    }
48
49
    /**
50
     * {@inheritDoc}
51
     * @see \SKien\Formgenerator\FormElement::fromXML()
52
     * @internal
53
     */
54
    static public function fromXML(\DOMElement $oXMLElement, FormCollection $oFormParent) : ?FormElement
55
    {
56
        $strName = self::getAttribString($oXMLElement, 'name', '');
57
        $wFlags = self::getAttribFlags($oXMLElement);
58
        $oFormElement = new self($strName, $wFlags);
59
        $oFormParent->add($oFormElement);
60
        $oFormElement->readAdditionalXML($oXMLElement);
61
        return $oFormElement;
62
    }
63
64
    /**
65
     * {@inheritDoc}
66
     * @see \SKien\Formgenerator\FormElement::readAdditionalXML()
67
     * @internal
68
     */
69
    public function readAdditionalXML(\DOMElement $oXMLElement) : void
70
    {
71
        parent::readAdditionalXML($oXMLElement);
72
        $aTitles = $oXMLElement->getElementsByTagName('title');
73
        if ($aTitles->length > 0) {
74
            $this->aTitles = [];
75
            $i = 0;
76
            foreach ($aTitles as $oTitle) {
77
                $this->aTitles[$i++] = $oTitle->nodeValue;
78
            }
79
        }
80
    }
81
82
    /**
83
     * We 'ask' the configuration for count and titles.
84
     * $this->oFG is not available until the parent is set!
85
     */
86
    protected function onParentSet() : void
87
    {
88
        if ($this->aTitles === null) {
89
            $this->aTitles = $this->oFG->getConfig()->getArray('StarRate.Titles', self::STAR_TITELS);
90
        }
91
    }
92
93
    /**
94
     * Build the HTML-markup for the radio group.
95
     * @return string
96
     * @internal l
97
     */
98
    public function getHTML() : string
99
    {
100
        $this->processFlags();
101
102
        $strStyle = '';
103
        if ($this->oFlags->isSet(FormFlags::ALIGN_CENTER)) {
104
            $strStyle = 'text-align: center;';
105
        } else if ($this->oFlags->isSet(FormFlags::ALIGN_RIGHT)) {
106
            $strStyle = 'text-align: right;';
107
        }
108
109
        $strHTML = $this->buildContainerDiv($strStyle) . PHP_EOL;
110
        $strHTML .= '    <div class="starrate">' . PHP_EOL;
111
112
        $iSelect = intval($this->oFG->getData()->getValue($this->strName));
113
114
        if (is_array($this->aTitles)) {
115
            $iStarCount = count($this->aTitles);
116
            for ($iStar = $iStarCount; $iStar > 0; $iStar--) {
117
                $strInputClassCSS = ($iStar == $iStarCount) ? ' class="best"' : '';
118
                $strId = $this->strName . 'Star' . $iStar;
119
                $strTitle = ($this->aTitles && isset($this->aTitles[$iStar-1])) ? $this->aTitles[$iStar-1] : $iStar . ' Star';
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->aTitles of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
120
121
                $strHTML .= '        <input' . $strInputClassCSS;
122
                $strHTML .= ' type="radio" id="' . $strId . '"';
123
                $strHTML .= ($iSelect == $iStar) ? ' checked' : '';
124
                $strHTML .= ' name="' . $this->strName . '"';
125
                $strHTML .= $this->buildAttributes();
126
                $strHTML .= ' value="' . $iStar . '"/>' . PHP_EOL;
127
128
                $strHTML .= '        <label for="' . $strId . '"';
129
                $strHTML .= ' id="' . $strId . 'Label"';
130
                $strHTML .= ' title="' . $strTitle . '"></label>' . PHP_EOL;
131
            }
132
            $strHTML .= '    </div>' . PHP_EOL;;
133
134
            $strHTML .= '</div>' . PHP_EOL;
135
        }
136
137
        return $strHTML;
138
    }
139
140
    /**
141
     * Set the titles for the stars.
142
     * @param array $aTitles
143
     */
144
    public function setTitles(array $aTitles) : void
145
    {
146
        $this->aTitles = $aTitles;
147
    }
148
}
149