GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

PageManager   F
last analyzed

Complexity

Total Complexity 89

Size/Duplication

Total Lines 956
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 270
c 1
b 0
f 0
dl 0
loc 956
rs 2
wmc 89

33 Methods

Rating   Name   Duplication   Size   Complexity  
A resolvePageFileLocation() 0 3 1
A isDataSourceUsed() 0 3 1
A isEventUsed() 0 3 1
A writePageFiles() 0 3 1
A createFilePath() 0 3 1
A add() 0 11 3
A getChildPagesCount() 0 18 4
A fetchAvailablePageTypes() 0 7 2
A fetchPageByID() 0 21 5
A resolvePageTitle() 0 5 1
A resolvePagePath() 0 5 1
A resolvePage() 0 45 4
A edit() 0 19 5
A editPageChildren() 0 27 5
A hasChildPages() 0 11 1
A fetchIDFromHandle() 0 8 1
A fetchTitleFromHandle() 0 8 1
A createPageFiles() 0 51 5
A fetchPageTypes() 0 14 2
A deletePageTypes() 0 7 2
A __buildTreeView() 0 11 4
A resolvePageByPath() 0 6 2
A fetchChildPages() 0 13 3
A addPageTypesToPage() 0 19 3
A fetchAllPagesPageTypes() 0 12 3
A hasPageTypeBeenUsed() 0 13 1
B fetch() 0 43 9
A delete() 0 35 5
A fetchPageByType() 0 19 3
A deletePageFiles() 0 15 3
A getTemplate() 0 10 3
A fetchNextSortOrder() 0 13 2
A createHandle() 0 5 1

How to fix   Complexity   

Complex Class

Complex classes like PageManager often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use PageManager, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * @package toolkit
5
 */
6
/**
7
 * The `PageManager` class is responsible for providing basic CRUD operations
8
 * for Symphony frontend pages. These pages are stored in the database in
9
 * `tbl_pages` and are resolved to an instance of `FrontendPage` class from a URL.
10
 * Additionally, this manager provides functions to access the Page's types,
11
 * and any linked datasources or events.
12
 *
13
 * @since Symphony 2.3
14
 */
15
class PageManager
16
{
17
    /**
18
     * Given an associative array of data, where the key is the column name
19
     * in `tbl_pages` and the value is the data, this function will create a new
20
     * Page and return a Page ID on success.
21
     *
22
     * @param array $fields
23
     *  Associative array of field names => values for the Page
24
     * @throws DatabaseException
25
     * @return integer|boolean
26
     *  Returns the Page ID of the created Page on success, false otherwise.
27
     */
28
    public static function add(array $fields)
29
    {
30
        if (!isset($fields['sortorder'])) {
31
            $fields['sortorder'] = self::fetchNextSortOrder();
32
        }
33
34
        if (!Symphony::Database()->insert($fields, 'tbl_pages')) {
35
            return false;
36
        }
37
38
        return Symphony::Database()->getInsertID();
39
    }
40
41
    /**
42
     * Return a Page title by the handle
43
     *
44
     * @param string $handle
45
     *  The handle of the page
46
     * @return integer
47
     *  The Page title
48
     */
49
    public static function fetchTitleFromHandle($handle)
50
    {
51
        return Symphony::Database()->fetchVar('title', 0, sprintf(
0 ignored issues
show
Bug Best Practice introduced by
The expression return Symphony::Databas...->cleanValue($handle))) also could return the type string which is incompatible with the documented return type integer.
Loading history...
52
            "SELECT `title`
53
            FROM `tbl_pages`
54
            WHERE `handle` = '%s'
55
            LIMIT 1",
56
            Symphony::Database()->cleanValue($handle)
57
        ));
58
    }
59
60
    /**
61
     * Return a Page ID by the handle
62
     *
63
     * @param string $handle
64
     *  The handle of the page
65
     * @return integer
66
     *  The Page ID
67
     */
68
    public static function fetchIDFromHandle($handle)
69
    {
70
        return Symphony::Database()->fetchVar('id', 0, sprintf(
0 ignored issues
show
Bug Best Practice introduced by
The expression return Symphony::Databas...->cleanValue($handle))) also could return the type string which is incompatible with the documented return type integer.
Loading history...
71
            "SELECT `id`
72
            FROM `tbl_pages`
73
            WHERE `handle` = '%s'
74
            LIMIT 1",
75
            Symphony::Database()->cleanValue($handle)
76
        ));
77
    }
78
79
    /**
80
     * Given a Page ID and an array of types, this function will add Page types
81
     * to that Page. If a Page types are stored in `tbl_pages_types`.
82
     *
83
     * @param integer $page_id
84
     *  The Page ID to add the Types to
85
     * @param array $types
86
     *  An array of page types
87
     * @throws DatabaseException
88
     * @return boolean
89
     */
90
    public static function addPageTypesToPage($page_id = null, array $types)
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$page_id" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$page_id"; expected 0 but found 1
Loading history...
Coding Style introduced by
Parameters which have default values should be placed at the end.

