Completed
Branch dev (a3767f)
by Michael
40:38
created

_replyToSetPointer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 5
rs 9.4286
cc 1
eloc 4
nc 1
nop 1
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_PointerToolTip(
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_PointerToolTip 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
    /**
44
     * Stores pointer data.
45
     */
46
    static private $aPointers = array();
47
    
48
    /**
49
     * Stores the pointer tool box id for the class instance.
50
     */
51
    public $sPointerID;
52
    
53
    /**
54
     * Stores the pointer tool box defintion for the class instance.
55
     */
56
    public $aPointerData;
57
    
58
    /**
59
     * User set screen IDs. Accepts APF page slugs.
60
     */
61
    public $aScreenIDs = array();
62
    
63
    
64
    /**
65
     * Sets up hooks and properties.
66
     * 
67
     * @since       DEVVER
68
     * @see         https://codex.wordpress.org/Plugin_API/Admin_Screen_Reference
69
     * @param       array|strin     $asScreenIDs        Screen IDs or page slug.
70
     * @param       string          $sPointerID         A unique pointer ID.
71
     * @Param       array           $aPointerData       The pointer data.
72
     */
73
    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...
74
75
        // Bail if the WordPress version is less than 3.3,
76
        if ( version_compare( $GLOBALS[ 'wp_version' ], '3.3', '<' ) ) {        
77
            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...
78
        }       
79
    
80
        // Store the registration data to the property.
81
        $this->aScreenIDs    = $this->getAsArray( $asScreenIDs );
82
        $this->sPointerID    = $sPointerID;
83
        $this->aPointerData  = $aPointerData;
84
85
        $this->_setHooks( $this->aScreenIDs );        
86
        
87
    }   
88
        /**
89
         * Sets up hooks.
90
         * @since       DEVVER
91
         */
92
        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...
93
            
94
            foreach( $aScreenIDs as $_sScreenID ) {            
95
                if ( ! $_sScreenID ) {
96
                    continue;
97
                }
98
                add_filter( 
99
                    get_class( $this ) . '-' . $_sScreenID, 
100
                    array( $this, '_replyToSetPointer' )
101
                );
102
                                
103
            }       
104
            
105
            if ( ! $this->_hasBeenCalled() ) {
106
                return;
107
            } 
108
            
109
            // Checks the screen id and page slug and add items if they match the current screen
110
            add_action(
111
                'admin_enqueue_scripts', 
112
                array( $this, '_replyToLoadPointers' ),
113
                1000
114
            );            
115
                        
116
        }    
117
            /**
118
             * @return      boolean
119
             */
120
            private function _hasBeenCalled() {
1 ignored issue
show
Coding Style introduced by
Method name "_hasBeenCalled" should not be prefixed with an underscore to indicate visibility
Loading history...
121
                if ( self::$_bResourceLoaded ) {
122
                    return false;
123
                }            
124
                self::$_bResourceLoaded = true;
125
                return true;
126
            }
127
    
128
        /**
129
         * @callback    filter      {class name}-{screen id}
130
         * @return      array
131
         */
132
        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...
133
            return array(
134
                $this->sPointerID   => $this->aPointerData
135
            ) + $aPointers;
136
        }    
137
    
138
    /**
139
     * Checks the screen id and page slug and add items if they match the current screen
140
     * 
141
     * @callback    action      admin_enqueue_scripts
142
     * @since       DEVVER
143
     * @return      void
144
     */
145
    public function _replyToLoadPointers( /* $hook_suffix */ ) {
1 ignored issue
show
Coding Style introduced by
Method name "_replyToLoadPointers" should not be prefixed with an underscore to indicate visibility
Loading history...
146
    
147
        $_aPointers = $this->_getValidPointers( $this->_getPointers() );
148
             
149
        if ( empty( $_aPointers ) || ! is_array( $_aPointers ) ) {
150
            return;
151
        }
152
        
153
        $this->_enqueueScripts(); 
154
        
155
        self::$aPointers = $_aPointers + self::$aPointers;
156
        
157
    }
158
        /**
159
         * Get pointers for this screen.
160
         * @since       DEVVER
161
         * @return      array
162
         */
163
        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...
164
            
165
            $_oScreen   = get_current_screen();
166
            $_sScreenID = $_oScreen->id;    
167
            if ( in_array( $_sScreenID, $this->aScreenIDs ) ) {
168
                return apply_filters( get_class( $this ) . '-' . $_sScreenID, array() );
169
            } 
170
            
171
            if ( isset( $_GET[ 'page' ] ) ) {
172
                return apply_filters( get_class( $this ) . '-' . $_GET[ 'page' ], array() );
173
            }
