Admin Page Framework Documentation
  • Package
  • Class
  • Tree

Packages

  • AdminPageFramework
    • FieldType
    • MetaBox
    • Page
    • PostType
    • TaxonomyField

Classes

  • AdminPageFramework
  • AdminPageFramework_Menu
  • AdminPageFramework_Page
  • AdminPageFramework_Setting
  1 <?php
  2 /**
  3  * Admin Page Framework
  4  * 
  5  * http://en.michaeluno.jp/admin-page-framework/
  6  * Copyright (c) 2013-2014 Michael Uno; Licensed MIT
  7  * 
  8  */
  9 if ( ! class_exists( 'AdminPageFramework_Menu' ) ) :
 10 /**
 11  * Provides methods to manipulate menu items.
 12  *
 13  * @abstract
 14  * @since           2.0.0
 15  * @extends         AdminPageFramework_Page
 16  * @package         AdminPageFramework
 17  * @subpackage      Page
 18  * @staticvar       array   $_aBuiltInRootMenuSlugs stores the WordPress built-in menu slugs.
 19  * @staticvar       array   $_aStructure_SubMenuPageForUser represents the structure of the sub-menu page array.
 20  */
 21 abstract class AdminPageFramework_Menu extends AdminPageFramework_Page {
 22     
 23     /**
 24      * Used to refer the built-in root menu slugs.
 25      * 
 26      * @since           2.0.0
 27      * @remark          Not for the user.
 28      * @var             array           Holds the built-in root menu slugs.
 29      * @static
 30      * @internal
 31      */ 
 32     protected static $_aBuiltInRootMenuSlugs = array(
 33         // All keys must be lower case to support case insensitive look-ups.
 34         'dashboard' =>          'index.php',
 35         'posts' =>              'edit.php',
 36         'media' =>              'upload.php',
 37         'links' =>              'link-manager.php',
 38         'pages' =>              'edit.php?post_type=page',
 39         'comments' =>           'edit-comments.php',
 40         'appearance' =>         'themes.php',
 41         'plugins' =>            'plugins.php',
 42         'users' =>              'users.php',
 43         'tools' =>              'tools.php',
 44         'settings' =>           'options-general.php',
 45         'network admin' =>      "network_admin_menu",
 46     );      
 47 
 48     /** 
 49      * Represents the structure of the sub-menu link array for the users.
 50      * @since           2.0.0
 51      * @since           2.1.4           Changed to be static since it is used from multiple classes.
 52      * @since           3.0.0           Moved from the link class.
 53      * @remark          The scope is public because this is accessed from an extended class.
 54      * @internal
 55      */ 
 56     protected static $_aStructure_SubMenuLinkForUser = array(       
 57         'type' => 'link',   
 58         'title' => null,    // required
 59         'href' => null,     // required
 60         'capability' => null,   // optional
 61         'order' => null,    // optional
 62         'show_page_heading_tab' => true,
 63         'show_in_menu' => true,
 64     );
 65         
 66     /**
 67      * Represents the structure of sub-menu page array for the users.
 68      * 
 69      * @since           2.0.0
 70      * @remark          Not for the user.
 71      * @var             array           Holds array structure of sub-menu page.
 72      * @static
 73      * @internal
 74      */ 
 75     protected static $_aStructure_SubMenuPageForUser = array(
 76         'type'                      => 'page',  // this is used to compare with the link type.
 77         'title'                     => null, 
 78         'page_slug'                 => null, 
 79         'screen_icon'               => null,    // this will become either href_icon_32x32 or screen_icon_id
 80         'capability'                => null, 
 81         'order'                     => null,
 82         'show_page_heading_tab'     => true,    // if this is false, the page title won't be displayed in the page heading tab.
 83         'show_in_menu'              => true,    // if this is false, the menu label will not be displayed in the sidebar menu.      
 84         'href_icon_32x32'           => null,
 85         'screen_icon_id'            => null,
 86         // 'show_menu'                  => null,    <-- not sure what this was for.
 87         'show_page_title'           => null,
 88         'show_page_heading_tabs'    => null,
 89         'show_in_page_tabs'         => null,
 90         'in_page_tab_tag'           => null,
 91         'page_heading_tab_tag'      => null,
 92     );
 93          
 94      /**
 95       * Registers necessary callbacks and sets up properties.
 96       * 
 97       * @internal
 98       */
 99     function __construct( $sOptionKey=null, $sCallerPath=null, $sCapability=null, $sTextDomain='admin-page-framework' ) {
100         
101         add_action( 'admin_menu', array( $this, '_replyToBuildMenu' ), 98 );        
102         
103         parent::__construct( $sOptionKey, $sCallerPath, $sCapability, $sTextDomain );
104         
105     } 
106      
107     /**
108      * Sets to which top level page is going to be adding sub-pages.
109      * 
110      * <h4>Example</h4>
111      * <code>$this->setRootMenuPage( 'Settings' );
112      * </code>
113      * <code>$this->setRootMenuPage( 
114      *  'APF Form',
115      *  plugins_url( 'image/screen_icon32x32.jpg', __FILE__ )
116      * );</code>
117      * 
118      * @acecss          public
119      * @since           2.0.0
120      * @since           2.1.6           The $sIcon16x16 parameter accepts a file path.
121      * @since           3.0.0           The scope was changed to public from protected.
122      * @remark          Only one root page can be set per one class instance.
123      * @param           string          If the method cannot find the passed string from the following listed items, it will create a top level menu item with the passed string. ( case insensitive )
124      * <blockquote>Dashboard, Posts, Media, Links, Pages, Comments, Appearance, Plugins, Users, Tools, Settings, Network Admin</blockquote>
125      * @param           string          ( optional ) the source of menu icon with either of the following forms:
126      * <ul>
127      *  <li>the URL of the menu icon with the size of 16 by 16 in pixel.</li>
128      *  <li>the file path of the menu icon with the size of 16 by 16 in pixel.</li>
129      *  <li>the name of a Dashicons helper class to use a font icon, e.g. <code>dashicons-editor-customchar</code>.</li>
130      *  <li>the string, 'none', to leave div.wp-menu-image empty so an icon can be added via CSS.</li>
131      *  <li>a base64-encoded SVG using a data URI, which will be colored to match the color scheme. This should begin with 'data:image/svg+xml;base64,'.</li>
132      * </ul>
133      * @param           string          ( optional ) the position number that is passed to the <var>$position</var> parameter of the <a href="http://codex.wordpress.org/Function_Reference/add_menu_page">add_menu_page()</a> function.
134      * @return          void
135      */
136     public function setRootMenuPage( $sRootMenuLabel, $sIcon16x16=null, $iMenuPosition=null ) {
137 
138         $sRootMenuLabel = trim( $sRootMenuLabel );
139         $sSlug = $this->_isBuiltInMenuItem( $sRootMenuLabel );  // if true, this method returns the slug
140         $this->oProp->aRootMenu = array(
141             'sTitle'            => $sRootMenuLabel,
142             'sPageSlug'         => $sSlug ? $sSlug : $this->oProp->sClassName,  
143             'sIcon16x16'        => $this->oUtil->resolveSRC( $sIcon16x16 ),
144             'iPosition'         => $iMenuPosition,
145             'fCreateRoot'       => $sSlug ? false : true,
146         );  
147                     
148     }
149         /**
150          * Checks if a menu item is a WordPress built-in menu item from the given menu label.
151          * 
152          * @since           2.0.0
153          * @internal
154          * @return          void|string         Returns the associated slug string, if true.
155          */ 
156         private function _isBuiltInMenuItem( $sMenuLabel ) {
157             
158             $sMenuLabelLower = strtolower( $sMenuLabel );
159             if ( array_key_exists( $sMenuLabelLower, self::$_aBuiltInRootMenuSlugs ) )
160                 return self::$_aBuiltInRootMenuSlugs[ $sMenuLabelLower ];
161             
162         }   
163     
164     /**
165      * Sets the top level menu page by page slug.
166      * 
167      * The page should be already created or scheduled to be created separately.
168      * 
169      * <h4>Example</h4>
170      * <code>$this->setRootMenuPageBySlug( 'edit.php?post_type=apf_posts' );
171      * </code>
172      * 
173      * @since           2.0.0
174      * @since           3.0.0           The scope was changed to public from protected.
175      * @access          public
176      * @param           string          The page slug of the top-level root page.
177      * @return          void
178      */ 
179     public function setRootMenuPageBySlug( $sRootMenuSlug ) {
180         
181         $this->oProp->aRootMenu['sPageSlug'] = $sRootMenuSlug;  // do not sanitize the slug here because post types includes a question mark.
182         $this->oProp->aRootMenu['fCreateRoot'] = false;     // indicates to use an existing menu item. 
183         
184     }
185     
186     /**
187     * Adds sub-menu items on the left sidebar menu of the administration panel. 
188     * 
189     * It supports pages and links. Each of them has the specific array structure.
190     * 
191     * <h4>Example</h4>
192     * <code>$this->addSubMenuItems(
193     *       array(
194     *           'title' => 'Various Form Fields',
195     *           'page_slug' => 'first_page',
196     *           'screen_icon' => 'options-general',
197     *       ),
198     *       array(
199     *           'title' => 'Manage Options',
200     *           'page_slug' => 'second_page',
201     *           'screen_icon' => 'link-manager',
202     *       ),
203     *       array(
204     *           'title' => 'Google',
205     *           'href' => 'http://www.google.com',  
206     *           'show_page_heading_tab' => false,   // this removes the title from the page heading tabs.
207     *       ),
208     *   );</code>
209     * 
210     * @since            2.0.0
211     * @since            3.0.0           Changed the scope to public.
212     * @remark           The sub menu page slug should be unique because add_submenu_page() can add one callback per page slug.
213     * @remark           Accepts variadic parameters; the number of accepted parameters are not limited to three.
214     * @param            array           a first sub-menu array. A sub-menu array can be a link or a page. The array structures are as follows:
215     * <h4>Sub-menu Page Array</h4>
216     * <ul>
217     * <li><strong>title</strong> - ( string ) the page title of the page.</li>
218     * <li><strong>page_slug</strong> - ( string ) the page slug of the page. Non-alphabetical characters should not be used including dots(.) and hyphens(-).</li>
219     * <li><strong>screen_icon</strong> - ( optional, string ) either the ID selector name from the following list or the icon URL. The size of the icon should be 32 by 32 in pixel. This is for WordPress 3.7.x or below.
220     *   <pre>edit, post, index, media, upload, link-manager, link, link-category, edit-pages, page, edit-comments, themes, plugins, users, profile, user-edit, tools, admin, options-general, ms-admin, generic</pre>
221     *   <p>( Notes: the <em>generic</em> icon is available WordPress version 3.5 or above.)</p> 
222     * </li>
223     * <li><strong>capability</strong> - ( optional, string ) the access level to the created admin pages defined <a href="http://codex.wordpress.org/Roles_and_Capabilities">here</a>. If not set, the overall capability assigned in the class constructor, which is *manage_options* by default, will be used.</li>
224     * <li><strong>order</strong> - ( optional, integer ) the order number of the page. The lager the number is, the lower the position it is placed in the menu.</li>
225     * <li><strong>show_page_heading_tab</strong> - ( optional, boolean ) if this is set to false, the page title won't be displayed in the page heading tab. Default: true.</li>
226     * </ul>
227     * <h4>Sub-menu Link Array</h4>
228     * <ul>
229     * <li><strong>title</strong> - ( string ) the link title.</li>
230     * <li><strong>href</strong> - ( string ) the URL of the target link.</li>
231     * <li><strong>capability</strong> - ( optional, string ) the access level to show the item, defined <a href="http://codex.wordpress.org/Roles_and_Capabilities">here</a>. If not set, the overall capability assigned in the class constructor, which is *manage_options* by default, will be used.</li>
232     * <li><strong>order</strong> - ( optional, integer ) the order number of the page. The lager the number is, the lower the position it is placed in the menu.</li>
233     * <li><strong>show_page_heading_tab</strong> - ( optional, boolean ) if this is set to false, the page title won't be displayed in the page heading tab. Default: true.</li>
234     * </ul>
235     * @param            array       ( optional ) a second sub-menu array.
236     * @param            array       ( optional ) a third and add items as many as necessary with next parameters.
237     * @access           public
238     * @return           void
239     */      
240     public function addSubMenuItems( $aSubMenuItem1, $aSubMenuItem2=null, $_and_more=null ) {
241         foreach ( func_get_args() as $aSubMenuItem ) 
242             $this->addSubMenuItem( $aSubMenuItem );     
243     }
244     
245     /**
246     * Adds the given sub-menu item on the left sidebar menu of the administration panel.
247     * 
248     * It supports pages and links. Each of them has the specific array structure.
249     * 
250     * @since            2.0.0
251     * @since            3.0.0           Changed the scope to public.
252     * @remark           The sub menu page slug should be unique because add_submenu_page() can add one callback per page slug.
253     * @param            array           a sub-menu array. It can be a page or a link. The array structures are as follows:
254     * <h4>Sub-menu Page Array</h4>
255     * <ul>
256     * <li><strong>title</strong> - ( string ) the page title of the page.</li>
257     * <li><strong>page_slug</strong> - ( string ) the page slug of the page. Non-alphabetical characters should not be used including dots(.) and hyphens(-).</li>
258     * <li><strong>screen_icon</strong> - ( optional, string ) either the ID selector name from the following list or the icon URL. The size of the icon should be 32 by 32 in pixel. This is for WordPress 3.7.x or below.
259     *   <pre>edit, post, index, media, upload, link-manager, link, link-category, edit-pages, page, edit-comments, themes, plugins, users, profile, user-edit, tools, admin, options-general, ms-admin, generic</pre>
260     *   <p>( Notes: the <em>generic</em> icon is available WordPress version 3.5 or above.)</p> 
261     * </li>
262     * <li><strong>capability</strong> - ( optional, string ) the access level to the created admin pages defined <a href="http://codex.wordpress.org/Roles_and_Capabilities">here</a>. If not set, the overall capability assigned in the class constructor, which is *manage_options* by default, will be used.</li>
263     * <li><strong>order</strong> - ( optional, integer ) the order number of the page. The lager the number is, the lower the position it is placed in the menu.</li>
264     * <li><strong>show_page_heading_tab</strong> - ( optional, boolean ) if this is set to false, the page title won't be displayed in the page heading tab. Default: true.</li>
265     * </ul>
266     * <h4>Sub-menu Link Array</h4>
267     * <ul>
268     * <li><strong>title</strong> - ( string ) the link title.</li>
269     * <li><strong>href</strong> - ( string ) the URL of the target link.</li>
270     * <li><strong>capability</strong> - ( optional, string ) the access level to show the item, defined <a href="http://codex.wordpress.org/Roles_and_Capabilities">here</a>. If not set, the overall capability assigned in the class constructor, which is *manage_options* by default, will be used.</li>
271     * <li><strong>order</strong> - ( optional, integer ) the order number of the page. The lager the number is, the lower the position it is placed in the menu.</li>
272     * <li><strong>show_page_heading_tab</strong> - ( optional, boolean ) if this is set to false, the page title won't be displayed in the page heading tab. Default: true.</li>
273     * </ul>
274     * @access           public
275     * @return           void
276     */  
277     public function addSubMenuItem( array $aSubMenuItem ) {
278         if ( isset( $aSubMenuItem['href'] ) ) 
279             $this->addSubMenuLink( $aSubMenuItem );
280         else 
281             $this->addSubMenuPage( $aSubMenuItem );
282     }
283 
284     /**
285     * Adds the given link into the menu on the left sidebar of the administration panel.
286     * 
287     * @since            2.0.0
288     * @since            3.0.0           Changed the scope to public from protected.
289     * @param            string          the menu title.
290     * @param            string          the URL linked to the menu.
291     * @param            string          ( optional ) the <a href="http://codex.wordpress.org/Roles_and_Capabilities" target="_blank">access level</a>.
292     * @param            string          ( optional ) the order number. The larger it is, the lower the position it gets.
293     * @param            string          ( optional ) if set to false, the menu title will not be listed in the tab navigation menu at the top of the page.
294     * @access           protected
295     * @return           void
296     * @internal
297     */  
298     protected function addSubMenuLink( array $aSubMenuLink ) {
299         
300         // If required keys are not set, return.
301         if ( ! isset( $aSubMenuLink['href'], $aSubMenuLink['title'] ) ) return;
302         
303         // If the set URL is not valid, return.
304         if ( ! filter_var( $aSubMenuLink['href'], FILTER_VALIDATE_URL ) ) return;
305 
306         $this->oProp->aPages[ $aSubMenuLink['href'] ] = $this->_formatSubmenuLinkArray( $aSubMenuLink );
307             
308     }   
309     
310     /**
311      * Adds sub-menu pages.
312      * 
313      * It is recommended to use addSubMenuItems() instead, which supports external links.
314      * 
315      * @since           2.0.0
316      * @since           3.0.0           The scope was changed to public from protected.
317      * @internal
318      * @return          void
319      * @remark          The sub menu page slug should be unique because add_submenu_page() can add one callback per page slug.
320      */ 
321     protected function addSubMenuPages() {
322         foreach ( func_get_args() as $aSubMenuPage ) 
323             $this->addSubMenuPage( $aSubMenuPage );
324     }
325     
326     /**
327      * Adds a single sub-menu page.
328      * 
329      * <h4>Example</h4>
330      * <code>
331         $this->addSubMenuPage(
332             array(
333                 'title' => __( 'First Page', 'admin-page-framework-demo' ),
334                 'page_slug' => 'apf_first_page',
335             ),
336             array(
337                 'title' => __( 'Second Page', 'admin-page-framework-demo' ),
338                 'page_slug' => 'apf_second_page',
339             )
340         );</code>
341      * 
342      * 
343      * @access          public
344      * @since           2.0.0
345      * @since           2.1.2           A key name was changed.
346      * @since           2.1.6           $sScreenIcon accepts a file path.
347      * @since           3.0.0           The scope was changed to public from protected. Deprecated all the parameters made it to accept them as an array. A key name was changed.
348      * @remark          The sub menu page slug should be unique because add_submenu_page() can add one callback per page slug.
349      * @param           array           The sub menu page array.
350      * <h4>Sub Menu Page Array</h4>
351      * <ul>
352      *  <li>title - ( required ) the title of the page.</li>
353      *  <li>page_slug - ( required ) the slug of the page. Do not use hyphens as it serves as the callback method name.</li>
354      *  <li>screen icon - ( optional ) Either a screen icon ID, a url of the icon, or a file path to the icon, with the size of 32 by 32 in pixel. The accepted icon IDs are as follows.</li>
355      * <blockquote>edit, post, index, media, upload, link-manager, link, link-category, edit-pages, page, edit-comments, themes, plugins, users, profile, user-edit, tools, admin, options-general, ms-admin, generic</blockquote>
356      * ( Note: the <em>generic</em> ID is available since WordPress 3.5. )
357      *  <li>capability - ( optional ) The <a href="http://codex.wordpress.org/Roles_and_Capabilities">access level</a> to the page.</li>
358      *  <li>order - ( optional ) the order number of the page. The lager the number is, the lower the position it is placed in the menu.</li>
359      *  <li>show_page_heading_tab - ( optional ) If this is set to false, the page title won't be displayed in the page heading tab. Default: true.</li>
360      *  <li>show_in_menu - ( optional ) If this is set to false, the page title won't be displayed in the sidebar menu while the page is still accessible. Default: true.</li>
361      * </ul>
362      * @return          void
363      * @internal
364      */ 
365     protected function addSubMenuPage( array $aSubMenuPage ) {
366 
367         if ( ! isset( $aSubMenuPage['page_slug'] ) ) return;
368             
369         $aSubMenuPage['page_slug'] = $this->oUtil->sanitizeSlug( $aSubMenuPage['page_slug'] );
370         $this->oProp->aPages[ $aSubMenuPage['page_slug'] ] = $this->_formatSubMenuPageArray( $aSubMenuPage );
371         
372     }
373                     
374     /**
375      * Builds the sidebar menu of the added pages.
376      * 
377      * @since           2.0.0
378      * @internal
379      */
380     public function _replyToBuildMenu() {
381         
382         // If the root menu label is not set but the slug is set, 
383         if ( $this->oProp->aRootMenu['fCreateRoot'] ) 
384             $this->_registerRootMenuPage();
385         
386         // Apply filters to let other scripts add sub menu pages.
387         $this->oProp->aPages = $this->oUtil->addAndApplyFilter(     // Parameters: $oCallerObject, $sFilter, $vInput, $vArgs...
388             $this,
389             "pages_{$this->oProp->sClassName}", 
390             $this->oProp->aPages
391         );
392         
393         // Sort the page array.
394         uasort( $this->oProp->aPages, array( $this, '_sortByOrder' ) ); 
395         
396         // Set the default page, the first element.
397         foreach ( $this->oProp->aPages as $aPage ) {
398             
399             if ( ! isset( $aPage['page_slug'] ) ) continue;
400             $this->oProp->sDefaultPageSlug = $aPage['page_slug'];
401             break;
402             
403         }
404         
405         // Register them.
406         foreach ( $this->oProp->aPages as &$aSubMenuItem ) {
407             $aSubMenuItem = $this->_formatSubMenuItemArray( $aSubMenuItem );    // needs to be sanitized because there are hook filters applied to this array.
408             $aSubMenuItem['_page_hook'] = $this->_registerSubMenuItem( $aSubMenuItem ); // store the page hook; this is same as the value stored in the global $page_hook or $hook_suffix variable. 
409         }
410                         
411         // After adding the sub menus, if the root menu is created, remove the page that is automatically created when registering the root menu.
412         if ( $this->oProp->aRootMenu['fCreateRoot'] ) 
413             remove_submenu_page( $this->oProp->aRootMenu['sPageSlug'], $this->oProp->aRootMenu['sPageSlug'] );
414         
415     }   
416         
417         /**
418          * Registers the root menu page.
419          * 
420          * @since           2.0.0
421          * @internal
422          */ 
423         private function _registerRootMenuPage() {
424             $this->oProp->aRootMenu['_page_hook'] = add_menu_page(  
425                 $this->oProp->sClassName,                       // Page title - will be invisible anyway
426                 $this->oProp->aRootMenu['sTitle'],              // Menu title - should be the root page title.
427                 $this->oProp->sCapability,                      // Capability - access right
428                 $this->oProp->aRootMenu['sPageSlug'],           // Menu ID 
429                 '', //array( $this, $this->oProp->sClassName ),     // Page content displaying function - the root page will be removed so no need to register a function.
430                 $this->oProp->aRootMenu['sIcon16x16'],      // icon path
431                 isset( $this->oProp->aRootMenu['iPosition'] ) ? $this->oProp->aRootMenu['iPosition'] : null // menu position
432             );
433         }
434         
435         /**
436          * Formats the sub-menu item arrays.
437          * @since           3.0.0
438          * @internal
439          */
440         private function _formatSubMenuItemArray( $aSubMenuItem ) {
441             
442             if ( isset( $aSubMenuItem['page_slug'] ) )
443                 return $this->_formatSubMenuPageArray( $aSubMenuItem );
444                 
445             if ( isset( $aSubMenuItem['href'] ) )
446                 return $this->_formatSubmenuLinkArray( $aSubMenuItem ); 
447                 
448             return array();
449             
450         }
451         
452         /**
453          * Formats the given sub-menu link array.
454          * @since           3.0.0
455          * @internal
456          */
457         private function _formatSubmenuLinkArray( $aSubMenuLink ) {
458             
459             // If the set URL is not valid, return.
460             if ( ! filter_var( $aSubMenuLink['href'], FILTER_VALIDATE_URL ) ) return array();
461             
462             return $this->oUtil->uniteArrays(       
463                 array(  
464                     'capability'    => isset( $aSubMenuLink['capability'] ) ? $aSubMenuLink['capability'] : $this->oProp->sCapability,
465                     'order'         => isset( $aSubMenuLink['order'] ) && is_numeric( $aSubMenuLink['order'] ) ? $aSubMenuLink['order'] : count( $this->oProp->aPages ) + 10,
466                 ),
467                 $aSubMenuLink + self::$_aStructure_SubMenuLinkForUser
468             );          
469             
470         }
471         /**
472          * Formats the given sub-menu page array.
473          * @since           3.0.0
474          * @internal
475          */
476         private function _formatSubMenuPageArray( $aSubMenuPage ) {
477             
478             $aSubMenuPage = $aSubMenuPage + self::$_aStructure_SubMenuPageForUser;
479 
480             $aSubMenuPage['screen_icon_id'] = trim( $aSubMenuPage['screen_icon_id'] );          
481             return $this->oUtil->uniteArrays(
482                 array( 
483                     'href_icon_32x32'           => $this->oUtil->resolveSRC( $aSubMenuPage['screen_icon'], true ),
484                     'screen_icon_id'            => in_array( $aSubMenuPage['screen_icon'], self::$_aScreenIconIDs ) ? $aSubMenuPage['screen_icon'] : 'generic',     // $_aScreenIconIDs is defined in the page class.
485                     'capability'                => isset( $aSubMenuPage['capability'] ) ? $aSubMenuPage['capability'] : $this->oProp->sCapability,
486                     'order'                     => is_numeric( $aSubMenuPage['order'] ) ? $aSubMenuPage['order'] : count( $this->oProp->aPages ) + 10,
487                 ),
488                 $aSubMenuPage,
489                 array(
490                     'show_page_title'           => $this->oProp->bShowPageTitle,            // boolean
491                     'show_page_heading_tabs'    => $this->oProp->bShowPageHeadingTabs,      // boolean
492                     'show_in_page_tabs'         => $this->oProp->bShowInPageTabs,           // boolean
493                     'in_page_tab_tag'           => $this->oProp->sInPageTabTag,             // string
494                     'page_heading_tab_tag'      => $this->oProp->sPageHeadingTabTag,        // string
495                 )
496             );          
497             
498         }
499         
500         /**
501          * Registers the sub-menu item.
502          * 
503          * @since           2.0.0
504          * @since           3.0.0           Changed the name from registerSubMenuPage().
505          * @remark          Used in the buildMenu() method. 
506          * @remark          Within the <em>admin_menu</em> hook callback process.
507          * @remark          The sub menu page slug should be unique because add_submenu_page() can add one callback per page slug.
508          * @internal
509          */ 
510         private function _registerSubMenuItem( $aArgs ) {
511                 
512             // Variables
513             $sType = $aArgs['type'];    // page or link
514             $sTitle = $sType == 'page' ? $aArgs['title'] : $aArgs['title'];
515             $sCapability = isset( $aArgs['capability'] ) ? $aArgs['capability'] : $this->oProp->sCapability;
516             $_sPageHook = '';
517 
518             // Check the capability
519             if ( ! current_user_can( $sCapability ) ) return;       
520             
521             // Add the sub-page to the sub-menu         
522             $sRootPageSlug = $this->oProp->aRootMenu['sPageSlug'];
523             $sMenuLabel = plugin_basename( $sRootPageSlug );    // Make it compatible with the add_submenu_page() function.
524             
525             // If it's a page - it's possible that the page_slug key is not set if the user uses a method like setPageHeadingTabsVisibility() prior to addSubMenuItam().
526             if ( $sType == 'page' && isset( $aArgs['page_slug'] ) ) {       
527                 
528                 $sPageSlug = $aArgs['page_slug'];
529                 $_sPageHook = add_submenu_page( 
530                     $sRootPageSlug,                     // the root(parent) page slug
531                     $sTitle,                                // page_title
532                     $sTitle,                                // menu_title
533                     $sCapability,                           // capability
534                     $sPageSlug, // menu_slug
535                     // In admin.php ( line 149 of WordPress v3.6.1 ), do_action($page_hook) ( where $page_hook is $_sPageHook )
536                     // will be executed and it triggers the __call magic method with the method name of "md5 class hash + _page_ + this page slug".
537                     array( $this, $this->oProp->sClassHash . '_page_' . $sPageSlug )
538                 );          
539                 
540                 add_action( "load-" . $_sPageHook , array( $this, "load_pre_" . $sPageSlug ) );
541 
542                 // If the visibility option is false, remove the one just added from the sub-menu array
543                 if ( ! $aArgs['show_in_menu'] ) {
544 
545                     foreach( ( array ) $GLOBALS['submenu'][ $sMenuLabel ] as $iIndex => $aSubMenu ) {
546                         
547                         if ( ! isset( $aSubMenu[ 3 ] ) ) continue;
548                         
549                         // the array structure is defined in plugin.php - $submenu[$parent_slug][] = array ( $menu_title, $capability, $menu_slug, $page_title ) 
550                         if ( $aSubMenu[0] == $sTitle && $aSubMenu[3] == $sTitle && $aSubMenu[2] == $sPageSlug ) {
551                             unset( $GLOBALS['submenu'][ $sMenuLabel ][ $iIndex ] );
552                             
553                             // The page title in the browser window title bar will miss the page title as this is left as it is.
554                             $this->oProp->aHiddenPages[ $sPageSlug ] = $sTitle;
555                             add_filter( 'admin_title', array( $this, '_replyToFixPageTitleForHiddenPages' ), 10, 2 );
556                             
557                             break;
558                         }
559                     }
560                 } 
561                     
562             } 
563             // If it's a link,
564             if ( $sType == 'link' && $aArgs['show_in_menu'] ) {
565                 
566                 if ( ! isset( $GLOBALS['submenu'][ $sMenuLabel ] ) )
567                     $GLOBALS['submenu'][ $sMenuLabel ] = array();
568                 
569                 $GLOBALS['submenu'][ $sMenuLabel ][] = array ( 
570                     $sTitle, 
571                     $sCapability, 
572                     $aArgs['href'],
573                 );  
574             }
575         
576             return $_sPageHook; // will be stored in the $this->oProp->aPages property.
577 
578         }       
579         
580         /**
581          * A callback function for the admin_title filter to fix the page title for hidden pages.
582          * @since           2.1.4
583          * @internal
584          */
585         public function _replyToFixPageTitleForHiddenPages( $sAdminTitle, $sPageTitle ) {
586 
587             if ( isset( $_GET['page'], $this->oProp->aHiddenPages[ $_GET['page'] ] ) )
588                 return $this->oProp->aHiddenPages[ $_GET['page'] ] . $sAdminTitle;
589                 
590             return $sAdminTitle;
591             
592         }       
593 }
594 endif;
Admin Page Framework Documentation API documentation generated by ApiGen 2.8.0