If you place a parameter with a default value before a parameter with a default value, the default value of the first parameter will never be used as it will always need to be passed anyway:

// $a must always be passed; it's default value is never used.
function someFunction($a = 5, $b) { }
Loading history...
91
    {
92
        if (is_null($page_id)) {
93
            return false;
94
        }
95
96
        PageManager::deletePageTypes($page_id);
97
98
        foreach ($types as $type) {
99
            Symphony::Database()->insert(
100
                array(
101
                    'page_id' => $page_id,
102
                    'type' => $type
103
                ),
104
                'tbl_pages_types'
105
            );
106
        }
107
108
        return true;
109
    }
110
111
112
    /**
113
     * Returns the path to the page-template by looking at the
114
     * `WORKSPACE/template/` directory, then at the `TEMPLATES`
115
     * directory for `$name.xsl`. If the template is not found,
116
     * false is returned
117
     *
118
     * @param string $name
119
     *  Name of the template
120
     * @return mixed
121
     *  String, which is the path to the template if the template is found,
122
     *  false otherwise
123
     */
124
    public static function getTemplate($name)
125
    {
126
        $format = '%s/%s.xsl';
127
128
        if (file_exists($template = sprintf($format, WORKSPACE . '/template', $name))) {
0 ignored issues
show
Bug introduced by
The constant WORKSPACE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
129
            return $template;
130
        } elseif (file_exists($template = sprintf($format, TEMPLATE, $name))) {
0 ignored issues
show
Bug introduced by
The constant TEMPLATE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
131
            return $template;
132
        } else {
133
            return false;
134
        }
135
    }
136
137
    /**
138
     * This function creates the initial `.xsl` template for the page, whether
139
     * that be from the `TEMPLATES/blueprints.page.xsl` file, or from an existing
140
     * template with the same name. This function will handle the renaming of a page
141
     * by creating the new files using the old files as the templates then removing
142
     * the old template. If a template already exists for a Page, it will not
143
     * be overridden and the function will return true.
144
     *
145
     * @see toolkit.PageManager#resolvePageFileLocation()
146
     * @see toolkit.PageManager#createHandle()
147
     * @param string $new_path
148
     *  The path of the Page, which is the handles of the Page parents. If the
149
     *  page has multiple parents, they will be separated by a forward slash.
150
     *  eg. article/read. If a page has no parents, this parameter should be null.
151
     * @param string $new_handle
152
     *  The new Page handle, generated using `PageManager::createHandle`.
153
     * @param string $old_path (optional)
154
     *  This parameter is only required when renaming a Page. It should be the 'old
155
     *  path' before the Page was renamed.
156
     * @param string $old_handle (optional)
157
     *  This parameter is only required when renaming a Page. It should be the 'old
158
     *  handle' before the Page was renamed.
159
     * @throws Exception
160
     * @return boolean
161
     *  true when the page files have been created successfully, false otherwise.
162
     */
163
    public static function createPageFiles($new_path, $new_handle, $old_path = null, $old_handle = null)
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$old_path" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$old_path"; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between argument "$old_handle" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$old_handle"; expected 0 but found 1
Loading history...
164
    {
165
        $new = PageManager::resolvePageFileLocation($new_path, $new_handle);
166
        $old = PageManager::resolvePageFileLocation($old_path, $old_handle);
167
168
        // Nothing to do:
169
        if (file_exists($new) && $new == $old) {
170
            return true;
171
        }
172
173
        // Old file doesn't exist, use template:
174
        if (!file_exists($old)) {
175
            $data = file_get_contents(self::getTemplate('blueprints.page'));
0 ignored issues
show
Bug introduced by
It seems like self::getTemplate('blueprints.page') can also be of type false; however, parameter $filename of file_get_contents() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

175
            $data = file_get_contents(/** @scrutinizer ignore-type */ self::getTemplate('blueprints.page'));
Loading history...
176
        } else {
177
            $data = file_get_contents($old);
178
        }
179
180
        /**
181
         * Just before a Page Template is about to be created & written to disk
182
         *
183
         * @delegate PageTemplatePreCreate
184
         * @since Symphony 2.2.2
185
         * @param string $context
186
         * '/blueprints/pages/'
187
         * @param string $file
188
         *  The path to the Page Template file
189
         * @param string $contents
190
         *  The contents of the `$data`, passed by reference
191
         */
192
        Symphony::ExtensionManager()->notifyMembers('PageTemplatePreCreate', '/blueprints/pages/', array('file' => $new, 'contents' => &$data));
193
194
        if (PageManager::writePageFiles($new, $data)) {
195
            // Remove the old file, in the case of a rename
196
            General::deleteFile($old);
197
198
            /**
199
             * Just after a Page Template is saved after been created.
200
             *
201
             * @delegate PageTemplatePostCreate
202
             * @since Symphony 2.2.2
203
             * @param string $context
204
             * '/blueprints/pages/'
205
             * @param string $file
206
             *  The path to the Page Template file
207
             */
208
            Symphony::ExtensionManager()->notifyMembers('PageTemplatePostCreate', '/blueprints/pages/', array('file' => $new));
209
210
            return true;
211
        }
212
213
        return false;
214
    }
