yourls_has_action()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 2
ccs 1
cts 1
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * The filter/plugin API is located in this file, which allows for creating filters
5
 * and hooking functions, and methods. The functions or methods will be run when
6
 * the filter is called.
7
 *
8
 * Any of the syntaxes explained in the PHP documentation for the
9
 * {@link http://us2.php.net/manual/en/language.pseudo-types.php#language.types.callback 'callback'}
10
 * type are valid.
11
 *
12
 * This API is heavily inspired by the one I implemented in Zenphoto 1.3, which was heavily inspired by the one used in WordPress.
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 130 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
13
 *
14
 * @author Ozh
15
 * @since 1.5
16
 */
17
18
if ( !isset( $yourls_filters ) ) {
19
    $yourls_filters = [];
20
}
21
/*
0 ignored issues
show
Coding Style introduced by
Empty line required before block comment
Loading history...
22
 * This global var will collect filters with the following structure:
23
 * $yourls_filters['hook']['array of priorities']['serialized function names']['array of ['array (functions, accepted_args, filter or action)]']
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 144 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
24
 */
25
26
if ( !isset( $yourls_actions ) ) {
27
    $yourls_actions = [];
28
}
29
/*
0 ignored issues
show
Coding Style introduced by
Empty line required before block comment
Loading history...
30
 * This global var will collect 'done' actions with the following structure:
31
 * $yourls_actions['hook'] => number of time this action was done
32
 */
33
34
/**
35
 * Registers a filtering function
36
 *
37
 * Typical use:
38
 *        yourls_add_filter('some_hook', 'function_handler_for_hook');
39
 *
40
 * @param string   $hook           the name of the YOURLS element to be filtered or YOURLS action to be triggered
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 113 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
41
 * @param callback $function_name  the name of the function that is to be called.
42
 * @param int      $priority       optional. Used to specify the order in which the functions associated with a
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 111 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
43
 *                                 particular action are executed (default=10, lower=earlier execution, and functions
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 117 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
44
 *                                 with the same priority are executed in the order in which they were added to the
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 115 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
45
 *                                 filter)
46
 * @param int      $accepted_args  optional. The number of arguments the function accept (default is the number
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 111 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
47
 *                                 provided).
48
 * @param string   $type
49
 * @global array   $yourls_filters Storage for all of the filters
50
 */
51
function yourls_add_filter( $hook, $function_name, $priority = 10, $accepted_args = NULL, $type = 'filter' ) {
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 110 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
52 109
    global $yourls_filters;
53
    // At this point, we cannot check if the function exists, as it may well be defined later (which is OK)
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 107 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
54 109
    $id = yourls_filter_unique_id( $hook, $function_name, $priority );
0 ignored issues
show
Bug introduced by
$function_name of type callable is incompatible with the type array|string expected by parameter $function of yourls_filter_unique_id(). ( Ignorable by Annotation )

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

54
    $id = yourls_filter_unique_id( $hook, /** @scrutinizer ignore-type */ $function_name, $priority );
Loading history...
55
56 109
    $yourls_filters[ $hook ][ $priority ][ $id ] = [
57 109
        'function'      => $function_name,
58 109
        'accepted_args' => $accepted_args,
59 109
        'type'          => $type,
60
    ];
0 ignored issues
show
Coding Style introduced by
The closing parenthesis does not seem to be aligned correctly; expected 51 space(s), but found 4.
Loading history...
61 109
}
62
63
/**
64
 * Hooks a function on to a specific action.
65
 *
66
 * Actions are the hooks that YOURLS launches at specific points
67
 * during execution, or when specific events occur. Plugins can specify that
68
 * one or more of its PHP functions are executed at these points, using the
69
 * Action API.
70
 *
71
 * @param string $hook The name of the action to which the $function_to_add is hooked.
72
 * @param callback $function_name The name of the function you wish to be called.
73
 * @param int $priority optional. Used to specify the order in which the functions associated with a particular action are executed (default: 10). Lower numbers correspond with earlier execution, and functions with the same priority are executed in the order in which they were added to the action.
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 298 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
74
 * @param int $accepted_args optional. The number of arguments the function accept (default 1).
75
 */
76
function yourls_add_action( $hook, $function_name, $priority = 10, $accepted_args = 1 ) {
77 29
	yourls_add_filter( $hook, $function_name, $priority, $accepted_args, 'action' );
78 29
}
79
80
/**
81
 * Build Unique ID for storage and retrieval.
82
 *
83
 * Simply using a function name is not enough, as several functions can have the same name when they are enclosed in classes.
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 125 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
84
 *
85
 * @global array $yourls_filters storage for all of the filters
86
 * @param string $hook hook to which the function is attached
87
 * @param string|array $function used for creating unique id
88
 * @param int|bool $priority used in counting how many hooks were applied.  If === false and $function is an object reference, we return the unique id only if it already has one, false otherwise.
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 195 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
89
 * @return string unique ID for usage as array key
90
 */
91
function yourls_filter_unique_id( $hook, $function, $priority ) {
0 ignored issues
show
Unused Code introduced by
The parameter $hook is not used and could be removed. ( Ignorable by Annotation )

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

91
function yourls_filter_unique_id( /** @scrutinizer ignore-unused */ $hook, $function, $priority ) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $priority is not used and could be removed. ( Ignorable by Annotation )

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

91
function yourls_filter_unique_id( $hook, $function, /** @scrutinizer ignore-unused */ $priority ) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Coding Style introduced by
The method parameter $hook is never used
Loading history...
Coding Style introduced by
The method parameter $priority is never used
Loading history...
92
    // If function then just skip all of the tests and not overwrite the following.
93 202
    if ( is_string( $function ) ) {
94 150
        return $function;
95
    }
96
97 64
    if ( is_object( $function ) ) {
0 ignored issues
show
introduced by
The condition is_object($function) is always false.
Loading history...
98
        // Closures are currently implemented as objects
99 15
        $function = [ $function, '' ];
0 ignored issues
show
Coding Style introduced by
Arrays with multiple values should not be declared on a single line.
Loading history...
100
    }
101
    else {
102 49
        $function = (array)$function;
103
    }
104
105
    // Object Class Calling
106 64
    if ( is_object( $function[ 0 ] ) ) {
107 59
        return spl_object_hash( $function[ 0 ] ).$function[ 1 ];
108
    }
109
110
    // Static Calling
111 5
    if ( is_string( $function[ 0 ] ) ) {
112 5
        return $function[ 0 ].'::'.$function[ 1 ];
113
    }
114
    // TODO: missing final return;
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
115
}
116
117
/**
118
 * Performs a filtering operation on a YOURLS element or event.
119
 *
120
 * Typical use:
121
 *
122
 * 		1) Modify a variable if a function is attached to hook 'yourls_hook'
123
 *		$yourls_var = "default value";
124
 *		$yourls_var = yourls_apply_filter( 'yourls_hook', $yourls_var );
125
 *
126
 *		2) Trigger functions is attached to event 'yourls_event'
127
 *		yourls_apply_filter( 'yourls_event' );
128
 *      (see yourls_do_action() )
129
 *
130
 * Returns an element which may have been filtered by a filter.
131
 *
132
 * @global array $yourls_filters storage for all of the filters
133
 * @param string $hook the name of the YOURLS element or action
134
 * @param mixed $value the value of the element before filtering
135
 * @return mixed
136
 */
137
function yourls_apply_filter( $hook, $value = '' ) {
138 456
    global $yourls_filters;
139 456
    if ( !isset( $yourls_filters[ $hook ] ) ) {
140 430
        return $value;
141
    }
142
143 105
    $args = func_get_args();
144
145
    // Sort filters by priority
146 105
    ksort( $yourls_filters[ $hook ] );
147
148
    // Loops through each filter
149 105
    reset( $yourls_filters[ $hook ] );
150
    do {
151 105
        foreach ( (array)current( $yourls_filters[ $hook ] ) as $the_ ) {
152 105
            if ( !is_null($the_[ 'function' ]) ) {
153 105
                $args[ 1 ] = $value;
154 105
                $count = $the_[ 'accepted_args' ];
155 105
                if ( is_null( $count ) ) {
156 82
                    $_value = call_user_func_array( $the_[ 'function' ], array_slice( $args, 1 ) );
157
                }
158
                else {
159 23
                    $_value = call_user_func_array( $the_[ 'function' ], array_slice( $args, 1, (int)$count ) );
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 112 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
160
                }
161
            }
162 100
            if ( $the_[ 'type' ] == 'filter' ) {
0 ignored issues
show
Coding Style introduced by
Operator == prohibited; use === instead
Loading history...
163 82
                $value = $_value;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $_value does not seem to be defined for all execution paths leading up to this point.
Loading history...
164
            }
165
        }
166 100
    } while ( next( $yourls_filters[ $hook ] ) !== false );
167
168
    // TODO: Missing final return - Why not just return all the time? It's up receiving code to use or not.
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 107 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
169 100
    if ( $the_[ 'type' ] == 'filter' ) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $the_ does not seem to be defined for all execution paths leading up to this point.
Loading history...
Coding Style introduced by
Operator == prohibited; use === instead
Loading history...
170 82
        return $value;
171
    }
172 18
}
173
174
/**
175
 * Performs an action triggered by a YOURLS event.
176
*
177
 * @param string $hook the name of the YOURLS action
178
 * @param mixed $arg action arguments
179
 */
