Completed
Branch dev (aae49a)
by
unknown
19:32
created

AdminPageFramework_PointerToolBox::_shouldSkip()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 20
rs 8.8571
cc 6
eloc 12
nc 6
nop 3
1
<?php
2
/**
3
 * Displays notification in the administration area.
4
 *    
5
 * @package      Admin Page Framework
6
 * @copyright    Copyright (c) 2015, <Michael Uno>
7
 * @author       Michael Uno
8
 * @authorurl    http://michaeluno.jp
9
 */
10
11
/**
12
 * Displays pointer tool boxes in the admin area.
13
 * 
14
 * Usage:
15
 * 
16
 * `
17
 * new AdminPageFramework_PointerToolBox(
18
 *     'post',  // screen id or page slug
19
 *     'xyz140', // unique id for the pointer tool box
20
 *     array(  // pointer data
21
 *         'target'    => '#change-permalinks',
22
 *         'options'   => array(
23
 *             'content' => sprintf( '<h3> %s </h3> <p> %s </p>',
24
 *                 __( 'Title' ,'plugindomain'), 
25
 *                 __( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.','plugindomain')
26
 *             ),
27
 *             'position'  => array( 'edge' => 'top', 'align' => 'middle' )
28
 *         )
29
 *     )
30
 * );  
31
 *  
32
 * `
33
 * 
34
 * @since       DEVVER
35
 * @package     AdminPageFramework
36
 * @subpackage  Utility
37
 * @extends     AdminPageFramework_WPUtility
38
 */