215
216
    /**
217
     * A wrapper for `General::writeFile`, this function takes a `$path`
218
     * and a `$data` and writes the new template to disk.
219
     *
220
     * @param string $path
221
     *  The path to write the template to
222
     * @param string $data
223
     *  The contents of the template
224
     * @return boolean
225
     *  true when written successfully, false otherwise
226
     */
227
    public static function writePageFiles($path, $data)
228
    {
229
        return General::writeFile($path, $data, Symphony::Configuration()->get('write_mode', 'file'));
0 ignored issues
show
Bug introduced by
It seems like Symphony::Configuration(...t('write_mode', 'file') can also be of type array; however, parameter $perm of General::writeFile() does only seem to accept integer|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

229
        return General::writeFile($path, $data, /** @scrutinizer ignore-type */ Symphony::Configuration()->get('write_mode', 'file'));
Loading history...
230
    }
231
232
    /**
233
     * This function will update a Page in `tbl_pages` given a `$page_id`
234
     * and an associative array of `$fields`. A third parameter, `$delete_types`
235
     * will also delete the Page's associated Page Types if passed true.
236
     *
237
     * @see toolkit.PageManager#addPageTypesToPage()
238
     * @param integer $page_id
239
     *  The ID of the Page that should be updated
240
     * @param array $fields
241
     *  Associative array of field names => values for the Page.
242
     *  This array does need to contain every value for the Page, it
243
     *  can just be the changed values.
244
     * @param boolean $delete_types
245
     *  If true, this parameter will cause the Page Types of the Page to
246
     *  be deleted. By default this is false.
247
     * @return boolean
248
     */
249
    public static function edit($page_id, array $fields, $delete_types = false)
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$delete_types" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$delete_types"; expected 0 but found 1
Loading history...
250
    {
251
        if (!is_numeric($page_id)) {
0 ignored issues
show
introduced by
The condition is_numeric($page_id) is always true.
Loading history...
252
            return false;
253
        }
254
255
        if (isset($fields['id'])) {
256
            unset($fields['id']);
257
        }
258
259
        if (Symphony::Database()->update($fields, 'tbl_pages', sprintf("`id` = %d", $page_id))) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal `id` = %d does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
260
            // If set, this will clear the page's types.
261
            if ($delete_types) {
262
                PageManager::deletePageTypes($page_id);
263
            }
264
265
            return true;
266
        } else {
267
            return false;
268
        }
269
    }
270
271
    /**
272
     * This function will update all children of a particular page (if any)
273
     * by renaming/moving all related files to their new path and updating
274
     * their database information. This is a recursive function and will work
275
     * to any depth.
276
     *
277
     * @param integer $page_id
278
     *  The ID of the Page whose children need to be updated
279
     * @param string $page_path
280
     *  The path of the Page, which is the handles of the Page parents. If the
281
     *  page has multiple parents, they will be separated by a forward slash.
282
     *  eg. article/read. If a page has no parents, this parameter should be null.
283
     * @throws Exception
284
     * @return boolean
285
     */
286
    public static function editPageChildren($page_id = null, $page_path = null)
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$page_id" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$page_id"; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between argument "$page_path" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$page_path"; expected 0 but found 1
Loading history...
287
    {
288
        if (!is_int($page_id)) {
289
            return false;
290
        }
291
292
        $page_path = trim($page_path, '/');
293
        $children = PageManager::fetchChildPages($page_id);
294
295
        foreach ($children as $child) {
296
            $child_id = (int)$child['id'];
297
            $fields = array(
298
                'path' => $page_path
299
            );
300
301
            if (!PageManager::createPageFiles($page_path, $child['handle'], $child['path'], $child['handle'])) {
302
                $success = false;
303
            }
304
305
            if (!PageManager::edit($child_id, $fields)) {
306
                $success = false;
0 ignored issues
show
Unused Code introduced by
The assignment to $success is dead and can be removed.
Loading history...
307
            }
308
309
            $success = PageManager::editPageChildren($child_id, $page_path . '/' . $child['handle']);
310
        }
311
312
        return $success;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $success seems to be defined by a foreach iteration on line 295. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
313
    }
314
315
    /**
316
     * This function takes a Page ID and removes the Page from the database
317
     * in `tbl_pages` and it's associated Page Types in `tbl_pages_types`.
318
     * This function does not delete any of the Page's children.
319
     *
320
     * @see toolkit.PageManager#deletePageTypes
321
     * @see toolkit.PageManager#deletePageFiles
322
     * @param integer $page_id
323
     *  The ID of the Page that should be deleted.
324
     * @param boolean $delete_files
325
     *  If true, this parameter will remove the Page's templates from the
326
     *  the filesystem. By default this is true.
327
     * @throws DatabaseException
328
     * @throws Exception
329
     * @return boolean
330
     */