180
function yourls_do_action( $hook, $arg = '' ) {
181 136
    global $yourls_actions;
182
183
    // Keep track of actions that are "done"
184 136
    if ( !isset( $yourls_actions ) ) {
185
        $yourls_actions = [];
186
    }
187 136
    if ( !isset( $yourls_actions[ $hook ] ) ) {
188 33
        $yourls_actions[ $hook ] = 1;
189
    }
190
    else {
191 119
        ++$yourls_actions[ $hook ];
192
    }
193
194 136
    $args = [];
195 136
    if ( is_array( $arg ) && 1 == count( $arg ) && isset( $arg[ 0 ] ) && is_object( $arg[ 0 ] ) ) { // array(&$this)
0 ignored issues
show
Coding Style introduced by
Operator == prohibited; use === instead
Loading history...
Unused Code Comprehensibility introduced by
100% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 116 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
196
        $args[] =& $arg[ 0 ];
197
    }
198
    else {
199 136
        $args[] = $arg;
200
    }
201
202 136
    for ( $a = 2 ; $a < func_num_args() ; $a++ ) {
0 ignored issues
show
Performance Best Practice introduced by
Consider avoiding function calls on each iteration of the for loop.

If you have a function call in the test part of a for loop, this function is executed on each iteration. Often such a function, can be moved to the initialization part and be cached.

// count() is called on each iteration
for ($i=0; $i < count($collection); $i++) { }

// count() is only called once
for ($i=0, $c=count($collection); $i<$c; $i++) { }
Loading history...
Coding Style introduced by
Space found before semicolon; expected "2;" but found "2 ;"
Loading history...
Coding Style introduced by
Space found before semicolon; expected ");" but found ") ;"
Loading history...
203 104
        $args[] = func_get_arg( $a );
204
    }
205
206 136
    yourls_apply_filter( $hook, $args );
207 132
}
208
209
/**
210
 * Retrieve the number times an action is fired.
211
 *
212
 * @param string $hook Name of the action hook.
213
 * @return int The number of times action hook <tt>$hook</tt> is fired
214
 */
