Commit | Line | Data |
---|---|---|
22c790fc MS |
1 | <?php |
2 | namespace wcf\system\form\builder\field\label; | |
3 | use wcf\data\IStorableObject; | |
4 | use wcf\data\label\group\ViewableLabelGroup; | |
5 | use wcf\data\label\Label; | |
5d086ddf | 6 | use wcf\system\form\builder\data\processor\CustomFormDataProcessor; |
22c790fc | 7 | use wcf\system\form\builder\field\AbstractFormField; |
22c790fc MS |
8 | use wcf\system\form\builder\field\validation\FormFieldValidationError; |
9 | use wcf\system\form\builder\IFormDocument; | |
10 | use wcf\system\form\builder\IObjectTypeFormNode; | |
11 | use wcf\system\form\builder\TObjectTypeFormNode; | |
12 | use wcf\system\label\LabelHandler; | |
13 | ||
14 | /** | |
15 | * Implementation of a form field to select labels. | |
16 | * | |
17 | * @author Matthias Schmidt | |
18 | * @copyright 2001-2019 WoltLab GmbH | |
19 | * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> | |
20 | * @package WoltLabSuite\Core\System\Form\Builder\Field | |
21 | * @since 5.2 | |
22 | */ | |
23 | class LabelFormField extends AbstractFormField implements IObjectTypeFormNode { | |
24 | use TObjectTypeFormNode; | |
25 | ||
477f6668 MS |
26 | /** |
27 | * @inheritDoc | |
28 | */ | |
29 | protected $javaScriptDataHandlerModule = 'WoltLabSuite/Core/Form/Builder/Field/Value'; | |
30 | ||
22c790fc MS |
31 | /** |
32 | * label group whose labels can be selected via this form field | |
33 | * @var ViewableLabelGroup | |
34 | */ | |
35 | protected $labelGroup; | |
36 | ||
37 | /** | |
38 | * @inheritDoc | |
39 | */ | |
40 | protected $templateName = '__labelFormField'; | |
41 | ||
42 | /** | |
43 | * loaded labels grouped by label object type and object id to avoid loading the same labels | |
44 | * over and over again for the same object and different label groups | |
45 | * @var Label[][] | |
46 | */ | |
47 | protected static $loadedLabels = []; | |
48 | ||
49 | /** | |
50 | * Returns the label group whose labels can be selected via this form field. | |
51 | * | |
52 | * @return ViewableLabelGroup label group whose labels can be selected | |
53 | * @throws \BadMethodCallException if no label has been set | |
54 | */ | |
55 | public function getLabelGroup() { | |
56 | if ($this->labelGroup === null) { | |
57 | throw new \BadMethodCallException("No label group has been set."); | |
58 | } | |
59 | ||
60 | return $this->labelGroup; | |
61 | } | |
62 | ||
63 | /** | |
64 | * @inheritDoc | |
65 | */ | |
66 | public function getObjectTypeDefinition() { | |
67 | return 'com.woltlab.wcf.label.object'; | |
68 | } | |
69 | ||
70 | /** | |
71 | * @inheritDoc | |
72 | */ | |
73 | public function hasSaveValue() { | |
74 | return false; | |
75 | } | |
76 | ||
77 | /** | |
78 | * Sets the label group whose labels can be selected via this form field and returns this | |
79 | * form field. | |
80 | * | |
81 | * If no form field label has been set, the title of the label group will be set as label. | |
82 | * | |
83 | * @param ViewableLabelGroup $labelGroup label group whose labels can be selected | |
84 | * @return static this form field | |
85 | */ | |
86 | public function labelGroup(ViewableLabelGroup $labelGroup) { | |
87 | $this->labelGroup = $labelGroup; | |
88 | ||
89 | if ($this->label === null) { | |
90 | $this->label($this->getLabelGroup()->getTitle()); | |
91 | } | |
92 | ||
93 | return $this; | |
94 | } | |
95 | ||
96 | /** | |
97 | * @inheritDoc | |
98 | */ | |
5d086ddf | 99 | public function loadValue(array $data, IStorableObject $object) { |
22c790fc | 100 | $objectTypeID = $this->getObjectType()->objectTypeID; |
5d086ddf | 101 | $objectID = $object->{$object::getDatabaseTableIndexName()}; |
22c790fc MS |
102 | |
103 | if (!isset(static::$loadedLabels[$objectTypeID])) { | |
104 | static::$loadedLabels[$objectTypeID] = []; | |
105 | } | |
106 | if (!isset(static::$loadedLabels[$objectTypeID][$objectID])) { | |
107 | static::$loadedLabels[$objectTypeID][$objectID] = LabelHandler::getInstance()->getAssignedLabels( | |
108 | $objectTypeID, | |
109 | [$objectID] | |
110 | )[$objectID]; | |
111 | } | |
112 | ||
113 | $labelIDs = $this->getLabelGroup()->getLabelIDs(); | |
114 | /** @var Label $label */ | |
115 | foreach (static::$loadedLabels[$objectTypeID][$objectID] as $label) { | |
116 | if (in_array($label->labelID, $labelIDs)) { | |
117 | $this->value($label->labelID); | |
118 | } | |
119 | } | |
120 | ||
121 | return $this; | |
122 | } | |
123 | ||
124 | /** | |
125 | * @inheritDoc | |
126 | */ | |
127 | public function populate() { | |
128 | parent::populate(); | |
129 | ||
5d086ddf | 130 | $this->getDocument()->getDataHandler()->addProcessor(new CustomFormDataProcessor('label', function(IFormDocument $document, array $parameters) { |
22c790fc MS |
131 | $value = $this->getValue(); |
132 | ||
133 | // `-1` and `0` are special values that are irrlevent for saving | |
134 | if ($value > 0) { | |
135 | if (!isset($parameters[$this->getObjectProperty()])) { | |
136 | $parameters[$this->getObjectProperty()] = []; | |
137 | } | |
138 | ||
139 | $parameters[$this->getObjectProperty()][$this->getLabelGroup()->groupID] = $value; | |
140 | } | |
141 | ||
142 | return $parameters; | |
143 | })); | |
144 | ||
145 | return $this; | |
146 | } | |
147 | ||
148 | /** | |
149 | * @inheritDoc | |
150 | */ | |
151 | public function readValue() { | |
152 | if ($this->getDocument()->hasRequestData($this->getPrefixedId())) { | |
153 | $this->value = intval($this->getDocument()->getRequestData($this->getPrefixedId())); | |
154 | } | |
155 | ||
156 | return $this; | |
157 | } | |
158 | ||
159 | /** | |
160 | * @inheritDoc | |
161 | */ | |
162 | public function validate() { | |
163 | if ($this->isRequired()) { | |
164 | if ($this->value <= 0) { | |
165 | $this->addValidationError(new FormFieldValidationError('empty')); | |
166 | } | |
167 | } | |
168 | else if ($this->value > 0 && !in_array($this->value, $this->getLabelGroup()->getLabelIDs())) { | |
169 | $this->addValidationError(new FormFieldValidationError( | |
170 | 'invalidValue', | |
171 | 'wcf.global.form.error.noValidSelection' | |
172 | )); | |
173 | } | |
174 | } | |
175 | ||
176 | /** | |
177 | * Returns label group fields based for the given label groups using the given object property. | |
178 | * | |
179 | * The id of each form fields is `{$objectProperty}{$labelGroupID}`. | |
180 | * | |
181 | * @param string $objectType `com.woltlab.wcf.label.object` object type | |
182 | * @param ViewableLabelGroup[] $labelGroups label groups for which label form fields are created | |
183 | * @param string $objectProperty object property of form fields | |
184 | * @return static[] | |
185 | */ | |
186 | public static function createFields($objectType, array $labelGroups, $objectProperty = 'labelIDs') { | |
187 | $formFields = []; | |
188 | foreach ($labelGroups as $labelGroup) { | |
189 | $formFields[] = static::create($objectProperty . $labelGroup->groupID) | |
190 | ->objectProperty($objectProperty) | |
191 | ->objectType($objectType) | |
192 | ->required($labelGroup->forceSelection) | |
193 | ->labelGroup($labelGroup); | |
194 | } | |
195 | ||
196 | return $formFields; | |
197 | } | |
198 | } |