331
    public static function delete($page_id = null, $delete_files = true)
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$page_id" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$page_id"; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between argument "$delete_files" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$delete_files"; expected 0 but found 1
Loading history...
332
    {
333
        if (!is_int($page_id)) {
334
            return false;
335
        }
336
337
        $can_proceed = true;
338
339
        // Delete Files (if told to)
340
        if ($delete_files) {
341
            $page = PageManager::fetchPageByID($page_id, array('path', 'handle'));
342
343
            if (empty($page)) {
344
                return false;
345
            }
346
347
            $can_proceed = PageManager::deletePageFiles($page['path'], $page['handle']);
348
        }
349
350
        // Delete from tbl_pages/tbl_page_types
351
        if ($can_proceed) {
352
            PageManager::deletePageTypes($page_id);
353
            Symphony::Database()->delete('tbl_pages', sprintf(" `id` = %d ", $page_id));
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal `id` = %d does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
354
            Symphony::Database()->query(sprintf(
355
                "UPDATE
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal UPDATE\n ... `sortorder` < %d does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
356
                    tbl_pages
357
                SET
358
                    `sortorder` = (`sortorder` + 1)
359
                WHERE
360
                    `sortorder` < %d",
361
                $page_id
362
            ));
363
        }
364
365
        return $can_proceed;
366
    }
367
368
    /**
369
     * Given a `$page_id`, this function will remove all associated
370
     * Page Types from `tbl_pages_types`.
371
     *
372
     * @param integer $page_id
373
     *  The ID of the Page that should be deleted.
374
     * @throws DatabaseException
375
     * @return boolean
376
     */
377
    public static function deletePageTypes($page_id = null)
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$page_id" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$page_id"; expected 0 but found 1
Loading history...
378
    {
379
        if (is_null($page_id)) {
380
            return false;
381
        }
382
383
        return Symphony::Database()->delete('tbl_pages_types', sprintf(" `page_id` = %d ", $page_id));
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal `page_id` = %d does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
384
    }
385
386
    /**
387
     * Given a Page's `$path` and `$handle`, this function will remove
388
     * it's templates from the `PAGES` directory returning boolean on
389
     * completion
390
     *
391
     * @param string $page_path
392
     *  The path of the Page, which is the handles of the Page parents. If the
393
     *  page has multiple parents, they will be separated by a forward slash.
394
     *  eg. article/read. If a page has no parents, this parameter should be null.
395
     * @param string $handle
396
     *  A Page handle, generated using `PageManager::createHandle`.
397
     * @throws Exception
398
     * @return boolean
399
     */
400
    public static function deletePageFiles($page_path, $handle)
401
    {
402
        $file = PageManager::resolvePageFileLocation($page_path, $handle);
403
404
        // Nothing to do:
405
        if (!file_exists($file)) {
406
            return true;
407
        }
408
409
        // Delete it:
410
        if (General::deleteFile($file)) {
411
            return true;
412
        }
413
414
        return false;
415
    }
416
417
    /**
418
     * This function will return an associative array of Page information. The
419
     * information returned is defined by the `$include_types` and `$select`
420
     * parameters, which will return the Page Types for the Page and allow
421
     * a developer to restrict what information is returned about the Page.
422
     * Optionally, `$where` and `$order_by` parameters allow a developer to
423
     * further refine their query.
424
     *
425
     * @param boolean $include_types
426
     *  Whether to include the resulting Page's Page Types in the return array,
427
     *  under the key `type`. Defaults to true.
428
     * @param array $select (optional)
429
     *  Accepts an array of columns to return from `tbl_pages`. If omitted,
430
     *  all columns from the table will be returned.
431
     * @param array $where (optional)
432
     *  Accepts an array of WHERE statements that will be appended with AND.
433
     *  If omitted, all pages will be returned.
434
     * @param string $order_by (optional)
435
     *  Allows a developer to return the Pages in a particular order. The string
436
     *  passed will be appended to `ORDER BY`. If omitted this will return
437
     *  Pages ordered by `sortorder`.
438
     * @param boolean $hierarchical (optional)
439
     *  If true, builds a multidimensional array representing the pages hierarchy.
440
     *  Defaults to false.
441
     * @return array|null
442
     *  An associative array of Page information with the key being the column
443
     *  name from `tbl_pages` and the value being the data. If requested, the array
444
     *  can be made multidimensional to reflect the pages hierarchy. If no Pages are
445
     *  found, null is returned.
446
     */
