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.

FieldManager::listAll()   B
last analyzed

Complexity

Conditions 8
Paths 4

Size

Total Lines 26
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 8
eloc 14
c 1
b 1
f 0
nc 4
nop 0
dl 0
loc 26
rs 8.4444
1
<?php
2
3
/**
4
 * @package toolkit
5
 */
6
/**
7
 * The `FieldManager` class is responsible for managing all fields types in Symphony.
8
 * Fields are stored on the file system either in the `/fields` folder of `TOOLKIT` or
9
 * in a `fields` folder in an extension directory.
10
 */
11
12
class FieldManager implements FileResource
13
{
14
    /**
15
     * An array of all the objects that the Manager is responsible for.
16
     * Defaults to an empty array.
17
     * @var array
18
     */
19
    protected static $_pool = array();
20
21
    /**
22
     * An array of all fields whose have been created by ID
23
     * @var array
24
     */
25
    private static $_initialiased_fields = array();
26
27
    /**
28
     * Given the filename of a Field, return it's handle. This will remove
29
     * the Symphony conventions of `field.*.php`
30
     *
31
     * @param string $filename
32
     *  The filename of the Field
33
     * @return string
34
     */
35
    public static function __getHandleFromFilename($filename)
36
    {
37
        return preg_replace(array('/^field./i', '/.php$/i'), '', $filename);
38
    }
39
40
    /**
41
     * Given a type, returns the full class name of a Field. Fields use a
42
     * 'field' prefix
43
     *
44
     * @param string $type
45
     *  A field handle
46
     * @return string
47
     */
48
    public static function __getClassName($type)
49
    {
50
        return 'field' . $type;
51
    }
52
53
    /**
54
     * Finds a Field by type by searching the `TOOLKIT . /fields` folder and then
55
     * any fields folders in the installed extensions. The function returns
56
     * the path to the folder where the field class resides.
57
     *
58
     * @param string $type
59
     *  The field handle, that is, `field.{$handle}.php`
60
     * @return string|boolean
61
     */
62
    public static function __getClassPath($type)
63
    {
64
        if (is_file(TOOLKIT . "/fields/field.{$type}.php")) {
0 ignored issues
show
Bug introduced by
The constant TOOLKIT was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $type 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...
65
            return TOOLKIT . '/fields';
66
        } else {
67
            $extensions = Symphony::ExtensionManager()->listInstalledHandles();
68
69
            if (is_array($extensions) && !empty($extensions)) {
70
                foreach ($extensions as $e) {
71
                    if (is_file(EXTENSIONS . "/{$e}/fields/field.{$type}.php")) {
0 ignored issues
show
Bug introduced by
The constant EXTENSIONS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $e 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...
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $type 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...
72
                        return EXTENSIONS . "/{$e}/fields";
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $e 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...
73
                    }
74
                }
75
            }
76
        }
77
78
        return false;
79
    }
80
81
    /**
82
     * Given a field type, return the path to it's class
83
     *
84
     * @see __getClassPath()
85
     * @param string $type
86
     *  The handle of the field to load (it's type)
87
     * @return string
88
     */
89
    public static function __getDriverPath($type)
90
    {
91
        return self::__getClassPath($type) . "/field.{$type}.php";
0 ignored issues
show
Bug introduced by
Are you sure self::__getClassPath($type) of type false|string can be used in concatenation? ( Ignorable by Annotation )

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

91
        return /** @scrutinizer ignore-type */ self::__getClassPath($type) . "/field.{$type}.php";
Loading history...
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $type 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...
92
    }
93
94
    /**
95
     * This function is not implemented by the `FieldManager` class
96
     *
97
     * @return boolean
98
     */
99
    public static function about($name)
100
    {
101
        return false;
102
    }
103
104
    /**
105
     * Given an associative array of fields, insert them into the database
106
     * returning the resulting Field ID if successful, or false if there
107
     * was an error. As fields are saved in order on a section, a query is
108
     * made to determine the sort order of this field to be current sort order
109
     * +1.
110
     *
111
     * @throws DatabaseException
112
     * @param array $fields
113
     *  Associative array of field names => values for the Field object
114
     * @return integer|boolean
115
     *  Returns a Field ID of the created Field on success, false otherwise.
116
     */
117
    public static function add(array $fields)
118
    {
119
        if (!isset($fields['sortorder'])) {
120
            $fields['sortorder'] = self::fetchNextSortOrder();
121
        }
122
123
        if (!Symphony::Database()->insert($fields, 'tbl_fields')) {
124
            return false;
125
        }
126
127
        return Symphony::Database()->getInsertID();
128
    }
129
130
    /**
131
     * Save the settings for a Field given it's `$field_id` and an associative
132
     * array of settings.
133
     *
134
     * @throws DatabaseException
135
     * @since Symphony 2.3
136
     * @param integer $field_id
137
     *  The ID of the field
138
     * @param array $settings
139
     *  An associative array of settings, where the key is the column name
140
     *  and the value is the value.
141
     * @return boolean
142
     *  true on success, false on failure
143
     */
144
    public static function saveSettings($field_id, $settings)
145
    {
146
        // Get the type of this field:
147
        $type = self::fetchFieldTypeFromID($field_id);
148
149
        // Delete the original settings:
150
        Symphony::Database()->delete("tbl_fields_$type", sprintf("`field_id` = %d LIMIT 1", $field_id));
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $type 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...
Coding Style Comprehensibility introduced by
The string literal `field_id` = %d 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...
151
152
        // Insert the new settings into the type table:
153
        if (!isset($settings['field_id'])) {
154
            $settings['field_id'] = $field_id;
155
        }
156
157
        return Symphony::Database()->insert($settings, 'tbl_fields_'.$type);
158
    }
159
160
    /**
161
     * Given a Field ID and associative array of fields, update an existing Field
162
     * row in the `tbl_fields`table. Returns boolean for success/failure
163
     *
164
     * @throws DatabaseException
165
     * @param integer $id
166
     *  The ID of the Field that should be updated
167
     * @param array $fields
168
     *  Associative array of field names => values for the Field object
169
     *  This array does need to contain every value for the field object, it
170
     *  can just be the changed values.
171
     * @return boolean
172
     */
173
    public static function edit($id, array $fields)
174
    {
175
        if (!Symphony::Database()->update($fields, "tbl_fields", sprintf(" `id` = %d", $id))) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal tbl_fields 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...
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...
176
            return false;
177
        }
178
179
        return true;
180
    }