215
function yourls_did_action( $hook ) {
216 25
    global $yourls_actions;
217 25
    return empty( $yourls_actions[ $hook ] ) ? 0 : $yourls_actions[ $hook ];
218
}
219
220
/**
221
 * Removes a function from a specified filter hook.
222
 *
223
 * This function removes a function attached to a specified filter hook. This
224
 * method can be used to remove default functions attached to a specific filter
225
 * hook and possibly replace them with a substitute.
226
 *
227
 * To remove a hook, the $function_to_remove and $priority arguments must match
228
 * when the hook was added.
229
 *
230
 * @global array $yourls_filters storage for all of the filters
231
 * @param string $hook The filter hook to which the function to be removed is hooked.
232
 * @param callback $function_to_remove The name of the function which should be removed.
233
 * @param int $priority optional. The priority of the function (default: 10).
234
 * @return bool Whether the function was registered as a filter before it was removed.
235
 */
236
function yourls_remove_filter( $hook, $function_to_remove, $priority = 10 ) {
237 122
    global $yourls_filters;
238
239 122
    $function_to_remove = yourls_filter_unique_id( $hook, $function_to_remove, $priority );
0 ignored issues
show
Bug introduced by
$function_to_remove of type callable is incompatible with the type array|string expected by parameter $function of yourls_filter_unique_id(). ( Ignorable by Annotation )

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

239
    $function_to_remove = yourls_filter_unique_id( $hook, /** @scrutinizer ignore-type */ $function_to_remove, $priority );
Loading history...
240
241 122
    $remove = isset( $yourls_filters[ $hook ][ $priority ][ $function_to_remove ] );
242
243 122
    if ( $remove === true ) {
244 32
        unset ( $yourls_filters[ $hook ][ $priority ][ $function_to_remove ] );
245 32
        if ( empty( $yourls_filters[ $hook ][ $priority ] ) ) {
246 32
            unset( $yourls_filters[ $hook ] );
247
        }
248
    }
249 122
    return $remove;
250
}
251
252
/**
253
 * Removes a function from a specified action hook.
254
 *
255
 * @see yourls_remove_filter()
256
 * @param string   $hook               The action hook to which the function to be removed is hooked.
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 101 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
257
 * @param callable $function_to_remove The name of the function which should be removed.
258
 * @param int      $priority           optional. The priority of the function (default: 10).
259
 * @return bool                        Whether the function was registered as an action before it was removed.
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 110 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
260
 */
