]> git.agnieray.net Git - galette.git/blob - galette/lib/Galette/Entity/ListsConfig.php
No longer need for a short text for birthdate
[galette.git] / galette / lib / Galette / Entity / ListsConfig.php
1 <?php
2
3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5 /**
6 * Lists config handling
7 *
8 * PHP version 5
9 *
10 * Copyright © 2020-2023 The Galette Team
11 *
12 * This file is part of Galette (http://galette.tuxfamily.org).
13 *
14 * Galette is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * Galette is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
26 *
27 * @category Entity
28 * @package Galette
29 *
30 * @author Johan Cwiklinski <johan@x-tnd.be>
31 * @copyright 2020-2023 The Galette Team
32 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
33 * @link http://galette.tuxfamily.org
34 * @since Available since 0.9.4dev - 2020-05-13
35 */
36
37 namespace Galette\Entity;
38
39 use ArrayObject;
40 use stdClass;
41 use Throwable;
42 use Analog\Analog;
43 use Galette\Core\Login;
44 use Galette\Core\Authentication;
45
46 /**
47 * Lists config class for galette:
48 * defines fields order and visibility
49 *
50 * @category Entity
51 * @name FieldsConfig
52 * @package Galette
53 * @author Johan Cwiklinski <johan@x-tnd.be>
54 * @copyright 2020-2023 The Galette Team
55 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
56 * @link http://galette.tuxfamily.org
57 * @since Available since 0.9.4dev - 2020-05-13
58 */
59 class ListsConfig extends FieldsConfig
60 {
61 protected $listed_fields = array();
62
63 /**
64 * Fields that are not part of lists
65 *
66 * @var array
67 */
68 private $non_list_elements = array(
69 'mdp_adh',
70 'info_adh',
71 'info_public_adh',
72 'nom_adh',
73 'prenom_adh'
74 );
75
76 /**
77 * ACL mapping for list elements not present in form configuration
78 *
79 * @var array
80 */
81 private $acl_mapping = array(
82 'list_adh_name' => 'nom_adh',
83 'list_adh_contribstatus' => 'id_statut'
84 );
85
86 /**
87 * Prepare a field (required data, automation)
88 *
89 * @param ArrayObject $rset DB ResultSet row
90 *
91 * @return array
92 */
93 protected function buildField(ArrayObject $rset): array
94 {
95 $f = parent::buildField($rset);
96 $f['list_position'] = (int)$rset->list_position;
97 $f['list_visible'] = ($f['list_position'] >= 0);
98 return $f;
99 }
100
101 /**
102 * Create field array configuration,
103 * Several lists of fields are kept (visible, requireds, etc), build them.
104 *
105 * @return void
106 */
107 protected function buildLists()
108 {
109 //Specific list fields does not have rights; fix this from mapping
110 //Cannot be done preparing fields, cannot be sure of the order it is processed
111 foreach ($this->acl_mapping as $list_key => $field_key) {
112 $this->core_db_fields[$list_key]['visible'] = $this->core_db_fields[$field_key]['visible'];
113 }
114
115 //handle parent field: is always inactive on form. Hardcode to STAFF.
116 if (isset($this->core_db_fields['parent_id'])) {
117 $this->core_db_fields['parent_id']['visible'] = self::STAFF;
118 }
119
120 parent::buildLists();
121 //make sure array order is the same as in the database, since query is ordered differently
122 ksort($this->listed_fields);
123 }
124
125 /**
126 * Adds a field to lists
127 *
128 * @param array $field Field values
129 *
130 * @return void
131 */
132 protected function addToLists(array $field)
133 {
134 if (in_array($field['field_id'], $this->non_list_elements)) {
135 return;
136 }
137 parent::addToLists($field);
138
139 if ($field['list_visible'] ?? false) {
140 $this->listed_fields[(int)$field['list_position']] = $field;
141 }
142 }
143
144 /**
145 * Retrieve display elements
146 *
147 * @param Login $login Login instance
148 *
149 * @return array
150 */
151 public function getDisplayElements(Login $login)
152 {
153 global $preferences;
154
155 $display_elements = [];
156 $access_level = $login->getAccessLevel();
157 try {
158 $elements = $this->listed_fields;
159
160 foreach ($elements as $elt) {
161 $o = (object)$elt;
162 $this->handleLabel($o);
163
164 if ($o->field_id == 'id_adh') {
165 // ignore access control, as member ID is always needed
166 //if (!isset($preferences) || !$preferences->pref_show_id) {
167 $o->type = self::TYPE_STR;
168 $display_elements[] = $o;
169 //}
170 } else {
171 // skip fields blacklisted for display
172 if (in_array($o->field_id, $this->non_list_elements)) {
173 continue;
174 }
175
176 // skip fields according to access control
177 if (
178 $o->visible == self::NOBODY ||
179 ($o->visible == self::ADMIN &&
180 $access_level < Authentication::ACCESS_ADMIN) ||
181 ($o->visible == self::STAFF &&
182 $access_level < Authentication::ACCESS_STAFF) ||
183 ($o->visible == self::MANAGER &&
184 $access_level < Authentication::ACCESS_MANAGER)
185 ) {
186 continue;
187 }
188 $display_elements[] = $o;
189 }
190 }
191
192 return $display_elements;
193 } catch (Throwable $e) {
194 Analog::log(
195 'An error occurred getting list elements to display',
196 Analog::ERROR
197 );
198 throw $e;
199 }
200 }
201
202 /**
203 * Handle list labels
204 *
205 * @param stdClass $field Field data
206 *
207 * @return stdClass
208 */
209 private function handleLabel($field)
210 {
211 switch ($field->field_id) {
212 case 'bool_admin_adh':
213 $field->label = __('Is admin');
214 break;
215 case 'date_modif_adh':
216 $field->label = _T('Modified');
217 break;
218 case 'tel_adh':
219 $field->label = _T('Phone');
220 break;
221 case 'bool_display_info':
222 $field->label = _T('Public');
223 break;
224 }
225
226 $field->label = trim(str_replace('&nbsp;', ' ', $field->label));
227 $field->label = preg_replace('/\s?:$/', '', $field->label);
228
229 return $field;
230 }
231
232 /**
233 * Get all fields for list
234 *
235 * @return array
236 */
237 public function getListedFields(): array
238 {
239 return $this->listed_fields;
240 }
241
242 /**
243 * Get remaining free fields for list
244 *
245 * @return array
246 */
247 public function getRemainingFields(): array
248 {
249 $db_fields = $this->core_db_fields;
250
251 //remove non list
252 foreach ($this->non_list_elements as $todrop) {
253 unset($db_fields[$todrop]);
254 }
255
256 //remove already listed
257 foreach ($this->listed_fields as $listed) {
258 unset($db_fields[$listed['field_id']]);
259 }
260
261 $remainings = [];
262 foreach ($db_fields as $key => $db_field) {
263 $remainings[$key] = $db_field;
264 }
265
266 return $remainings;
267 }
268
269 /**
270 * Set fields
271 *
272 * @param array $fields categorized fields array
273 *
274 * @return boolean
275 */
276 public function setListFields($fields)
277 {
278 $this->listed_fields = $fields;
279 return $this->storeList();
280 }
281
282 /**
283 * Store list config in database
284 *
285 * @return boolean
286 */
287 private function storeList()
288 {
289 $class = get_class($this);
290
291 try {
292 if (!count($this->listed_fields)) {
293 throw new \RuntimeException('No fields for list, aborting.');
294 }
295
296 $this->zdb->connection->beginTransaction();
297
298 $update = $this->zdb->update(self::TABLE);
299 $update->set(
300 array(
301 'list_visible' => ':list_visible',
302 'list_position' => ':list_position'
303 )
304 )->where(
305 array(
306 'field_id' => ':field_id',
307 'table_name' => $this->table
308 )
309 );
310 $stmt = $this->zdb->sql->prepareStatementForSqlObject($update);
311
312 $params = null;
313
314 foreach ($this->listed_fields as $pos => $field) {
315 $params = array(
316 'list_visible' => $field['list_visible'],
317 'list_position' => $pos,
318 'field_id' => $field['field_id']
319 );
320 $stmt->execute($params);
321 }
322
323 foreach (array_keys($this->getRemainingFields()) as $field) {
324 $params = array(
325 'list_visible' => $this->zdb->isPostgres() ? 'false' : 0,
326 'list_position' => -1,
327 'field_id' => $field
328 );
329 $stmt->execute($params);
330 }
331
332 Analog::log(
333 str_replace(
334 '%s',
335 $this->table,
336 '[' . $class . '] List configuration for table %s stored ' .
337 'successfully.'
338 ),
339 Analog::INFO
340 );
341
342 $this->zdb->connection->commit();
343 return $this->load();
344 } catch (Throwable $e) {
345 $this->zdb->connection->rollBack();
346 Analog::log(
347 '[' . $class . '] An error occurred while storing list ' .
348 'configuration for table `' . $this->table . '`.' .
349 $e->getMessage(),
350 Analog::ERROR
351 );
352 throw $e;
353 }
354 }
355
356 /**
357 * Get ACL mapping for list elements not present in form configuration
358 *
359 * @return array
360 */
361 public function getAclMapping(): array
362 {
363 return $this->acl_mapping;
364 }
365
366 /**
367 * Get visibility for specified field
368 *
369 * @param string $field The requested field
370 *
371 * @return integer
372 */
373 public function getVisibility($field)
374 {
375 if (in_array($field, $this->non_list_elements)) {
376 return self::NOBODY;
377 }
378 return $this->all_visibles[$field];
379 }
380 }