447
    public static function fetch($include_types = true, array $select = array(), array $where = array(), $order_by = null, $hierarchical = false)
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$include_types" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$include_types"; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between argument "$select" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$select"; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between argument "$where" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$where"; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between argument "$order_by" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$order_by"; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between argument "$hierarchical" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$hierarchical"; expected 0 but found 1
Loading history...
448
    {
449
        if ($hierarchical) {
450
            $select = array_merge($select, array('id', 'parent'));
451
        }
452
453
        if (empty($select)) {
454
            $select = array('*');
455
        }
456
457
        if (is_null($order_by)) {
458
            $order_by = 'sortorder ASC';
459
        }
460
461
        $pages = Symphony::Database()->fetch(sprintf(
462
            "SELECT
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal SELECT\n ... BY\n %s does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
463
                %s
464
            FROM
465
                `tbl_pages` AS p
466
            WHERE
467
                %s
468
            ORDER BY
469
                %s",
470
            implode(',', $select),
471
            empty($where) ? '1' : implode(' AND ', $where),
472
            $order_by
473
        ));
474
475
        // Fetch the Page Types for each page, if required
476
        if ($include_types) {
477
            foreach ($pages as &$page) {
478
                $page['type'] = PageManager::fetchPageTypes($page['id']);
479
            }
480
        }
481
482
        if ($hierarchical) {
483
            $output = array();
484
485
            self::__buildTreeView(null, $pages, $output);
0 ignored issues
show
Bug Best Practice introduced by
The method PageManager::__buildTreeView() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

485
            self::/** @scrutinizer ignore-call */ 
486
                  __buildTreeView(null, $pages, $output);
Loading history...
486
            $pages = $output;
487
        }
488
489
        return !empty($pages) ? $pages : array();
490
    }
491
492
    private function __buildTreeView($parent_id, $pages, &$results)
493
    {
494
        if (!is_array($pages)) {
495
            return;
496
        }
497
498
        foreach ($pages as $page) {
499
            if ($page['parent'] == $parent_id) {
500
                $results[] = $page;
501
502
                self::__buildTreeView($page['id'], $pages, $results[count($results) - 1]['children']);
0 ignored issues
show
Bug Best Practice introduced by
The method PageManager::__buildTreeView() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

502
                self::/** @scrutinizer ignore-call */ 
503
                      __buildTreeView($page['id'], $pages, $results[count($results) - 1]['children']);
Loading history...
503
            }
504
        }
505
    }
506
507
    /**
508
     * Returns Pages that match the given `$page_id`. Developers can optionally
509
     * choose to specify what Page information is returned using the `$select`
510
     * parameter.
511
     *
512
     * @param integer|array $page_id
513
     *  The ID of the Page, or an array of ID's
514
     * @param array $select (optional)
515
     *  Accepts an array of columns to return from `tbl_pages`. If omitted,
516
     *  all columns from the table will be returned.
517
     * @return array|null
518
     *  An associative array of Page information with the key being the column
519
     *  name from `tbl_pages` and the value being the data. If multiple Pages
520
     *  are found, an array of Pages will be returned. If no Pages are found
521
     *  null is returned.
522
     */
523
    public static function fetchPageByID($page_id = null, array $select = array())
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$page_id" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$page_id"; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between argument "$select" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$select"; expected 0 but found 1
Loading history...
524
    {
525
        if (is_null($page_id)) {
526
            return null;
527
        }
528
529
        if (!is_array($page_id)) {
530
            $page_id = array(
531
                Symphony::Database()->cleanValue($page_id)
532
            );
533
        }
534
535
        if (empty($select)) {
536
            $select = array('*');
537
        }
538
539
        $page = PageManager::fetch(true, $select, array(
540
            sprintf("id IN (%s)", implode(',', $page_id))
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal id IN (%s) does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
541
        ));
542
543
        return count($page) == 1 ? array_pop($page) : $page;
0 ignored issues
show
Coding Style introduced by
Inline shorthand IF statement requires brackets around comparison
Loading history...
544
    }
545
546
    /**
547
     * Returns Pages that match the given `$type`. If no `$type` is provided
548
     * the function returns the result of `PageManager::fetch`.
549
     *
550
     * @param string $type
551
     *  Where the type is one of the available Page Types.
552
     * @return array|null
553
     *  An associative array of Page information with the key being the column
554
     *  name from `tbl_pages` and the value being the data. If multiple Pages
555
     *  are found, an array of Pages will be returned. If no Pages are found
556
     *  null is returned.
557
     */
558
    public static function fetchPageByType($type = null)
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$type" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$type"; expected 0 but found 1
Loading history...
559
    {
560
        if (is_null($type)) {
561
            return PageManager::fetch();
562
        }
563
564
        $pages = Symphony::Database()->fetch(sprintf(
565
            "SELECT
566
                `p`.*
567
            FROM
568
                `tbl_pages` AS `p`
569
            LEFT JOIN
570
                `tbl_pages_types` AS `pt` ON (p.id = pt.page_id)
571
            WHERE
572
                `pt`.type = '%s'",
573
            Symphony::Database()->cleanValue($type)
574
        ));
575
576
        return count($pages) == 1 ? array_pop($pages) : $pages;
0 ignored issues
show
Coding Style introduced by
Inline shorthand IF statement requires brackets around comparison
Loading history...
577
    }
