63c60dd4197b5dc2723473509d30dfdd4379fcc9
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / data / option / Option.class.php
1 <?php
2 namespace wcf\data\option;
3 use wcf\data\DatabaseObject;
4 use wcf\data\TDatabaseObjectOptions;
5 use wcf\data\TDatabaseObjectPermissions;
6 use wcf\system\WCF;
7 use wcf\util\StringUtil;
8
9 /**
10 * Represents an option.
11 *
12 * @author Alexander Ebert
13 * @copyright 2001-2018 WoltLab GmbH
14 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
15 * @package WoltLabSuite\Core\Data\Option
16 *
17 * @property-read integer $optionID unique id of the option
18 * @property-read integer $packageID id of the package the which delivers the option
19 * @property-read string $optionName name and textual identifier of the option
20 * @property-read string $categoryName name of the option category the option belongs to
21 * @property-read string $optionType textual identifier of the option (corresponds to a class implementing `wcf\system\option\IOptionType`)
22 * @property-read string $optionValue value of the option
23 * @property-read string $validationPattern regular expression used to validate the option's value or empty if no such regular expression exists
24 * @property-read string $selectOptions newline-separated list of selectable options for a selectable option type (line pattern: `{value}:{language item name}`)
25 * @property-read string $enableOptions list of options that are enabled based on the option's value (simple comma-separated list of boolean options, otherwise newline-separated list with line pattern: `{select value}:{comma-separated list}`)
26 * @property-read integer $showOrder position of the option in relation to the other option in the option category
27 * @property-read integer $hidden is `1` if the option is hidden and thus cannot be explicitly set by in the acp, otherwise `0`
28 * @property-read string $permissions comma separated list of user group permissions of which the active user needs to have at least one to set the option value
29 * @property-read string $options comma separated list of options of which at least one needs to be enabled for the option to be editable
30 * @property-read integer $supportI18n is `1` if the option supports different values for all available languages, otherwise `0`
31 * @property-read integer $requireI18n is `1` if `$supportI18n = 1` and the option's value has to explicitly set for all values so that the `monolingual` option is not available, otherwise `0`
32 * @property-read array $additionalData array with additional data of the option
33 */
34 class Option extends DatabaseObject {
35 use TDatabaseObjectOptions;
36 use TDatabaseObjectPermissions;
37
38 /**
39 * @inheritDoc
40 */
41 public function __get($name) {
42 $value = parent::__get($name);
43
44 // treat additional data as data variables if it is an array
45 if ($value === null) {
46 if (is_array($this->data['additionalData']) && isset($this->data['additionalData'][$name])) {
47 $value = $this->data['additionalData'][$name];
48 }
49 }
50
51 return $value;
52 }
53
54 /**
55 * @inheritDoc
56 */
57 protected function handleData($data) {
58 parent::handleData($data);
59
60 // unserialize additional data
61 $this->data['additionalData'] = (empty($data['additionalData']) ? [] : @unserialize($data['additionalData']));
62 }
63
64 /**
65 * Returns a list of options.
66 *
67 * @return Option[]
68 */
69 public static function getOptions() {
70 $sql = "SELECT *
71 FROM wcf".WCF_N."_option";
72 $statement = WCF::getDB()->prepareStatement($sql);
73 $statement->execute();
74
75 $options = [];
76 while ($row = $statement->fetchArray()) {
77 $option = new Option(null, $row);
78 $options[$option->getConstantName()] = $option;
79 }
80
81 return $options;
82 }
83
84 /**
85 * Returns the option with the given name or `null` if no such option exists.
86 *
87 * @param string $optionName name of the requested option
88 * @return Option|null requested option
89 */
90 public static function getOptionByName($optionName) {
91 $sql = "SELECT *
92 FROM wcf".WCF_N."_option
93 WHERE optionName = ?";
94 $statement = WCF::getDB()->prepareStatement($sql);
95 $statement->execute([$optionName]);
96
97 return $statement->fetchObject(self::class);
98 }
99
100 /**
101 * Parses enableOptions.
102 *
103 * @param string $optionData
104 * @return array
105 */
106 public static function parseEnableOptions($optionData) {
107 $disableOptions = $enableOptions = '';
108
109 if (!empty($optionData)) {
110 $options = explode(',', $optionData);
111
112 foreach ($options as $item) {
113 if ($item{0} == '!') {
114 if (!empty($disableOptions)) $disableOptions .= ',';
115 $disableOptions .= "'".mb_substr($item, 1)."' ";
116 }
117 else {
118 if (!empty($enableOptions)) $enableOptions .= ',';
119 $enableOptions .= "'".$item."' ";
120 }
121 }
122 }
123
124 return [
125 'disableOptions' => $disableOptions,
126 'enableOptions' => $enableOptions
127 ];
128 }
129
130 /**
131 * Returns a list of the available options.
132 *
133 * @return array
134 */
135 public function parseSelectOptions() {
136 $result = [];
137 $options = explode("\n", StringUtil::trim(StringUtil::unifyNewlines($this->selectOptions)));
138 foreach ($options as $option) {
139 $key = $value = $option;
140 if (mb_strpos($option, ':') !== false) {
141 $optionData = explode(':', $option);
142 $key = array_shift($optionData);
143 $value = implode(':', $optionData);
144 }
145
146 $result[$key] = $value;
147 }
148
149 return $result;
150 }
151
152 /**
153 * Returns a list of the enable options.
154 *
155 * @return array
156 */
157 public function parseMultipleEnableOptions() {
158 $result = [];
159 if (!empty($this->enableOptions)) {
160 $options = explode("\n", StringUtil::trim(StringUtil::unifyNewlines($this->enableOptions)));
161 $key = -1;
162 foreach ($options as $option) {
163 if (mb_strpos($option, ':') !== false) {
164 $optionData = explode(':', $option);
165 $key = array_shift($optionData);
166 $value = implode(':', $optionData);
167 }
168 else {
169 $key++;
170 $value = $option;
171 }
172
173 $result[$key] = $value;
174 }
175 }
176
177 return $result;
178 }
179
180 /**
181 * Returns true if option is visible
182 *
183 * @return boolean
184 */
185 public function isVisible() {
186 return !$this->hidden;
187 }
188
189 /**
190 * @inheritDoc
191 */
192 public static function getDatabaseTableAlias() {
193 return 'option_table';
194 }
195
196 /**
197 * Returns the constant name.
198 *
199 * @return string
200 */
201 public function getConstantName() {
202 return strtoupper($this->optionName);
203 }
204
205 /**
206 * Allows modifications of select options.
207 *
208 * @param string $selectOptions
209 */
210 public function modifySelectOptions($selectOptions) {
211 $this->data['selectOptions'] = $selectOptions;
212 }
213
214 /**
215 * Allows modifications of enable options.
216 *
217 * @param string $enableOptions
218 */
219 public function modifyEnableOptions($enableOptions) {
220 $this->data['enableOptions'] = $enableOptions;
221 }
222
223 /**
224 * Allows modifications of hidden option.
225 *
226 * @param string $hiddenOption
227 */
228 public function modifyHiddenOption($hiddenOption) {
229 $this->data['hidden'] = $hiddenOption;
230 }
231 }