261
function yourls_remove_action( $hook, $function_to_remove, $priority = 10 ) {
262 1
    return yourls_remove_filter( $hook, $function_to_remove, $priority );
263
}
264
265
/**
266
 * Removes all functions from a specified action hook.
267
 *
268
 * @see   yourls_remove_all_filters()
269
 * @since 1.7.1
270
 * @param string    $hook     The action to remove hooks from
271
 * @param int|false $priority optional. The priority of the functions to remove
272
 * @return bool true when it's finished
273
 */
274
function yourls_remove_all_actions( $hook, $priority = false ) {
275 28
    return yourls_remove_all_filters( $hook, $priority );
276
}
277
278
/**
279
 * Removes all functions from a specified filter hook.
280
 *
281
 * @since 1.7.1
282
 * @param string    $hook     The filter to remove hooks from
283
 * @param int|false $priority optional. The priority of the functions to remove
284
 * @return bool true when it's finished
285
 */
286
function yourls_remove_all_filters( $hook, $priority = false ) {
287 84
    global $yourls_filters;
288
289 84
    if ( isset( $yourls_filters[ $hook ] ) ) {
290 51
        if ( $priority === false ) {
291 50
            unset( $yourls_filters[ $hook ] );
292
        }
293 1
        elseif ( isset( $yourls_filters[ $hook ][ $priority ] ) ) {
294 1
            unset( $yourls_filters[ $hook ][ $priority ] );
295
        }
296
    }
297
298 84
    return true;
299
}
300
301
/**
302
 * Check if any filter has been registered for a hook.
303
 *
304
 * @param string         $hook              The name of the filter hook.
305
 * @param callable|false $function_to_check optional. If specified, return the priority of that function on this hook or false if not attached.
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 143 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
306
 * @return int|bool Optionally returns the priority on that hook for the specified function.
307
 * @global array         $yourls_filters    storage for all of the filters
308
 */