578
579
    /**
580
     * Returns the child Pages (if any) of the given `$page_id`.
581
     *
582
     * @param integer $page_id
583
     *  The ID of the Page.
584
     * @param array $select (optional)
585
     *  Accepts an array of columns to return from `tbl_pages`. If omitted,
586
     *  all columns from the table will be returned.
587
     * @return array|null
588
     *  An associative array of Page information with the key being the column
589
     *  name from `tbl_pages` and the value being the data. If multiple Pages
590
     *  are found, an array of Pages will be returned. If no Pages are found
591
     *  null is returned.
592
     */
593
    public static function fetchChildPages($page_id = null, array $select = array())
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$page_id" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$page_id"; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between argument "$select" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$select"; expected 0 but found 1
Loading history...
594
    {
595
        if (is_null($page_id)) {
596
            return null;
597
        }
598
599
        if (empty($select)) {
600
            $select = array('*');
601
        }
602
603
        return PageManager::fetch(false, $select, array(
604
            sprintf('id != %d', $page_id),
605
            sprintf('parent = %d', $page_id)
606
        ));
607
    }
608
609
    /**
610
     * This function returns a Page's Page Types. If the `$page_id`
611
     * parameter is given, the types returned will be for that Page.
612
     *
613
     * @param integer $page_id
614
     *  The ID of the Page.
615
     * @return array
616
     *  An array of the Page Types
617
     */
618
    public static function fetchPageTypes($page_id = null)
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$page_id" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$page_id"; expected 0 but found 1
Loading history...
619
    {
620
        return Symphony::Database()->fetchCol('type', sprintf(
621
            "SELECT
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal SELECT\n ... pt.type ASC does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
622
                type
623
            FROM
624
                `tbl_pages_types` AS pt
625
            WHERE
626
                %s
627
            GROUP BY
628
                pt.type
629
            ORDER BY
630
                pt.type ASC",
631
            (is_null($page_id) ? '1' : sprintf('pt.page_id = %d', $page_id))
632
        ));
633
    }
634
635
    /**
636
     * Returns all the page types that exist in this Symphony install.
637
     * There are 6 default system page types, and new types can be added
638
     * by Developers via the Page Editor.
639
     *
640
     * @since Symphony 2.3 introduced the JSON type.
641
     * @return array
642
     *  An array of strings of the page types used in this Symphony
643
     *  install. At the minimum, this will be an array with the values
644
     * 'index', 'XML', 'JSON', 'admin', '404' and '403'.
645
     */
646
    public static function fetchAvailablePageTypes()
647
    {
648
        $system_types = array('index', 'XML', 'JSON', 'admin', '404', '403');
649
650
        $types = PageManager::fetchPageTypes();
651
652
        return (!empty($types) ? General::array_remove_duplicates(array_merge($system_types, $types)) : $system_types);
653
    }
654
655
    /**
656
     * Work out the next available sort order for a new page
657
     *
658
     * @return integer
659
     *  Returns the next sort order
660
     */
661
    public static function fetchNextSortOrder()
662
    {
663
        $next = Symphony::Database()->fetchVar(
664
            "next",
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal next does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
665
            0,
666
            "SELECT
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal SELECT\n ... p\n LIMIT 1 does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
667
                MAX(p.sortorder) + 1 AS `next`
668
            FROM
669
                `tbl_pages` AS p
670
            LIMIT 1"
671
        );
672
673
        return ($next ? (int)$next : 1);
0 ignored issues
show
Coding Style introduced by
Inline shorthand IF statement requires brackets around comparison
Loading history...
674
    }
675
676
    /**
677
     * Fetch an associated array with Page ID's and the types they're using.
678
     *
679
     * @throws DatabaseException
680
     * @return array
681
     *  A 2-dimensional associated array where the key is the page ID.
682
     */
683
    public static function fetchAllPagesPageTypes()
684
    {
685
        $types = Symphony::Database()->fetch("SELECT `page_id`,`type` FROM `tbl_pages_types`");
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal SELECT `page_id`,`type` FROM `tbl_pages_types` does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
686
        $page_types = array();
687
688
        if (is_array($types)) {
0 ignored issues
show
introduced by
The condition is_array($types) is always true.
Loading history...
689
            foreach ($types as $type) {
690
                $page_types[$type['page_id']][] = $type['type'];
691
            }
692
        }
693
694
        return $page_types;
695
    }
696
697
    /**
698
     * Given a name, this function will return a page handle. These handles
699
     * will only contain latin characters
700
     *
701
     * @param string $name
702
     *  The Page name to generate a handle for
703
     * @return string
704
     */
705
    public static function createHandle($name)
706
    {
707
        return Lang::createHandle($name, 255, '-', false, true, array(
708
            '@^[^a-z\d]+@i' => '',
709
            '/[^\w\-\.]/i' => ''
710
        ));
711
    }
