PluginProbe
BlockSpare – Gutenberg Blocks for News, Magazine, Blog & Business Websites / 1.2.2
BlockSpare – Gutenberg Blocks for News, Magazine, Blog & Business Websites v1.2.2
4.1.0 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.1.0 1.1.1 1.1.2 1.2.0 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 2.1.2 2.5.0 2.5.3 2.6.1 All 38 releases
blockspare / freemius / includes / managers / class-fs-admin-menu-manager.php

class-fs-admin-menu-manager.php in BlockSpare – Gutenberg Blocks for News, Magazine, Blog & Business Websites 1.2.2, at freemius/includes/managers/class-fs-admin-menu-manager.php

1,001 lines 25.5 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 $first_path = $this->get_option( $menu, 'first-path', false );
208
209 if ( ! empty( $first_path ) && is_string( $first_path ) ) {
210 $this->_first_time_path = $first_path;
211 }
212 }
213 }
214
215 /**
216 * Check if top level menu.
217 *
218 * @author Vova Feldman (@svovaf)
219 * @since 1.1.3
220 *
221 * @return bool False if submenu item.
222 */
223 function is_top_level() {
224 return $this->_is_top_level;
225 }
226
227 /**
228 * Check if the page should be override on exact URL match.
229 *
230 * @author Vova Feldman (@svovaf)
231 * @since 1.1.3
232 *
233 * @return bool False if submenu item.
234 */
235 function is_override_exact() {
236 return $this->_is_override_exact;
237 }
238
239
240 /**
241 * Get the path of the page the user should be forwarded to after first activation.
242 *
243 * @author Vova Feldman (@svovaf)
244 * @since 1.1.3
245 *
246 * @param bool $is_network Since 2.4.5
247 *
248 * @return string
249 */
250 function get_first_time_path( $is_network = false ) {
251 if ( empty ( $this->_first_time_path ) ) {
252 return $this->_first_time_path;
253 }
254
255 if ( $is_network ) {
256 return network_admin_url( $this->_first_time_path );
257 } else {
258 return admin_url( $this->_first_time_path );
259 }
260 }
261
262 /**
263 * Check if plugin's menu item is part of a custom top level menu.
264 *
265 * @author Vova Feldman (@svovaf)
266 * @since 1.1.3
267 *
268 * @return bool
269 */
270 function has_custom_parent() {
271 return ! $this->_is_top_level && is_string( $this->_parent_slug );
272 }
273
274 /**
275 * @author Leo Fajardo (@leorw)
276 * @since 1.2.2
277 *
278 * @return bool
279 */
280 function has_menu() {
281 return $this->_menu_exists;
282 }
283
284 /**
285 * @author Vova Feldman (@svovaf)
286 * @since 2.0.0
287 *
288 * @return bool
289 */
290 function has_network_menu() {
291 return $this->_network_menu_exists;
292 }
293
294 /**
295 * @author Leo Fajardo (@leorw)
296 *
297 * @param string $menu_slug
298 *
299 * @since 2.1.3
300 */
301 function set_slug_and_network_menu_exists_flag($menu_slug ) {
302 $this->_menu_slug = $menu_slug;
303 $this->_network_menu_exists = false;
304 }
305
306 /**
307 * @author Vova Feldman (@svovaf)
308 * @since 1.1.3
309 *
310 * @param string $id
311 * @param bool $default
312 * @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.
313 *
314 * @return bool
315 */
316 function is_submenu_item_visible( $id, $default = true, $ignore_menu_existence = false ) {
317 if ( ! $ignore_menu_existence && ! $this->has_menu() ) {
318 return false;
319 }
320
321 return fs_apply_filter(
322 $this->_module_unique_affix,
323 'is_submenu_visible',
324 $this->get_bool_option( $this->_default_submenu_items, $id, $default ),
325 $id
326 );
327 }
328
329 /**
330 * Calculates admin settings menu slug.
331 * If plugin's menu slug is a file (e.g. CPT), uses plugin's slug as the menu slug.
332 *
333 * @author Vova Feldman (@svovaf)
334 * @since 1.1.3
335 *
336 * @param string $page
337 *
338 * @return string
339 */
340 function get_slug( $page = '' ) {
341 return ( ( false === strpos( $this->_menu_slug, '.php?' ) ) ?
342 $this->_menu_slug :
343 $this->_module_unique_affix ) . ( empty( $page ) ? '' : ( '-' . $page ) );
344 }
345
346 /**
347 * @author Vova Feldman (@svovaf)
348 * @since 1.1.3
349 *
350 * @return string
351 */
352 function get_parent_slug() {
353 return $this->_parent_slug;
354 }
355
356 /**
357 * @author Vova Feldman (@svovaf)
358 * @since 1.1.3
359 *
360 * @return string
361 */
362 function get_type() {
363 return $this->_type;
364 }
365
366 /**
367 * @author Vova Feldman (@svovaf)
368 * @since 1.1.3
369 *
370 * @return bool
371 */
372 function is_cpt() {
373 return ( 0 === strpos( $this->_menu_slug, 'edit.php?post_type=' ) ||
374 // Back compatibility.
375 'cpt' === $this->_type
376 );
377 }
378
379 /**
380 * @author Vova Feldman (@svovaf)
381 * @since 1.1.3
382 *
383 * @return string
384 */
385 function get_parent_type() {
386 return $this->_parent_type;
387 }
388
389 /**
390 * @author Vova Feldman (@svovaf)
391 * @since 1.1.3
392 *
393 * @return string
394 */
395 function get_raw_slug() {
396 return $this->_menu_slug;
397 }
398
399 /**
400 * Get plugin's original menu slug.
401 *
402 * @author Vova Feldman (@svovaf)
403 * @since 1.1.3
404 *
405 * @return string
406 */
407 function get_original_menu_slug() {
408 if ( 'cpt' === $this->_type ) {
409 return add_query_arg( array(
410 'post_type' => $this->_menu_slug
411 ), 'edit.php' );
412 }
413
414 if ( false === strpos( $this->_menu_slug, '.php?' ) ) {
415 return $this->_menu_slug;
416 } else {
417 return $this->_module_unique_affix;
418 }
419 }
420
421 /**
422 * @author Vova Feldman (@svovaf)
423 * @since 1.1.3
424 *
425 * @return string
426 */
427 function get_top_level_menu_slug() {
428 return $this->has_custom_parent() ?
429 $this->get_parent_slug() :
430 $this->get_raw_slug();
431 }
432
433 /**
434 * Is user on plugin's admin activation page.
435 *
436 * @author Vova Feldman (@svovaf)
437 * @since 1.0.8
438 *
439 * @param bool $show_opt_in_on_themes_page Since 2.3.1
440 *
441 * @return bool
442 *
443 * @deprecated Please use is_activation_page() instead.
444 */
445 function is_main_settings_page( $show_opt_in_on_themes_page = false ) {
446 return $this->is_activation_page( $show_opt_in_on_themes_page );
447 }
448
449 /**
450 * Is user on product's admin activation page.
451 *
452 * @author Vova Feldman (@svovaf)
453 * @since 2.3.1
454 *
455 * @param bool $show_opt_in_on_themes_page Since 2.3.1
456 *
457 * @return bool
458 */
459 function is_activation_page( $show_opt_in_on_themes_page = false ) {
460 if ( $show_opt_in_on_themes_page ) {
461 /**
462 * In activation only when show_optin query string param is given.
463 *
464 * @since 1.2.2
465 */
466 return (
467 ( WP_FS__MODULE_TYPE_THEME === $this->_module_type ) &&
468 Freemius::is_themes_page() &&
469 fs_request_get_bool( $this->_module_unique_affix . '_show_optin' )
470 );
471 }
472
473 if ( $this->_menu_exists &&
474 ( fs_is_plugin_page( $this->_menu_slug ) || fs_is_plugin_page( $this->_module_unique_affix ) )
475 ) {
476 /**
477 * Module has a settings menu and the context page is the main settings page, so assume it's in
478 * activation (doesn't really check if already opted-in/skipped or not).
479 *
480 * @since 1.2.2
481 */
482 return true;
483 }
484
485 return false;
486 }
487
488 #region Submenu Override
489
490 /**
491 * Override submenu's action.
492 *
493 * @author Vova Feldman (@svovaf)
494 * @since 1.1.0
495 *
496 * @param string $parent_slug
497 * @param string $menu_slug
498 * @param callable $function
499 *
500 * @return false|string If submenu exist, will return the hook name.
501 */
502 function override_submenu_action( $parent_slug, $menu_slug, $function ) {
503 global $submenu;
504
505 $menu_slug = plugin_basename( $menu_slug );
506 $parent_slug = plugin_basename( $parent_slug );
507
508 if ( ! isset( $submenu[ $parent_slug ] ) ) {
509 // Parent menu not exist.
510 return false;
511 }
512
513 $found_submenu_item = false;
514 foreach ( $submenu[ $parent_slug ] as $submenu_item ) {
515 if ( $menu_slug === $submenu_item[2] ) {
516 $found_submenu_item = $submenu_item;
517 break;
518 }
519 }
520
521 if ( false === $found_submenu_item ) {
522 // Submenu item not found.
523 return false;
524 }
525
526 // Remove current function.
527 $hookname = get_plugin_page_hookname( $menu_slug, $parent_slug );
528 remove_all_actions( $hookname );
529
530 // Attach new action.
531 add_action( $hookname, $function );
532
533 return $hookname;
534 }
535
536 #endregion Submenu Override
537
538 #region Top level menu Override
539
540 /**
541 * Find plugin's admin dashboard main menu item.
542 *
543 * @author Vova Feldman (@svovaf)
544 * @since 1.0.2
545 *
546 * @return string[]|false
547 */
548 private function find_top_level_menu() {
549 global $menu;
550
551 $position = - 1;
552 $found_menu = false;
553
554 $menu_slug = $this->get_raw_slug();
555
556 $hook_name = get_plugin_page_hookname( $menu_slug, '' );
557 foreach ( $menu as $pos => $m ) {
558 if ( $menu_slug === $m[2] ) {
559 $position = $pos;
560 $found_menu = $m;
561 break;
562 }
563 }
564
565 if ( false === $found_menu ) {
566 return false;
567 }
568
569 return array(
570 'menu' => $found_menu,
571 'position' => $position,
572 'hook_name' => $hook_name
573 );
574 }
575
576 /**
577 * Find plugin's admin dashboard main submenu item.
578 *
579 * @author Vova Feldman (@svovaf)
580 * @since 1.2.1.6
581 *
582 * @return array|false
583 */
584 private function find_main_submenu() {
585 global $submenu;
586
587 $top_level_menu_slug = $this->get_top_level_menu_slug();
588
589 if ( ! isset( $submenu[ $top_level_menu_slug ] ) ) {
590 return false;
591 }
592
593 $submenu_slug = $this->get_raw_slug();
594
595 $position = - 1;
596 $found_submenu = false;
597
598 $hook_name = get_plugin_page_hookname( $submenu_slug, '' );
599
600 foreach ( $submenu[ $top_level_menu_slug ] as $pos => $sub ) {
601 if ( $submenu_slug === $sub[2] ) {
602 $position = $pos;
603 $found_submenu = $sub;
604 }
605 }
606
607 if ( false === $found_submenu ) {
608 return false;
609 }
610
611 return array(
612 'menu' => $found_submenu,
613 'parent_slug' => $top_level_menu_slug,
614 'position' => $position,
615 'hook_name' => $hook_name
616 );
617 }
618
619 /**
620 * Remove all sub-menu items.
621 *
622 * @author Vova Feldman (@svovaf)
623 * @since 1.0.7
624 *
625 * @return bool If submenu with plugin's menu slug was found.
626 */
627 private function remove_all_submenu_items() {
628 global $submenu;
629
630 $menu_slug = $this->get_raw_slug();
631
632 if ( ! isset( $submenu[ $menu_slug ] ) ) {
633 return false;
634 }
635
636 /**
637 * This method is NOT executed for WordPress.org themes.
638 * Since we maintain only one version of the SDK we added this small
639 * hack to avoid the error from Theme Check since it's a false-positive.
640 *
641 * @author Vova Feldman (@svovaf)
642 * @since 1.2.2.7
643 */
644 $submenu_ref = &$submenu;
645 $submenu_ref[ $menu_slug ] = array();
646
647 return true;
648 }
649
650 /**
651 *
652 * @author Vova Feldman (@svovaf)
653 * @since 1.0.9
654 *
655 * @param bool $remove_top_level_menu
656 *
657 * @return false|array[string]mixed
658 */
659 function remove_menu_item( $remove_top_level_menu = false ) {
660 $this->_logger->entrance();
661
662 // Find main menu item.
663 $top_level_menu = $this->find_top_level_menu();
664
665 if ( false === $top_level_menu ) {
666 return false;
667 }
668
669 // Remove it with its actions.
670 remove_all_actions( $top_level_menu['hook_name'] );
671
672 // Remove all submenu items.
673 $this->remove_all_submenu_items();
674
675 if ( $remove_top_level_menu ) {
676 global $menu;
677 unset( $menu[ $top_level_menu['position'] ] );
678 }
679
680 return $top_level_menu;
681 }
682
683 /**
684 * Get module's main admin setting page URL.
685 *
686 * @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.
687 *
688 * @author Vova Feldman (@svovaf)
689 * @since 1.2.2.7
690 *
691 * @return string
692 */
693 function main_menu_url() {
694 $this->_logger->entrance();
695
696 if ( $this->_is_top_level ) {
697 $menu = $this->find_top_level_menu();
698 } else {
699 $menu = $this->find_main_submenu();
700 }
701
702 $parent_slug = isset( $menu['parent_slug'] ) ?
703 $menu['parent_slug'] :
704 'admin.php';
705
706 return admin_url( $parent_slug . '?page=' . $menu['menu'][2] );
707 }
708
709 /**
710 * @author Vova Feldman (@svovaf)
711 * @since 1.1.4
712 *
713 * @param callable $function
714 *
715 * @return false|array[string]mixed
716 */
717 function override_menu_item( $function ) {
718 $found_menu = $this->remove_menu_item();
719
720 if ( false === $found_menu ) {
721 return false;
722 }
723
724 if ( ! $this->is_top_level() || ! $this->is_cpt() ) {
725 $menu_slug = plugin_basename( $this->get_slug() );
726
727 $hookname = get_plugin_page_hookname( $menu_slug, '' );
728
729 // Override menu action.
730 add_action( $hookname, $function );
731 } else {
732 global $menu;
733
734 // Remove original CPT menu.
735 unset( $menu[ $found_menu['position'] ] );
736
737 // Create new top-level menu action.
738 $hookname = self::add_page(
739 $found_menu['menu'][3],
740 $found_menu['menu'][0],
741 'manage_options',
742 $this->get_slug(),
743 $function,
744 $found_menu['menu'][6],
745 $found_menu['position']
746 );
747 }
748
749 return $hookname;
750 }
751
752 /**
753 * Adds a counter to the module's top level menu item.
754 *
755 * @author Vova Feldman (@svovaf)
756 * @since 1.2.1.5
757 *
758 * @param int $counter
759 * @param string $class
760 */
761 function add_counter_to_menu_item( $counter = 1, $class = '' ) {
762 global $menu, $submenu;
763
764 $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>';
765
766 /**
767 * This method is NOT executed for WordPress.org themes.
768 * Since we maintain only one version of the SDK we added this small
769 * hack to avoid the error from Theme Check since it's a false-positive.
770 *
771 * @author Vova Feldman (@svovaf)
772 * @since 1.2.2.7
773 */
774 $menu_ref = &$menu;
775 $submenu_ref = &$submenu;
776
777 if ( $this->_is_top_level ) {
778 // Find main menu item.
779 $found_menu = $this->find_top_level_menu();
780
781 if ( false !== $found_menu ) {
782 // Override menu label.
783 $menu_ref[ $found_menu['position'] ][0] = sprintf(
784 $mask,
785 $found_menu['menu'][0],
786 $class,
787 $counter
788 );
789 }
790 } else {
791 $found_submenu = $this->find_main_submenu();
792
793 if ( false !== $found_submenu ) {
794 // Override menu label.
795 $submenu_ref[ $found_submenu['parent_slug'] ][ $found_submenu['position'] ][0] = sprintf(
796 $mask,
797 $found_submenu['menu'][0],
798 $class,
799 $counter
800 );
801 }
802 }
803 }
804
805 #endregion Top level menu Override
806
807 /**
808 * Add a top-level menu page.
809 *
810 * Note for WordPress.org Theme/Plugin reviewer:
811 *
812 * This is a replication of `add_menu_page()` to avoid Theme Check warning.
813 *
814 * Why?
815 * ====
816 * Freemius is an SDK for plugin and theme developers. Since the core
817 * of the SDK is relevant both for plugins and themes, for obvious reasons,
818 * we only develop and maintain one code base.
819 *
820 * This method will not run for wp.org themes (only plugins) since theme
821 * admin settings/options are now only allowed in the customizer.
822 *
823 * If you have any questions or need clarifications, please don't hesitate
824 * pinging me on slack, my username is @svovaf.
825 *
826 * @author Vova Feldman (@svovaf)
827 * @since 1.2.2
828 *
829 * @param string $page_title The text to be displayed in the title tags of the page when the menu is
830 * selected.
831 * @param string $menu_title The text to be used for the menu.
832 * @param string $capability The capability required for this menu to be displayed to the user.
833 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu).
834 * @param callable|string $function The function to be called to output the content for this page.
835 * @param string $icon_url The URL to the icon to be used for this menu.
836 * * Pass a base64-encoded SVG using a data URI, which will be colored to
837 * match the color scheme. This should begin with
838 * 'data:image/svg+xml;base64,'.
839 * * Pass the name of a Dashicons helper class to use a font icon,
840 * e.g. 'dashicons-chart-pie'.
841 * * Pass 'none' to leave div.wp-menu-image empty so an icon can be added
842 * via CSS.
843 * @param int $position The position in the menu order this one should appear.
844 *
845 * @return string The resulting page's hook_suffix.
846 */
847 static function add_page(
848 $page_title,
849 $menu_title,
850 $capability,
851 $menu_slug,
852 $function = '',
853 $icon_url = '',
854 $position = null
855 ) {
856 $fn = 'add_menu' . '_page';
857
858 return $fn(
859 $page_title,
860 $menu_title,
861 $capability,
862 $menu_slug,
863 $function,
864 $icon_url,
865 $position
866 );
867 }
868
869 /**
870 * Add page and update menu instance settings.
871 *
872 * @author Vova Feldman (@svovaf)
873 * @since 2.0.0
874 *
875 * @param string $page_title
876 * @param string $menu_title
877 * @param string $capability
878 * @param string $menu_slug
879 * @param callable|string $function
880 * @param string $icon_url
881 * @param int|null $position
882 *
883 * @return string
884 */
885 function add_page_and_update(
886 $page_title,
887 $menu_title,
888 $capability,
889 $menu_slug,
890 $function = '',
891 $icon_url = '',
892 $position = null
893 ) {
894 $this->_menu_slug = $menu_slug;
895 $this->_is_top_level = true;
896 $this->_menu_exists = true;
897 $this->_network_menu_exists = true;
898
899 return self::add_page(
900 $page_title,
901 $menu_title,
902 $capability,
903 $menu_slug,
904 $function,
905 $icon_url,
906 $position
907 );
908 }
909
910 /**
911 * Add a submenu page.
912 *
913 * Note for WordPress.org Theme/Plugin reviewer:
914 *
915 * This is a replication of `add_submenu_page()` to avoid Theme Check warning.
916 *
917 * Why?
918 * ====
919 * Freemius is an SDK for plugin and theme developers. Since the core
920 * of the SDK is relevant both for plugins and themes, for obvious reasons,
921 * we only develop and maintain one code base.
922 *
923 * This method will not run for wp.org themes (only plugins) since theme
924 * admin settings/options are now only allowed in the customizer.
925 *
926 * If you have any questions or need clarifications, please don't hesitate
927 * pinging me on slack, my username is @svovaf.
928 *
929 * @author Vova Feldman (@svovaf)
930 * @since 1.2.2
931 *
932 * @param string $parent_slug The slug name for the parent menu (or the file name of a standard
933 * WordPress admin page).
934 * @param string $page_title The text to be displayed in the title tags of the page when the menu is
935 * selected.
936 * @param string $menu_title The text to be used for the menu.
937 * @param string $capability The capability required for this menu to be displayed to the user.
938 * @param string $menu_slug The slug name to refer to this menu by (should be unique for this menu).
939 * @param callable|string $function The function to be called to output the content for this page.
940 *
941 * @return false|string The resulting page's hook_suffix, or false if the user does not have the capability
942 * required.
943 */
944 static function add_subpage(
945 $parent_slug,
946 $page_title,
947 $menu_title,
948 $capability,
949 $menu_slug,
950 $function = ''
951 ) {
952 $fn = 'add_submenu' . '_page';
953
954 return $fn( $parent_slug,
955 $page_title,
956 $menu_title,
957 $capability,
958 $menu_slug,
959 $function
960 );
961 }
962
963 /**
964 * Add sub page and update menu instance settings.
965 *
966 * @author Vova Feldman (@svovaf)
967 * @since 2.0.0
968 *
969 * @param string $parent_slug
970 * @param string $page_title
971 * @param string $menu_title
972 * @param string $capability
973 * @param string $menu_slug
974 * @param callable|string $function
975 *
976 * @return string
977 */
978 function add_subpage_and_update(
979 $parent_slug,
980 $page_title,
981 $menu_title,
982 $capability,
983 $menu_slug,
984 $function = ''
985 ) {
986 $this->_menu_slug = $menu_slug;
987 $this->_parent_slug = $parent_slug;
988 $this->_is_top_level = false;
989 $this->_menu_exists = true;
990 $this->_network_menu_exists = true;
991
992 return self::add_subpage(
993 $parent_slug,
994 $page_title,
995 $menu_title,
996 $capability,
997 $menu_slug,
998 $function
999 );
1000 }
1001 }