181
182
    /**
183
     * Given a Field ID, delete a Field from Symphony. This will remove the field from
184
     * the fields table, all of the data stored in this field's `tbl_entries_data_$id` any
185
     * existing section associations. This function additionally call the Field's `tearDown`
186
     * method so that it can cleanup any additional settings or entry tables it may of created.
187
     *
188
     * @since Symphony 2.7.0 it will check to see if the field requires a data table before
189
     * blindly trying to delete it.
190
     *
191
     * @throws DatabaseException
192
     * @throws Exception
193
     * @param integer $id
194
     *  The ID of the Field that should be deleted
195
     * @return boolean
196
     */
197
    public static function delete($id)
198
    {
199
        $existing = self::fetch($id);
200
        $existing->tearDown();
201
202
        Symphony::Database()->delete('tbl_fields', sprintf(" `id` = %d", $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...
203
        Symphony::Database()->delete('tbl_fields_'.$existing->handle(), sprintf(" `field_id` = %d", $id));
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal `field_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...
204
        SectionManager::removeSectionAssociation($id);
205
206
        if ($existing->requiresTable()) {
207
            Symphony::Database()->query('DROP TABLE IF EXISTS `tbl_entries_data_'.$id.'`');
208
        }
209
210
        return true;
211
    }
212
213
    /**
214
     * The fetch method returns a instance of a Field from tbl_fields. The most common
215
     * use of this function is to retrieve a Field by ID, but it can be used to retrieve
216
     * Fields from a Section also. There are several parameters that can be used to fetch
217
     * fields by their Type, Location, by a Field Constant or with a custom WHERE query.
218
     *
219
     * @throws DatabaseException
220
     * @throws Exception
221
     * @param integer|array $id
222
     *  The ID of the field to retrieve. Defaults to null which will return multiple field
223
     *  objects. Since Symphony 2.3, `$id` will accept an array of Field ID's
224
     * @param integer $section_id
225
     *  The ID of the section to look for the fields in. Defaults to null which will allow
226
     *  all fields in the Symphony installation to be searched on.
227
     * @param string $order
228
     *  Available values of ASC (Ascending) or DESC (Descending), which refer to the
229
     *  sort order for the query. Defaults to ASC (Ascending)
230
     * @param string $sortfield
231
     *  The field to sort the query by. Can be any from the tbl_fields schema. Defaults to
232
     *  'sortorder'
233
     * @param string $type
234
     *  Filter fields by their type, ie. input, select. Defaults to null
235
     * @param string $location
236
     *  Filter fields by their location in the entry form. There are two possible values,
237
     *  'main' or 'sidebar'. Defaults to null
238
     * @param string $where
239
     *  Allows a custom where query to be included. Must be valid SQL. The tbl_fields alias
240
     *  is t1
241
     * @param integer|string $restrict
242
     *  Only return fields if they match one of the Field Constants. Available values are
243
     *  `__TOGGLEABLE_ONLY__`, `__UNTOGGLEABLE_ONLY__`, `__FILTERABLE_ONLY__`,
244
     *  `__UNFILTERABLE_ONLY__` or `__FIELD_ALL__`. Defaults to `__FIELD_ALL__`
245
     * @return array
246
     *  An array of Field objects. If no Field are found, null is returned.
247
     */
248
    public static function fetch($id = null, $section_id = null, $order = 'ASC', $sortfield = 'sortorder', $type = null, $location = null, $where = null, $restrict = Field::__FIELD_ALL__)
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$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 "$id"; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between argument "$section_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 "$section_id"; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between argument "$order" 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"; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between argument "$sortfield" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$sortfield"; expected 0 but found 1
Loading history...
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...
Coding Style introduced by
Incorrect spacing between argument "$location" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$location"; 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 "$restrict" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$restrict"; expected 0 but found 1
Loading history...
249
    {
250
        $fields = array();
251
        $returnSingle = false;
252
        $ids = array();
253
        $field_contexts = array();
254
255
        if (!is_null($id)) {
256
            if (is_numeric($id)) {
257
                $returnSingle = true;
258
            }
259
260
            if (!is_array($id)) {
261
                $field_ids = array((int)$id);
262
            } else {
263
                $field_ids = $id;
264
            }
265
266
            // Loop over the `$field_ids` and check to see we have
267
            // instances of the request fields
268
            foreach ($field_ids as $key => $field_id) {
269
                if (
0 ignored issues
show
Coding Style introduced by
Expected 0 spaces after opening bracket; newline found
Loading history...
270
                    isset(self::$_initialiased_fields[$field_id])
271
                    && self::$_initialiased_fields[$field_id] instanceof Field
272
                ) {
273
                    $fields[$field_id] = self::$_initialiased_fields[$field_id];
274
                    unset($field_ids[$key]);
275
                }
276
            }
277
        }
278
279
        // If there is any `$field_ids` left to be resolved lets do that, otherwise
280
        // if `$id` wasn't provided in the first place, we'll also continue
281
        if (!empty($field_ids) || is_null($id)) {
282
            $sql = sprintf(
283
                "SELECT t1.*
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal SELECT t1.*\n ... %s\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...
284
                FROM tbl_fields AS `t1`
285
                WHERE 1
286
                %s %s %s %s
287
                %s",
288
                (isset($type) ? " AND t1.`type` = '{$type}' " : null),
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $type 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...
289
                (isset($location) ? " AND t1.`location` = '{$location}' " : null),
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $location 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...
290
                (isset($section_id) ? " AND t1.`parent_section` = '{$section_id}' " : null),
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $section_id 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...
291
                $where,
292
                isset($field_ids) ? " AND t1.`id` IN(" . implode(',', $field_ids) . ") " : " ORDER BY t1.`{$sortfield}` {$order}"
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal AND t1.`id` IN( 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...
Coding Style Comprehensibility introduced by
The string literal ) 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...
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $sortfield 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...
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $order 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...
293
            );
294
295
            if (!$result = Symphony::Database()->fetch($sql)) {
296
                return ($returnSingle ? null : array());
0 ignored issues
show
Coding Style introduced by
Inline shorthand IF statement requires brackets around comparison
Loading history...
297
            }
298
299
            // Loop over the resultset building an array of type, field_id
300
            foreach ($result as $f) {
301
                $ids[$f['type']][] = $f['id'];
302
            }
303
304
            // Loop over the `ids` array, which is grouped by field type
305
            // and get the field context.
306
            foreach ($ids as $type => $field_id) {
307
                $field_contexts[$type] = Symphony::Database()->fetch(sprintf(
308
                    "SELECT * FROM `tbl_fields_%s` WHERE `field_id` IN (%s)",
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal SELECT * FROM `tbl_field...HERE `field_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...
309
                    $type,
310
                    implode(',', $field_id)
311
                ), 'field_id');
312
            }
313
314
            foreach ($result as $f) {
315
                // We already have this field in our static store
316
                if (
0 ignored issues
show
Coding Style introduced by
Expected 0 spaces after opening bracket; newline found
Loading history...
317
                    isset(self::$_initialiased_fields[$f['id']])
318
                    && self::$_initialiased_fields[$f['id']] instanceof Field
319
                ) {
320
                    $field = self::$_initialiased_fields[$f['id']];
321
322
                    // We don't have an instance of this field, so let's set one up
323
                } else {
324
                    $field = self::create($f['type']);
325
                    $field->setArray($f);
326
                    // If the field has said that's going to have associations, then go find the
327
                    // association setting value. In future this check will be most robust with
328
                    // an interface, but for now, this is what we've got. RE: #2082
329
                    if ($field->canShowAssociationColumn()) {
330
                        $field->set('show_association', SectionManager::getSectionAssociationSetting($f['id']));
331
                    }
332
333
                    // Get the context for this field from our previous queries.
334
                    $context = $field_contexts[$f['type']][$f['id']];
335
336
                    if (is_array($context) && !empty($context)) {
337
                        try {
338
                            unset($context['id']);
339
                            $field->setArray($context);
340
                        } catch (Exception $e) {
341
                            throw new Exception(__(
342
                                'Settings for field %s could not be found in table tbl_fields_%s.',
343
                                array($f['id'], $f['type'])
344
                            ));
345
                        }
346
                    }
347
348
                    self::$_initialiased_fields[$f['id']] = $field;
349
                }
350
351
                // Check to see if there was any restricts imposed on the fields
352
                if (
0 ignored issues
show
Coding Style introduced by
Expected 0 spaces after opening bracket; newline found
Loading history...
353
                    $restrict == Field::__FIELD_ALL__
354
                    || ($restrict == Field::__TOGGLEABLE_ONLY__ && $field->canToggle())
355
                    || ($restrict == Field::__UNTOGGLEABLE_ONLY__ && !$field->canToggle())
356
                    || ($restrict == Field::__FILTERABLE_ONLY__ && $field->canFilter())
357
                    || ($restrict == Field::__UNFILTERABLE_ONLY__ && !$field->canFilter())
358
                ) {
359
                    $fields[$f['id']] = $field;
360
                }
361
            }
362
        }
363
364
        return count($fields) <= 1 && $returnSingle ? current($fields) : $fields;
0 ignored issues
show
Coding Style introduced by
Inline shorthand IF statement requires brackets around comparison
Loading history...
365
    }
366
367
    /**
368
     * Given a field ID, return the type of the field by querying `tbl_fields`
369
     *
370
     * @param integer $id
371
     * @return string
372
     */
373
    public static function fetchFieldTypeFromID($id)
374
    {
375
        return Symphony::Database()->fetchVar('type', 0, sprintf("
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal \n SELECT `ty...WHERE `id` = %d 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...
376
            SELECT `type` FROM `tbl_fields` WHERE `id` = %d LIMIT 1",
377
            $id
378
        ));
379
    }