309
function yourls_has_filter( $hook, $function_to_check = false ) {
310 26
    global $yourls_filters;
311
312 26
    $has = !empty( $yourls_filters[ $hook ] );
313 26
    if ( false === $function_to_check || false === $has ) {
314 26
        return $has;
315
    }
316
317 4
    if ( !$idx = yourls_filter_unique_id( $hook, $function_to_check, false ) ) {
0 ignored issues
show
Bug introduced by
$function_to_check of type callable is incompatible with the type array|string expected by parameter $function of yourls_filter_unique_id(). ( Ignorable by Annotation )

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

317
    if ( !$idx = yourls_filter_unique_id( $hook, /** @scrutinizer ignore-type */ $function_to_check, false ) ) {
Loading history...
Coding Style introduced by
Variable assignment found within a condition. Did you mean to do a comparison ?
Loading history...
318
        return false;
319
    }
320
321 4
    foreach ( array_keys( $yourls_filters[ $hook ] ) as $priority ) {
322 4
        if ( isset( $yourls_filters[ $hook ][ $priority ][ $idx ] ) ) {
323 4
            return $priority;
324
        }
325
    }
326 1
    return false;
327
}
328
329
/**
330
 * @param string         $hook
331
 * @param callable|false $function_to_check
332
 * @return bool|int
333
 */
334
function yourls_has_action( $hook, $function_to_check = false ) {
335 13
    return yourls_has_filter( $hook, $function_to_check );
336
}
337
338
/**
339
 * Return number of active plugins
340
 *
341
 * @return int Number of activated plugins
342
 */
343
function yourls_has_active_plugins() {
344 15
    return count( yourls_get_db()->get_plugins() );
345
}
346
347
/**
348
 * List plugins in /user/plugins
349
 *
350
 * @return array Array of [/plugindir/plugin.php]=>array('Name'=>'Ozh', 'Title'=>'Hello', )
351
 */
352
function yourls_get_plugins() {
353 3
    $plugins = (array)glob( YOURLS_PLUGINDIR.'/*/plugin.php' );
354
355 3
    if ( is_array( $plugins ) ) {
0 ignored issues
show
introduced by
The condition is_array($plugins) is always true.
Loading history...
356 3
        foreach ( $plugins as $key => $plugin ) {
357 3
            $plugins[ yourls_plugin_basename( $plugin ) ] = yourls_get_plugin_data( $plugin );
358 3
            unset( $plugins[ $key ] );
359
        }
360
    }
361
362 3
    return empty( $plugins ) ? [] : $plugins;
363
}
364
365
/**
366
 * Check if a plugin is active
367
 *
368
 * @param string $plugin Physical path to plugin file
369
 * @return bool
370
 */
371
function yourls_is_active_plugin( $plugin ) {
372 5
    return yourls_has_active_plugins() > 0 ?
373 3
        in_array( yourls_plugin_basename( $plugin ), yourls_get_db()->get_plugins() )
374 5
        : false;
375
}
376
377
/**
378
 * Parse a plugin header
379
 *
380
 * The plugin header has the following form:
381
 *      /*
382
 *      Plugin Name: <plugin name>
383
 *      Plugin URI: <plugin home page>
384
 *      Description: <plugin description>
385
 *      Version: <plugin version number>
386
 *      Author: <author name>
387
 *      Author URI: <author home page>
388
 *      * /
389
 *
390
 * Or in the form of a phpdoc block
391
 *      /**
392
 *       * Plugin Name: <plugin name>
393
 *       * Plugin URI: <plugin home page>
394
 *       * Description: <plugin description>
395
 *       * Version: <plugin version number>
396
 *       * Author: <author name>
397
 *       * Author URI: <author home page>
398
 *       * /
399
 *
400
 * @since 1.5
401
 * @param string $file Physical path to plugin file
402
 * @return array Array of 'Field'=>'Value' from plugin comment header lines of the form "Field: Value"
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 102 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
403
 */
404
function yourls_get_plugin_data( $file ) {
405 8
    $fp = fopen( $file, 'r' ); // assuming $file is readable, since yourls_load_plugins() filters this
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 102 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
406 8
    $data = fread( $fp, 8192 ); // get first 8kb
0 ignored issues
show
Bug introduced by
It seems like $fp can also be of type false; however, parameter $handle of fread() does only seem to accept resource, 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

406
    $data = fread( /** @scrutinizer ignore-type */ $fp, 8192 ); // get first 8kb
Loading history...
407 8
    fclose( $fp );
0 ignored issues
show
Bug introduced by
It seems like $fp can also be of type false; however, parameter $handle of fclose() does only seem to accept resource, 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

407
    fclose( /** @scrutinizer ignore-type */ $fp );
Loading history...
408
409
    // Capture all the header within first comment block
410 8
    if ( !preg_match( '!.*?/\*(.*?)\*/!ms', $data, $matches ) )
411
        return [];
412
413
    // Capture each line with "Something: some text"
414 8
    unset( $data );
415 8
    $lines = preg_split( "[\n|\r]", $matches[ 1 ] );
416 8
    unset( $matches );
417
418 8
    $plugin_data = [];
419 8
    foreach ( $lines as $line ) {
420 8
        if ( !preg_match( '!(\s*)?\*?(\s*)?(.*?):\s+(.*)!', $line, $matches ) ) {
421 8
            continue;
422
        }
423
424 6
        $plugin_data[ trim($matches[3]) ] = yourls_esc_html(trim($matches[4]));
425
    }
426
427 8
    return $plugin_data;
428
}
429
430
/**
431
 * Include active plugins
432
 *
433
 * This function includes every 'YOURLS_PLUGINDIR/plugin_name/plugin.php' found in option 'active_plugins'
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 106 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
434
 * It will return a diagnosis array with the following keys:
435
 *    (bool)'loaded' : true if plugin(s) loaded, false otherwise
436
 *    (string)'info' : extra information
437
 *
438
 * @since 1.5
439
 * @return array    Array('loaded' => bool, 'info' => string)
440
 */
441
function yourls_load_plugins() {
442
    // Don't load plugins when installing or updating
443 1
    if ( yourls_is_installing() OR yourls_is_upgrading() OR !yourls_is_installed() ) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
Coding Style introduced by
As per coding-style, PHP keywords should be in lowercase; expected or, but found OR.
Loading history...
444
        return [
445
            'loaded' => false,
446
            'info'   => 'install/upgrade'
0 ignored issues
show
Coding Style introduced by
Each line in an array declaration must end in a comma
Loading history...
447
        ];
0 ignored issues
show
Coding Style introduced by
The closing parenthesis does not seem to be aligned correctly; expected 15 space(s), but found 8.
Loading history...
448
    }
449
450 1
    $active_plugins = (array)yourls_get_option( 'active_plugins' );
451 1
    if ( empty( $active_plugins ) ) {
452
        return [
453
            'loaded' => false,
454
            'info'   => 'no active plugin'
0 ignored issues
show
Coding Style introduced by
Each line in an array declaration must end in a comma
Loading history...
455
        ];
0 ignored issues
show
Coding Style introduced by
The closing parenthesis does not seem to be aligned correctly; expected 15 space(s), but found 8.
Loading history...
456
    }
457
458 1
    $plugins = [];
459 1
    foreach ( $active_plugins as $key => $plugin ) {
460 1
        if ( yourls_validate_plugin_file( YOURLS_PLUGINDIR.'/'.$plugin ) ) {
461 1
            include_once( YOURLS_PLUGINDIR.'/'.$plugin );
462 1
            $plugins[] = $plugin;
463 1
            unset( $active_plugins[ $key ] );
464
        }
465
    }
466
467
    // Replace active plugin list with list of plugins we just activated
468 1
    yourls_get_db()->set_plugins( $plugins );
469 1
    $info = count( $plugins ).' activated';
470
471
    // $active_plugins should be empty now, if not, a plugin could not be find: remove it
472 1
    $missing_count = count( $active_plugins );
473 1
    if ( $missing_count > 0 ) {
474 1
        yourls_update_option( 'active_plugins', $plugins );
475 1
        $message = yourls_n( 'Could not find and deactivate plugin :', 'Could not find and deactivate plugins :', $missing_count );
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 131 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
476 1
        $missing = '<strong>'.implode( '</strong>, <strong>', $active_plugins ).'</strong>';
477 1
        yourls_add_notice( $message.' '.$missing );
478 1
        $info .= ', '.$missing_count.' removed';
479
    }
480
481
    return [
482 1
        'loaded' => true,
483 1
        'info'   => $info
0 ignored issues
show
Coding Style introduced by
Each line in an array declaration must end in a comma
Loading history...
484
    ];
0 ignored issues
show
Coding Style introduced by
The closing parenthesis does not seem to be aligned correctly; expected 11 space(s), but found 4.
Loading history...
485
}
486
487
/**
488
 * Check if a file is safe for inclusion (well, "safe", no guarantee)
489
 *
490
 * @param string $file Full pathname to a file
491
 * @return bool
492
 */
