Completed
Push — master ( 64c9c6...973681 )
by Michael
02:15
created

MetaSlider::get_custom_javascript_after()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 12
Ratio 100 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 0
dl 12
loc 12
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Generic Slider super class. Extended by library specific classes.
5
 *
6
 * This class handles all slider related functionality, including saving settings and outputting
7
 * the slider HTML (front end and back end)
8
 */
9
class MetaSlider
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
10
{
11
    public $id         = 0; // slider ID
12
    public $identifier = 0; // unique identifier
13
    public $slides     = array(); //slides belonging to this slider
14
    public $settings   = array(); // slider settings
15
16
    /**
17
     * Constructor
18
     * @param $id
19
     * @param $shortcode_settings
20
     */
21
    public function __construct($id, $shortcode_settings)
22
    {
23
        $this->id         = $id;
24
        $this->settings   = array_merge($shortcode_settings, $this->get_settings());
25
        $this->identifier = 'metaslider_' . $this->id;
0 ignored issues
show
Documentation Bug introduced by
The property $identifier was declared of type integer, but 'metaslider_' . $this->id is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
26
        $this->save();
27
        $this->populate_slides();
28
    }
29
30
    /**
31
     * Return the unique identifier for the slider (used to avoid javascript conflicts)
32
     *
33
     * @return string unique identifier for slider
0 ignored issues
show
Documentation introduced by
Should the return type not be integer?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
34
     */
35
    protected function get_identifier()
36
    {
37
        return $this->identifier;
38
    }
39
40
    /**
41
     * Get settings for the current slider
42
     *
43
     * @return array slider settings
0 ignored issues
show
Documentation introduced by
Should the return type not be array|string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
44
     */
45
    private function get_settings()
46
    {
47
        $settings = get_post_meta($this->id, 'ml-slider_settings', true);
48
49
        if (is_array($settings) && isset($settings['type']) && in_array($settings['type'], array('flex', 'coin', 'nivo', 'responsive'))) {
50
            return $settings;
51
        } else {
52
            return $this->get_default_parameters();
53
        }
54
    }
55
56
    /**
57
     * Return an individual setting
58
     *
59
     * @param  string $name Name of the setting
60
     * @return string setting value or 'false'
61
     */
62
    public function get_setting($name)
63
    {
64
        if (!isset($this->settings[$name])) {
65
            $defaults = $this->get_default_parameters();
66
67
            if (isset($defaults[$name])) {
68
                return $defaults[$name] ?: 'false';
69
            }
70
        } else {
71
            if (strlen($this->settings[$name]) > 0) {
72
                return $this->settings[$name];
73
            }
74
        }
75
76
        return 'false';
77
    }
78
79
    /**
80
     * Get the slider libary parameters, this lists all possible parameters and their
81
     * default values. Slider subclasses override this and disable/rename parameters
82
     * appropriately.
83
     *
84
     * @return string javascript options
85
     */
86
    public function get_default_parameters()
87
    {
88
        $params = array(
89
            'type'           => 'flex',
90
            'random'         => false,
91
            'cssClass'       => '',
92
            'printCss'       => true,
93
            'printJs'        => true,
94
            'width'          => 700,
95
            'height'         => 300,
96
            'spw'            => 7,
97
            'sph'            => 5,
98
            'delay'          => 3000,
99
            'sDelay'         => 30,
100
            'opacity'        => 0.7,
101
            'titleSpeed'     => 500,
102
            'effect'         => 'random',
103
            'navigation'     => true,
104
            'links'          => true,
105
            'hoverPause'     => true,
106
            'theme'          => 'default',
107
            'direction'      => 'horizontal',
108
            'reverse'        => false,
109
            'animationSpeed' => 600,
110
            'prevText'       => '<',
111
            'nextText'       => '>',
112
            'slices'         => 15,
113
            'center'         => false,
114
            'smartCrop'      => true,
115
            'carouselMode'   => false,
116
            'easing'         => 'linear',
117
            'autoPlay'       => true,
118
            'thumb_width'    => 150,
119
            'thumb_height'   => 100,
120
            'fullWidth'      => false,
121
            'noConflict'     => false
122
        );
123
124
        $params = apply_filters('metaslider_default_parameters', $params);
125
126
        return $params;
127
    }
128
129
    /**
130
     * Save the slider details and initiate the update of all slides associated with slider.
131
     */
132
    private function save()
0 ignored issues
show
Coding Style introduced by
save uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
save uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
133
    {
134
        if (!is_admin()) {
135
            return;
136
        }
137
138
        // make changes to slider
139
        if (isset($_POST['settings'])) {
140
            check_admin_referer('metaslider_save_' . $this->id);
141
            $this->update_settings($_POST['settings']);
142
        }
143
        if (isset($_POST['title'])) {
144
            check_admin_referer('metaslider_save_' . $this->id);
145
            $this->update_title($_POST['title']);
146
        }
147
        if (isset($_GET['deleteSlide'])) {
148
            $this->delete_slide((int)$_GET['deleteSlide']);
149
        }
150
151
        // make changes to slides
152
        if (isset($_POST['attachment'])) {
153
            check_admin_referer('metaslider_save_' . $this->id);
154
            $this->update_slides($_POST['attachment']);
155
        }
156
    }
157
158
    /**
159
     * The main query for extracting the slides for the slideshow
160
     */
161
    public function get_slides()
162
    {
163
        $args = array(
164
            'force_no_custom_order' => true,
165
            'orderby'               => 'menu_order',
166
            'order'                 => 'ASC',
167
            'post_type'             => 'attachment',
168
            'post_status'           => 'inherit',
169
            'lang'                  => '', // polylang, ingore language filter
170
            'suppress_filters'      => 1, // wpml, ignore language filter
171
            'posts_per_page'        => -1,
172
            'tax_query'             => array(
173
                array(
174
                    'taxonomy' => 'ml-slider',
175
                    'field'    => 'slug',
176
                    'terms'    => $this->id
177
                )
178
            )
179
        );
180
181
        $args = apply_filters('metaslider_populate_slides_args', $args, $this->id, $this->settings);
182
183
        $query = new WP_Query($args);
184
185
        return $query;
186
    }
187
188
    /**
189
     * Return slides for the current slider
190
     *
191
     * @return array collection of slides belonging to the current slider
192
     */
193
    private function populate_slides()
194
    {
195
        $slides = array();
196
197
        $query = $this->get_slides();
198
199
        while ($query->have_posts()) {
200
            $query->next_post();
201
202
            $type = get_post_meta($query->post->ID, 'ml-slider_type', true);
203
            $type = $type ?: 'image'; // backwards compatibility, fall back to 'image'
204
205
            if (has_filter("metaslider_get_{$type}_slide")) {
206
                $return = apply_filters("metaslider_get_{$type}_slide", $query->post->ID, $this->id);
207
208
                if (is_array($return)) {
209
                    $slides = array_merge($slides, $return);
210
                } else {
211
                    $slides[] = $return;
212
                }
213
            }
214
        }
215
216
        // apply random setting
217
        if ($this->get_setting('random') === 'true' && !is_admin()) {
218
            shuffle($slides);
219
        }
220
221
        $this->slides = $slides;
222
223
        return $this->slides;
224
    }
225
226
    /**
227
     * Render each slide belonging to the slider out to the screen
228
     */
229
    public function render_admin_slides()
230
    {
231
        foreach ($this->slides as $slide) {
232
            echo $slide;
233
        }
234
    }
235
236
    /**
237
     * Output the HTML and Javascript for this slider
238
     *
239
     * @return string HTML & Javascrpt
240
     */
241
    public function render_public_slides()
242
    {
243
        $html[] = '<!-- meta slider -->';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$html was never initialized. Although not strictly required by PHP, it is generally a good practice to add $html = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
244
        $html[] = '<div style="' . $this->get_container_style() . '" class="' . $this->get_container_class() . '">';
245
        $html[] = '    ' . $this->get_inline_css();
246
        $html[] = '    <div id="' . $this->get_container_id() . '">';
247
        $html[] = '        ' . $this->get_html();
0 ignored issues
show
Bug introduced by
The method get_html() does not exist on MetaSlider. Did you maybe mean get_html_after()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
248
        $html[] = '        ' . $this->get_html_after();
249
        $html[] = '    </div>';
250
        $html[] = '    <script type="text/javascript">';
251
        $html[] = '        ' . $this->get_inline_javascript();
252
        $html[] = '    </script>';
253
        $html[] = '</div>';
254
        $html[] = '<!--// meta slider-->';
255
256
        $slideshow = implode("\n", $html);
257
258
        $slideshow = apply_filters('metaslider_slideshow_output', $slideshow, $this->id, $this->settings);
259
260
        return $slideshow;
261
    }
262
263
    /**
264
     * Return the ID to use for the container
265
     */
266
    private function get_container_id()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
267
    {
268
        $container_id = 'metaslider_container_' . $this->id;
269
270
        $id = apply_filters('metaslider_container_id', $container_id, $this->id, $this->settings);
271
272
        return $id;
273
    }
274
275
    /**
276
     * Return the classes to use for the slidehsow container
277
     */
278
    private function get_container_class()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
279
    {
280
        $class = "metaslider metaslider-{$this->get_setting('type')} metaslider-{$this->id} ml-slider";
281
282
        // apply the css class setting
283
        if ($this->get_setting('cssClass') !== 'false') {
284
            $class .= ' ' . $this->get_setting('cssClass');
285
        }
286
287
        // handle any custom classes
288
        $class = apply_filters('metaslider_css_classes', $class, $this->id, $this->settings);
289
290
        return $class;
291
    }
292
293
    /**
294
     * Return the inline CSS style for the slideshow container.
295
     */
296
    private function get_container_style()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
297
    {
298
        // default
299
        $style = "max-width: {$this->get_setting('width')}px;";
300
301
        // carousels are always 100% wide
302
        if ($this->get_setting('carouselMode') === 'true' || ($this->get_setting('fullWidth') === 'true') && $this->get_setting('type') !== 'coin') {
303
            $style = 'width: 100%;';
304
        }
305
306
        // percentWidth showcode parameter takes precedence
307
        if ($this->get_setting('percentwidth') !== 'false' && $this->get_setting('percentwidth') > 0) {
308
            $style = "width: {$this->get_setting('percentwidth')}%;";
309
        }
310
311
        // center align the slideshow
312
        if ($this->get_setting('center') !== 'false') {
313
            $style .= ' margin: 0 auto;';
314
        }
315
316
        // handle any custom container styles
317
        $style = apply_filters('metaslider_container_style', $style, $this->id, $this->settings);
318
319
        return $style;
320
    }
321
322
    /**
323
     * Return the Javascript to kick off the slider. Code is wrapped in a timer
324
     * to allow for themes that load jQuery at the bottom of the page.
325
     *
326
     * Delay execution of slider code until jQuery is ready (supports themes where
327
     * jQuery is loaded at the bottom of the page)
328
     *
329
     * @return string javascript
330
     */
331
    private function get_inline_javascript()
332
    {
333
        $custom_js_before = $this->get_custom_javascript_before();
334
        $custom_js_after  = $this->get_custom_javascript_after();
335
336
        $script = 'var ' . $this->identifier . " = function($) {";
337
        $script .= $custom_js_before;
338
        $script .= "\n            $('#" . $this->identifier . "')." . $this->js_function . '({ ';
0 ignored issues
show
Bug introduced by
The property js_function does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
339
        $script .= "\n                " . $this->get_javascript_parameters();
340
        $script .= "\n            });";
341
        $script .= $custom_js_after;
342
        $script .= "\n        };";
343
        $script .= "\n        var timer_" . $this->identifier . ' = function() {';
344
        $script .= "\n            var slider = !window.jQuery ? window.setTimeout(timer_{$this->identifier}, 100) : !jQuery.isReady ? window.setTimeout(timer_{$this->identifier}, 100) : {$this->identifier}(window.jQuery);";
345
        $script .= "\n        };";
346
        $script .= "\n        timer_" . $this->identifier . '();';
347
348
        return $script;
349
    }
350
351
    /**
352
     * Custom HTML to add immediately below the markup
353
     */
354 View Code Duplication
    private function get_html_after()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
355
    {
356
        $type = $this->get_setting('type');
357
358
        $html = apply_filters("metaslider_{$type}_slider_html_after", '', $this->id, $this->settings);
359
360
        if (strlen($html)) {
361
            return "        {$html}";
362
        }
363
364
        return '';
365
    }
366
367
    /**
368
     * Custom JavaScript to execute immediately before the slideshow is initialized
369
     */
370
    private function get_custom_javascript_before()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
371
    {
372
        $type = $this->get_setting('type');
373
374
        $javascript = '';
375
376
        if ($this->get_setting('noConflict') === 'true' && $type === 'flex') {
377
            $javascript = "$('#metaslider_{$this->id}').addClass('flexslider'); // theme/plugin conflict avoidance";
378
        }
379
380
        $custom_js = apply_filters("metaslider_{$type}_slider_javascript_before", $javascript, $this->id);
381
382
        if (strlen($custom_js)) {
383
            return "\n            {$custom_js}";
384
        }
385
386
        return '';
387
    }
388
389
    /**
390
     * Custom Javascript to execute immediately after the slideshow is initialized
391
     */
392 View Code Duplication
    private function get_custom_javascript_after()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
393
    {
394
        $type = $this->get_setting('type');
395
396
        $custom_js = apply_filters("metaslider_{$type}_slider_javascript", '', $this->id);
397
398
        if (strlen($custom_js)) {
399
            return "\n            {$custom_js}";
400
        }
401
402
        return '';
403
    }
404
405
    /**
406
     * Build the javascript parameter arguments for the slider.
407
     *
408
     * @return string parameters
409
     */
410
    private function get_javascript_parameters()
411
    {
412
        $options = array();
413
414
        // construct an array of all parameters
415
        foreach ($this->get_default_parameters() as $name => $default) {
0 ignored issues
show
Bug introduced by
The expression $this->get_default_parameters() of type string is not traversable.
Loading history...
416
            if ($param = $this->get_param($name)) {
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class MetaSlider as the method get_param() does only exist in the following sub-classes of MetaSlider: MetaCoinSlider, MetaFlexSlider, MetaNivoSlider, MetaResponsiveSlider. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
417
                $val = $this->get_setting($name);
418
419
                if (gettype($default) === 'integer' || $val === 'true' || $val === 'false') {
420
                    $options[$param] = $val;
421
                } else {
422
                    $options[$param] = '"' . $val . '"';
423
                }
424
            }
425
        }
426
427
        // deal with any customised parameters
428
        $type    = $this->get_setting('type');
429
        $options = apply_filters("metaslider_{$type}_slider_parameters", $options, $this->id, $this->settings);
430
        $arg     = $type === 'flex' ? 'slider' : '';
431
432
        // create key:value strings
433
        foreach ($options as $key => $value) {
434
            if (is_array($value)) {
435
                $pairs[] = "{$key}: function($arg) {\n                " . implode("\n                ", $value) . "\n                }";
0 ignored issues
show
Coding Style Comprehensibility introduced by
$pairs was never initialized. Although not strictly required by PHP, it is generally a good practice to add $pairs = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
436
            } else {
437
                $pairs[] = "{$key}:{$value}";
0 ignored issues
show
Bug introduced by
The variable $pairs does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
438
            }
439
        }
440
441
        return implode(",\n                ", $pairs);
442
    }
443
444
    /**
445
     * Apply any custom inline styling
446
     *
447
     * @return string
448
     */
449 View Code Duplication
    private function get_inline_css()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
450
    {
451
        $css = apply_filters('metaslider_css', '', $this->settings, $this->id);
452
453
        // use this to add the scoped attribute for HTML5 validation (if needed)
454
        $attributes = apply_filters('metaslider_style_attributes', '', $this->settings, $this->id);
455
456
        if (strlen($css)) {
457
            return "<style type=\"text/css\"{$attributes}>{$css}\n    </style>";
458
        }
459
460
        return '';
461
    }
462
463
    /**
464
     * Include slider assets, JS and CSS paths are specified by child classes.
465
     */
466
    public function enqueue_scripts()
467
    {
468
        if ($this->get_setting('printJs') === 'true') {
469
            wp_enqueue_script('metaslider-' . $this->get_setting('type') . '-slider', METASLIDER_ASSETS_URL . $this->js_path, array('jquery'), METASLIDER_VERSION);
0 ignored issues
show
Bug introduced by
The property js_path does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
470
        }
471
472
        if ($this->get_setting('printCss') === 'true') {
473
            // this will be added to the bottom of the page as <head> has already been processed by WordPress.
474
            // For HTML5 compatibility, use a minification plugin to move the CSS to the <head>
475
            wp_enqueue_style('metaslider-' . $this->get_setting('type') . '-slider', METASLIDER_ASSETS_URL . $this->css_path, false, METASLIDER_VERSION);
0 ignored issues
show
Bug introduced by
The property css_path does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
476
            wp_enqueue_style('metaslider-public', METASLIDER_ASSETS_URL . 'metaslider/public.css', false, METASLIDER_VERSION);
477
        }
478
479
        do_action('metaslider_register_public_styles');
480
    }
481
482
    /**
483
     * Update the slider settings, converting checkbox values (on/off) to true or false.
484
     * @param $new_settings
485
     */
486
    public function update_settings($new_settings)
487
    {
488
        $old_settings = $this->get_settings();
489
490
        // convert submitted checkbox values from 'on' or 'off' to boolean values
491
        $checkboxes = array('noConflict', 'fullWidth', 'hoverPause', 'links', 'reverse', 'random', 'printCss', 'printJs', 'smoothHeight', 'center', 'smartCrop', 'carouselMode', 'autoPlay');
492
493
        foreach ($checkboxes as $checkbox) {
494
            if (isset($new_settings[$checkbox]) && $new_settings[$checkbox] === 'on') {
495
                $new_settings[$checkbox] = 'true';
496
            } else {
497
                $new_settings[$checkbox] = 'false';
498
            }
499
        }
500
501
        // update the slider settings
502
        update_post_meta($this->id, 'ml-slider_settings', array_merge((array)$old_settings, $new_settings));
503
504
        $this->settings = $this->get_settings();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->get_settings() can also be of type string. However, the property $settings is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
505
    }
506
507
    /**
508
     * Update the title of the slider
509
     * @param $title
510
     */
511
    private function update_title($title)
512
    {
513
        $slide = array(
514
            'ID'         => $this->id,
515
            'post_title' => $title
516
        );
517
518
        wp_update_post($slide);
519
    }
520
521
    /**
522
     * Delete a slide. This doesn't actually remove the slide from WordPress, simply untags
523
     * it from the slide taxonomy.
524
     *
525
     * @param int $slide_id
526
     */
527
    private function delete_slide($slide_id)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
528
    {
529
        // Get the existing terms and only keep the ones we don't want removed
530
        $new_terms     = array();
531
        $current_terms = wp_get_object_terms($slide_id, 'ml-slider', array('fields' => 'ids'));
532
        $term          = get_term_by('name', $this->id, 'ml-slider');
533
534
        foreach ($current_terms as $current_term) {
535
            if ($current_term != $term->term_id) {
536
                $new_terms[] = (int)$current_term;
537
            }
538
        }
539
540
        return wp_set_object_terms($slide_id, $new_terms, 'ml-slider');
541
    }
542
543
    /**
544
     * Loop over each slide and call the save action on each
545
     *
546
     * @param array $data - posted form data.
547
     */
548
    private function update_slides($data)
549
    {
550
        foreach ($data as $slide_id => $fields) {
551
            do_action("metaslider_save_{$fields['type']}_slide", $slide_id, $this->id, $fields);
552
        }
553
    }
554
}
555