380
381
    /**
382
     * Given a field ID, return the handle of the field by querying `tbl_fields`
383
     *
384
     * @param integer $id
385
     * @return string
386
     */
387
    public static function fetchHandleFromID($id)
388
    {
389
        return Symphony::Database()->fetchVar('element_name', 0, sprintf("
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal \n SELECT `el...WHERE `id` = %d 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...
390
            SELECT `element_name` FROM `tbl_fields` WHERE `id` = %d LIMIT 1",
391
            $id
392
        ));
393
    }
394
395
    /**
396
     * Given an `$element_name` and a `$section_id`, return the Field ID. Symphony enforces
397
     * a uniqueness constraint on a section where every field must have a unique
398
     * label (and therefore handle) so whilst it is impossible to have two fields
399
     * from the same section, it would be possible to have two fields with the same
400
     * name from different sections. Passing the `$section_id` lets you to specify
401
     * which section should be searched. If `$element_name` is null, this function will
402
     * return all the Field ID's from the given `$section_id`.
403
     *
404
     * @throws DatabaseException
405
     * @since Symphony 2.3 This function can now accept $element_name as an array
406
     *  of handles. These handles can now also include the handle's mode, eg. `title: formatted`
407
     * @param string|array $element_name
408
     *  The handle of the Field label, or an array of handles. These handles may contain
409
     *  a mode as well, eg. `title: formatted`.
410
     * @param integer $section_id
411
     *  The section that this field belongs too
412
     *  The field ID, or an array of field ID's
413
     * @return mixed
414
     */
415
    public static function fetchFieldIDFromElementName($element_name, $section_id = null)
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$section_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 "$section_id"; expected 0 but found 1
Loading history...
416
    {
417
        if (is_null($element_name)) {
0 ignored issues
show
introduced by
The condition is_null($element_name) is always false.
Loading history...
418
            $schema_sql = sprintf("
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal \n SELECT...RDER BY `sortorder` 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...
419
                SELECT `id`
420
                FROM `tbl_fields`
421
                WHERE `parent_section` = %d
422
                ORDER BY `sortorder` ASC",
423
                $section_id
424
            );
425
        } else {
426
            $element_names = !is_array($element_name) ? array($element_name) : $element_name;
427
428
            // allow for pseudo-fields containing colons (e.g. Textarea formatted/unformatted)
429
            foreach ($element_names as $index => $name) {
430
                $parts = explode(':', $name, 2);
431
432
                if (count($parts) == 1) {
433
                    continue;
434
                }
435
436
                unset($element_names[$index]);
437
438
                // Prevent attempting to look up 'system', which will arise
439
                // from `system:pagination`, `system:id` etc.
440
                if ($parts[0] == 'system') {
441
                    continue;
442
                }
443
444
                $element_names[] = Symphony::Database()->cleanValue(trim($parts[0]));
445
            }
446
447
            $schema_sql = empty($element_names) ? null : sprintf("
0 ignored issues
show
Coding Style introduced by
Inline shorthand IF statement must be declared on a single line
Loading history...
448
                SELECT `id`
449
                FROM `tbl_fields`
450
                WHERE 1
451
                %s
452
                AND `element_name` IN ('%s')
453
                ORDER BY `sortorder` ASC",
454
                (!is_null($section_id) ? sprintf("AND `parent_section` = %d", $section_id) : ""),
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal AND `parent_section` = %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...
Coding Style Comprehensibility introduced by
The string literal 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...
455
                implode("', '", array_map(array('MySQL', 'cleanValue'), array_unique($element_names)))
456
            );
457
        }
458
459
        if (is_null($schema_sql)) {
460
            return false;
461
        }
462
463
        $result = Symphony::Database()->fetch($schema_sql);
464
465
        if (count($result) == 1) {
466
            return (int)$result[0]['id'];
467
        } elseif (empty($result)) {
468
            return false;
469
        } else {
470
            foreach ($result as &$r) {
471
                $r = (int)$r['id'];
472
            }
473
474
            return $result;
475
        }
476
    }
477
478
    /**
479
     * Work out the next available sort order for a new field
480
     *
481
     * @return integer
482
     *  Returns the next sort order
483
     */
484
    public static function fetchNextSortOrder()
485
    {
486
        $next = Symphony::Database()->fetchVar(
487
            "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...
488
            0,
489
            "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...
490
                MAX(p.sortorder) + 1 AS `next`
491
            FROM
492
                `tbl_fields` AS p
493
            LIMIT 1"
494
        );
495
        return ($next ? (int)$next : 1);
0 ignored issues
show
Coding Style introduced by
Inline shorthand IF statement requires brackets around comparison
Loading history...
496
    }
497
498
    /**
499
     * Given a `$section_id`, this function returns an array of the installed
500
     * fields schema. This includes the `id`, `element_name`, `type`
501
     * and `location`.
502
     *
503
     * @throws DatabaseException
504
     * @since Symphony 2.3
505
     * @param integer $section_id
506
     * @return array
507
     *  An associative array that contains four keys, `id`, `element_name`,
508
     * `type` and `location`
509
     */
510
    public static function fetchFieldsSchema($section_id)
511
    {
512
        return Symphony::Database()->fetch(sprintf(
513
            "SELECT `id`, `element_name`, `type`, `location`
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal SELECT `id`, `element_na...RDER BY `sortorder` 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...
514
            FROM `tbl_fields`
515
            WHERE `parent_section` = %d
516
            ORDER BY `sortorder` ASC",
517
            $section_id
518
        ));
519
    }