712
713
    /**
714
     * This function takes a `$path` and `$handle` and generates a flattened
715
     * string for use as a filename for a Page's template.
716
     *
717
     * @param string $path
718
     *  The path of the Page, which is the handles of the Page parents. If the
719
     *  page has multiple parents, they will be separated by a forward slash.
720
     *  eg. article/read. If a page has no parents, this parameter should be null.
721
     * @param string $handle
722
     *  A Page handle, generated using `PageManager::createHandle`.
723
     * @return string
724
     */
725
    public static function createFilePath($path, $handle)
726
    {
727
        return trim(str_replace('/', '_', $path . '_' . $handle), '_');
728
    }
729
730
    /**
731
     * This function will return the number of child pages for a given
732
     * `$page_id`. This is a recursive function and will return the absolute
733
     * count.
734
     *
735
     * @param integer $page_id
736
     *  The ID of the Page.
737
     * @return integer
738
     *  The number of child pages for the given `$page_id`
739
     */
740
    public static function getChildPagesCount($page_id = null)
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$page_id" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$page_id"; expected 0 but found 1
Loading history...
741
    {
742
        if (is_null($page_id)) {
743
            return null;
744
        }
745
746
        $children = PageManager::fetch(false, array('id'), array(
747
            sprintf('parent = %d', $page_id)
748
        ));
749
        $count = count($children);
750
751
        if ($count > 0) {
752
            foreach ($children as $c) {
753
                $count += self::getChildPagesCount($c['id']);
754
            }
755
        }
756
757
        return $count;
758
    }
759
760
    /**
761
     * Returns boolean if a the given `$type` has been used by Symphony
762
     * for a Page that is not `$page_id`.
763
     *
764
     * @param integer $page_id
765
     *  The ID of the Page to exclude from the query.
766
     * @param string $type
767
     *  The Page Type to look for in `tbl_page_types`.
768
     * @return boolean
769
     *  true if the type is used, false otherwise
770
     */
771
    public static function hasPageTypeBeenUsed($page_id = null, $type)
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$page_id" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$page_id"; expected 0 but found 1
Loading history...
Coding Style introduced by
Parameters which have default values should be placed at the end.

If you place a parameter with a default value before a parameter with a default value, the default value of the first parameter will never be used as it will always need to be passed anyway:

// $a must always be passed; it's default value is never used.
function someFunction($a = 5, $b) { }
Loading history...
772
    {
773
        return (boolean)Symphony::Database()->fetchRow(0, sprintf(
774
            "SELECT
775
                pt.id
776
            FROM
777
                `tbl_pages_types` AS pt
778
            WHERE
779
                pt.page_id != %d
780
                AND pt.type = '%s'
781
            LIMIT 1",
782
            $page_id,
783
            Symphony::Database()->cleanValue($type)
784
        ));
785
    }
786
787
    /**
788
     * Given a `$page_id`, this function returns boolean if the page
789
     * has child pages.
790
     *
791
     * @param integer $page_id
792
     *  The ID of the Page to check
793
     * @return boolean
794
     *  true if the page has children, false otherwise
795
     */
796
    public static function hasChildPages($page_id = null)
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$page_id" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$page_id"; expected 0 but found 1
Loading history...
797
    {
798
        return (boolean)Symphony::Database()->fetchVar('id', 0, sprintf(
799
            "SELECT
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal SELECT\n ...%d\n LIMIT 1 does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
800
                p.id
801
            FROM
802
                `tbl_pages` AS p
803
            WHERE
804
                p.parent = %d
805
            LIMIT 1",
806
            $page_id
807
        ));
808
    }
809
810
    /**
811
     * Resolves the path to this page's XSLT file. The Symphony convention
812
     * is that they are stored in the `PAGES` folder. If this page has a parent
813
     * it will be as if all the / in the URL have been replaced with _. ie.
814
     * /articles/read/ will produce a file `articles_read.xsl`
815
     *
816
     * @see toolkit.PageManager#createFilePath()
817
     * @param string $path
818
     *  The URL path to this page, excluding the current page. ie, /articles/read
819
     *  would make `$path` become articles/
820
     * @param string $handle
821
     *  The handle of the page.
822
     * @return string
823
     *  The path to the XSLT of the page
824
     */
825
    public static function resolvePageFileLocation($path, $handle)
826
    {
827
        return PAGES . '/' . PageManager::createFilePath($path, $handle) . '.xsl';
0 ignored issues
show
Bug introduced by
The constant PAGES was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
828
    }
829
830
    /**
831
     * Given the `$page_id` and a `$column`, this function will return an
832
     * array of the given `$column` for the Page, including all parents.
833
     *
834
     * @param mixed $page_id
835
     *  The ID of the Page that currently being viewed, or the handle of the
836
     *  current Page
837
     * @param string $column
838
     * @return array
839
     *  An array of the current Page, containing the `$column`
840
     *  requested. The current page will be the last item the array, as all
841
     *  parent pages are prepended to the start of the array
842
     */
