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_Page' ) ) :
 10 /**
 11  * Provides methods to render admin page elements.
 12  *
 13  * @abstract
 14  * @extends         AdminPageFramework_Page_MetaBox
 15  * @since           2.0.0
 16  * @since           2.1.0       Extends AdminPageFramework_HelpPane_Page.
 17  * @since           3.0.0       No longer extends AdminPageFramework_HelpPane_Page.
 18  * @package         AdminPageFramework
 19  * @subpackage      Page
 20  * @staticvar       array       $_aScreenIconIDs                    stores the ID selector names for screen icons.
 21  * @staticvar       array       $_aHookPrefixes                         stores the prefix strings for filter and action hooks.
 22  * @staticvar       array       $_aStructure_InPageTabElements      represents the array structure of an in-page tab array.
 23  */
 24 abstract class AdminPageFramework_Page extends AdminPageFramework_Page_MetaBox {
 25                 
 26     /**
 27      * Stores the ID selector names for screen icons. <em>generic</em> is not available in WordPress v3.4.x.
 28      * 
 29      * @since           2.0.0
 30      * @var             array
 31      * @static
 32      * @access          protected
 33      * @internal
 34      */     
 35     protected static $_aScreenIconIDs = array(
 36         'edit', 'post', 'index', 'media', 'upload', 'link-manager', 'link', 'link-category', 
 37         'edit-pages', 'page', 'edit-comments', 'themes', 'plugins', 'users', 'profile', 
 38         'user-edit', 'tools', 'admin', 'options-general', 'ms-admin', 'generic',
 39     );  
 40 
 41     /**
 42      * Represents the array structure of an in-page tab array.
 43      * 
 44      * @since           2.0.0
 45      * @var             array
 46      * @static
 47      * @access          private
 48      * @internal
 49      */     
 50     private static $_aStructure_InPageTabElements = array(
 51         'page_slug' => null,
 52         'tab_slug' => null,
 53         'title' => null,
 54         'order' => null,
 55         'show_in_page_tab'  => true,
 56         'parent_tab_slug' => null,  // this needs to be set if the above show_in_page_tab is false so that the framework can mark the parent tab to be active when the hidden page is accessed.
 57     );
 58         
 59     /**
 60      * Registers necessary hooks and sets up properties.
 61      * 
 62      * @internal
 63      */
 64     function __construct( $sOptionKey=null, $sCallerPath=null, $sCapability=null, $sTextDomain='admin-page-framework' ) {   
 65     
 66         add_action( 'admin_menu', array( $this, '_replyToFinalizeInPageTabs' ), 99 );   // must be called before the _replyToRegisterSettings() method which uses the same hook.
 67                 
 68         parent::__construct( $sOptionKey, $sCallerPath, $sCapability, $sTextDomain );
 69                 
 70     }
 71     
 72     /**
 73      * Adds in-page tabs.
 74      *
 75      * The parameters accept in-page tab arrays and they must have the following array keys.
 76      * 
 77      * <h4>Example</h4>
 78      * <code>$this->addInPageTabs(
 79      *      array(
 80      *          'page_slug' => 'myfirstpage'
 81      *          'tab_slug' => 'firsttab',
 82      *          'title' => __( 'Text Fields', 'my-text-domain' ),
 83      *      ),
 84      *      array(
 85      *          'page_slug' => 'myfirstpage'
 86      *          'tab_slug' => 'secondtab',
 87      *          'title' => __( 'Selectors and Checkboxes', 'my-text-domain' ),
 88      *      )
 89      *  );</code>
 90      *
 91      * <code>$this->addInPageTabs(
 92      *      'myfirstpage', // sets the target page slug
 93      *      array(
 94      *          'tab_slug' => 'firsttab',
 95      *          'title' => __( 'Text Fields', 'my-text-domain' ),
 96      *      ),
 97      *      array(
 98      *          'tab_slug' => 'secondtab',
 99      *          'title' => __( 'Selectors and Checkboxes', 'my-text-domain' ),
100      *      )
101      *  );</code>
102      * @since           2.0.0
103      * @since           3.0.0           Changed the scope to public. Added page slug target support. 
104      * @param           array           $aTab1          The in-page tab array.
105      * <h4>In-Page Tab Array</h4>
106      * <ul>
107      *  <li><strong>page_slug</strong> - ( string ) the page slug that the tab belongs to.</li>
108      *  <li><strong>tab_slug</strong> -  ( string ) the tab slug. Non-alphabetical characters should not be used including dots(.) and hyphens(-).</li>
109      *  <li><strong>title</strong> - ( string ) the title of the tab.</li>
110      *  <li><strong>order</strong> - ( optional, integer ) the order number of the tab. The lager the number is, the lower the position it is placed in the menu.</li>
111      *  <li><strong>show_in_page_tab</strong> - ( optional, boolean ) default: false. If this is set to false, the tab title will not be displayed in the tab navigation menu; however, it is still accessible from the direct URL.</li>
112      *  <li><strong>parent_tab_slug</strong> - ( optional, string ) this needs to be set if the above show_in_page_tab is true so that the parent tab will be emphasized as active when the hidden page is accessed.</li>
113      * </ul>
114      * @param           array           $aTab2          Another in-page tab array.
115      * @param           array           $_and_more          Add in-page tab arrays as many as necessary to the next parameters.
116      * @param           string          (optional) $sPageSlug           If the passed parameter item is a string, it will be stored as the target page slug so that it will be applied to the next passed tab arrays as the page_slug element.
117      * @remark          Accepts variadic parameters; the number of accepted parameters are not limited to three.
118      * @remark          In-page tabs are different from page-heading tabs which is automatically added with page titles.     
119      * @return          void
120      */             
121     public function addInPageTabs( $aTab1, $aTab2=null, $_and_more=null ) {
122         foreach( func_get_args() as $asTab ) $this->addInPageTab( $asTab );
123     }
124     
125     /**
126      * Adds an in-page tab.
127      * 
128      * The singular form of the addInPageTabs() method, which takes only one parameter.
129      * 
130      * @since           2.0.0
131      * @since           3.0.0           Changed the scope to public.
132      * @param           array|string    $asInPageTab            The in-page tab array or the target page slug. If the target page slug is set, the page_slug key can be omitted from next calls.
133      * @remark          Use this method to add in-page tabs to ensure the array holds all the necessary keys.
134      * @remark          In-page tabs are different from page-heading tabs which are automatically added with page titles.
135      * @return          void
136      */         
137     public function addInPageTab( $asInPageTab ) {  
138         
139         static $__sTargetPageSlug;  // stores the target page slug which will be applied when no page slug is specified.
140         if ( ! is_array( $asInPageTab ) ) {
141             $__sTargetPageSlug = is_string( $asInPageTab ) ? $asInPageTab : $__sTargetPageSlug; // set the target page slug
142             return;
143         }       
144         
145         $aInPageTab = $this->oUtil->uniteArrays( $asInPageTab, self::$_aStructure_InPageTabElements, array( 'page_slug' => $__sTargetPageSlug ) );  // avoid undefined index warnings.                  
146         $__sTargetPageSlug = $aInPageTab['page_slug'];  // set the target page slug for next calls
147         if ( ! isset( $aInPageTab['page_slug'], $aInPageTab['tab_slug'] ) ) return; // check the required keys.
148         
149         $iCountElement = isset( $this->oProp->aInPageTabs[ $aInPageTab['page_slug'] ] ) ? count( $this->oProp->aInPageTabs[ $aInPageTab['page_slug'] ] ) : 0;
150         $aInPageTab = array(    // sanitize some elements
151             'page_slug' =>  $this->oUtil->sanitizeSlug( $aInPageTab['page_slug'] ),
152             'tab_slug'  =>  $this->oUtil->sanitizeSlug( $aInPageTab['tab_slug'] ),
153             'order' =>  is_numeric( $aInPageTab['order'] ) ? $aInPageTab['order'] : $iCountElement + 10,
154         ) + $aInPageTab;
155 
156         $this->oProp->aInPageTabs[ $aInPageTab['page_slug'] ][ $aInPageTab['tab_slug'] ] = $aInPageTab;
157     
158     }       
159     
160     /**
161      * Sets whether the page title is displayed or not.
162      * 
163      * <h4>Example</h4>
164      * <code>$this->setPageTitleVisibility( false );    // disables the page title.
165      * </code>
166      * 
167      * @since           2.0.0
168      * @since           3.0.0           Changed the scope to public.
169      * @param           boolean         $bShow          If false, the page title will not be displayed.
170      * @return          void
171      */ 
172     public function setPageTitleVisibility( $bShow=true, $sPageSlug='' ) {
173         
174         $sPageSlug = $this->oUtil->sanitizeSlug( $sPageSlug );
175         if ( $sPageSlug ) {
176             $this->oProp->aPages[ $sPageSlug ]['show_page_title'] = $bShow;
177             return;
178         }
179         $this->oProp->bShowPageTitle = $bShow;
180         foreach( $this->oProp->aPages as &$aPage ) 
181             $aPage['show_page_title'] = $bShow;
182         
183     }   
184     
185     /**
186      * Sets whether page-heading tabs are displayed or not.
187      * 
188      * <h4>Example</h4>
189      * <code>$this->setPageHeadingTabsVisibility( false );    // disables the page heading tabs by passing false.
190      * </code>
191      * 
192      * @since           2.0.0
193      * @since           3.0.0           Changed the scope to public.
194      * @param           boolean         $bShow                  If false, page-heading tabs will be disabled; otherwise, enabled.
195      * @param           string          $sPageSlug          The page to apply the visibility setting. If not set, it applies to all the pages.
196      * @remark          Page-heading tabs and in-page tabs are different. The former displays page titles and the latter displays tab titles.
197      * @remark          If the second parameter is omitted, it sets the default value.
198      */ 
199     public function setPageHeadingTabsVisibility( $bShow=true, $sPageSlug='' ) {
200         
201         $sPageSlug = $this->oUtil->sanitizeSlug( $sPageSlug );
202         if ( $sPageSlug ) {
203             $this->oProp->aPages[ $sPageSlug ]['show_page_heading_tabs'] = $bShow;
204             return;         
205         }       
206         $this->oProp->bShowPageHeadingTabs = $bShow;
207         foreach( $this->oProp->aPages as &$aPage ) 
208             $aPage['show_page_heading_tabs'] = $bShow;
209         
210     }
211     
212     /**
213      * Sets whether in-page tabs are displayed or not.
214      * 
215      * Sometimes, it is required to disable in-page tabs in certain pages. In that case, use the second parameter.
216      * 
217      * @since           2.1.1
218      * @since           3.0.0           Changed the scope to public. Changed the name from showInPageTabs() to setInPageTabsVisibility().
219      * @param           boolean         $bShow              If false, in-page tabs will be disabled.
220      * @param           string          $sPageSlug      The page to apply the visibility setting. If not set, it applies to all the pages.
221      * @remark          If the second parameter is omitted, it sets the default value.
222      */
223     public function setInPageTabsVisibility( $bShow=true, $sPageSlug='' ) {
224         
225         $sPageSlug = $this->oUtil->sanitizeSlug( $sPageSlug );
226         if ( $sPageSlug ) {
227             $this->oProp->aPages[ $sPageSlug ]['show_in_page_tabs'] = $bShow;
228             return;
229         }
230         $this->oProp->bShowInPageTabs = $bShow;
231         foreach( $this->oProp->aPages as &$aPage )
232             $aPage['show_in_page_tabs'] = $bShow;
233         
234     }
235     
236     /**
237      * Sets in-page tab's HTML tag.
238      * 
239      * <h4>Example</h4>
240      * <code>$this->setInPageTabTag( 'h2' );
241      * </code>
242      * 
243      * @since           2.0.0
244      * @since           3.0.0           Changed the scope to public.
245      * @param           string          $sTag                   The HTML tag that encloses each in-page tab title. Default: h3.
246      * @param           string          $sPageSlug          The page slug that applies the setting. 
247      * @remark          If the second parameter is omitted, it sets the default value.
248      */     
249     public function setInPageTabTag( $sTag='h3', $sPageSlug='' ) {
250         
251         $sPageSlug = $this->oUtil->sanitizeSlug( $sPageSlug );
252         if ( $sPageSlug ) {
253             $this->oProp->aPages[ $sPageSlug ]['in_page_tab_tag'] = $sTag;
254             return;
255         }
256         $this->oProp->sInPageTabTag = $sTag;
257         foreach( $this->oProp->aPages as &$aPage )
258             $aPage['in_page_tab_tag'] = $sTag;
259         
260     }
261     
262     /**
263      * Sets page-heading tab's HTML tag.
264      * 
265      * <h4>Example</h4>
266      * <code>$this->setPageHeadingTabTag( 'h2' );
267      * </code>
268      * 
269      * @since           2.1.2
270      * @since           3.0.0           Changed the scope to public.
271      * @param           string          $sTag                   The HTML tag that encloses the page-heading tab title. Default: h2.
272      * @param           string          $sPageSlug          The page slug that applies the setting. 
273      * @remark          If the second parameter is omitted, it sets the default value.
274      */
275     public function setPageHeadingTabTag( $sTag='h2', $sPageSlug='' ) {
276         
277         $sPageSlug = $this->oUtil->sanitizeSlug( $sPageSlug );
278         if ( $sPageSlug ) {
279             $this->oProp->aPages[ $sPageSlug ]['page_heading_tab_tag'] = $sTag;
280             return;
281         }
282         $this->oProp->sPageHeadingTabTag = $sTag;
283         foreach( $this->oProp->aPages as &$aPage )
284             $aPage[ $sPageSlug ]['page_heading_tab_tag'] = $sTag;
285         
286     }
287     
288     /*
289      * Internal Methods
290      */
291     
292     /**
293      * Renders the admin page.
294      * 
295      * @remark          This is not intended for the users to use.
296      * @since           2.0.0
297      * @access          protected
298      * @return          void
299      * @internal
300      */ 
301     protected function _renderPage( $sPageSlug, $sTabSlug=null ) {
302 
303         // Do actions before rendering the page. In this order, global -> page -> in-page tab
304         $this->oUtil->addAndDoActions( $this, $this->oUtil->getFilterArrayByPrefix( 'do_before_', $this->oProp->sClassName, $sPageSlug, $sTabSlug, true ) );    
305         ?>
306         <div class="wrap">
307             <?php
308                 // Screen icon, page heading tabs(page title), and in-page tabs.
309                 $sContentTop = $this->_getScreenIcon( $sPageSlug ); 
310                 $sContentTop .= $this->_getPageHeadingTabs( $sPageSlug, $this->oProp->sPageHeadingTabTag );     
311                 $sContentTop .= $this->_getInPageTabs( $sPageSlug, $this->oProp->sInPageTabTag );
312 
313                 // Apply filters in this order, in-page tab -> page -> global.
314                 echo $this->oUtil->addAndApplyFilters( $this, $this->oUtil->getFilterArrayByPrefix( 'content_foot_', $this->oProp->sClassName, $sPageSlug, $sTabSlug, false ), $sContentTop );
315 
316             ?>
317             <div class="admin-page-framework-container">    
318                 <?php
319                     $this->_showSettingsErrors();
320                     $this->oUtil->addAndDoActions( $this, $this->oUtil->getFilterArrayByPrefix( 'do_form_', $this->oProp->sClassName, $sPageSlug, $sTabSlug, true ) );  
321                     echo $this->_getFormOpeningTag();   // <form ... >
322                 ?>
323                 <div id="poststuff">
324                     <div id="post-body" class="metabox-holder columns-<?php echo $this->_getNumberOfColumns(); ?>">
325                     <?php
326                         $this->_printMainContent( $sPageSlug, $sTabSlug );
327                         $this->_printMetaBox( 'side', 1 );  // defined in the parrent class.
328                         $this->_printMetaBox( 'normal', 2 );
329                         $this->_printMetaBox( 'advanced', 3 );
330                     ?>                      
331                     </div><!-- #post-body -->   
332                 </div><!-- #poststuff -->
333                 
334             <?php echo $this->_getFormClosingTag( $sPageSlug, $sTabSlug );  // </form> ?>
335             </div><!-- .admin-page-framework-container -->
336                 
337             <?php   
338                 // Apply the content_bottom filters.
339                 echo $this->oUtil->addAndApplyFilters( $this, $this->oUtil->getFilterArrayByPrefix( 'content_bottom_', $this->oProp->sClassName, $sPageSlug, $sTabSlug, false ), '' );  // empty string
340             ?>
341         </div><!-- .wrap -->
342         <?php
343         // Do actions after rendering the page.
344         $this->oUtil->addAndDoActions( $this, $this->oUtil->getFilterArrayByPrefix( 'do_after_', $this->oProp->sClassName, $sPageSlug, $sTabSlug, true ) );
345         
346     }
347 
348         /**
349          * Renders the main content of the admin page.
350          * @since           3.0.0
351          */
352         private function _printMainContent( $sPageSlug, $sTabSlug ) {
353             
354             /* Check if a sidebar meta box is registered */
355             $_bIsSideMetaboxExist = ( isset( $GLOBALS['wp_meta_boxes'][ $GLOBALS['page_hook'] ][ 'side' ] ) && count( $GLOBALS['wp_meta_boxes'][ $GLOBALS['page_hook'] ][ 'side' ] ) > 0 );
356 
357             echo "<!-- main admin page content -->";
358             echo "<div class='admin-page-framework-content'>";
359             if ( $_bIsSideMetaboxExist ) 
360                 echo "<div id='post-body-content'>";
361     
362             /* Capture the output buffer */
363             ob_start(); // start buffer
364                                         
365             // Render the form elements by Settings API
366             if ( $this->oProp->bEnableForm ) {
367 
368                 // this value also determines the $option_page global variable value. This is important to get redirected back from option.php page.
369                 // This also is needed for page meta box fields.
370                 settings_fields( $this->oProp->sOptionKey );    
371                 
372                 // do_settings_sections( $sPageSlug ); // deprecated                        
373                 if ( $this->oForm->isPageAdded( $sPageSlug ) ) {
374 
375                     $oFieldsTable = new AdminPageFramework_FormTable( $this->oProp->aFieldTypeDefinitions, $this->oMsg );
376                     $this->oForm->setCurrentPageSlug( $sPageSlug );
377                     $this->oForm->setCurrentTabSlug( $sTabSlug );
378                     $this->oForm->applyConditions();
379                     $this->oForm->applyFiltersToFields( $this, $this->oProp->sClassName );  // applies filters to the conditioned field definition arrays.
380                     $this->oForm->setDynamicElements( $this->oProp->aOptions ); // will update $this->oForm->aConditionedFields
381                     
382                     echo $oFieldsTable->getFormTables( $this->oForm->aConditionedSections, $this->oForm->aConditionedFields, array( $this, '_replyToGetSectionHeaderOutput' ), array( $this, '_replyToGetFieldOutput' ) );
383                     // echo $oFieldsTable->getFormTables( $this->oForm->getFieldsByPageSlug( $sPageSlug, $sTabSlug ), array( $this, '_replyToGetSectionHeaderOutput' ), array( $this, '_replyToGetFieldOutput' ) );
384                 } 
385                 
386             }               
387              
388             $sContent = ob_get_contents(); // assign the content buffer to a variable
389             ob_end_clean(); // end buffer and remove the buffer
390                         
391             // Apply the content filters.
392             echo $this->oUtil->addAndApplyFilters( $this, $this->oUtil->getFilterArrayByPrefix( 'content_', $this->oProp->sClassName, $sPageSlug, $sTabSlug, false ), $sContent );
393 
394             // Do the page actions.
395             $this->oUtil->addAndDoActions( $this, $this->oUtil->getFilterArrayByPrefix( 'do_', $this->oProp->sClassName, $sPageSlug, $sTabSlug, true ) );           
396             
397             if ( $_bIsSideMetaboxExist )
398                 echo "</div><!-- #post-body-content -->";
399             echo "</div><!-- .admin-page-framework-content -->";
400         }
401     
402         /**
403          * Retrieves the form opening tag.
404          * 
405          * @since           2.0.0
406          * @internal
407          */ 
408         private function _getFormOpeningTag() { 
409             return $this->oProp->bEnableForm
410                 ? "<form action='options.php' method='post' enctype='{$this->oProp->sFormEncType}' id='admin-page-framework-form'>"
411                 : "";
412         }
413         /**
414          * Retrieves the form closing tag.
415          * 
416          * @since           2.0.0
417          * @internal
418          */     
419         private function _getFormClosingTag( $sPageSlug, $sTabSlug ) {
420             return $this->oProp->bEnableForm 
421                 ? "<input type='hidden' name='page_slug' value='{$sPageSlug}' />" . PHP_EOL
422                     . "<input type='hidden' name='tab_slug' value='{$sTabSlug}' />" . PHP_EOL           
423                     . "<input type='hidden' name='_is_admin_page_framework' value='1' />" . PHP_EOL         
424                     . "</form><!-- End Form -->"
425                 : '';
426         }   
427     
428         /**
429          * Displays admin notices set for the settings.
430          * 
431          * @global          $pagenow
432          * @since           2.0.0
433          * @since           2.0.1           Fixed a bug that the admin messages were displayed twice in the options-general.php page.
434          * @return          void
435          * @internal        
436          */ 
437         private function _showSettingsErrors() {
438             
439             // WordPress automatically performs the settings_errors() function in the options pages. See options-head.php.
440             if ( $GLOBALS['pagenow'] == 'options-general.php' ) return; 
441             
442             $aSettingsMessages = get_settings_errors( $this->oProp->sOptionKey );
443             
444             // If custom messages are added, remove the default one. 
445             if ( count( $aSettingsMessages ) > 1 ) 
446                 $this->_removeDefaultSettingsNotice();
447             
448             settings_errors( $this->oProp->sOptionKey );    // Show the message like "The options have been updated" etc.
449         
450         }
451             /**
452              * Removes default admin notices set for the settings.
453              * 
454              * This removes the settings messages ( admin notice ) added automatically by the framework when the form is submitted.
455              * This is used when a custom message is added manually and the default message should not be displayed.
456              * 
457              * @since           2.0.0
458              * @internal
459              */ 
460             private function _removeDefaultSettingsNotice() {
461                         
462                 global $wp_settings_errors;
463                 /*
464                  * The structure of $wp_settings_errors
465                  *  array(
466                  *      array(
467                             'setting' => $setting,
468                             'code' => $code,
469                             'message' => $message,
470                             'type' => $type
471                         ),
472                         array( ...
473                     )
474                  * */
475                 
476                 $aDefaultMessages = array(
477                     $this->oMsg->__( 'option_cleared' ),
478                     $this->oMsg->__( 'option_updated' ),
479                 );
480                 
481                 foreach ( ( array ) $wp_settings_errors as $iIndex => $aDetails ) {
482                     
483                     if ( $aDetails['setting'] != $this->oProp->sOptionKey ) continue;
484                     
485                     if ( in_array( $aDetails['message'], $aDefaultMessages ) )
486                         unset( $wp_settings_errors[ $iIndex ] );
487                         
488                 }
489             }       
490     
491         /**
492          * Retrieves the screen icon output as HTML.
493          * 
494          * @remark          the screen object is supported in WordPress 3.3 or above.
495          * @since           2.0.0
496          */     
497         private function _getScreenIcon( $sPageSlug ) {
498 
499             // If the icon path is explicitly set, use it.
500             if ( isset( $this->oProp->aPages[ $sPageSlug ]['href_icon_32x32'] ) ) 
501                 return '<div class="icon32" style="background-image: url(' . $this->oProp->aPages[ $sPageSlug ]['href_icon_32x32'] . ');"><br /></div>';
502             
503             // If the screen icon ID is explicitly set, use it.
504             if ( isset( $this->oProp->aPages[ $sPageSlug ]['screen_icon_id'] ) )
505                 return '<div class="icon32" id="icon-' . $this->oProp->aPages[ $sPageSlug ]['screen_icon_id'] . '"><br /></div>';
506                 
507             // Retrieve the screen object for the current page.
508             $oScreen = get_current_screen();
509             $sIconIDAttribute = $this->_getScreenIDAttribute( $oScreen );
510 
511             $sClass = 'icon32';
512             if ( empty( $sIconIDAttribute ) && $oScreen->post_type ) 
513                 $sClass .= ' ' . sanitize_html_class( 'icon32-posts-' . $oScreen->post_type );
514             
515             if ( empty( $sIconIDAttribute ) || $sIconIDAttribute == $this->oProp->sClassName )
516                 $sIconIDAttribute = 'generic';      // the default value
517             
518             return '<div id="icon-' . $sIconIDAttribute . '" class="' . $sClass . '"><br /></div>';
519                 
520         }
521             /**
522              * Retrieves the screen ID attribute from the given screen object.
523              * 
524              * @since           2.0.0
525              */     
526             private function _getScreenIDAttribute( $oScreen ) {
527                 
528                 if ( ! empty( $oScreen->parent_base ) )
529                     return $oScreen->parent_base;
530             
531                 if ( 'page' == $oScreen->post_type )
532                     return 'edit-pages';        
533                     
534                 return esc_attr( $oScreen->base );
535                 
536             }
537 
538         /**
539          * Retrieves the output of page heading tab navigation bar as HTML.
540          * 
541          * @since           2.0.0
542          * @return          string          the output of page heading tabs.
543          */         
544         private function _getPageHeadingTabs( $sCurrentPageSlug, $sTag='h2', $aOutput=array() ) {
545             
546             // If the page title is disabled, return an empty string.
547             if ( ! $this->oProp->aPages[ $sCurrentPageSlug ][ 'show_page_title' ] ) return "";
548 
549             $sTag = $this->oProp->aPages[ $sCurrentPageSlug ][ 'page_heading_tab_tag' ]
550                 ? $this->oProp->aPages[ $sCurrentPageSlug ][ 'page_heading_tab_tag' ]
551                 : $sTag;
552         
553             // If the page heading tab visibility is disabled, or only one page is registered, return the title.
554             if ( ! $this->oProp->aPages[ $sCurrentPageSlug ][ 'show_page_heading_tabs' ] || count( $this->oProp->aPages ) == 1 )
555                 return "<{$sTag}>" . $this->oProp->aPages[ $sCurrentPageSlug ]['title'] . "</{$sTag}>";     
556 
557             foreach( $this->oProp->aPages as $aSubPage ) {
558                 
559                 // For added sub-pages
560                 if ( isset( $aSubPage['page_slug'] ) && $aSubPage['show_page_heading_tab'] ) {
561                     // Check if the current tab number matches the iteration number. If not match, then assign blank; otherwise put the active class name.
562                     $sClassActive =  $sCurrentPageSlug == $aSubPage['page_slug']  ? 'nav-tab-active' : '';      
563                     $aOutput[] = "<a class='nav-tab {$sClassActive}' "
564                         . "href='" . $this->oUtil->getQueryAdminURL( array( 'page' => $aSubPage['page_slug'], 'tab' => false ), $this->oProp->aDisallowedQueryKeys ) 
565                         . "'>"
566                         . $aSubPage['title']
567                         . "</a>";   
568                 }
569                 
570                 // For added menu links
571                 if ( 
572                     isset( $aSubPage['href'] )
573                     && $aSubPage['type'] == 'link' 
574                     && $aSubPage['show_page_heading_tab']
575                 ) 
576                     $aOutput[] = 
577                         "<a class='nav-tab link' "
578                         . "href='{$aSubPage['href']}'>"
579                             . $aSubPage['title']
580                         . "</a>";                   
581                 
582             }           
583             return "<div class='admin-page-framework-page-heading-tab'><{$sTag} class='nav-tab-wrapper'>" 
584                 .  implode( '', $aOutput ) 
585                 . "</{$sTag}></div>";
586             
587         }
588 
589         /**
590          * Retrieves the output of in-page tab navigation bar as HTML.
591          * 
592          * @since           2.0.0
593          * @return          string          the output of in-page tabs.
594          */     
595         private function _getInPageTabs( $sCurrentPageSlug, $sTag='h3', $aOutput=array() ) {
596             
597             // If in-page tabs are not set, return an empty string.
598             if ( empty( $this->oProp->aInPageTabs[ $sCurrentPageSlug ] ) ) return implode( '', $aOutput );
599                     
600             // Determine the current tab slug.
601             $sCurrentTabSlug = isset( $_GET['tab'] ) ? $_GET['tab'] : $this->oProp->getDefaultInPageTab( $sCurrentPageSlug );
602             $sCurrentTabSlug = $this->_getParentTabSlug( $sCurrentPageSlug, $sCurrentTabSlug );
603             
604             $sTag = $this->oProp->aPages[ $sCurrentPageSlug ][ 'in_page_tab_tag' ]
605                 ? $this->oProp->aPages[ $sCurrentPageSlug ][ 'in_page_tab_tag' ]
606                 : $sTag;
607         
608             // If the in-page tabs' visibility is set to false, returns the title.
609             if ( ! $this->oProp->aPages[ $sCurrentPageSlug ][ 'show_in_page_tabs' ] )
610                 return isset( $this->oProp->aInPageTabs[ $sCurrentPageSlug ][ $sCurrentTabSlug ]['title'] ) 
611                     ? "<{$sTag}>{$this->oProp->aInPageTabs[ $sCurrentPageSlug ][ $sCurrentTabSlug ]['title']}</{$sTag}>" 
612                     : "";
613 
614             // Get the actual string buffer.
615             foreach( $this->oProp->aInPageTabs[ $sCurrentPageSlug ] as $sTabSlug => $aInPageTab ) {
616                         
617                 // If it's hidden and its parent tab is not set, skip
618                 if ( ! $aInPageTab['show_in_page_tab'] && ! isset( $aInPageTab['parent_tab_slug'] ) ) continue;
619                 
620                 // The parent tab means the root tab when there is a hidden tab that belongs to it. Also check it the specified parent tab exists.
621                 $sInPageTabSlug = isset( $aInPageTab['parent_tab_slug'], $this->oProp->aInPageTabs[ $sCurrentPageSlug ][ $aInPageTab['parent_tab_slug'] ] ) 
622                     ? $aInPageTab['parent_tab_slug'] 
623                     : $aInPageTab['tab_slug'];
624                     
625                 // Check if the current tab slug matches the iteration slug. If not match, assign blank; otherwise, put the active class name.
626                 $bIsActiveTab = ( $sCurrentTabSlug == $sInPageTabSlug );
627 
628                 $aOutput[ $sInPageTabSlug ] = "<a class='nav-tab " . ( $bIsActiveTab ? "nav-tab-active" : "" ) . "' "
629                     . "href='" . $this->oUtil->getQueryAdminURL( array( 'page' => $sCurrentPageSlug, 'tab' => $sInPageTabSlug ), $this->oProp->aDisallowedQueryKeys ) 
630                     . "'>"
631                     . $this->oProp->aInPageTabs[ $sCurrentPageSlug ][ $sInPageTabSlug ]['title'] // "{$aInPageTab['title']}"
632                     . "</a>";
633             
634             }       
635             
636             return empty( $aOutput )
637                 ? ""
638                 : "<div class='admin-page-framework-in-page-tab'><{$sTag} class='nav-tab-wrapper in-page-tab'>" 
639                         . implode( '', $aOutput )
640                     . "</{$sTag}></div>";
641                 
642         }
643 
644             /**
645              * Retrieves the parent tab slug from the given tab slug.
646              * 
647              * @since           2.0.0
648              * @since           2.1.2           If the parent slug has the show_in_page_tab to be true, it returns an empty string.
649              * @return          string          the parent tab slug.
650              */     
651             private function _getParentTabSlug( $sPageSlug, $sTabSlug ) {
652                 
653                 $sParentTabSlug = isset( $this->oProp->aInPageTabs[ $sPageSlug ][ $sTabSlug ]['parent_tab_slug'] ) 
654                     ? $this->oProp->aInPageTabs[ $sPageSlug ][ $sTabSlug ]['parent_tab_slug']
655                     : $sTabSlug;
656  
657                 return isset( $this->oProp->aInPageTabs[ $sPageSlug ][ $sParentTabSlug ]['show_in_page_tab'] ) && $this->oProp->aInPageTabs[ $sPageSlug ][ $sParentTabSlug ]['show_in_page_tab']
658                     ? $sParentTabSlug
659                     : '';
660 
661             }
662 
663     /**
664      * Finalizes the in-page tab property array.
665      * 
666      * This finalizes the added in-page tabs and sets the default in-page tab for each page.
667      * Also this sorts the in-page tab property array.
668      * This must be done before registering settings sections because the default tab needs to be determined in the process.
669      * 
670      * @since           2.0.0
671      * @remark          A callback for the <em>admin_menu</em> hook.
672      * @return          void
673      */         
674     public function _replyToFinalizeInPageTabs() {
675     
676         if ( ! $this->oProp->isPageAdded() ) return;
677         
678         foreach( $this->oProp->aPages as $sPageSlug => $aPage ) {
679             
680             if ( ! isset( $this->oProp->aInPageTabs[ $sPageSlug ] ) ) continue;
681             
682             // Apply filters to let modify the in-page tab array.
683             $this->oProp->aInPageTabs[ $sPageSlug ] = $this->oUtil->addAndApplyFilter(      // Parameters: $oCallerObject, $sFilter, $vInput, $vArgs...
684                 $this,
685                 "tabs_{$this->oProp->sClassName}_{$sPageSlug}",
686                 $this->oProp->aInPageTabs[ $sPageSlug ]         
687             );  
688             // Added in-page arrays may be missing necessary keys so merge them with the default array structure.
689             foreach( $this->oProp->aInPageTabs[ $sPageSlug ] as &$aInPageTab ) 
690                 $aInPageTab = $aInPageTab + self::$_aStructure_InPageTabElements;
691                         
692             // Sort the in-page tab array.
693             uasort( $this->oProp->aInPageTabs[ $sPageSlug ], array( $this, '_sortByOrder' ) );
694             
695             // Set the default tab for the page.
696             // Read the value as reference; otherwise, a strange bug occurs. It may be due to the variable name, $aInPageTab, is also used as reference in the above foreach.
697             foreach( $this->oProp->aInPageTabs[ $sPageSlug ] as $sTabSlug => &$aInPageTab ) {   
698             
699                 if ( ! isset( $aInPageTab['tab_slug'] ) ) continue; 
700                 
701                 // Regardless of whether it's a hidden tab, it is stored as the default in-page tab.
702                 $this->oProp->aDefaultInPageTabs[ $sPageSlug ] = $aInPageTab['tab_slug'];
703                     
704                 break;  // The first iteration item is the default one.
705             }
706         }
707     }           
708     
709 }
710 endif;
Admin Page Framework Documentation API documentation generated by ApiGen 2.8.0