520
521
    /**
522
     * Returns an array of all available field handles discovered in the
523
     * `TOOLKIT . /fields` or `EXTENSIONS . /extension_handle/fields`.
524
     *
525
     * @return array
526
     *  A single dimensional array of field handles.
527
     */
528
    public static function listAll()
529
    {
530
        $structure = General::listStructure(TOOLKIT . '/fields', '/field.[a-z0-9_-]+.php/i', false, 'asc', TOOLKIT . '/fields');
0 ignored issues
show
Bug introduced by
The constant TOOLKIT was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
Are you sure the assignment to $structure is correct as General::listStructure(T...', TOOLKIT . '/fields') targeting General::listStructure() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
531
        $extensions = Symphony::ExtensionManager()->listInstalledHandles();
532
        $types = array();
533
534
        if (is_array($extensions) && !empty($extensions)) {
535
            foreach ($extensions as $handle) {
536
                $path = EXTENSIONS . '/' . $handle . '/fields';
0 ignored issues
show
Bug introduced by
The constant EXTENSIONS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
537
                if (is_dir($path)) {
538
                    $tmp = General::listStructure($path, '/field.[a-z0-9_-]+.php/i', false, 'asc', $path);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $tmp is correct as General::listStructure($...', false, 'asc', $path) targeting General::listStructure() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
539
540
                    if (is_array($tmp['filelist']) && !empty($tmp['filelist'])) {
541
                        $structure['filelist'] = array_merge($structure['filelist'], $tmp['filelist']);
542
                    }
543
                }
544
            }
545
546
            $structure['filelist'] = General::array_remove_duplicates($structure['filelist']);
547
        }
548
549
        foreach ($structure['filelist'] as $filename) {
550
            $types[] = self::__getHandleFromFilename($filename);
551
        }
552
553
        return $types;
554
    }
555
556
    /**
557
     * Creates an instance of a given class and returns it. Adds the instance
558
     * to the `$_pool` array with the key being the handle.
559
     *
560
     * @throws Exception
561
     * @param string $type
562
     *  The handle of the Field to create (which is it's handle)
563
     * @return Field
564
     */
565
    public static function create($type)
566
    {
567
        if (!isset(self::$_pool[$type])) {
568
            $classname = self::__getClassName($type);
569
            $path = self::__getDriverPath($type);
570
571
            if (!file_exists($path)) {
572
                throw new Exception(
573
                    __('Could not find Field %1$s at %2$s.', array('<code>' . $type . '</code>', '<code>' . $path . '</code>'))
574
                    . ' ' . __('If it was provided by an Extension, ensure that it is installed, and enabled.')
575
                );
576
            }
577
578
            if (!class_exists($classname)) {
579
                require_once($path);
580
            }
581
582
            self::$_pool[$type] = new $classname;
583
584
            if (self::$_pool[$type]->canShowTableColumn() && !self::$_pool[$type]->get('show_column')) {
585
                self::$_pool[$type]->set('show_column', 'yes');
586
            }
587
        }
588
589
        return clone self::$_pool[$type];
590
    }
591
592
    /**
593
     * Return boolean if the given `$field_type` is in use anywhere in the
594
     * current Symphony install.
595
     *
596
     * @since Symphony 2.3
597
     * @param string $field_type
598
     * @return boolean
599
     */
600
    public static function isFieldUsed($field_type)
601
    {
602
        return Symphony::Database()->fetchVar('count', 0, sprintf(
603
            "SELECT COUNT(*) AS `count` FROM `tbl_fields` WHERE `type` = '%s'",
604
            $field_type
605
        )) > 0;
606
    }
607
608
    /**
609
     * Check if a specific text formatter is used by a Field
610
     *
611
     * @since Symphony 2.3
612
     * @param string $text_formatter_handle
613
     *  The handle of the `TextFormatter`
614
     * @return boolean
615
     *  true if used, false if not
616
     */
617
    public static function isTextFormatterUsed($text_formatter_handle)
618
    {
619
        $fields = Symphony::Database()->fetchCol('type', "SELECT DISTINCT `type` FROM `tbl_fields` WHERE `type` NOT IN ('author', 'checkbox', 'date', 'input', 'select', 'taglist', 'upload')");
620
621
        if (!empty($fields)) {
622
            foreach ($fields as $field) {
623
                try {
624
                    $table = Symphony::Database()->fetchVar('count', 0, sprintf(
625
                        "SELECT COUNT(*) AS `count`
626
                        FROM `tbl_fields_%s`
627
                        WHERE `formatter` = '%s'",
628
                        Symphony::Database()->cleanValue($field),
629
                        $text_formatter_handle
630
                    ));
631
                } catch (DatabaseException $ex) {
632
                    // Table probably didn't have that column
633
                }
634
635
                if ($table > 0) {
636
                    return true;
637
                }
638
            }
639
        }
640
641
        return false;
642
    }
643
}
644