843
    public static function resolvePage($page_id, $column)
844
    {
845
        $page = Symphony::Database()->fetchRow(0, sprintf(
846
            "SELECT
847
                p.%s,
848
                p.parent
849
            FROM
850
                `tbl_pages` AS p
851
            WHERE
852
                p.id = %d
853
                OR p.handle = '%s'
854
            LIMIT 1",
855
            $column,
856
            $page_id,
857
            Symphony::Database()->cleanValue($page_id)
858
        ));
859
860
        if (empty($page)) {
861
            return $page;
862
        }
863
864
        $path = array($page[$column]);
865
866
        if (!is_null($page['parent'])) {
867
            $next_parent = $page['parent'];
868
869
            while (
0 ignored issues
show
Coding Style introduced by
Expected 0 spaces after opening bracket; newline found
Loading history...
870
                $parent = Symphony::Database()->fetchRow(0, sprintf(
871
                    "SELECT
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal SELECT\n ... p.id = %d does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
872
                        p.%s,
873
                        p.parent
874
                    FROM
875
                        `tbl_pages` AS p
876
                    WHERE
877
                        p.id = %d",
878
                    $column,
879
                    $next_parent
880
                ))
881
            ) {
882
                array_unshift($path, $parent[$column]);
883
                $next_parent = $parent['parent'];
884
            }
885
        }
886
887
        return $path;
888
    }
889
890
    /**
891
     * Given the `$page_id`, return the complete title of the
892
     * current page. Each part of the Page's title will be
893
     * separated by ': '.
894
     *
895
     * @param mixed $page_id
896
     *  The ID of the Page that currently being viewed, or the handle of the
897
     *  current Page
898
     * @return string
899
     *  The title of the current Page. If the page is a child of another
900
     *  it will be prepended by the parent and a colon, ie. Articles: Read
901
     */
902
    public static function resolvePageTitle($page_id)
903
    {
904
        $path = PageManager::resolvePage($page_id, 'title');
905
906
        return implode(': ', $path);
907
    }
908
909
    /**
910
     * Given the `$page_id`, return the complete path to the
911
     * current page. Each part of the Page's path will be
912
     * separated by '/'.
913
     *
914
     * @param mixed $page_id
915
     *  The ID of the Page that currently being viewed, or the handle of the
916
     *  current Page
917
     * @return string
918
     *  The complete path to the current Page including any parent
919
     *  Pages, ie. /articles/read
920
     */
921
    public static function resolvePagePath($page_id)
922
    {
923
        $path = PageManager::resolvePage($page_id, 'handle');
924
925
        return implode('/', $path);
926
    }
927
928
    /**
929
     * Resolve a page by it's handle and path
930
     *
931
     * @param $handle
932
     *  The handle of the page
933
     * @param boolean $path
934
     *  The path to the page
935
     * @return mixed
936
     *  Array if found, false if not
937
     */
938
    public static function resolvePageByPath($handle, $path = false)
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$path" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$path"; expected 0 but found 1
Loading history...
939
    {
940
        return Symphony::Database()->fetchRow(0, sprintf(
941
            "SELECT * FROM `tbl_pages` WHERE `path` %s AND `handle` = '%s' LIMIT 1",
942
            ($path ? " = '".Symphony::Database()->cleanValue($path)."'" : 'IS NULL'),
0 ignored issues
show
Coding Style introduced by
Inline shorthand IF statement requires brackets around comparison
Loading history...
Bug introduced by
$path of type true is incompatible with the type string expected by parameter $value of MySQL::cleanValue(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

942
            ($path ? " = '".Symphony::Database()->cleanValue(/** @scrutinizer ignore-type */ $path)."'" : 'IS NULL'),
Loading history...
943
            Symphony::Database()->cleanValue($handle)
944
        ));
945
    }
946
947
    /**
948
     * Check whether a datasource is used or not
949
     *
950
     * @param string $handle
951
     *  The datasource handle
952
     * @return boolean
953
     *  true if used, false if not
954
     */
955
    public static function isDataSourceUsed($handle)
956
    {
957
        return (boolean)Symphony::Database()->fetchVar('count', 0, "SELECT COUNT(*) AS `count` FROM `tbl_pages` WHERE `data_sources` REGEXP '[[:<:]]{$handle}[[:>:]]' ") > 0;
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $handle instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
958
    }
959
960
    /**
961
     * Check whether a event is used or not
962
     *
963
     * @param string $handle
964
     *  The event handle
965
     * @return boolean
966
     *  true if used, false if not
967
     */
968
    public static function isEventUsed($handle)
969
    {
970
        return (boolean)Symphony::Database()->fetchVar('count', 0, "SELECT COUNT(*) AS `count` FROM `tbl_pages` WHERE `events` REGEXP '[[:<:]]{$handle}[[:>:]]' ") > 0;
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $handle instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
971
    }
972
}
973