174
            return array();
175
            
176
        }
177
    
178
        /**
179
         * @return      array
180
         * @since       DEVVER
181
         */
182
        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...
183
        
184
            // Get dismissed pointers
185
            $_aDismissed      = explode( 
186
                ',', 
187
                ( string ) get_user_meta( 
188
                    get_current_user_id(), 
189
                    'dismissed_wp_pointers', 
190
                    true 
191
               )
192
            );
193
            $_aValidPointers = array();
194
         
195
            // Check pointers and remove dismissed ones.
196
            foreach ( $_aPointers as $_iPointerID => $_aPointer ) {
197
                
198
                $_aPointer = $_aPointer + array(
199
                    'target'        => null,
200
                    'options'       => null,
201
                    'pointer_id'    => null,
202
                );
203
                
204
                // Sanity check
205
                if ( $this->_shouldSkip( $_iPointerID, $_aDismissed, $_aPointer ) ) {
206
                    continue;
207
                }
208
209
                $_aPointer[ 'pointer_id' ] = $_iPointerID;
210
                
211
                // Add the pointer to $_aValidPointers array
212
                $_aValidPointers[] =  $_aPointer;
213
                
214
            }            
215
            return $_aValidPointers;
216
            
217
        }        
218
            
219
            /**
220
             * @return      boolean
221
             * @since       DEVVER
222
             */
223
            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...
224
                
225
                if ( in_array( $_iPointerID, $_aDismissed ) ) {
226
                    return true;
227
                }               
228
                if ( empty( $_aPointer ) ) {
229
                    return true;
230
                }
231
                if ( empty( $_iPointerID ) ) {
232
                    return true;
233
                }
234
                if ( empty( $_aPointer[ 'target' ] ) ) {
235
                    return true;
236
                }
237
                if ( empty( $_aPointer[ 'options' ] ) ) {
238
                    return true;
239
                }
240
                return false;
241
                
242
            }   
243
        
244
        /**
245
         * Enqueues scripts.
246
         */
247
        private function _enqueueScripts() {
1 ignored issue
show
Coding Style introduced by
Method name "_enqueueScripts" should not be prefixed with an underscore to indicate visibility
Loading history...
248
               
249
            wp_enqueue_script( 'jquery' );         
250
         
251
            // Add pointers style to queue.
252
            wp_enqueue_script( 'wp-pointer' );
253
            wp_enqueue_style( 'wp-pointer' );
254
255
            // Embeds the inline script
256
            add_action( 
257
                'admin_print_footer_scripts',
258
                array( $this, '_replyToInsertInlineScript' )
259
            );            
260
            
261
        }    
262
    
263
    /**
264
     * @since       DVVER
265
     * @callback    action      admin_print_footer_scripts
266
     */
267
    public function _replyToInsertInlineScript() {
1 ignored issue
show
Coding Style introduced by
Method name "_replyToInsertInlineScript" should not be prefixed with an underscore to indicate visibility
Loading history...
268
   
269
        echo "<script type='text/javascript' class='admin-page-framework-pointer-tool-tip'>"
270
            . '/* <![CDATA[ */'
271
            . $this->_getInlineScript( self::$aPointers )
272
            . '/* ]]> */'
273
        . "</script>";
274
        
275
    }
276
        /**
277
         * Returns an inline JavaScript script.
278
         * 
279
         * @since       DEVVER
280
         * @return      string     
281
         */
282
        public function _getInlineScript( $aPointers=array() ) {
1 ignored issue
show
Coding Style introduced by
Method name "_getInlineScript" should not be prefixed with an underscore to indicate visibility
Loading history...
283
284
            $_aJSArray      = json_encode( $aPointers );
285
286
            /**
287
             * Checks checkboxes in siblings.
288
             */
289
            return <<<JAVASCRIPTS
290
( function( jQuery ) {
291
jQuery( document ).ready( function( jQuery ) {
292
    jQuery.each( $_aJSArray, function( iIndex, _aPointer ) {
293
        var _aOptions = jQuery.extend( _aPointer.options, {
294
            close: function() {
295
console.log( 'dismissing: ' + _aPointer.pointer_id );
296
                jQuery.post( ajaxurl, {
297
                    pointer: _aPointer.pointer_id,
298
                    action: 'dismiss-wp-pointer'
299
                });
300
            }
301
        });
302
        jQuery( _aPointer.target ).pointer( _aOptions ).pointer( 'open' );
303
    });
304
});
305
}( jQuery ));
306
JAVASCRIPTS;
307
        
308
        }         
309
    
310
}
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...