493
function yourls_validate_plugin_file( $file ) {
494 6
    return false === strpos( $file, '..' )
495 6
           && false === strpos( $file, './' )
496 6
           && 'plugin.php' === substr( $file, -10 )
497 6
           && is_readable( $file );
498
}
499
500
/**
501
 * Activate a plugin
502
 *
503
 * @param string $plugin Plugin filename (full or relative to plugins directory)
504
 * @return string|true  string if error or true if success
505
 */
506
function yourls_activate_plugin( $plugin ) {
507
    // validate file
508 3
    $plugin = yourls_plugin_basename( $plugin );
509 3
    $plugindir = yourls_sanitize_filename( YOURLS_PLUGINDIR );
510 3
    if ( !yourls_validate_plugin_file( $plugindir.'/'.$plugin ) ) {
511 1
        return yourls__( 'Not a valid plugin file' );
512
    }
513
514
    // check not activated already
515 2
    $ydb = yourls_get_db();
516 2
    if ( yourls_is_active_plugin( $plugin ) ) {
517 1
        return yourls__( 'Plugin already activated' );
518
    }
519
520
    // attempt activation. TODO: uber cool fail proof sandbox like in WP.
521 1
    ob_start();
522 1
    include_once( $plugindir.'/'.$plugin );
523 1
    if ( ob_get_length() > 0 ) {
524
        // there was some output: error
525
        // @codeCoverageIgnoreStart
526
        $output = ob_get_clean();
527
        return yourls_s( 'Plugin generated unexpected output. Error was: <br/><pre>%s</pre>', $output );
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 104 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
528
        // @codeCoverageIgnoreEnd
529
    }
530 1
    ob_end_clean();
531
532
    // so far, so good: update active plugin list
533 1
    $ydb->add_plugin( $plugin );
534 1
    yourls_update_option( 'active_plugins', $ydb->get_plugins() );
535 1
    yourls_do_action( 'activated_plugin', $plugin );
536 1
    yourls_do_action( 'activated_'.$plugin );
537
538 1
    return true;
539
}
540
541
/**
542
 * Deactivate a plugin
543
 *
544
 * @param string $plugin Plugin filename (full relative to plugins directory)
545
 * @return string|true  string if error or true if success
546
 */
