options-page.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. <?php
  2. if ( ! defined( 'ABSPATH' ) ) {
  3. exit; // Exit if accessed directly
  4. }
  5. if ( ! class_exists( 'acf_options_page' ) ) :
  6. class acf_options_page {
  7. /** @var array Contains an array of options page settings */
  8. var $pages = array();
  9. /*
  10. * __construct
  11. *
  12. * Initialize filters, action, variables and includes
  13. *
  14. * @type function
  15. * @date 23/06/12
  16. * @since 5.0.0
  17. *
  18. * @param n/a
  19. * @return n/a
  20. */
  21. function __construct() {
  22. /* do nothing */
  23. }
  24. /**
  25. * Validates an Options Page settings array.
  26. *
  27. * @date 28/2/17
  28. * @since 5.5.8
  29. *
  30. * @param array|string $page The Options Page settings array or name.
  31. * @return array
  32. */
  33. function validate_page( $page ) {
  34. // Allow empty arg to generate the default Options Page.
  35. if ( empty( $page ) ) {
  36. $page_title = __( 'Options', 'acf' );
  37. $page = array(
  38. 'page_title' => $page_title,
  39. 'menu_title' => $page_title,
  40. 'menu_slug' => 'acf-options',
  41. );
  42. // Allow string to define Options Page name.
  43. } elseif ( is_string( $page ) ) {
  44. $page_title = $page;
  45. $page = array(
  46. 'page_title' => $page_title,
  47. 'menu_title' => $page_title,
  48. );
  49. }
  50. // Apply defaults.
  51. $page = wp_parse_args(
  52. $page,
  53. array(
  54. 'page_title' => '',
  55. 'menu_title' => '',
  56. 'menu_slug' => '',
  57. 'capability' => 'edit_posts',
  58. 'parent_slug' => '',
  59. 'position' => null,
  60. 'icon_url' => false,
  61. 'redirect' => true,
  62. 'post_id' => 'options',
  63. 'autoload' => false,
  64. 'update_button' => __( 'Update', 'acf' ),
  65. 'updated_message' => __( 'Options Updated', 'acf' ),
  66. )
  67. );
  68. // Allow compatibility for changed settings.
  69. $migrate = array(
  70. 'title' => 'page_title',
  71. 'menu' => 'menu_title',
  72. 'slug' => 'menu_slug',
  73. 'parent' => 'parent_slug',
  74. );
  75. foreach ( $migrate as $old => $new ) {
  76. if ( ! empty( $page[ $old ] ) ) {
  77. $page[ $new ] = $page[ $old ];
  78. }
  79. }
  80. // If no menu_title is set, use the page_title value.
  81. if ( empty( $page['menu_title'] ) ) {
  82. $page['menu_title'] = $page['page_title'];
  83. }
  84. // If no menu_slug is set, generate one using the menu_title value.
  85. if ( empty( $page['menu_slug'] ) ) {
  86. $page['menu_slug'] = 'acf-options-' . sanitize_title( $page['menu_title'] );
  87. }
  88. // Standardize on position being either null or int.
  89. $page['position'] = is_numeric( $page['position'] ) ? (int) $page['position'] : null;
  90. /**
  91. * Filters the $page array after it has been validated.
  92. *
  93. * @since 5.5.8
  94. * @param array $page The Options Page settings array.
  95. */
  96. return apply_filters( 'acf/validate_options_page', $page );
  97. }
  98. /*
  99. * add_page
  100. *
  101. * This function will store an options page settings
  102. *
  103. * @type function
  104. * @date 9/6/17
  105. * @since 5.6.0
  106. *
  107. * @param $page (array)
  108. * @return n/a
  109. */
  110. function add_page( $page ) {
  111. // validate
  112. $page = $this->validate_page( $page );
  113. $slug = $page['menu_slug'];
  114. // bail early if already exists
  115. if ( isset( $this->pages[ $slug ] ) ) {
  116. return false;
  117. }
  118. // append
  119. $this->pages[ $slug ] = $page;
  120. // return
  121. return $page;
  122. }
  123. /*
  124. * add_sub_page
  125. *
  126. * description
  127. *
  128. * @type function
  129. * @date 9/6/17
  130. * @since 5.6.0
  131. *
  132. * @param $post_id (int)
  133. * @return $post_id (int)
  134. */
  135. function add_sub_page( $page ) {
  136. // validate
  137. $page = $this->validate_page( $page );
  138. // default parent
  139. if ( ! $page['parent_slug'] ) {
  140. $page['parent_slug'] = 'acf-options';
  141. }
  142. // create default parent if not yet exists
  143. if ( $page['parent_slug'] == 'acf-options' && ! $this->get_page( 'acf-options' ) ) {
  144. $this->add_page( '' );
  145. }
  146. // return
  147. return $this->add_page( $page );
  148. }
  149. /*
  150. * update_page
  151. *
  152. * This function will update an options page settings
  153. *
  154. * @type function
  155. * @date 9/6/17
  156. * @since 5.6.0
  157. *
  158. * @param $slug (string)
  159. * @param $data (array)
  160. * @return (array)
  161. */
  162. function update_page( $slug = '', $data = array() ) {
  163. // vars
  164. $page = $this->get_page( $slug );
  165. // bail early if no page
  166. if ( ! $page ) {
  167. return false;
  168. }
  169. // loop
  170. $page = array_merge( $page, $data );
  171. // set
  172. $this->pages[ $slug ] = $page;
  173. // return
  174. return $page;
  175. }
  176. /*
  177. * get_page
  178. *
  179. * This function will return an options page settings
  180. *
  181. * @type function
  182. * @date 6/07/2016
  183. * @since 5.4.0
  184. *
  185. * @param $slug (string)
  186. * @return (mixed)
  187. */
  188. function get_page( $slug ) {
  189. return isset( $this->pages[ $slug ] ) ? $this->pages[ $slug ] : null;
  190. }
  191. /*
  192. * get_pages
  193. *
  194. * This function will return all options page settings
  195. *
  196. * @type function
  197. * @date 6/07/2016
  198. * @since 5.4.0
  199. *
  200. * @param $slug (string)
  201. * @return (mixed)
  202. */
  203. function get_pages() {
  204. return $this->pages;
  205. }
  206. }
  207. /*
  208. * acf_options_page
  209. *
  210. * This function will return the options page instance
  211. *
  212. * @type function
  213. * @date 9/6/17
  214. * @since 5.6.0
  215. *
  216. * @param n/a
  217. * @return (object)
  218. */
  219. function acf_options_page() {
  220. global $acf_options_page;
  221. if ( ! isset( $acf_options_page ) ) {
  222. $acf_options_page = new acf_options_page();
  223. }
  224. return $acf_options_page;
  225. }
  226. // remove Options Page add-on conflict
  227. unset( $GLOBALS['acf_options_page'] );
  228. // initialize
  229. acf_options_page();
  230. endif; // class_exists check
  231. /*
  232. * acf_add_options_page
  233. *
  234. * alias of acf_options_page()->add_page()
  235. *
  236. * @type function
  237. * @date 24/02/2014
  238. * @since 5.0.0
  239. *
  240. * @param $page (mixed)
  241. * @return (array)
  242. */
  243. if ( ! function_exists( 'acf_add_options_page' ) ) :
  244. function acf_add_options_page( $page = '' ) {
  245. return acf_options_page()->add_page( $page );
  246. }
  247. endif;
  248. /*
  249. * acf_add_options_sub_page
  250. *
  251. * alias of acf_options_page()->add_sub_page()
  252. *
  253. * @type function
  254. * @date 24/02/2014
  255. * @since 5.0.0
  256. *
  257. * @param $page (mixed)
  258. * @return (array)
  259. */
  260. if ( ! function_exists( 'acf_add_options_sub_page' ) ) :
  261. function acf_add_options_sub_page( $page = '' ) {
  262. return acf_options_page()->add_sub_page( $page );
  263. }
  264. endif;
  265. /*
  266. * acf_update_options_page
  267. *
  268. * alias of acf_options_page()->update_page()
  269. *
  270. * @type function
  271. * @date 24/02/2014
  272. * @since 5.0.0
  273. *
  274. * @param $slug (string)
  275. * @param $page (mixed)
  276. * @return (array)
  277. */
  278. if ( ! function_exists( 'acf_update_options_page' ) ) :
  279. function acf_update_options_page( $slug = '', $data = array() ) {
  280. return acf_options_page()->update_page( $slug, $data );
  281. }
  282. endif;
  283. /*
  284. * acf_get_options_page
  285. *
  286. * This function will return an options page settings
  287. *
  288. * @type function
  289. * @date 24/02/2014
  290. * @since 5.0.0
  291. *
  292. * @param $slug (string)
  293. * @return (array)
  294. */
  295. if ( ! function_exists( 'acf_get_options_page' ) ) :
  296. function acf_get_options_page( $slug ) {
  297. // vars
  298. $page = acf_options_page()->get_page( $slug );
  299. // bail early if no page
  300. if ( ! $page ) {
  301. return false;
  302. }
  303. // filter
  304. $page = apply_filters( 'acf/get_options_page', $page, $slug );
  305. // return
  306. return $page;
  307. }
  308. endif;
  309. /*
  310. * acf_get_options_pages
  311. *
  312. * This function will return all options page settings
  313. *
  314. * @type function
  315. * @date 24/02/2014
  316. * @since 5.0.0
  317. *
  318. * @param n/a
  319. * @return (array)
  320. */
  321. if ( ! function_exists( 'acf_get_options_pages' ) ) :
  322. function acf_get_options_pages() {
  323. // global
  324. global $_wp_last_utility_menu;
  325. // vars
  326. $pages = acf_options_page()->get_pages();
  327. // bail early if no pages
  328. if ( empty( $pages ) ) {
  329. return false;
  330. }
  331. // apply filter to each page
  332. foreach ( $pages as $slug => &$page ) {
  333. $page = acf_get_options_page( $slug );
  334. }
  335. // calculate parent => child redirectes
  336. foreach ( $pages as $slug => &$page ) {
  337. // bail early if is child
  338. if ( $page['parent_slug'] ) {
  339. continue;
  340. }
  341. // add missing position
  342. if ( ! $page['position'] ) {
  343. $_wp_last_utility_menu++;
  344. $page['position'] = $_wp_last_utility_menu;
  345. }
  346. // bail early if no redirect
  347. if ( ! $page['redirect'] ) {
  348. continue;
  349. }
  350. // vars
  351. $parent = $page['menu_slug'];
  352. $child = '';
  353. // update children
  354. foreach ( $pages as &$sub_page ) {
  355. // bail early if not child of this parent
  356. if ( $sub_page['parent_slug'] !== $parent ) {
  357. continue;
  358. }
  359. // set child (only once)
  360. if ( ! $child ) {
  361. $child = $sub_page['menu_slug'];
  362. }
  363. // update parent_slug to the first child
  364. $sub_page['parent_slug'] = $child;
  365. }
  366. // finally update parent menu_slug
  367. if ( $child ) {
  368. $page['menu_slug'] = $child;
  369. }
  370. }
  371. // filter
  372. $pages = apply_filters( 'acf/get_options_pages', $pages );
  373. // return
  374. return $pages;
  375. }
  376. endif;
  377. /*
  378. * acf_set_options_page_title
  379. *
  380. * This function is used to customize the options page admin menu title
  381. *
  382. * @type function
  383. * @date 13/07/13
  384. * @since 4.0.0
  385. *
  386. * @param $title (string)
  387. * @return n/a
  388. */
  389. if ( ! function_exists( 'acf_set_options_page_title' ) ) :
  390. function acf_set_options_page_title( $title = 'Options' ) {
  391. acf_update_options_page(
  392. 'acf-options',
  393. array(
  394. 'page_title' => $title,
  395. 'menu_title' => $title,
  396. )
  397. );
  398. }
  399. endif;
  400. /*
  401. * acf_set_options_page_menu
  402. *
  403. * This function is used to customize the options page admin menu name
  404. *
  405. * @type function
  406. * @date 13/07/13
  407. * @since 4.0.0
  408. *
  409. * @param $title (string)
  410. * @return n/a
  411. */
  412. if ( ! function_exists( 'acf_set_options_page_menu' ) ) :
  413. function acf_set_options_page_menu( $title = 'Options' ) {
  414. acf_update_options_page(
  415. 'acf-options',
  416. array(
  417. 'menu_title' => $title,
  418. )
  419. );
  420. }
  421. endif;
  422. /*
  423. * acf_set_options_page_capability
  424. *
  425. * This function is used to customize the options page capability. Defaults to 'edit_posts'
  426. *
  427. * @type function
  428. * @date 13/07/13
  429. * @since 4.0.0
  430. *
  431. * @param $title (string)
  432. * @return n/a
  433. */
  434. if ( ! function_exists( 'acf_set_options_page_capability' ) ) :
  435. function acf_set_options_page_capability( $capability = 'edit_posts' ) {
  436. acf_update_options_page(
  437. 'acf-options',
  438. array(
  439. 'capability' => $capability,
  440. )
  441. );
  442. }
  443. endif;
  444. /*
  445. * register_options_page()
  446. *
  447. * This is an old function which is now referencing the new 'acf_add_options_sub_page' function
  448. *
  449. * @type function
  450. * @since 3.0.0
  451. * @date 29/01/13
  452. *
  453. * @param {string} $title
  454. * @return N/A
  455. */
  456. if ( ! function_exists( 'register_options_page' ) ) :
  457. function register_options_page( $page = '' ) {
  458. acf_add_options_sub_page( $page );
  459. }
  460. endif;