39
class AdminPageFramework_PointerToolBox extends AdminPageFramework_WPUtility {
2 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...
Coding Style introduced by
As per PSR2, the opening brace for this class should be on a new line.
Loading history...
40
    
41
    static private $_bResourceLoaded = false;
1 ignored issue
show
Coding Style introduced by
Please declare explicit visibility instead of using a prefixed underscore.
Loading history...
42
        
43
    public $sPointerID;
44
    
45
    public $aPointerData;
46
    
47
    /**
48
     * User set screen IDs. Accepts APF page slugs.
49
     */
50
    public $aScreenIDs = array();
51
    
52
    
53
    /**
54
     * Sets up hooks and properties.
55
     * 
56
     * @since       DEVVER
57
     * @see         https://codex.wordpress.org/Plugin_API/Admin_Screen_Reference
58
     * @param       array|strin     $asScreenIDs        Screen IDs or page slug.
59
     * @param       string          $sPointerID         A unique pointer ID.
60
     * @Param       array           $aPointerData       The pointer data.
61
     */
62
    public function __construct( $asScreenIDs, $sPointerID, array $aPointerData ) {
0 ignored issues
show
Coding Style introduced by
__construct uses the super-global variable $GLOBALS 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
__construct 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...
63
64
        // Bail if the WordPress version is less than 3.3,
65
        if ( version_compare( $GLOBALS[ 'wp_version' ], '3.3', '<' ) ) {        
66
            return false;
0 ignored issues
show
Bug introduced by
Constructors do not have meaningful return values, anything that is returned from here is discarded. Are you sure this is correct?
Loading history...
67
        }       
68
    
69
        // Prints out the script in the background.
70
        if ( 'admin-page-framework-pointer-tool-box' === $this->getElement( $_GET, 'script' ) ) {
71
            exit( $this->_renderScript() );
0 ignored issues
show
Coding Style Compatibility introduced by
The method __construct() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
72
        }
73
        
74
        // Store the registration data to the property.
75
        $this->aScreenIDs    = $this->getAsArray( $asScreenIDs );
76
        $this->sPointerID    = $sPointerID;
77
        $this->aPointerData  = $aPointerData;
78
79
        $this->_setHooks( $this->aScreenIDs );
80
        
81
        if ( ! $this->_shouldProceed() ) {
82
            return;
83
        }
84
   
85
        add_action(
86
            'admin_enqueue_scripts', 
87
            array( $this, '_replyToLoadPointer' ),
88
            1000
89
        );
90
        
91
    }   
92
        /**
93
         * 
94
         */
95
        private function _setHooks( $aScreenIDs ) {
1 ignored issue
show
Coding Style introduced by
Method name "_setHooks" should not be prefixed with an underscore to indicate visibility
Loading history...
96
            foreach( $aScreenIDs as $_sScreenID ) {            
97
                if ( ! $_sScreenID ) {
98
                    continue;
99
                }
100
                add_filter( 
101
                    get_class( $this ) . '-' . $_sScreenID, 
102
                    array( $this, '_replyToSetPointer' )
103
                );
104
                                
105
            }       
106
        }    
107
        /**
108
         * @return      boolean
109
         */
110
        private function _shouldProceed() {
0 ignored issues
show
Coding Style introduced by
Method name "_shouldProceed" should not be prefixed with an underscore to indicate visibility
Loading history...
111
            if ( self::$_bResourceLoaded ) {
112
                return false;
113
            }            
114
            self::$_bResourceLoaded = true;
115
            return true;
116
        }
117
    
118
        /**
119
         * @callback    filter      {class name}-{screen id}
120
         * @return      array
121
         */
122
        public function _replyToSetPointer( $aPointers ) {
1 ignored issue
show
Coding Style introduced by
Method name "_replyToSetPointer" should not be prefixed with an underscore to indicate visibility
Loading history...
123
            return array(
124
                $this->sPointerID   => $this->aPointerData
125
            ) + $aPointers;
126
        }    
127
    
128
    /**
129
     * @callback        action      admin_enqueue_scripts
130
     */
131
    public function _replyToLoadPointer( /* $hook_suffix */ ) {
0 ignored issues
show
Coding Style introduced by
Method name "_replyToLoadPointer" should not be prefixed with an underscore to indicate visibility
Loading history...
132
    
133
        $_aPointers = $this->_getPointers();
134
             
135
        if ( empty( $_aPointers ) || ! is_array( $_aPointers ) ) {
136
            return;
137
        }
138
        
139
        $this->_loadScripts( 
140
            $this->_getValidPointers( $_aPointers )
141
        );
142
        
143
    }
144
        /**
145
         * Get pointers for this screen
146
         * @return      array
147
         */
148
        private function _getPointers() {
1 ignored issue
show
Coding Style introduced by
_getPointers 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...
Coding Style introduced by
Method name "_getPointers" should not be prefixed with an underscore to indicate visibility
Loading history...
149
            
150
            $_oScreen   = get_current_screen();
151
            $_sScreenID = $_oScreen->id;    
152
            if ( in_array( $_sScreenID, $this->aScreenIDs ) ) {
153
                return apply_filters( get_class( $this ) . '-' . $_sScreenID, array() );
154
            } 
155
            
156
            if ( isset( $_GET[ 'page' ] ) ) {
157
                return apply_filters( get_class( $this ) . '-' . $_GET[ 'page' ], array() );
158
            }
159
            return array();
160
            
161
        }
162
    
163
        /**
164
         * @return      array
165
         * @since       DEVVER
166
         */
167
        private function _getValidPointers( $_aPointers ) {
1 ignored issue
show
Coding Style introduced by
Method name "_getValidPointers" should not be prefixed with an underscore to indicate visibility
Loading history...
168
        
169
            // Get dismissed pointers
170
            $_aDismissed      = explode( 
171
                ',', 
172
                ( string ) get_user_meta( 
173
                    get_current_user_id(), 
174
                    'dismissed_wp_pointers', 
175
                    true 
176
               )
177
            );
178
            $_aValidPointers = array(
179
                'pointers'  => array(),
180
            );
181
         
182
            // Check pointers and remove dismissed ones.
183
            foreach ( $_aPointers as $_iPointerID => $_aPointer ) {
184
                
185
                $_aPointer = $_aPointer + array(
186
                    'target'        => null,
187
                    'options'       => null,
188
                    'pointer_id'    => null,
189
                );
190
                
191
                // Sanity check
192
                if ( $this->_shouldSkip( $_iPointerID, $_aDismissed, $_aPointer ) ) {
193
                    continue;
194
                }
195
196
                $_aPointer[ 'pointer_id' ] = $_iPointerID;
197
         
198
                // Add the pointer to $_aValidPointers array
199
                $_aValidPointers[ 'pointers' ][] =  $_aPointer;
200
                
201
            }            
202
            return $_aValidPointers;
203
            
204
        }        
205
            /**
206
             * @return      boolean
207
             * @since       DEVVER
208
             */
209
            private function _shouldSkip( $_iPointerID, $_aDismissed, $_aPointer ) {
1 ignored issue
show
Coding Style introduced by
Method name "_shouldSkip" should not be prefixed with an underscore to indicate visibility
Loading history...
210
                
211
                if ( in_array( $_iPointerID, $_aDismissed ) ) {
212
                    return true;
213
                }               
214
                if ( empty( $_aPointer ) ) {
215
                    return true;
216
                }
217
                if ( empty( $_iPointerID ) ) {
218
                    return true;
219
                }
220
                if ( empty( $_aPointer[ 'target' ] ) ) {
221
                    return true;
222
                }
223
                if ( empty( $_aPointer[ 'options' ] ) ) {
224
                    return true;
225
                }
226
                return false;
227
                
228
            }   
229
            
230
        private function _loadScripts( $_aValidPointers ) {
0 ignored issues
show
Coding Style introduced by
Method name "_loadScripts" should not be prefixed with an underscore to indicate visibility
Loading history...
231
               
232
            // No valid pointers? Stop here.
233
            if ( empty( $_aValidPointers ) ) {
234
                return;
235
            }           
236
            
237
            wp_enqueue_script( 'jquery' );         
238
         
239
            // Add pointers style to queue.
240
            wp_enqueue_style( 'wp-pointer' );
241
         
242
            // Add pointers script to queue. Add custom script.
243
            wp_enqueue_script( 
244
                'admin-page-framework-pointer',     // handle id
245
                add_query_arg( 
246
                    array( 
247
                        'script' => 'admin-page-framework-pointer-tool-box'
248
                    ), 
249
                    admin_url()
250
                ),
251
                array( 'wp-pointer' ) 
252
            );
253
         
254
            // Add pointer options to script.
255
            wp_localize_script( 
256
                'admin-page-framework-pointer',     // handle id
257
                'AdminPageFrameworkPointerToolBoxes',    // data name
258
                $_aValidPointers 
259
            );
260
            
261
        }    
262
263
    /**
264
     * Renders the script.
265
     */
266
    public function _renderScript() {
0 ignored issues
show
Coding Style introduced by
Method name "_renderScript" should not be prefixed with an underscore to indicate visibility
Loading history...
267
        echo $this->_getScript();
268
    }
269
        /**
270
         * Returns an inline JavaScript script.
271
         * 
272
         * @since       DEVVER
273
         * @return      string     
274
         */
275
        public function _getScript() {
0 ignored issues
show
Coding Style introduced by
Method name "_getScript" should not be prefixed with an underscore to indicate visibility
Loading history...
276
            
277
            /**
278
             * Checks checkboxes in siblings.
279
             */
280
            return <<<JAVASCRIPTS
281
( function( $ ) {
282
jQuery( document ).ready( function( $ ) {
283
    
284
    $.each( AdminPageFrameworkPointerToolBoxes.pointers, function( iIndex, _aPointer ) {
285
        
286
        var _aOptions = $.extend( _aPointer.options, {
287
            close: function() {
288
                $.post( ajaxurl, {
289
                    pointer: _aPointer.pointer_id,
290
                    action: 'dismiss-wp-pointer'
291
                });
292
            }
293
        });
294
 
295
        $( _aPointer.target ).pointer( _aOptions ).pointer( 'open' );
296
297
    });
298
});
299
}( jQuery ));
300
JAVASCRIPTS;
301
        
302
        } 
303
    
304
}
1 ignored issue
show
Coding Style introduced by
According to PSR2, the closing brace of classes should be placed on the next line directly after the body.

Below you find some examples:

// Incorrect placement according to PSR2
class MyClass
{
    public function foo()
    {

    }
    // This blank line is not allowed.

}

// Correct
class MyClass
{
    public function foo()
    {

    } // No blank lines after this line.
}
Loading history...