547
function yourls_deactivate_plugin( $plugin ) {
548 2
    $plugin = yourls_plugin_basename( $plugin );
549
550
    // Check plugin is active
551 2
    if ( !yourls_is_active_plugin( $plugin ) ) {
552 1
        return yourls__( 'Plugin not active' );
553
    }
554
555
    // Deactivate the plugin
556 1
    $ydb = yourls_get_db();
557 1
    $plugins = $ydb->get_plugins();
558 1
    $key = array_search( $plugin, $plugins );
559 1
    if ( $key !== false ) {
560 1
        array_splice( $plugins, $key, 1 );
0 ignored issues
show
Bug introduced by
It seems like $key can also be of type string; however, parameter $offset of array_splice() does only seem to accept integer, 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

560
        array_splice( $plugins, /** @scrutinizer ignore-type */ $key, 1 );
Loading history...
561
    }
562
563 1
    $ydb->set_plugins( $plugins );
564 1
    yourls_update_option( 'active_plugins', $plugins );
565 1
    yourls_do_action( 'deactivated_plugin', $plugin );
566 1
    yourls_do_action( 'deactivated_'.$plugin );
567
568 1
    return true;
569
}
570
571
/**
572
 * Return the path of a plugin file, relative to the plugins directory
573
 * @param string $file
574
 * @return string
575
 */
576
function yourls_plugin_basename( $file ) {
577 11
	return trim( str_replace( yourls_sanitize_filename( YOURLS_PLUGINDIR ), '', yourls_sanitize_filename( $file ) ), '/' );
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 120 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
578
}
579
580
/**
581
 * Return the URL of the directory a plugin
582
 * @param string $file
583
 * @return string
584
 */
585
function yourls_plugin_url( $file ) {
586 4
    $url = YOURLS_PLUGINURL.'/'.yourls_plugin_basename( $file );
587 4
    if ( yourls_is_ssl() or yourls_needs_ssl() ) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
588 3
        $url = str_replace( 'http://', 'https://', $url );
589
    }
590 4
    return (string)yourls_apply_filter( 'plugin_url', $url, $file );
591
}
592
593
/**
594
 * Build list of links to plugin admin pages, if any
595
 *
596
 * @return array[]  Array of arrays of URL and anchor of plugin admin pages, or void if no plugin page
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 102 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
597
 */
598
function yourls_list_plugin_admin_pages() {
599 1
    $plugin_links = [];
600 1
    foreach ( yourls_get_db()->get_plugin_pages() as $plugin => $page ) {
601 1
        $plugin_links[ $plugin ] = [
602 1
            'url'    => yourls_admin_url( 'plugins.php?page='.$page[ 'slug' ] ),
603 1
            'anchor' => $page[ 'title' ],
604
        ];
0 ignored issues
show
Coding Style introduced by
The closing parenthesis does not seem to be aligned correctly; expected 35 space(s), but found 8.
Loading history...
605
    }
606 1
    return $plugin_links;
607
}
608
609
/**
610
 * Register a plugin administration page
611
 * @param string   $slug
612
 * @param string   $title
613
 * @param callable $function
614
 */
615
function yourls_register_plugin_page( $slug, $title, $function ) {
616 4
    yourls_get_db()->add_plugin_page( $slug, $title, $function );
617 4
}
618
619
/**
620
 * Handle plugin administration page
621
 *
622
 * @param string $plugin_page
623
 */
