/
class.sectionmanager.php
430 lines (389 loc) · 15.3 KB
/
class.sectionmanager.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
<?php
/**
* @package toolkit
*/
/**
* The `SectionManager` is responsible for managing all Sections in a Symphony
* installation by exposing basic CRUD operations. Sections are stored in the
* database in `tbl_sections`.
*/
class SectionManager
{
/**
* An array of all the objects that the Manager is responsible for.
*
* @var array
* Defaults to an empty array.
*/
protected static $_pool = array();
/**
* Takes an associative array of Section settings and creates a new
* entry in the `tbl_sections` table, returning the ID of the Section.
* The ID of the section is generated using auto_increment and returned
* as the Section ID.
*
* @param array $settings
* An associative of settings for a section with the key being
* a column name from `tbl_sections`
* @throws DatabaseException
* @return integer
* The newly created Section's ID
*/
public static function add(array $settings)
{
$defaults = array();
$defaults['creation_date'] = $defaults['modification_date'] = DateTimeObj::get('Y-m-d H:i:s');
$defaults['creation_date_gmt'] = $defaults['modification_date_gmt'] = DateTimeObj::getGMT('Y-m-d H:i:s');
$defaults['author_id'] = 1;
$defaults['modification_author_id'] = 1;
$settings = array_replace($defaults, $settings);
if (!Symphony::Database()->insert($settings, 'tbl_sections')) {
return false;
}
return Symphony::Database()->getInsertID();
}
/**
* Updates an existing Section given it's ID and an associative
* array of settings. The array does not have to contain all the
* settings for the Section as there is no deletion of settings
* prior to updating the Section
*
* @param integer $section_id
* The ID of the Section to edit
* @param array $settings
* An associative of settings for a section with the key being
* a column name from `tbl_sections`
* @throws DatabaseException
* @return boolean
*/
public static function edit($section_id, array $settings)
{
$defaults = array();
$defaults['modification_date'] = DateTimeObj::get('Y-m-d H:i:s');
$defaults['modification_date_gmt'] = DateTimeObj::getGMT('Y-m-d H:i:s');
$defaults['author_id'] = 1;
$defaults['modification_author_id'] = 1;
$settings = array_replace($defaults, $settings);
if (!Symphony::Database()->update($settings, 'tbl_sections', sprintf(" `id` = %d", $section_id))) {
return false;
}
return true;
}
/**
* Deletes a Section by Section ID, removing all entries, fields, the
* Section and any Section Associations in that order
*
* @param integer $section_id
* The ID of the Section to delete
* @throws DatabaseException
* @throws Exception
* @return boolean
* Returns true when completed
*/
public static function delete($section_id)
{
$details = Symphony::Database()->fetchRow(0, sprintf("
SELECT `sortorder` FROM tbl_sections WHERE `id` = %d",
$section_id
));
// Delete all the entries
$entries = Symphony::Database()->fetchCol('id', "SELECT `id` FROM `tbl_entries` WHERE `section_id` = '$section_id'");
EntryManager::delete($entries);
// Delete all the fields
$fields = FieldManager::fetch(null, $section_id);
if (is_array($fields) && !empty($fields)) {
foreach ($fields as $field) {
FieldManager::delete($field->get('id'));
}
}
// Delete the section
Symphony::Database()->delete('tbl_sections', sprintf("
`id` = %d", $section_id
));
// Update the sort orders
Symphony::Database()->query(sprintf("
UPDATE tbl_sections
SET `sortorder` = (`sortorder` - 1)
WHERE `sortorder` > %d",
$details['sortorder']
));
// Delete the section associations
Symphony::Database()->delete('tbl_sections_association', sprintf("
`parent_section_id` = %d", $section_id
));
return true;
}
/**
* Returns a Section object by ID, or returns an array of Sections
* if the Section ID was omitted. If the Section ID is omitted, it is
* possible to sort the Sections by providing a sort order and sort
* field. By default, Sections will be order in ascending order by
* their name
*
* @param integer|array $section_id
* The ID of the section to return, or an array of ID's. Defaults to null
* @param string $order
* If `$section_id` is omitted, this is the sortorder of the returned
* objects. Defaults to ASC, other options id DESC
* @param string $sortfield
* The name of the column in the `tbl_sections` table to sort
* on. Defaults to name
* @throws DatabaseException
* @return Section|array
* A Section object or an array of Section objects
*/
public static function fetch($section_id = null, $order = 'ASC', $sortfield = 'name')
{
$returnSingle = false;
$section_ids = array();
if (!is_null($section_id)) {
if (!is_array($section_id)) {
$returnSingle = true;
$section_ids = array($section_id);
} else {
$section_ids = $section_id;
}
}
if ($returnSingle && isset(self::$_pool[$section_id])) {
return self::$_pool[$section_id];
}
// Ensure they are always an ID
$section_ids = array_map('intval', $section_ids);
$sql = sprintf(
"SELECT `s`.*
FROM `tbl_sections` AS `s`
%s
%s",
!empty($section_id) ? " WHERE `s`.`id` IN (" . implode(',', $section_ids) . ") " : "",
empty($section_id) ? " ORDER BY `s`.`$sortfield` $order" : ""
);
if (!$sections = Symphony::Database()->fetch($sql)) {
return ($returnSingle ? false : array());
}
$ret = array();
foreach ($sections as $s) {
$obj = self::create();
foreach ($s as $name => $value) {
$obj->set($name, $value);
}
$obj->set('creation_date', DateTimeObj::get('c', $obj->get('creation_date')));
if (!empty($obj->get('modification_date'))) {
$obj->set('modification_date', DateTimeObj::get('c', $obj->get('modification_date')));
} else {
$obj->set('modification_date', $obj->get('creation_date'));
}
self::$_pool[$obj->get('id')] = $obj;
$ret[] = $obj;
}
return (count($ret) == 1 && $returnSingle ? $ret[0] : $ret);
}
/**
* Return a Section ID by the handle
*
* @param string $handle
* The handle of the section
* @return integer
* The Section ID
*/
public static function fetchIDFromHandle($handle)
{
return Symphony::Database()->fetchVar('id', 0, "SELECT `id` FROM `tbl_sections` WHERE `handle` = '$handle' LIMIT 1");
}
/**
* Work out the next available sort order for a new section
*
* @return integer
* Returns the next sort order
*/
public static function fetchNextSortOrder()
{
$next = Symphony::Database()->fetchVar(
"next",
0,
"SELECT
MAX(p.sortorder) + 1 AS `next`
FROM
`tbl_sections` AS p
LIMIT 1"
);
return ($next ? (int)$next : 1);
}
/**
* Returns a new Section object, using the SectionManager
* as the Section's $parent.
*
* @return Section
*/
public static function create()
{
$obj = new Section;
return $obj;
}
/**
* Create an association between a section and a field.
*
* @since Symphony 2.3
* @param integer $parent_section_id
* The linked section id.
* @param integer $child_field_id
* The field ID of the field that is creating the association
* @param integer $parent_field_id (optional)
* The field ID of the linked field in the linked section
* @param boolean $show_association (optional)
* Whether of not the link should be shown on the entries table of the
* linked section. This defaults to true.
* @throws DatabaseException
* @throws Exception
* @return boolean
* true if the association was successfully made, false otherwise.
*/
public static function createSectionAssociation($parent_section_id = null, $child_field_id = null, $parent_field_id = null, $show_association = true, $interface = null, $editor = null)
{
if (is_null($parent_section_id) && (is_null($parent_field_id) || !$parent_field_id)) {
return false;
}
if (is_null($parent_section_id)) {
$parent_field = FieldManager::fetch($parent_field_id);
$parent_section_id = $parent_field->get('parent_section');
}
$child_field = FieldManager::fetch($child_field_id);
$child_section_id = $child_field->get('parent_section');
$fields = array(
'parent_section_id' => $parent_section_id,
'parent_section_field_id' => $parent_field_id,
'child_section_id' => $child_section_id,
'child_section_field_id' => $child_field_id,
'hide_association' => ($show_association ? 'no' : 'yes'),
'interface' => $interface,
'editor' => $editor
);
return Symphony::Database()->insert($fields, 'tbl_sections_association');
}
/**
* Permanently remove a section association for this field in the database.
*
* @since Symphony 2.3
* @param integer $field_id
* the field ID of the linked section's linked field.
* @throws DatabaseException
* @return boolean
*/
public static function removeSectionAssociation($field_id)
{
return Symphony::Database()->delete('tbl_sections_association', sprintf(
'`child_section_field_id` = %1$d OR `parent_section_field_id` = %1$d',
$field_id
));
}
/**
* Returns the association settings for the given field id. This is to be used
* when configuring the field so we can correctly show the association setting
* the UI.
*
* @since Symphony 2.6.0
* @param integer $field_id
* @return string
*/
public static function getSectionAssociationSetting($field_id)
{
// We must inverse the setting. The database stores 'hide', whereas the UI
// refers to 'show'. Hence if the database says 'yes', it really means, hide
// the association. In the UI, this needs to be flipped to 'no' so the checkbox
// won't be checked.
return Symphony::Database()->fetchVar('show_association', 0, sprintf('
SELECT
CASE hide_association WHEN "no" THEN "yes" ELSE "no" END as show_association
FROM `tbl_sections_association`
WHERE `child_section_field_id` = %d
', $field_id));
}
/**
* Returns any section associations this section has with other sections
* linked using fields. Has an optional parameter, `$respect_visibility` that
* will only return associations that are deemed visible by a field that
* created the association. eg. An articles section may link to the authors
* section, but the field that links these sections has hidden this association
* so an Articles column will not appear on the Author's Publish Index
*
* @deprecated This function will be removed in Symphony 3.0. Use `fetchChildAssociations` instead.
* @since Symphony 2.3
* @param integer $section_id
* The ID of the section
* @param boolean $respect_visibility
* Whether to return all the section associations regardless of if they
* are deemed visible or not. Defaults to false, which will return all
* associations.
* @return array
*/
public static function fetchAssociatedSections($section_id, $respect_visibility = false)
{
if (Symphony::Log()) {
Symphony::Log()->pushDeprecateWarningToLog('SectionManager::fetchAssociatedSections()', 'SectionManager::fetchChildAssociations()');
}
self::fetchChildAssociations($section_id, $respect_visibility);
}
/**
* Returns any section associations this section has with other sections
* linked using fields, and where this section is the parent in the association.
* Has an optional parameter, `$respect_visibility` that
* will only return associations that are deemed visible by a field that
* created the association. eg. An articles section may link to the authors
* section, but the field that links these sections has hidden this association
* so an Articles column will not appear on the Author's Publish Index
*
* @since Symphony 2.3.3
* @param integer $section_id
* The ID of the section
* @param boolean $respect_visibility
* Whether to return all the section associations regardless of if they
* are deemed visible or not. Defaults to false, which will return all
* associations.
* @throws DatabaseException
* @return array
*/
public static function fetchChildAssociations($section_id, $respect_visibility = false)
{
return Symphony::Database()->fetch(sprintf("
SELECT *
FROM `tbl_sections_association` AS `sa`, `tbl_sections` AS `s`
WHERE `sa`.`parent_section_id` = %d
AND `s`.`id` = `sa`.`child_section_id`
%s
ORDER BY `s`.`sortorder` ASC",
$section_id,
($respect_visibility) ? "AND `sa`.`hide_association` = 'no'" : ""
));
}
/**
* Returns any section associations this section has with other sections
* linked using fields, and where this section is the child in the association.
* Has an optional parameter, `$respect_visibility` that
* will only return associations that are deemed visible by a field that
* created the association. eg. An articles section may link to the authors
* section, but the field that links these sections has hidden this association
* so an Articles column will not appear on the Author's Publish Index
*
* @since Symphony 2.3.3
* @param integer $section_id
* The ID of the section
* @param boolean $respect_visibility
* Whether to return all the section associations regardless of if they
* are deemed visible or not. Defaults to false, which will return all
* associations.
* @throws DatabaseException
* @return array
*/
public static function fetchParentAssociations($section_id, $respect_visibility = false)
{
return Symphony::Database()->fetch(sprintf(
"SELECT *
FROM `tbl_sections_association` AS `sa`, `tbl_sections` AS `s`
WHERE `sa`.`child_section_id` = %d
AND `s`.`id` = `sa`.`parent_section_id`
%s
ORDER BY `s`.`sortorder` ASC",
$section_id,
($respect_visibility) ? "AND `sa`.`hide_association` = 'no'" : ""
));
}
}