PluginProbe
Tiered Pricing Table for WooCommerce / 2.1.1
Tiered Pricing Table for WooCommerce v2.1.1
7.1.7 7.1.5 7.1.4 7.1.1 6.5.0 6.4.0 6.1.0 trunk 1.0 1.1 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2 2.2.3 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 All 90 releases
tier-pricing-table / freemius / includes / managers / class-fs-admin-menu-manager.php

class-fs-admin-menu-manager.php in Tiered Pricing Table for WooCommerce 2.1.1, at freemius/includes/managers/class-fs-admin-menu-manager.php

969 lines 24.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package Freemius
4 * @copyright Copyright (c) 2015, Freemius, Inc.
5 * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 * @since 1.1.3
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 class FS_Admin_Menu_Manager {
14
15 #region Properties
16
17 /**
18 * @since 1.2.2
19 *
20 * @var string
21 */
22 protected $_module_unique_affix;
23
24 /**
25 * @since 1.2.2
26 *
27 * @var number
28 */
29 protected $_module_id;
30
31 /**
32 * @since 1.2.2
33 *
34 * @var string
35 */
36 protected $_module_type;
37
38 /**
39 * @since 1.0.6
40 *
41 * @var string
42 */
43 private $_menu_slug;
44 /**
45 * @since 1.1.3
46 *
47 * @var string
48 */
49 private $_parent_slug;
50 /**
51 * @since 1.1.3
52 *
53 * @var string
54 */
55 private $_parent_type;
56 /**
57 * @since 1.1.3
58 *
59 * @var string
60 */
61 private $_type;
62 /**
63 * @since 1.1.3
64 *
65 * @var bool
66 */
67 private $_is_top_level;
68 /**
69 * @since 1.1.3
70 *
71 * @var bool
72 */
73 private $_is_override_exact;
74 /**
75 * @since 1.1.3
76 *
77 * @var array<string,bool>
78 */
79 private $_default_submenu_items;
80 /**
81 * @since 1.1.3
82 *
83 * @var string
84 */
85 private $_first_time_path;
86 /**
87 * @since 1.2.2
88 *
89 * @var bool
90 */
91 private $_menu_exists;
92 /**
93 * @since 2.0.0
94 *
95 * @var bool
96 */
97 private $_network_menu_exists;
98
99 #endregion Properties
100
101 /**
102 * @var FS_Logger
103 */
104 protected $_logger;
105
106 #region Singleton
107
108 /**
109 * @var FS_Admin_Menu_Manager[]
110 */
111 private static $_instances = array();
112
113 /**
114 * @param number $module_id
115 * @param string $module_type
116 * @param string $module_unique_affix
117 *
118 * @return FS_Admin_Menu_Manager
119 */
120 static function instance( $module_id, $module_type, $module_unique_affix ) {
121 $key = 'm_' . $module_id;
122
123 if ( ! isset( self::$_instances[ $key ] ) ) {
124 self::$_instances[ $key ] = new FS_Admin_Menu_Manager( $module_id, $module_type, $module_unique_affix );
125 }
126
127 return self::$_instances[ $key ];
128 }
129
130 protected function __construct( $module_id, $module_type, $module_unique_affix ) {
131 $this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $module_id . '_admin_menu', WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
132
133 $this->_module_id = $module_id;
134 $this->_module_type = $module_type;
135 $this->_module_unique_affix = $module_unique_affix;
136 }
137
138 #endregion Singleton
139
140 #region Helpers
141
142 private function get_option( &$options, $key, $default = false ) {
143 return ! empty( $options[ $key ] ) ? $options[ $key ] : $default;
144 }
145
146 private function get_bool_option( &$options, $key, $default = false ) {
147 return isset( $options[ $key ] ) && is_bool( $options[ $key ] ) ? $options[ $key ] : $default;
148 }
149
150 #endregion Helpers
151
152 /**
153 * @param array $menu
154 * @param bool $is_addon
155 */
156 function init( $menu, $is_addon = false ) {
157 $this->_menu_exists = ( isset( $menu['slug'] ) && ! empty( $menu['slug'] ) );
158 $this->_network_menu_exists = ( ! empty( $menu['network'] ) && true === $menu['network'] );
159
160 $this->_menu_slug = ( $this->_menu_exists ? $menu['slug'] : $this->_module_unique_affix );
161
162 $this->_default_submenu_items = array();
163 // @deprecated
164 $this->_type = 'page';
165 $this->_is_top_level = true;
166 $this->_is_override_exact = false;
167 $this->_parent_slug = false;
168 // @deprecated
169 $this->_parent_type = 'page';
170
171 if ( isset( $menu ) ) {
172 if ( ! $is_addon ) {
173 $this->_default_submenu_items = array(
174 'contact' => $this->get_bool_option( $menu, 'contact', true ),
175 'support' => $this->get_bool_option( $menu, 'support', true ),
176 'affiliation' => $this->get_bool_option( $menu, 'affiliation', true ),
177 'account' => $this->get_bool_option( $menu, 'account', true ),
178 'pricing' => $this->get_bool_option( $menu, 'pricing', true ),
179 'addons' => $this->get_bool_option( $menu, 'addons', true ),
180 );
181
182 // @deprecated
183 $this->_type = $this->get_option( $menu, 'type', 'page' );
184 }
185
186 $this->_is_override_exact = $this->get_bool_option( $menu, 'override_exact' );
187
188 if ( isset( $menu['parent'] ) ) {
189 $this->_parent_slug = $this->get_option( $menu['parent'], 'slug' );
190 // @deprecated
191 $this->_parent_type = $this->get_option( $menu['parent'], 'type', 'page' );
192
193 // If parent's slug is different, then it's NOT a top level menu item.
194 $this->_is_top_level = ( $this->_parent_slug === $this->_menu_slug );
195 } else {
196 /**
197 * If no parent then top level if:
198 * - Has custom admin menu ('page')
199 * - CPT menu type ('cpt')
200 */
201 // $this->_is_top_level = in_array( $this->_type, array(
202 // 'cpt',
203 // 'page'
204 // ) );
205 }
206
207 $this->_first_time_path = $this->get_option( $menu, 'first-path', false );
208 if ( ! empty( $this->_first_time_path ) && is_string( $this->_first_time_path ) ) {
209 $this->_first_time_path = admin_url( $this->_first_time_path, 'admin' );
210 }
211 }
212 }
213
214 /**
215 * Check if top level menu.
216 *
217 * @author Vova Feldman (@svovaf)
218 * @since 1.1.3
219 *
220 * @return bool False if submenu item.
221 */
222 function is_top_level() {
223 return $this->_is_top_level;
224 }
225
226 /**
227 * Check if the page should be override on exact URL match.
228 *
229 * @author Vova Feldman (@svovaf)
230 * @since 1.1.3
231 *
232 * @return bool False if submenu item.
233 */
234 function is_override_exact() {
235 return $this->_is_override_exact;
236 }
237
238
239 /**
240 * Get the path of the page the user should be forwarded to after first activation.
241 *
242 * @author Vova Feldman (@svovaf)
243 * @since 1.1.3
244 *
245 * @return string
246 */
247 function get_first_time_path() {
248 return $this->_first_time_path;
249 }
250
251 /**
252 * Check if plugin's menu item is part of a custom top level menu.
253 *
254 * @author Vova Feldman (@svovaf)
255 * @since 1.1.3
256 *
257 * @return bool
258 */
259 function has_custom_parent() {
260 return ! $this->_is_top_level && is_string( $this->_parent_slug );
261 }
262
263 /**
264 * @author Leo Fajardo (@leorw)
265 * @since 1.2.2
266 *
267 * @return bool
268 */
269 function has_menu() {
270 return $this->_menu_exists;
271 }
272
273 /**
274 * @author Vova Feldman (@svovaf)
275 * @since 2.0.0
276 *
277 * @return bool
278 */
279 function has_network_menu() {
280 return $this->_network_menu_exists;
281 }
282
283 /**
284 * @author Leo Fajardo (@leorw)
285 *
286 * @param string $menu_slug
287 *
288 * @since 2.1.3
289 */
290 function set_slug_and_network_menu_exists_flag($menu_slug ) {
291 $this->_menu_slug = $menu_slug;
292 $this->_network_menu_exists = false;
293 }
294
295 /**
296 * @author Vova Feldman (@svovaf)
297 * @since 1.1.3
298 *
299 * @param string $id
300 * @param bool $default
301 * @param bool $ignore_menu_existence Since 1.2.2.7 If true, check if the submenu item visible even if there's no parent menu.
302 *
303 * @return bool
304 */
305 function is_submenu_item_visible( $id, $default = true, $ignore_menu_existence = false ) {
306 if ( ! $ignore_menu_existence && ! $this->has_menu() ) {
307 return false;
308 }
309
310 return fs_apply_filter(
311 $this->_module_unique_affix,
312 'is_submenu_visible',
313 $this->get_bool_option( $this->_default_submenu_items, $id, $default ),
314 $id
315 );
316 }
317
318 /**
319 * Calculates admin settings menu slug.
320 * If plugin's menu slug is a file (e.g. CPT), uses plugin's slug as the menu slug.
321 *
322 * @author Vova Feldman (@svovaf)
323 * @since 1.1.3
324 *
325 * @param string $page
326 *
327 * @return string
328 */
329 function get_slug( $page = '' ) {
330 return ( ( false === strpos( $this->_menu_slug, '.php?' ) ) ?
331 $this->_menu_slug :
332 $this->_module_unique_affix ) . ( empty( $page ) ? '' : ( '-' . $page ) );
333 }
334
335 /**
336 * @author Vova Feldman (@svovaf)
337 * @since 1.1.3
338 *
339 * @return string
340 */
341 function get_parent_slug() {
342 return $this->_parent_slug;
343 }
344
345 /**
346 * @author Vova Feldman (@svovaf)
347 * @since 1.1.3
348 *
349 * @return string
350 */
351 function get_type() {
352 return $this->_type;
353 }
354
355 /**
356 * @author Vova Feldman (@svovaf)
357 * @since 1.1.3
358 *
359 * @return bool
360 */
361 function is_cpt() {
362 return ( 0 === strpos( $this->_menu_slug, 'edit.php?post_type=' ) ||
363 // Back compatibility.
364 'cpt' === $this->_type
365 );
366 }
367
368 /**
369 * @author Vova Feldman (@svovaf)
370 * @since 1.1.3
371 *
372 * @return string
373 */
374 function get_parent_type() {
375 return $this->_parent_type;
376 }
377
378 /**
379 * @author Vova Feldman (@svovaf)
380 * @since 1.1.3
381 *
382 * @return string
383 */
384 function get_raw_slug() {
385 return $this->_menu_slug;
386 }
387
388 /**
389 * Get plugin's original menu slug.
390 *
391 * @author Vova Feldman (@svovaf)
392 * @since 1.1.3
393 *
394 * @return string
395 */
396 function get_original_menu_slug() {
397 if ( 'cpt' === $this->_type ) {
398 return add_query_arg( array(
399 'post_type' => $this->_menu_slug
400 ), 'edit.php' );
401 }
402
403 if ( false === strpos( $this->_menu_slug, '.php?' ) ) {
404 return $this->_menu_slug;
405 } else {
406 return $this->_module_unique_affix;
407 }
408 }
409
410 /**
411 * @author Vova Feldman (@svovaf)
412 * @since 1.1.3
413 *
414 * @return string
415 */
416 function get_top_level_menu_slug() {
417 return $this->has_custom_parent() ?
418 $this->get_parent_slug() :
419 $this->get_raw_slug();
420 }
421
422 /**
423 * Is user on plugin's admin activation page.
424 *
425 * @author Vova Feldman (@svovaf)
426 * @since 1.0.8
427 *
428 * @return bool
429 */
430 function is_main_settings_page() {
431 if ( $this->_menu_exists &&
432 ( fs_is_plugin_page( $this->_menu_slug ) || fs_is_plugin_page( $this->_module_unique_affix ) )
433 ) {
434 /**
435 * Module has a settings menu and the context page is the main settings page, so assume it's in
436 * activation (doesn't really check if already opted-in/skipped or not).
437 *
438 * @since 1.2.2
439 */
440 return true;
441 }
442
443 global $pagenow;
444 if ( ( WP_FS__MODULE_TYPE_THEME === $this->_module_type ) && Freemius::is_themes_page() ) {
445 /**
446 * In activation only when show_optin query string param is given.
447 *
448 * @since 1.2.2
449 */
450 return fs_request_get_bool( $this->_module_unique_affix . '_show_optin' );
451 }
452
453 return false;
454 }
455
456 #region Submenu Override
457
458 /**
459 * Override submenu's action.
460 *
461 * @author Vova Feldman (@svovaf)
462 * @since 1.1.0
463 *
464 * @param string $parent_slug
465 * @param string $menu_slug
466 * @param callable $function
467 *
468 * @return false|string If submenu exist, will return the hook name.
469 */
470 function override_submenu_action( $parent_slug, $menu_slug, $function ) {
471 global $submenu;
472
473 $menu_slug = plugin_basename( $menu_slug );
474 $parent_slug = plugin_basename( $parent_slug );
475
476 if ( ! isset( $submenu[ $parent_slug ] ) ) {
477 // Parent menu not exist.
478 return false;
479 }
480
481 $found_submenu_item = false;
482 foreach ( $submenu[ $parent_slug ] as $submenu_item ) {
483 if ( $menu_slug === $submenu_item[2] ) {
484 $found_submenu_item = $submenu_item;
485 break;
486 }
487 }
488
489 if ( false === $found_submenu_item ) {
490 // Submenu item not found.
491 return false;
492 }
493
494 // Remove current function.
495 $hookname = get_plugin_page_hookname( $menu_slug, $parent_slug );
496 remove_all_actions( $hookname );
497
498 // Attach new action.
499 add_action( $hookname, $function );
500
501 return $hookname;
502 }
503
504 #endregion Submenu Override
505
506 #region Top level menu Override
507
508 /**
509 * Find plugin's admin dashboard main menu item.
510 *
511 * @author Vova Feldman (@svovaf)
512 * @since 1.0.2
513 *
514 * @return string[]|false
515 */
516 private function find_top_level_menu() {
517 global $menu;
518
519 $position = - 1;
520 $found_menu = false;
521
522 $menu_slug = $this->get_raw_slug();
523
524 $hook_name = get_plugin_page_hookname( $menu_slug, '' );
525 foreach ( $menu as $pos => $m ) {
526 if ( $menu_slug === $m[2] ) {
527 $position = $pos;
528 $found_menu = $m;
529 break;
530 }
531 }
532
533 if ( false === $found_menu ) {
534 return false;
535 }
536
537 return array(
538 'menu' => $found_menu,
539 'position' => $position,
540 'hook_name' => $hook_name
541 );
542 }
543
544 /**
545 * Find plugin's admin dashboard main submenu item.
546 *
547 * @author Vova Feldman (@svovaf)
548 * @since 1.2.1.6
549 *
550 * @return array|false
551 */
552 private function find_main_submenu() {
553 global $submenu;
554
555 $top_level_menu_slug = $this->get_top_level_menu_slug();
556
557 if ( ! isset( $submenu[ $top_level_menu_slug ] ) ) {
558 return false;
559 }
560
561 $submenu_slug = $this->get_raw_slug();
562
563 $position = - 1;
564 $found_submenu = false;
565
566 $hook_name = get_plugin_page_hookname( $submenu_slug, '' );
567
568 foreach ( $submenu[ $top_level_menu_slug ] as $pos => $sub ) {
569 if ( $submenu_slug === $sub[2] ) {
570 $position = $pos;
571 $found_submenu = $sub;
572 }
573 }
574
575 if ( false === $found_submenu ) {
576 return false;
577 }
578
579 return array(
580 'menu' => $found_submenu,
581 'parent_slug' => $top_level_menu_slug,
582 'position' => $position,
583 'hook_name' => $hook_name
584 );
585 }
586
587 /**
588 * Remove all sub-menu items.
589 *
590 * @author Vova Feldman (@svovaf)
591 * @since 1.0.7
592 *
593 * @return bool If submenu with plugin's menu slug was found.
594 */
595 private function remove_all_submenu_items() {
596 global $submenu;
597
598 $menu_slug = $this->get_raw_slug();
599
600 if ( ! isset( $submenu[ $menu_slug ] ) ) {
601 return false;
602 }
603
604 /**
605 * This method is NOT executed for WordPress.org themes.
606 * Since we maintain only one version of the SDK we added this small
607 * hack to avoid the error from Theme Check since it's a false-positive.
608 *
609 * @author Vova Feldman (@svovaf)
610 * @since 1.2.2.7
611 */
612 $submenu_ref = &$submenu;
613 $submenu_ref[ $menu_slug ] = array();
614
615 return true;
616 }
617
618 /**
619 *
620 * @author Vova Feldman (@svovaf)
621 * @since 1.0.9
622 *
623 * @param bool $remove_top_level_menu
624 *
625 * @return false|array[string]mixed
626 */
627 function remove_menu_item( $remove_top_level_menu = false ) {
628 $this->_logger->entrance();
629
630 // Find main menu item.
631 $top_level_menu = $this->find_top_level_menu();
632
633 if ( false === $top_level_menu ) {
634 return false;
635 }
636
637 // Remove it with its actions.
638 remove_all_actions( $top_level_menu['hook_name'] );
639
640 // Remove all submenu items.
641 $this->remove_all_submenu_items();
642
643 if ( $remove_top_level_menu ) {
644 global $menu;
645 unset( $menu[ $top_level_menu['position'] ] );
646 }
647
648 return $top_level_menu;
649 }
650
651 /**
652 * Get module's main admin setting page URL.
653 *
654 * @todo This method was only tested for wp.org compliant themes with a submenu item. Need to test for plugins with top level, submenu, and CPT top level, menu items.
655 *
656 * @author Vova Feldman (@svovaf)
657 * @since 1.2.2.7
658 *
659 * @return string
660 */
661 function main_menu_url() {
662 $this->_logger->entrance();
663
664 if ( $this->_is_top_level ) {
665 $menu = $this->find_top_level_menu();
666 } else {
667 $menu = $this->find_main_submenu();
668 }
669
670 $parent_slug = isset( $menu['parent_slug'] ) ?
671 $menu['parent_slug'] :
672 'admin.php';
673
674 return admin_url( $parent_slug . '?page=' . $menu['menu'][2] );
675 }
676
677 /**
678 * @author Vova Feldman (@svovaf)
679 * @since 1.1.4
680 *
681 * @param callable $function
682 *
683 * @return false|array[string]mixed
684 */
685 function override_menu_item( $function ) {
686 $found_menu = $this->remove_menu_item();
687
688 if ( false === $found_menu ) {
689 return false;
690 }
691
692 if ( ! $this->is_top_level() || ! $this->is_cpt() ) {
693 $menu_slug = plugin_basename( $this->get_slug() );
694
695 $hookname = get_plugin_page_hookname( $menu_slug, '' );
696
697 // Override menu action.
698 add_action( $hookname, $function );
699 } else {
700 global $menu;
701
702 // Remove original CPT menu.
703 unset( $menu[ $found_menu['position'] ] );
704
705 // Create new top-level menu action.
706 $hookname = self::add_page(
707 $found_menu['menu'][3],
708 $found_menu['menu'][0],
709 'manage_options',
710 $this->get_slug(),
711 $function,
712 $found_menu['menu'][6],
713 $found_menu['position']
714 );
715 }
716
717 return $hookname;
718 }
719
720 /**
721 * Adds a counter to the module's top level menu item.
722 *
723 * @author Vova Feldman (@svovaf)
724 * @since 1.2.1.5
725 *
726 * @param int $counter
727 * @param string $class
728 */
729 function add_counter_to_menu_item( $counter = 1, $class = '' ) {
730 global $menu, $submenu;
731
732 $mask = '%s <span class="update-plugins %s count-%3$s" aria-hidden="true"><span>%3$s<span class="screen-reader-text">%3$s notifications</span></span></span>';
733
734 /**
735 * This method is NOT executed for WordPress.org themes.
736 * Since we maintain only one version of the SDK we added this small
737 * hack to avoid the error from Theme Check since it's a false-positive.
738 *
739 * @author Vova Feldman (@svovaf)
740 * @since 1.2.2.7
741 */
742 $menu_ref = &$menu;
743 $submenu_ref = &$submenu;
744
745 if ( $this->_is_top_level ) {
746 // Find main menu item.
747 $found_menu = $this->find_top_level_menu();
748
749 if ( false !== $found_menu ) {
750 // Override menu label.
751 $menu_ref[ $found_menu['position'] ][0] = sprintf(
752 $mask,
753 $found_menu['menu'][0],
754 $class,
755 $counter
756 );
757 }
758 } else {
759 $found_submenu = $this->find_main_submenu();
760
761 if ( false !== $found_submenu ) {
762 // Override menu label.
763 $submenu_ref[ $found_submenu['parent_slug'] ][ $found_submenu['position'] ][0] = sprintf(
764 $mask,
765 $found_submenu['menu'][0],
766 $class,
767 $counter
768 );
769 }
770 }
771 }
772
773 #endregion Top level menu Override
774
775 /**
776 * Add a top-level menu page.
777 *
778 * Note for WordPress.org Theme/Plugin reviewer:
779 *
780 * This is a replication of `add_menu_page()` to avoid Theme Check warning.
781 *
782 * Why?
783 * ====
784 * Freemius is an SDK for plugin and theme developers. Since the core
785 * of the SDK is relevant both for plugins and themes, for obvious reasons,
786 * we only develop and maintain one code base.
787 *
788 * This method will not run for wp.org themes (only plugins) since theme
789 * admin settings/options are now only allowed in the customizer.
790 *
791 * If you have any questions or need clarifications, please don't hesitate
792 * pinging me on slack, my username is @svovaf.
793 *
794 * @author Vova Feldman (@svovaf)
795 * @since 1.2.2
796 *
797 * @param string $page_title The text to be displayed in the title tags of the page when the menu is
798 * selected.
799 * @param string $menu_title The text to be used for the menu.
800 * @param string $capability The capability required for this menu to be displayed to the user.
801 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu).
802 * @param callable|string $function The function to be called to output the content for this page.
803 * @param string $icon_url The URL to the icon to be used for this menu.
804 * * Pass a base64-encoded SVG using a data URI, which will be colored to
805 * match the color scheme. This should begin with
806 * 'data:image/svg+xml;base64,'.
807 * * Pass the name of a Dashicons helper class to use a font icon,
808 * e.g. 'dashicons-chart-pie'.
809 * * Pass 'none' to leave div.wp-menu-image empty so an icon can be added
810 * via CSS.
811 * @param int $position The position in the menu order this one should appear.
812 *
813 * @return string The resulting page's hook_suffix.
814 */
815 static function add_page(
816 $page_title,
817 $menu_title,
818 $capability,
819 $menu_slug,
820 $function = '',
821 $icon_url = '',
822 $position = null
823 ) {
824 $fn = 'add_menu' . '_page';
825
826 return $fn(
827 $page_title,
828 $menu_title,
829 $capability,
830 $menu_slug,
831 $function,
832 $icon_url,
833 $position
834 );
835 }
836
837 /**
838 * Add page and update menu instance settings.
839 *
840 * @author Vova Feldman (@svovaf)
841 * @since 2.0.0
842 *
843 * @param string $page_title
844 * @param string $menu_title
845 * @param string $capability
846 * @param string $menu_slug
847 * @param callable|string $function
848 * @param string $icon_url
849 * @param int|null $position
850 *
851 * @return string
852 */
853 function add_page_and_update(
854 $page_title,
855 $menu_title,
856 $capability,
857 $menu_slug,
858 $function = '',
859 $icon_url = '',
860 $position = null
861 ) {
862 $this->_menu_slug = $menu_slug;
863 $this->_is_top_level = true;
864 $this->_menu_exists = true;
865 $this->_network_menu_exists = true;
866
867 return self::add_page(
868 $page_title,
869 $menu_title,
870 $capability,
871 $menu_slug,
872 $function,
873 $icon_url,
874 $position
875 );
876 }
877
878 /**
879 * Add a submenu page.
880 *
881 * Note for WordPress.org Theme/Plugin reviewer:
882 *
883 * This is a replication of `add_submenu_page()` to avoid Theme Check warning.
884 *
885 * Why?
886 * ====
887 * Freemius is an SDK for plugin and theme developers. Since the core
888 * of the SDK is relevant both for plugins and themes, for obvious reasons,
889 * we only develop and maintain one code base.
890 *
891 * This method will not run for wp.org themes (only plugins) since theme
892 * admin settings/options are now only allowed in the customizer.
893 *
894 * If you have any questions or need clarifications, please don't hesitate
895 * pinging me on slack, my username is @svovaf.
896 *
897 * @author Vova Feldman (@svovaf)
898 * @since 1.2.2
899 *
900 * @param string $parent_slug The slug name for the parent menu (or the file name of a standard
901 * WordPress admin page).
902 * @param string $page_title The text to be displayed in the title tags of the page when the menu is
903 * selected.
904 * @param string $menu_title The text to be used for the menu.
905 * @param string $capability The capability required for this menu to be displayed to the user.
906 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu).
907 * @param callable|string $function The function to be called to output the content for this page.
908 *
909 * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability
910 * required.
911 */
912 static function add_subpage(
913 $parent_slug,
914 $page_title,
915 $menu_title,
916 $capability,
917 $menu_slug,
918 $function = ''
919 ) {
920 $fn = 'add_submenu' . '_page';
921
922 return $fn( $parent_slug,
923 $page_title,
924 $menu_title,
925 $capability,
926 $menu_slug,
927 $function
928 );
929 }
930
931 /**
932 * Add sub page and update menu instance settings.
933 *
934 * @author Vova Feldman (@svovaf)
935 * @since 2.0.0
936 *
937 * @param string $parent_slug
938 * @param string $page_title
939 * @param string $menu_title
940 * @param string $capability
941 * @param string $menu_slug
942 * @param callable|string $function
943 *
944 * @return string
945 */
946 function add_subpage_and_update(
947 $parent_slug,
948 $page_title,
949 $menu_title,
950 $capability,
951 $menu_slug,
952 $function = ''
953 ) {
954 $this->_menu_slug = $menu_slug;
955 $this->_parent_slug = $parent_slug;
956 $this->_is_top_level = false;
957 $this->_menu_exists = true;
958 $this->_network_menu_exists = true;
959
960 return self::add_subpage(
961 $parent_slug,
962 $page_title,
963 $menu_title,
964 $capability,
965 $menu_slug,
966 $function
967 );
968 }
969 }