624
function yourls_plugin_admin_page( $plugin_page ) {
625
    // Check the plugin page is actually registered
626 3
    $pages = yourls_get_db()->get_plugin_pages();
627 3
    if ( !isset( $pages[ $plugin_page ] ) ) {
628 1
        yourls_die( yourls__( 'This page does not exist. Maybe a plugin you thought was activated is inactive?' ), yourls__( 'Invalid link' ) );
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 144 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
629
    }
630
631
    // Check the plugin page function is actually callable
632 2
    $page_function = $pages[ $plugin_page ][ 'function' ];
633 2
    if (!is_callable($page_function)) {
634 1
        yourls_die( yourls__( 'This page cannot be displayed because the displaying function is not callable.' ), yourls__( 'Invalid code' ) );
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 143 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
635
    }
636
637
    // Draw the page itself
638 1
    yourls_do_action( 'load-'.$plugin_page );
639 1
    yourls_html_head( 'plugin_page_'.$plugin_page, $pages[ $plugin_page ][ 'title' ] );
640 1
    yourls_html_logo();
641 1
    yourls_html_menu();
642
643 1
    $page_function( );
644
645 1
    yourls_html_footer();
646 1
}
647
648
/**
649
 * Callback function: Sort plugins
650
 *
651
 * @link http://php.net/uasort
652
 * @codeCoverageIgnore
653
 *
654
 * @param array $plugin_a
655
 * @param array $plugin_b
656
 * @return int 0, 1 or -1, see uasort()
657
 */
658
function yourls_plugins_sort_callback( $plugin_a, $plugin_b ) {
659
    $orderby = yourls_apply_filter( 'plugins_sort_callback', 'Plugin Name' );
660
    $order = yourls_apply_filter( 'plugins_sort_callback', 'ASC' );
661
662
    $a = isset( $plugin_a[ $orderby ] ) ? $plugin_a[ $orderby ] : '';
663
    $b = isset( $plugin_b[ $orderby ] ) ? $plugin_b[ $orderby ] : '';
664
665
    if ( $a == $b ) {
0 ignored issues
show
Coding Style introduced by
Operator == prohibited; use === instead
Loading history...
666
        return 0;
667
    }
668
669
    if ( 'DESC' == $order ) {
0 ignored issues
show
Coding Style introduced by
Operator == prohibited; use === instead
Loading history...
670
        return ( $a < $b ) ? 1 : -1;
671
    }
672
    else {
673
        return ( $a < $b ) ? -1 : 1;
674
    }
675
}
676
677
/**
678
 * Shutdown function, runs just before PHP shuts down execution. Stolen from WP
679
 *
680
 * This function is automatically tied to the script execution end at startup time, see
681
 * var $actions->register_shutdown in includes/Config/Init.php
682
 *
683
 * You can use this function to fire one or several actions when the PHP execution ends.
684
 * Example of use:
685
 *   yourls_add_action('shutdown', 'my_plugin_action_this');
686
 *   yourls_add_action('shutdown', 'my_plugin_action_that');
687
 *   // functions my_plugin_action_this() and my_plugin_action_that() will be triggered
688
 *   // after YOURLS is completely executed
689
 *
690
 * @since 1.5.1
691
 * @return void
692
 */
693
function yourls_shutdown() {
694
    yourls_do_action( 'shutdown' );
695
}
696
697
/**
698
 * Returns true.
699
 *
700
 * Useful for returning true to filters easily.
701
 *
702
 * @since 1.7.1
703
 * @return bool True.
704
 */
705
function yourls_return_true() {
706 35
    return true;
707
}
708
709
/**
710
 * Returns false.
711
 *
712
 * Useful for returning false to filters easily.
713
 *
714
 * @since 1.7.1
715
 * @return bool False.
716
 */
717
function yourls_return_false() {
718 16
    return false;
719
}
720
721
/**
722
 * Returns 0.
723
 *
724
 * Useful for returning 0 to filters easily.
725
 *
726
 * @since 1.7.1
727
 * @return int 0.
728
 */
729
function yourls_return_zero() {
730 1
    return 0;
731
}
732
733
/**
734
 * Returns an empty array.
735
 *
736
 * Useful for returning an empty array to filters easily.
737
 *
738
 * @since 1.7.1
739
 * @return array Empty array.
740
 */
741
function yourls_return_empty_array() {
742 4
    return [];
743
}
744
745
/**
746
 * Returns null.
747
 *
748
 * Useful for returning null to filters easily.
749
 *
750
 * @since 1.7.1
751
 * @return null Null value.
752
 */
753
function yourls_return_null() {
754
    return null;
755
}
756
757
/**
758
 * Returns an empty string.
759
 *
760
 * Useful for returning an empty string to filters easily.
761
 *
762
 * @since 1.7.1
763
 * @return string Empty string.
764
 */
765
function yourls_return_empty_string() {
766
    return '';
767
}
768