PageRenderTime 70ms CodeModel.GetById 38ms RepoModel.GetById 0ms app.codeStats 1ms

/admin/class-apl-admin.php

https://github.com/Advanced-Post-List/advanced-post-list
PHP | 2227 lines | 1214 code | 266 blank | 747 comment | 121 complexity | dc05c4f4aa7d94e9ee2d9c74bcd7f0e1 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * APL Admin API: APL_Admin Class
  4. *
  5. * Admin core object to Advanced Post List
  6. *
  7. * @link https://github.com/Advanced-Post-List/advanced-post-list/
  8. *
  9. * @package advanced-post-list\APL_Core
  10. * @since 0.4.0
  11. */
  12. /**
  13. * APL Admin
  14. *
  15. * Admin core class.
  16. *
  17. * @since 0.4.0
  18. */
  19. class APL_Admin {
  20. /**
  21. * Singleton Instance
  22. *
  23. * @since 0.4.0
  24. * @access private
  25. * @var null $instance Singleton Class Instance.
  26. */
  27. protected static $instance = null;
  28. /**
  29. * Get Singleton Instance
  30. *
  31. * Singleton Get Instance.
  32. *
  33. * @since 0.4.0
  34. * @access private
  35. *
  36. * @return object
  37. */
  38. public static function get_instance() {
  39. if ( null === static::$instance ) {
  40. static::$instance = new static();
  41. // TODO - Catch WP Error.
  42. }
  43. return static::$instance;
  44. }
  45. /**
  46. * Throws error on object clone
  47. *
  48. * The whole idea of the singleton design pattern is that there is a single
  49. * object therefore, we don't want the object to be cloned.
  50. *
  51. * @ignore
  52. * @since 0.4.0
  53. * @access private
  54. */
  55. private function __clone() {
  56. // Cloning instances of the class is forbidden.
  57. _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin\' huh?', 'advanced-post-list' ), APL_VERSION );
  58. }
  59. /**
  60. * Disable unserializing of the class
  61. *
  62. * @ignore
  63. * @since 0.4.0
  64. * @access protected
  65. */
  66. private function __wakeup() {
  67. // Unserializing instances of the class is forbidden.
  68. _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin\' huh?', 'advanced-post-list' ), APL_VERSION );
  69. }
  70. /**
  71. * Constructor
  72. *
  73. * Private Singleton Constructor.
  74. *
  75. * @ignore
  76. * @since 0.4.0
  77. * @access private
  78. *
  79. * @todo Complete Admin Encapsulation. Concept linked.
  80. * @link https://florianbrinkmann.com/en/3815/wordpress-backend-request/
  81. */
  82. private function __construct() {
  83. // Exit if Non-Admins access this object. Also wrapped in APL_Core.
  84. if ( ! is_admin() ) {
  85. return new WP_Error( 'apl_admin', esc_html__( 'You do not have admin capabilities in APL_Admin.', 'advanced-post-list' ) );
  86. }
  87. // Initialize Core Class functions.
  88. $this->_requires();
  89. apl_notice_set_activation_review_plugin( false, false );
  90. // Settings Data.
  91. add_action( 'admin_post_apl_save_general_settings', array( $this, 'save_general_settings' ) );
  92. // AJAX.
  93. add_action( 'admin_init', array( $this, 'add_settings_ajax_hooks' ) );
  94. // Check if wp-admin.php is loaded, and WP_Screen is defined.
  95. // is_admin_bar_showing().
  96. if ( defined( 'WP_ADMIN' ) && WP_ADMIN && is_blog_admin() ) {
  97. // Menu & Scripts.
  98. add_action( 'admin_menu', array( $this, 'admin_menu' ) );
  99. add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue' ) );
  100. // Admin Screens for Modular Screen Execution.
  101. // NOTE: Settings Page needs to hook sooner (in constructor/here).
  102. add_action( 'current_screen', array( $this, 'current_screen_hooks' ) );
  103. // Hook into WP to customize Screens.
  104. add_action( 'admin_head', array( $this, 'disable_screen_boxes' ) );
  105. add_action( 'load-edit.php', array( $this, 'post_list_screen_options_all' ) );
  106. add_action( 'load-post-new.php', array( $this, 'post_list_screen_options_add_new' ) );
  107. add_action( 'manage_apl_post_list_posts_columns', array( $this, 'post_list_posts_columns' ) );
  108. add_action( 'manage_apl_post_list_posts_custom_column', array( $this, 'post_list_posts_custom_column' ), 10, 2 );
  109. add_action( 'manage_edit-apl_post_list_sortable_columns', array( $this, 'post_list_sortable_columns' ) );
  110. // Editor Meta Boxes.
  111. add_action( 'add_meta_boxes', array( $this, 'post_list_meta_boxes' ) );
  112. add_action( 'add_meta_boxes', array( $this, 'settings_meta_boxes' ) );
  113. if ( defined( 'ICL_SITEPRESS_VERSION' ) || defined( 'APLP_VERSION' ) ) {
  114. add_action( 'add_meta_boxes', array( $this, 'design_meta_boxes' ) );
  115. }
  116. add_filter( 'mce_external_plugins', array( $this, 'mce_external_plugins' ) );
  117. add_filter( 'mce_buttons', array( $this, 'mce_buttons' ) );
  118. add_action( 'admin_head', array( $this, 'tinymce_extra_vars' ) );
  119. }
  120. }
  121. /**
  122. * Requires Files
  123. *
  124. * Files that this class object needs to load.
  125. *
  126. * @ignore
  127. * @since 0.4.0
  128. * @access private
  129. */
  130. private function _requires() {
  131. // Example.
  132. // 'require_once( APL_DIR . 'includes/example.php' )'.
  133. require_once APL_DIR . 'admin/functions-admin.php';
  134. require_once APL_DIR . 'admin/export.php';
  135. require_once APL_DIR . 'admin/import.php';
  136. require_once APL_DIR . 'admin/class-apl-notices.php';
  137. }
  138. /**
  139. * Current Admin Screen Hooks
  140. *
  141. * Adds hooks according to the admin screen in use.
  142. *
  143. * @since 0.4.0
  144. *
  145. * @param WP_Screen $current_screen Current WP_Screen object.
  146. */
  147. public function current_screen_hooks( $current_screen ) {
  148. if ( 'apl_post_list' === $current_screen->id || 'edit-apl_post_list' === $current_screen->id ) {
  149. // Post Data.
  150. add_action( 'draft_apl_post_list', array( $this, 'draft_post_list' ), 10, 2 );
  151. add_action( 'private_apl_post_list', array( $this, 'save_post_list' ), 10, 2 );
  152. add_action( 'publish_apl_post_list', array( $this, 'save_post_list' ), 10, 2 );
  153. add_action( 'pending_apl_post_list', array( $this, 'save_post_list' ), 10, 2 );
  154. add_action( 'future_apl_post_list', array( $this, 'save_post_list' ), 10, 2 );
  155. // //add_action( 'trash_apl_post_list', array( $this, 'trash_post_list' ), 10, 3 );
  156. add_action( 'wp_trash_post', array( $this, 'action_wp_trash_post_apl_post_list' ) );
  157. add_action( 'untrash_post', array( $this, 'action_untrash_post_apl_post_list' ) );
  158. add_action( 'before_delete_post', array( $this, 'action_before_delete_post_apl_post_list' ) );
  159. // //if ( 'apl_post_list' === $current_screen->id ) {
  160. // // $current_screen->add_help_tab( array(
  161. // // 'id' => 'apl_post_list_help', //unique id for the tab.
  162. // // 'title' => 'Testing Help Tab', //unique visible title for the tab.
  163. // // 'content' => 'Hello World', //actual help text.
  164. // // //'callback' => $callback //optional function to callback.
  165. // // ) );
  166. // //}
  167. } elseif ( 'apl_design' === $current_screen->id || 'edit-apl_design' === $current_screen->id ) {
  168. // Post Data.
  169. add_action( 'draft_apl_design', array( $this, 'draft_design' ), 10, 2 );
  170. add_action( 'private_apl_design', array( $this, 'save_design' ), 10, 2 );
  171. add_action( 'publish_apl_design', array( $this, 'save_design' ), 10, 2 );
  172. add_action( 'pending_apl_design', array( $this, 'save_design' ), 10, 2 );
  173. add_action( 'future_apl_design', array( $this, 'save_design' ), 10, 2 );
  174. // //add_action( 'trash_apl_post_list', array( $this, 'trash_design' ), 10, 3 );
  175. // //add_action( 'wp_trash_post', array( $this, 'action_wp_trash_post_apl_design' ) );
  176. // //add_action( 'untrash_post', array( $this, 'action_untrash_post_apl_design' ) );
  177. // //add_action( 'before_delete_post', array( $this, 'action_before_delete_post_apl_design' ) );
  178. } elseif ( 'adv-post-list_page_apl_settings' === $current_screen->id ) {
  179. // SETTINGS (Page).
  180. // DOES NOT always work as intended. Use self::_constructor().
  181. } else {
  182. // //add_filter( 'mce_external_plugins', array( $this, 'mce_external_plugins' ) );
  183. // //add_filter( 'mce_buttons', array( $this, 'mce_register_buttons' ) );
  184. }// End if().
  185. }
  186. /**
  187. * APL Admin Menu
  188. *
  189. * Adds the Admin Menu and Scripts for APL.
  190. *
  191. * @since 0.4.0
  192. *
  193. * @see 'admin_menu' hook
  194. * @see wp-admin/admin-header.php
  195. * @link https://developer.wordpress.org/reference/functions/add_menu_page/
  196. * @link https://developer.wordpress.org/reference/functions/add_submenu_page/
  197. */
  198. public function admin_menu() {
  199. add_menu_page(
  200. __( 'Advanced Post List', 'advanced-post-list' ),
  201. __( 'Adv. Post List', 'advanced-post-list' ),
  202. 'administrator',
  203. 'advanced_post_list',
  204. 'edit.php?post_type=apl_post_list', // Callback function if dashboard is added.
  205. 'dashicons-welcome-widgets-menus',
  206. 58
  207. );
  208. // TODO Add APL Dashboard.
  209. // All Post Lists (Submenu) - Submenu setting is added during CPT registration.
  210. // Add New (Submenu).
  211. add_submenu_page(
  212. 'advanced_post_list',
  213. __( 'Add New Post List', 'advanced-post-list' ),
  214. __( '- New Post List', 'advanced-post-list' ),
  215. 'administrator',
  216. 'post-new.php?post_type=apl_post_list'
  217. );
  218. // Settings (Submenu).
  219. add_submenu_page(
  220. 'advanced_post_list',
  221. // // edit.php?post_type=apl_post_list',
  222. __( 'APL Settings', 'advanced-post-list' ),
  223. __( 'Settings', 'advanced-post-list' ),
  224. 'administrator',
  225. 'apl_settings',
  226. array( $this, 'submenu_settings_page' )
  227. );
  228. add_action( 'admin_init', array( $this, 'settings_register_settings' ) );
  229. // TODO - Add Help API.
  230. // EXTENSIONS.
  231. do_action( 'apl_admin_menu_ext' );
  232. }
  233. /**
  234. * Submenu Callback for Settings Page
  235. *
  236. * @since 0.4.0
  237. */
  238. public function submenu_settings_page() {
  239. apl_get_template( 'admin/settings-page.php' );
  240. }
  241. /**
  242. * Registers Input Settings for Settings Page
  243. *
  244. * @since 0.4.0
  245. */
  246. public function settings_register_settings() {
  247. register_setting( 'apl_settings_general', 'apl_delete_on_deactivation', 'strval' );
  248. register_setting( 'apl_settings_general', 'apl_default_empty_enable', 'strval' );
  249. register_setting( 'apl_settings_general', 'apl_default_empty_message', 'strval' );
  250. // //register_setting( 'apl_settings_import_export', 'apl_export_file_name', 'strval' );
  251. // //register_setting( 'apl_settings_import_export', 'apl_import_opt', 'strval' );
  252. // //register_setting( 'apl_settings_import_export', 'apl_import_file', 'strval' );
  253. // //register_setting( 'apl_settings_import_export', 'apl_restore_database', 'strval' );
  254. }
  255. /**
  256. * APL Admin Enqueue Scripts & Styles
  257. *
  258. * Loads APL scripts and styles. If not in APL Admin Pages, then remove.
  259. *
  260. * @since 0.4.0
  261. *
  262. * @see wp-admin/admin-header.php
  263. * @link https://developer.wordpress.org/reference/hooks/admin_enqueue_scripts/
  264. *
  265. * @param string $hook_suffix The suffix for the current Admin page.
  266. */
  267. public function admin_enqueue( $hook_suffix ) {
  268. $screen = get_current_screen();
  269. /*
  270. * ************** REMOVE SCRIPTS & STYLES *********************
  271. */
  272. // STEP 1 - By default, remove any scripts & styles.
  273. wp_deregister_script( 'apl-admin-js' );
  274. wp_deregister_script( 'apl-admin-ui-js' );
  275. wp_deregister_script( 'apl-admin-ui-multiselect-js' );
  276. wp_deregister_script( 'apl-admin-ui-multiselect-filter-js' );
  277. wp_deregister_style( 'apl-admin-css' );
  278. wp_deregister_style( 'apl-admin-ui-multiselect-css' );
  279. wp_deregister_style( 'apl-admin-ui-multiselect-filter-css' );
  280. wp_deregister_style( 'apl-admin-settings-css' );
  281. if ( 'apl_post_list' === $screen->id || 'edit-apl_post_list' === $screen->id || 'apl_design' === $screen->id || 'edit-apl_design' === $screen->id ) {
  282. /*
  283. * ************** AJAX ACTION HOOKS ***************************
  284. */
  285. // TODO - Add meta box to side to load different presets from 'edit.php'.
  286. // //add_action( 'wp_ajax_apl_load_preset', array( $this, 'hook_ajax_load_preset' ) );
  287. /*
  288. * ************** REGISTER SCRIPTS ****************************
  289. */
  290. // Step 2 - Register scripts to be enqueued.
  291. wp_register_script(
  292. 'apl-admin-js',
  293. APL_URL . 'admin/js/admin.js',
  294. array(
  295. 'jquery',
  296. ),
  297. APL_VERSION,
  298. false
  299. );
  300. wp_register_script(
  301. 'apl-admin-ui-js',
  302. APL_URL . 'admin/js/admin-ui.js',
  303. array(
  304. 'jquery',
  305. 'jquery-ui-core',
  306. 'jquery-ui-widget',
  307. 'jquery-ui-tabs',
  308. 'jquery-ui-spinner',
  309. 'jquery-ui-slider',
  310. 'jquery-ui-button',
  311. 'jquery-ui-dialog',
  312. 'jquery-ui-selectmenu',
  313. 'jquery-ui-position',
  314. 'jquery-ui-tooltip',
  315. ),
  316. APL_VERSION,
  317. true
  318. );
  319. wp_register_script(
  320. 'apl-admin-ui-multiselect-js',
  321. APL_URL . 'admin/js/jquery-multiselect/jquery.multiselect.min.js',
  322. array(
  323. 'jquery',
  324. 'jquery-ui-core',
  325. 'jquery-ui-widget',
  326. 'jquery-ui-selectmenu',
  327. ),
  328. APL_VERSION,
  329. false
  330. );
  331. wp_register_script(
  332. 'apl-admin-ui-multiselect-filter-js',
  333. APL_URL . 'admin/js/jquery-multiselect/jquery.multiselect.filter.min.js',
  334. array(
  335. 'jquery',
  336. 'jquery-ui-core',
  337. 'jquery-ui-widget',
  338. ),
  339. APL_VERSION,
  340. false
  341. );
  342. global $wp_version;
  343. if ( version_compare( $wp_version, '4.9', '>' ) && ( 'apl_post_list' === $screen->id || 'apl_design' === $screen->id ) ) {
  344. // Enqueue code editor and settings for manipulating HTML.
  345. // https://developer.wordpress.org/reference/functions/wp_enqueue_code_editor/
  346. $args = array( 'type' => 'application/x-httpd-php' );
  347. $settings = wp_enqueue_code_editor( $args );
  348. if ( false !== $settings ) {
  349. wp_add_inline_script(
  350. 'code-editor',
  351. sprintf(
  352. 'jQuery( function() { wp.codeEditor.initialize( "apl_textarea_before", %s ); } );',
  353. wp_json_encode( $settings )
  354. )
  355. );
  356. wp_add_inline_script(
  357. 'code-editor',
  358. sprintf(
  359. 'jQuery( function() { wp.codeEditor.initialize( "apl_textarea_content", %s ); } );',
  360. wp_json_encode( $settings )
  361. )
  362. );
  363. wp_add_inline_script(
  364. 'code-editor',
  365. sprintf(
  366. 'jQuery( function() { wp.codeEditor.initialize( "apl_textarea_after", %s ); } );',
  367. wp_json_encode( $settings )
  368. )
  369. );
  370. // Empty is disabled for now, but will need to be hidden when checkbox is unchecked.
  371. // Hold off until 5.0.
  372. }
  373. }
  374. // STEP 3 - Enqueue scripts.
  375. wp_enqueue_script( 'apl-admin-js' );
  376. wp_enqueue_script( 'apl-admin-ui-js' );
  377. wp_enqueue_script( 'apl-admin-ui-multiselect-js' );
  378. wp_enqueue_script( 'apl-admin-ui-multiselect-filter-js' );
  379. /*
  380. * ************** REGISTER STYLES *****************************
  381. */
  382. // Step 4 - (Register) Enqueue styles.
  383. wp_enqueue_style(
  384. 'apl-admin-css',
  385. APL_URL . 'admin/css/admin.css',
  386. false,
  387. APL_VERSION,
  388. false
  389. );
  390. $wp_scripts = wp_scripts();
  391. wp_enqueue_style(
  392. 'apl-admin-ui-css',
  393. APL_URL . 'admin/css/jquery-ui/jquery-ui.min.css',
  394. false,
  395. APL_VERSION,
  396. false
  397. );
  398. wp_enqueue_style(
  399. 'apl-admin-ui-multiselect-css',
  400. APL_URL . 'admin/css/jquery-multiselect/jquery.multiselect.css',
  401. false,
  402. APL_VERSION,
  403. false
  404. );
  405. wp_enqueue_style(
  406. 'apl-admin-ui-multiselect-filter-css',
  407. APL_URL . 'admin/css/jquery-multiselect/jquery.multiselect.filter.css',
  408. false,
  409. APL_VERSION,
  410. false
  411. );
  412. // Get values for variables to localize into JS files.
  413. // POST => TAXONOMIES.
  414. $data_post_tax = apl_get_post_tax();
  415. // TAXONOMIES => TERMS.
  416. $data_tax_terms = apl_get_tax_terms();
  417. $data_ui_trans = array(
  418. 'tax_noneSelectedText' => esc_html__( 'Select Taxonomy', 'advanced-post-list' ),
  419. 'tax_selectedText' => esc_html__( '# of # taxonomies selected', 'advanced-post-list' ),
  420. 'author_ids_noneSelectedText' => esc_html__( '- None -', 'advanced-post-list' ),
  421. 'author_ids_selectedText' => esc_html__( '# Selected', 'advanced-post-list' ),
  422. 'post_status_1_noneSelectedText' => esc_html__( 'Select Status', 'advanced-post-list' ),
  423. 'post_status_1_selectedText' => esc_html__( 'Both', 'advanced-post-list' ),
  424. 'post_status_2_noneSelectedText' => esc_html__( 'Published', 'advanced-post-list' ),
  425. 'post_status_2_selectedText' => esc_html__( '# Selected', 'advanced-post-list' ),
  426. );
  427. $admin_localize = array();
  428. $admin_ui_localize = array(
  429. 'post_tax' => $data_post_tax,
  430. 'tax_terms' => $data_tax_terms,
  431. 'trans' => $data_ui_trans,
  432. );
  433. // Add variables to JS files.
  434. // '../admin/js/admin.js'.
  435. // '../admin/js/admin-ui.js'.
  436. wp_localize_script( 'apl-admin-js', 'apl_admin_local', $admin_localize );
  437. wp_localize_script( 'apl-admin-ui-js', 'apl_admin_ui_local', $admin_ui_localize );
  438. // //} elseif ( 'apl_design' === $screen->id || 'edit-apl_design' === $screen->id ) {
  439. // TODO Add handling APL Designs without extra code from APL_Post_Lists..
  440. } elseif ( 'adv-post-list_page_apl_settings' === $screen->id ) {
  441. // If we are not viewing APL Post List area, then return.
  442. // SETTINGS PAGE.
  443. // SCRIPTS.
  444. wp_register_script(
  445. 'apl-settings-js',
  446. APL_URL . 'admin/js/settings.js',
  447. array(
  448. 'jquery',
  449. 'jquery-ui-core',
  450. 'jquery-ui-widget',
  451. 'jquery-ui-button',
  452. 'jquery-ui-dialog',
  453. ),
  454. APL_VERSION,
  455. true
  456. );
  457. wp_register_script(
  458. 'apl-settings-ui-js',
  459. APL_URL . 'admin/js/settings-ui.js',
  460. array(
  461. 'jquery',
  462. 'jquery-ui-core',
  463. 'jquery-ui-widget',
  464. 'jquery-ui-dialog',
  465. 'jquery-ui-position',
  466. 'jquery-ui-tooltip',
  467. ),
  468. APL_VERSION,
  469. true
  470. );
  471. wp_enqueue_script( 'postbox' );
  472. wp_enqueue_script( 'apl-settings-js' );
  473. wp_enqueue_script( 'apl-settings-ui-js' );
  474. // STYLES.
  475. wp_enqueue_style(
  476. 'apl-admin-settings-css',
  477. APL_URL . 'admin/css/settings.css',
  478. false,
  479. APL_VERSION,
  480. false
  481. );
  482. wp_enqueue_style(
  483. 'apl-admin-ui-css',
  484. APL_URL . 'admin/css/jquery-ui/jquery-ui.css',
  485. false,
  486. APL_VERSION,
  487. false
  488. );
  489. $trans_arr = array(
  490. 'default_alert_title' => __( 'Alert', 'advanced-post-list' ),
  491. 'default_alert_message' => __( 'No Message to Display.', 'advanced-post-list' ),
  492. 'fileName_empty_alert_title' => __( 'Filename Required', 'advanced-post-list' ),
  493. 'fileName_empty_alert_message' => __( 'A filename doesn\'t exist. \n Please enter a filename before exporting.', 'advanced-post-list' ),
  494. 'import_no_file_message' => __( 'No file(s) selected. Please choose a JSON file to upload.', 'advanced-post-list' ),
  495. 'import_no_file_title' => __( 'No File', 'advanced-post-list' ),
  496. 'import_invalid_file_message' => __( 'Invalid file type. Please choose a JSON file to upload.', 'advanced-post-list' ),
  497. 'import_invalid_file_title' => __( 'Invalid File', 'advanced-post-list' ),
  498. 'import_success_message' => __( 'Data successfully imported.', 'advanced-post-list' ),
  499. 'import_success_title' => __( 'Complete', 'advanced-post-list' ),
  500. 'import_overwrite_dialog_title' => __( 'Overwrite Presets', 'advanced-post-list' ),
  501. 'fileName_char_alert_title' => __( 'Illegal Characters', 'advanced-post-list' ),
  502. 'fileName_char_alert_message1' => __( 'Cannot use (< > : " / \\ | , ? *).', 'advanced-post-list' ),
  503. 'fileName_char_alert_message2' => __( 'Please rename your filename.', 'advanced-post-list' ),
  504. );
  505. $trans_ui_arr = array(
  506. 'fileName_char_alert_title' => __( 'Illegal Characters', 'advanced-post-list' ),
  507. 'fileName_char_alert_message1' => __( 'Cannot use (< > : " / \\ | , ? *).', 'advanced-post-list' ),
  508. 'fileName_char_alert_message2' => __( 'Please rename your filename.', 'advanced-post-list' ),
  509. );
  510. $settings_localize = array(
  511. 'export_nonce' => wp_create_nonce( 'apl_settings_export' ),
  512. 'import_nonce' => wp_create_nonce( 'apl_settings_import' ),
  513. 'restoreDefaultsNonce' => wp_create_nonce( 'apl_settings_restore_defaults' ),
  514. 'trans' => $trans_arr,
  515. );
  516. $settings_ui_localize = array(
  517. 'trans' => $trans_ui_arr,
  518. );
  519. wp_localize_script( 'apl-settings-js', 'apl_settings_local', $settings_localize );
  520. wp_localize_script( 'apl-settings-ui-js', 'apl_settings_ui_local', $settings_ui_localize );
  521. global $post_type;
  522. do_action( 'add_meta_boxes', $hook_suffix, $post_type );
  523. $screen_args = array(
  524. 'max' => 2,
  525. 'default' => 2,
  526. );
  527. add_screen_option( 'layout_columns', $screen_args );
  528. } else {
  529. // REGISTER.
  530. // LOCALIZE.
  531. // ENQUEUE.
  532. wp_enqueue_style(
  533. 'apl-admin-wp-editor-css',
  534. APL_URL . 'admin/css/wp-editor.css',
  535. false,
  536. APL_VERSION,
  537. false
  538. );
  539. }// End if().
  540. }
  541. /**
  542. * Disables/Hides Screen Option Settings
  543. *
  544. * Disables / Hides the Screen Option's display Meta Boxes Settings. Basically
  545. * prevents certain Meta Boxes from being hidden, and forces the box to display.
  546. *
  547. * @since 0.4.0
  548. *
  549. * @see 'admin_head' hook.
  550. * @link https://wordpress.stackexchange.com/questions/149602/hiding-metabox-from-screen-options-pull-down
  551. */
  552. public function disable_screen_boxes() {
  553. echo '<style>label[for=apl-post-list-filter-hide] { display: none; }</style>';
  554. echo '<style>#apl-post-list-filter { display: block; }</style>';
  555. }
  556. /**
  557. * Screen Options for 'All Post List' page
  558. *
  559. * Hook 'load-edit.php', sets additional Screen Options.
  560. *
  561. * @see 'load-edit.php' hook.
  562. * @since 0.4.0
  563. */
  564. public function post_list_screen_options_all() {
  565. $screen = get_current_screen();
  566. // Get out of here if we are not on our settings page.
  567. if ( ! is_object( $screen ) || 'edit-apl_post_list' !== $screen->id ) {
  568. return;
  569. }
  570. $options = $screen->get_options();
  571. }
  572. /**
  573. * Screen Options for 'Add New' page
  574. *
  575. * Hook 'load-post-new.php', sets additional Screen Options.
  576. *
  577. * @see 'load-post-new.php' hook.
  578. * @since 0.4.0
  579. */
  580. public function post_list_screen_options_add_new() {
  581. $screen = get_current_screen();
  582. // Get out of here if we are not on our settings page.
  583. if ( ! is_object( $screen ) || 'apl_post_list' !== $screen->id ) {
  584. return;
  585. }
  586. $options = $screen->get_options();
  587. }
  588. /**
  589. * Post List All Posts Columns
  590. *
  591. * Adds additional columns to All Post Lists page.
  592. *
  593. * @since 0.4.0
  594. *
  595. * @see 'manage_apl_post_list_posts_columns'
  596. * @uses manage_${post_type}_posts_columns
  597. * @link https://codex.wordpress.org/Plugin_API/Filter_Reference/manage_$post_type_posts_columns
  598. *
  599. * @param array $columns Columns use in the 'All Post Lists' page.
  600. * @return array
  601. */
  602. public function post_list_posts_columns( $columns ) {
  603. $tmp_date = $columns['date'];
  604. unset( $columns['date'] );
  605. $columns['post_name'] = __( 'Slug', 'advanced-post-list' );
  606. $columns['apl_shortcode'] = __( 'Shortcode', 'advanced-post-list' );
  607. $columns['date'] = $tmp_date;
  608. return $columns;
  609. }
  610. /**
  611. * Post List Custom Column
  612. *
  613. * Adds content to custom column.
  614. *
  615. * @since 0.4.0
  616. *
  617. * @uses manage_${post_type}_posts_columns hook.
  618. * @link https://codex.wordpress.org/Plugin_API/Action_Reference/manage_$post_type_posts_custom_column
  619. *
  620. * @param array $column The name of the column to display. Default: None.
  621. * @param int $post_id The ID of the current post. Can also be taken from the global $post->ID. Default: None.
  622. */
  623. public function post_list_posts_custom_column( $column, $post_id ) {
  624. $args = array(
  625. 'post__in' => array( $post_id ),
  626. 'post_type' => 'apl_post_list',
  627. 'post_status' => array(
  628. 'draft',
  629. 'pending',
  630. 'publish',
  631. 'future',
  632. 'private',
  633. 'trash',
  634. ),
  635. );
  636. $post_lists = new WP_Query( $args );
  637. $post_list = $post_lists->post;
  638. switch ( $column ) {
  639. case 'post_name':
  640. echo esc_attr( $post_list->post_name );
  641. break;
  642. case 'apl_shortcode':
  643. echo '<input value="[post_list name=\'' . esc_attr( $post_list->post_name ) . '\']" type="text" size="32" onfocus="this.select();" onclick="this.select();" readonly="readonly" />';
  644. break;
  645. }
  646. }
  647. /**
  648. * Post List Sortable Columns
  649. *
  650. * Sets Custom Columns to be sortable.
  651. *
  652. * @link https://developer.wordpress.org/reference/hooks/manage_this-screen-id_sortable_columns/
  653. *
  654. * @param array $columns An array of sortable columns.
  655. * @return array
  656. */
  657. public function post_list_sortable_columns( $columns ) {
  658. $columns['post_name'] = 'post_name';
  659. return $columns;
  660. }
  661. /**
  662. * Post List Meta Boxes
  663. *
  664. * Hook 'add_meta_boxes', adds meta boxes used in post lists.
  665. *
  666. * @since 0.4.0
  667. *
  668. * @see $this->_construct Used by.
  669. * @see 'add_meta_boxes' hook.
  670. * @see wp-admin/includes/template.php
  671. * @link https://codex.wordpress.org/Plugin_API/Action_Reference/add_meta_boxes
  672. * @link https://developer.wordpress.org/reference/functions/add_meta_box/
  673. */
  674. public function post_list_meta_boxes() {
  675. add_meta_box(
  676. 'apl-post-list-filter',
  677. __( 'Filter Settings', 'advanced-post-list' ),
  678. array( $this, 'post_list_meta_box_filter' ),
  679. 'apl_post_list',
  680. // 'normal', 'advanced', 'side'.
  681. 'normal',
  682. // 'high', 'sorted', 'core', 'default', 'low'.
  683. 'high'
  684. );
  685. add_meta_box(
  686. 'apl-post-list-display',
  687. __( 'Display Settings', 'advanced-post-list' ),
  688. array( $this, 'post_list_meta_box_design' ),
  689. 'apl_post_list',
  690. 'normal',
  691. 'core'
  692. );
  693. }
  694. /**
  695. * Design Meta Boxes
  696. *
  697. * Hook 'add_meta_boxes', adds meta boxes used in designs.
  698. *
  699. * @since 0.4.0
  700. *
  701. * @see $this->_construct Used by.
  702. * @see 'add_meta_boxes' hook.
  703. * @see wp-admin/includes/template.php
  704. * @link https://codex.wordpress.org/Plugin_API/Action_Reference/add_meta_boxes
  705. * @link https://developer.wordpress.org/reference/functions/add_meta_box/
  706. */
  707. public function design_meta_boxes() {
  708. add_meta_box(
  709. 'apl-post-list-display',
  710. __( 'Display Settings', 'advanced-post-list' ),
  711. array( $this, 'design_meta_box_design' ),
  712. 'apl_design',
  713. 'normal',
  714. 'core'
  715. );
  716. }
  717. /**
  718. * Add Settings Page Meta Boxes
  719. *
  720. * @see $this->_construct Used by.
  721. * @see 'add_meta_boxes' hook.
  722. * @see add_meta_box();
  723. * @link https://codex.wordpress.org/Plugin_API/Action_Reference/add_meta_boxes
  724. * @link https://developer.wordpress.org/reference/functions/add_meta_box/
  725. */
  726. public function settings_meta_boxes() {
  727. add_meta_box(
  728. 'apl-info',
  729. __( 'About', 'advanced-post-list' ),
  730. array( $this, 'settings_meta_box_info' ),
  731. 'adv-post-list_page_apl_settings',
  732. // 'normal', 'advanced', 'side'.
  733. 'side',
  734. // 'high', 'sorted', 'core', 'default', 'low'.
  735. 'core'
  736. );
  737. // TODO - Add Documentation Link to Admin Page/Metabox documentation.
  738. // //$title = '<a id="info16" class="info_a_link" style="float:right;">Export/Import Info<span class="ui-icon ui-icon-info info-icon" style="float:right"></span></a>';
  739. add_meta_box(
  740. 'apl-general',
  741. // //$title . __( 'General Settings', 'advanced-post-list' ),
  742. __( 'General Settings', 'advanced-post-list' ),
  743. array( $this, 'settings_meta_box_general' ),
  744. 'adv-post-list_page_apl_settings',
  745. 'normal',
  746. 'high'
  747. );
  748. add_meta_box(
  749. 'apl-import-export',
  750. __( 'Import / Export', 'advanced-post-list' ),
  751. array( $this, 'settings_meta_box_import_export' ),
  752. 'adv-post-list_page_apl_settings',
  753. 'advanced',
  754. 'core'
  755. );
  756. }
  757. /**
  758. * Settings Info Meta Box
  759. *
  760. * @since 0.4.0
  761. *
  762. * @param WP_Post $post Current WP_Post object.
  763. * @param array $metabox With Meta Box id, title, callback, and args elements.
  764. */
  765. public function settings_meta_box_info( $post, $metabox ) {
  766. $args = array(
  767. 'post' => $post,
  768. 'metabox' => $metabox,
  769. );
  770. apl_get_template( 'admin/meta-box/settings-info.php', $args );
  771. }
  772. /**
  773. * Settings General Settings Meta Box
  774. *
  775. * @since 0.4.0
  776. *
  777. * @param WP_Post $post Current WP_Post object.
  778. * @param array $metabox With Meta Box id, title, callback, and args elements.
  779. */
  780. public function settings_meta_box_general( $post, $metabox ) {
  781. $args = array(
  782. 'post' => $post,
  783. 'metabox' => $metabox,
  784. );
  785. apl_get_template( 'admin/meta-box/settings-general.php', $args );
  786. }
  787. /**
  788. * Settings Import/Export Meta Box
  789. *
  790. * @since 0.4.0
  791. *
  792. * @param WP_Post $post Current WP_Post object.
  793. * @param array $metabox With Meta Box id, title, callback, and args elements.
  794. */
  795. public function settings_meta_box_import_export( $post, $metabox ) {
  796. $args = array(
  797. 'post' => $post,
  798. 'metabox' => $metabox,
  799. );
  800. apl_get_template( 'admin/meta-box/settings-import-export.php', $args );
  801. }
  802. /**
  803. * Post List Filter Meta box Template
  804. *
  805. * @since 0.4.0
  806. *
  807. * @param WP_Post $post Current WP_Post object.
  808. * @param array $metabox With Meta Box id, title, callback, and args elements.
  809. */
  810. public function post_list_meta_box_filter( $post, $metabox ) {
  811. $args = array(
  812. 'post' => $post,
  813. 'metabox' => $metabox,
  814. 'apl_post_tax' => apl_get_post_tax(),
  815. 'apl_tax_terms' => apl_get_tax_terms(),
  816. 'apl_display_post_types' => apl_get_display_post_types(),
  817. );
  818. apl_get_template( 'admin/meta-box/post-list-filter.php', $args );
  819. }
  820. /**
  821. * Post List Design Meta box Template
  822. *
  823. * Hook '$this->post_list_meta_boxes()', renders the Design Meta Box Template.
  824. *
  825. * @since 0.4.0
  826. *
  827. * @param WP_Post $post Current WP_Post object.
  828. * @param array $metabox With Meta Box id, title, callback, and args elements.
  829. */
  830. public function post_list_meta_box_design( $post, $metabox ) {
  831. $args = array(
  832. 'post' => $post,
  833. 'metabox' => $metabox,
  834. );
  835. apl_get_template( 'admin/meta-box/post-list-design.php', $args );
  836. }
  837. /**
  838. * Post List Design Meta box Template
  839. *
  840. * Renders the Design Meta Box Template.
  841. *
  842. * @see self::design_meta_boxes()
  843. * @since 0.4.0
  844. *
  845. * @param WP_Post $post Current WP_Post object.
  846. * @param array $metabox With Meta Box id, title, callback, and args elements.
  847. */
  848. public function design_meta_box_design( $post, $metabox ) {
  849. $args = array(
  850. 'post' => $post,
  851. 'metabox' => $metabox,
  852. );
  853. apl_get_template( 'admin/meta-box/design-design.php', $args );
  854. }
  855. /**
  856. * Draft Post List
  857. *
  858. * Hook for draft Post Transitions with Post Lists.
  859. *
  860. * @since 0.4.0
  861. *
  862. * @param int $post_id
  863. * @param WP_Post $post
  864. */
  865. public function draft_post_list( $post_id, $post ) {
  866. if ( isset( $_REQUEST['action'] ) ) {
  867. if ( 'untrash' === $_REQUEST['action'] ) {
  868. return;
  869. }
  870. }
  871. if ( empty( $post->post_name ) ) {
  872. if ( empty( $post->post_title ) ) {
  873. $post->post_title = 'APL-' . $post->ID;
  874. }
  875. remove_action( 'draft_apl_post_list', array( $this, 'draft_post_list' ) );
  876. $post->post_name = sanitize_title_with_dashes( $post->post_title );
  877. $post_arr = array(
  878. 'ID' => $post->ID,
  879. 'post_title' => $post->post_title,
  880. 'post_name' => $post->post_name,
  881. //'post_status' => $post->post_status,
  882. );
  883. wp_update_post( $post_arr );
  884. add_action( 'draft_apl_post_list', array( $this, 'draft_post_list' ), 10, 2 );
  885. }
  886. $this->post_list_process( $post_id, $post );
  887. }
  888. /**
  889. * Save Post List
  890. *
  891. * Hook for saving object during post transitions.
  892. *
  893. * @since 0.4.0
  894. *
  895. * @see self::current_screen_hooks() Used by.
  896. * @see private_apl_post_list hook.
  897. * @see publish_apl_post_list hook.
  898. * @see pending_apl_post_list hook.
  899. * @see future_apl_post_list hook.
  900. * @see {status}_{post_type} Hook Transitions.
  901. * @link https://codex.wordpress.org/Post_Status_Transitions
  902. *
  903. * @param int $post_id Old post ID.
  904. * @param WP_Post $post Current Post object.
  905. */
  906. public function save_post_list( $post_id, $post ) {
  907. // CHECK AJAX REFERENCE.
  908. // ACTION = editpost
  909. // Doesn't work if there is no action ( Add New )
  910. // //check_admin_referer( 'update-post_' . $post_id );
  911. // //add_action( 'private_apl_post_list', array( $this, 'save_post_list' ), 10, 2 );
  912. // //add_action( 'publish_apl_post_list', array( $this, 'save_post_list' ), 10, 2 );
  913. // //add_action( 'pending_apl_post_list', array( $this, 'save_post_list' ), 10, 2 );
  914. // //add_action( 'future_apl_post_list', array( $this, 'save_post_list' ), 10, 2 );
  915. $this->post_list_process( $post_id, $post );
  916. }
  917. /**
  918. * Draft Design
  919. *
  920. * Hook for draft Post Transitions with Designs.
  921. *
  922. * @since 0.4.0
  923. *
  924. * @param int $post_id Post ID.
  925. * @param WP_Post $post (New) Post Data content.
  926. */
  927. public function draft_design( $post_id, $post ) {
  928. if ( isset( $_REQUEST['action'] ) ) {
  929. if ( 'untrash' === $_REQUEST['action'] ) {
  930. return;
  931. }
  932. }
  933. if ( empty( $post->post_name ) ) {
  934. if ( empty( $post->post_title ) ) {
  935. $post->post_title = 'APL-' . $post->ID;
  936. }
  937. remove_action( 'draft_apl_design', array( $this, 'draft_design' ) );
  938. $post->post_name = sanitize_title_with_dashes( $post->post_title );
  939. $postarr = array(
  940. 'ID' => $post->ID,
  941. 'post_title' => $post->post_title,
  942. 'post_name' => $post->post_name,
  943. );
  944. wp_update_post( $postarr );
  945. add_action( 'draft_apl_design', array( $this, 'draft_design' ), 10, 2 );
  946. }
  947. $this->design_process( $post_id, $post );
  948. }
  949. /**
  950. * Save Design
  951. *
  952. * Hook for saving object during post transitions.
  953. *
  954. * @since 0.4.0
  955. *
  956. * @see self::current_screen_hooks() Used by.
  957. * @see private_apl_design hook.
  958. * @see publish_apl_design hook.
  959. * @see pending_apl_design hook.
  960. * @see future_apl_design hook.
  961. * @see {status}_{post_type} Hook Transitions.
  962. * @link https://codex.wordpress.org/Post_Status_Transitions
  963. *
  964. * @param int $post_id Old post ID.
  965. * @param WP_Post $post Current Post object.
  966. */
  967. public function save_design( $post_id, $post ) {
  968. $this->design_process( $post_id, $post );
  969. }
  970. /**
  971. * WP_Trash_Post APL Post List
  972. *
  973. * Host for trash post transitions with Post Lists.
  974. *
  975. * @since 0.4.0
  976. *
  977. * @link https://developer.wordpress.org/reference/functions/wp_trash_post/
  978. *
  979. * @param int $post_id Post ID. Default is ID of the global $post if EMPTY_TRASH_DAYS equals true.
  980. * @return boolean
  981. */
  982. public function action_wp_trash_post_apl_post_list( $post_id ) {
  983. $args = array(
  984. 'post__in' => array( $post_id ),
  985. 'post_type' => 'apl_post_list',
  986. //'post_status' => 'trash',
  987. );
  988. $post_lists = new WP_Query( $args );
  989. if ( 1 > $post_lists->post_count ) {
  990. return false;
  991. }
  992. $post_list = $post_lists->post;
  993. if ( 'apl_post_list' !== $post_list->post_type ) {
  994. return false;
  995. }
  996. $apl_post_list = new APL_Post_List( $post_list->post_name );
  997. $apl_design = new APL_Design( $apl_post_list->pl_apl_design );
  998. $new_post_list_slug = $post_list->post_name . '__trashed';
  999. $new_design_slug = '';
  1000. if ( ! empty( $post_list->post_name ) ) {
  1001. // //$slug_suffix = apply_filters( 'apl_design_slug_suffix', '-design' );
  1002. $design_slug = apply_filters( 'apl_design_trash_slug', $new_post_list_slug );
  1003. // //$new_design_slug = $design_slug . $slug_suffix;
  1004. $new_design_slug = $design_slug;
  1005. }
  1006. $apl_post_list->pl_apl_design = $new_design_slug;
  1007. $apl_design->slug = $new_design_slug;
  1008. $apl_design->save_design();
  1009. }
  1010. /**
  1011. * Un-Trash for Post List
  1012. *
  1013. * Hook for untrash Post Transition with Post Lists.
  1014. *
  1015. * @since 0.4.0
  1016. * @since 0.4.4 Added stricter APL_Design object referencing.
  1017. *
  1018. * @hook `untrash_post`
  1019. * @link https://codex.wordpress.org/Plugin_API/Action_Reference/untrash_post
  1020. *
  1021. * @param int $post_id ID of the post being untrashed.
  1022. * @return boolean
  1023. */
  1024. public function action_untrash_post_apl_post_list( $post_id ) {
  1025. $args = array(
  1026. 'post__in' => array( $post_id ),
  1027. 'post_type' => 'apl_post_list',
  1028. 'post_status' => 'trash',
  1029. );
  1030. $post_lists = new WP_Query( $args );
  1031. if ( 1 > $post_lists->post_count ) {
  1032. return false;
  1033. }
  1034. $post_list = $post_lists->post;
  1035. if ( 'apl_post_list' !== $post_list->post_type ) {
  1036. return false;
  1037. }
  1038. $apl_post_list = new APL_Post_List( $post_list->post_name );
  1039. $apl_design = new APL_Design( $apl_post_list->pl_apl_design_id );
  1040. $new_post_list_slug = str_replace( '__trashed', '', $post_list->post_name );
  1041. $new_design_slug = '';
  1042. if ( ! empty( $post_list->post_name ) ) {
  1043. // //$slug_suffix = apply_filters( 'apl_design_slug_suffix', '-design' );
  1044. $design_slug = apply_filters( 'apl_design_trash_slug', $new_post_list_slug );
  1045. // //$new_design_slug = $design_slug . $slug_suffix;
  1046. $new_design_slug = $design_slug;
  1047. }
  1048. $apl_post_list->pl_apl_design = $new_design_slug;
  1049. $apl_design->slug = $new_design_slug;
  1050. $apl_design->save_design();
  1051. }
  1052. /**
  1053. * WP_Delete_Post APL Post List
  1054. *
  1055. * Host for delete post transitions with Post Lists.
  1056. *
  1057. * @since 0.4.0
  1058. * @since 0.4.4 Added stricter APL_Design object referencing.
  1059. * @see https://codex.wordpress.org/Plugin_API/Action_Reference/before_delete_post
  1060. *
  1061. * @param int $post_id The post id that is being deleted.
  1062. * @return boolean
  1063. */
  1064. public function action_before_delete_post_apl_post_list( $post_id ) {
  1065. $args = array(
  1066. 'post__in' => array( $post_id ),
  1067. 'post_type' => 'apl_post_list',
  1068. 'post_status' => 'trash',
  1069. );
  1070. $post_lists = new WP_Query( $args );
  1071. if ( 1 > $post_lists->post_count ) {
  1072. return false;
  1073. }
  1074. $post_list = $post_lists->post;
  1075. if ( 'apl_post_list' !== $post_list->post_type ) {
  1076. return false;
  1077. }
  1078. $apl_post_list = new APL_Post_List( $post_list->post_name );
  1079. $apl_design = new APL_Design( $apl_post_list->pl_apl_design_id );
  1080. $apl_design->delete_design();
  1081. }
  1082. /**
  1083. * Save General Settings
  1084. *
  1085. * Uses a lazy REST API built into WP.
  1086. *
  1087. * @uses Hook 'admin_post_{SCREEN ID}' ex. 'admin_post_apl_save_general_settings'.
  1088. * @link https://developer.wordpress.org/reference/hooks/admin_post_action/
  1089. */
  1090. public function save_general_settings() {
  1091. if (
  1092. ! wp_verify_nonce( $_POST['apl_general_settings_nonce'], 'apl_settings_general_save' ) &&
  1093. ! current_user_can( 'administrator' )
  1094. ) {
  1095. wp_die();
  1096. }
  1097. $options = apl_options_load();
  1098. $tmp_ignore_pt = array();
  1099. $post_types = get_post_types( '', 'names' );
  1100. foreach ( $post_types as $post_type ) {
  1101. if ( isset( $_POST[ 'apl_ignore_pt_' . $post_type ] ) ) {
  1102. $input = filter_input( INPUT_POST, 'apl_ignore_pt_' . $post_type, FILTER_SANITIZE_STRING );
  1103. $tmp_ignore_pt[ $post_type ] = sanitize_key( $input );
  1104. }
  1105. }
  1106. $options['ignore_post_types'] = $tmp_ignore_pt;
  1107. if ( isset( $_POST['apl_delete_on_deactivate'] ) ) {
  1108. $input = filter_input( INPUT_POST, 'apl_delete_on_deactivate', FILTER_SANITIZE_STRING );
  1109. if ( 'yes' === $input ) {
  1110. $options['delete_core_db'] = true;
  1111. } elseif ( 'no' === $input ) {
  1112. $options['delete_core_db'] = false;
  1113. } else {
  1114. $options['delete_core_db'] = false;
  1115. }
  1116. }
  1117. if ( isset( $_POST['apl_default_empty_enable'] ) ) {
  1118. $input = filter_input( INPUT_POST, 'apl_delete_on_deactivate', FILTER_SANITIZE_STRING );
  1119. if ( 'yes' === $input ) {
  1120. $options['default_empty_enable'] = true;
  1121. } elseif ( 'no' === $input ) {
  1122. $options['default_empty_enable'] = false;
  1123. } else {
  1124. $options['default_empty_enable'] = true;
  1125. }
  1126. }
  1127. $options['default_empty_output'] = '';
  1128. if ( isset( $_POST['apl_default_empty_message'] ) ) {
  1129. // Sanitize with admins?
  1130. // TODO Possibly change to a WP_Post Object. Db update would be required.
  1131. $tmp_empty_messaage = filter_input( INPUT_POST, 'apl_default_empty_message', FILTER_UNSAFE_RAW );
  1132. $options['default_empty_output'] = $tmp_empty_messaage;
  1133. }
  1134. apl_options_save( $options );
  1135. wp_redirect( 'admin.php?page=apl_settings' );
  1136. //wp_die();
  1137. exit();
  1138. }
  1139. /**
  1140. * Settings Page AJAX Hooks
  1141. *
  1142. * Add AJAX hooks for Settings Page.
  1143. *
  1144. * @uses 'wp_ajax_{name}'
  1145. */
  1146. public function add_settings_ajax_hooks() {
  1147. add_action( 'wp_ajax_apl_settings_export', array( $this, 'ajax_settings_export' ) );
  1148. add_action( 'wp_ajax_apl_export', 'apl_export' );
  1149. add_action( 'wp_ajax_apl_settings_import', array( $this, 'ajax_settings_import' ) );
  1150. add_action( 'wp_ajax_apl_import', 'apl_import' );
  1151. add_action( 'wp_ajax_apl_settings_restore_defaults', array( $this, 'ajax__restore_defaults' ) );
  1152. }
  1153. /**
  1154. * MCE External Plugins
  1155. *
  1156. * @since 0.4.2
  1157. *
  1158. * @see 'mce_external_plugins' filter hook
  1159. * @link https://codex.wordpress.org/Plugin_API/Filter_Reference/mce_external_plugins
  1160. *
  1161. * @param array $plugin_array Other plugin's mce buttons.
  1162. * @return mixed
  1163. */
  1164. public function mce_external_plugins( $plugin_array ) {
  1165. $plugin_array['advanced_post_list'] = APL_URL . 'admin/js/wp-editor-mce.js';
  1166. return $plugin_array;
  1167. }
  1168. /**
  1169. * MCE Buttons
  1170. *
  1171. * @since 0.4.2
  1172. *
  1173. * @uses 'mce_buttons' filter hook
  1174. * @link https://codex.wordpress.org/Plugin_API/Filter_Reference/mce_buttons,_mce_buttons_2,_mce_buttons_3,_mce_buttons_4
  1175. *
  1176. * @param array $buttons Buttons for MCE Editor.
  1177. * @return mixed
  1178. */
  1179. public function mce_buttons( $buttons ) {
  1180. array_push( $buttons, 'apl_post_list' );
  1181. array_push( $buttons, 'dropcap', 'showrecent' );
  1182. return $buttons;
  1183. }
  1184. /**
  1185. * TinyMCE Extra Vars
  1186. *
  1187. * @since 0.4.0
  1188. */
  1189. public function tinymce_extra_vars() {
  1190. $args = array(
  1191. 'post_type' => 'apl_post_list',
  1192. 'post_status' => array(
  1193. 'draft',
  1194. 'pending',
  1195. 'publish',
  1196. 'future',
  1197. 'private',
  1198. 'trash',
  1199. ),
  1200. );
  1201. $pl_query = new WP_Query( $args );
  1202. $post_lists = array();
  1203. foreach ( $pl_query->posts as $apl_post ) {
  1204. $post_lists[ $apl_post->post_name ] = $apl_post->post_title;
  1205. }
  1206. $trans = array(
  1207. 'button_title' => __( 'APL Post List', 'advanced-post-list' ),
  1208. 'button_tooltip' => __( 'Insert APL Shortcode', 'advanced-post-list' ),
  1209. 'window_title' => __( 'APL Shortcode', 'advanced-post-list' ),
  1210. 'window_body_1_label' => __( 'Post List', 'advanced-post-list' ),
  1211. 'window_body_1_tooltip' => __( 'Select the Post List you want.', 'advanced-post-list' ),
  1212. );
  1213. $apl_tinymce_json = wp_json_encode(
  1214. array(
  1215. 'post_lists' => $post_lists,
  1216. 'trans' => $trans,
  1217. )
  1218. );
  1219. ?>
  1220. <script type="text/javascript">
  1221. var apl_tinyMCE = <?php echo $apl_tinymce_json; ?>;
  1222. </script>
  1223. <?php
  1224. }
  1225. /**
  1226. * AJAX Settings Page Export
  1227. *
  1228. * Handles the AJAX call for exporting data.
  1229. *
  1230. * @since 0.3
  1231. * @since 0.4.4 Added stricter APL_Design object referencing.
  1232. */
  1233. public function ajax_settings_export() {
  1234. check_ajax_referer( 'apl_settings_export' );
  1235. $rtn_data = array(
  1236. 'action' => 'apl_export',
  1237. '_ajax_nonce' => wp_create_nonce( 'apl_export' ),
  1238. );
  1239. $tmp_filename = 'file_export_name';
  1240. if ( isset( $_POST['filename'] ) ) {
  1241. $tmp_filename = filter_input( INPUT_POST, 'filename', FILTER_SANITIZE_STRING );
  1242. }
  1243. $rtn_data['filename'] = $tmp_filename;
  1244. $export_data = array(
  1245. 'version' => APL_VERSION,
  1246. 'apl_post_list_arr' => array(),
  1247. 'apl_design_arr' => array(),
  1248. );
  1249. $args = array(
  1250. 'post_type' => 'apl_post_list',
  1251. 'post_status' => 'publish',
  1252. 'posts_per_page' => -1,
  1253. );
  1254. $apl_post_lists = new WP_Query( $args );
  1255. foreach ( $apl_post_lists->posts as $post_obj ) {
  1256. $apl_post_list = new APL_Post_List( $post_obj->post_name );
  1257. $apl_design = new APL_Design( $apl_post_list->pl_apl_design_id );
  1258. $export_data['apl_post_list_arr'][] = $apl_post_list->slug;
  1259. $export_data['apl_design_arr'][] = $apl_design->slug;
  1260. }
  1261. update_option( 'apl_export_data', $export_data );
  1262. echo json_encode( $rtn_data );
  1263. wp_die();
  1264. }
  1265. /**
  1266. * AJAX Settings Import
  1267. *
  1268. * @since 0.4.0
  1269. * @since 0.4.4 Handle 0.3 and 0.4 database types separately, and stricter handling APL_Design with APL_Post_List.
  1270. *
  1271. * @uses add_settings_ajax_hooks().
  1272. * @uses wp_ajax_apl_settings_import.
  1273. */
  1274. public function ajax_settings_import() {
  1275. check_ajax_referer( 'apl_settings_import' );
  1276. $raw_content = array();
  1277. $i = 0;
  1278. while ( isset( $_FILES[ 'file_' . $i ] ) ) {
  1279. /**
  1280. * @type array $file_{$i} {
  1281. * @type int $error
  1282. * @type string $name
  1283. * @type int $size
  1284. * @type string $tmp_name
  1285. * @type string $type
  1286. * }
  1287. */
  1288. if ( isset( $_FILES[ 'file_' . $i ]['tmp_name'] ) && ! empty( $_FILES[ 'file_' . $i ]['tmp_name'] ) ) {
  1289. $file_error = ( isset( $_FILES[ 'file_' . $i ]['error'] ) ) ? intval( filter_var( $_FILES[ 'file_' . $i ]['error'], FILTER_SANITIZE_NUMBER_INT ) ) : 1;
  1290. $file_type = ( isset( $_FILES[ 'file_' . $i ]['type'] ) ) ? filter_var( $_FILES[ 'file_' . $i ]['type'], FILTER_SANITIZE_STRING ) : '';
  1291. $file_tmp = ( isset( $_FILES[ 'file_' . $i ]['type'] ) ) ? filter_var( $_FILES[ 'file_' . $i ]['tmp_name'], FILTER_SANITIZE_STRING ) : '';
  1292. // 2 = validate_file() - windows drive paths are needed for development purposes.
  1293. if ( ! $file_error && 'application/json' === $file_type && ! in_array( validate_file( $file_tmp ), array( 1, 3 ) ) ) {
  1294. $file_content = file_get_contents( $_FILES[ 'file_' . $i ]['tmp_name'] );
  1295. $raw_content[] = json_decode( $file_content );
  1296. }
  1297. }
  1298. $i++;
  1299. }
  1300. $imported_content = array();
  1301. foreach ( $raw_content as $v1_content ) {
  1302. $update_items = array();
  1303. if (
  1304. isset( $v1_content->version ) &&
  1305. preg_match( '/([0-9]+)\.([0-9]+)(?:\.([0-9]+))?(?:\.([0-9]|dev|a[1-9]|b[1-9]+))?/', $v1_content->version ) )
  1306. {
  1307. $version = $v1_content->version;
  1308. } else {
  1309. return new WP_Error( 'apl_admin', __( 'Version number is missing or invalid in imported file.', 'advanced-post-list' ) );
  1310. }
  1311. // 0.3 Database.
  1312. if ( version_compare( '0.3.0', $version, '<' ) && version_compare( '0.4.0', $version, '>' ) ) {
  1313. if ( isset( $v1_content->presetDbObj ) && $v1_content->presetDbObj instanceof APL_Preset_Db ) {
  1314. $update_items['preset_db'] = $v1_content->presetDbObj;
  1315. }
  1316. }
  1317. // 0.4+ Database.
  1318. elseif( version_compare( '0.4.0', $version, '<' ) ) {
  1319. if ( isset( $v1_content->apl_post_list_arr ) && $v1_content->apl_post_list_arr instanceof APL_Post_List ) {
  1320. $update_items['apl_post_list_arr'] = $v1_content->apl_post_list_arr;
  1321. }
  1322. if ( isset( $v1_content->apl_design_arr ) && $v1_content->apl_design_arr instanceof APL_Design ) {
  1323. $update_items['apl_design_arr'] = $v1_content->apl_design_arr;
  1324. }
  1325. }
  1326. $updater = new APL_Updater( $version, $update_items, 'OBJECT' );
  1327. $imported_content[] = array(
  1328. 'apl_post_list_arr' => $updater->apl_post_list_arr,
  1329. 'apl_design_arr' => $updater->apl_design_arr,
  1330. );
  1331. }
  1332. $overwrite_apl_post_list = array();
  1333. $overwrite_apl_design = array();
  1334. $data_overwrite_post_list = array();
  1335. $data_overwrite_design = array();
  1336. foreach ( $imported_content as $v1_content ) {
  1337. // POST LISTS.
  1338. foreach ( $v1_content['apl_post_list_arr'] as $v2_post_list ) {
  1339. $db_post_list = new APL_Post_List( $v2_post_list->slug );
  1340. // Check if Post List (ID) already exists.
  1341. if ( 0 !== $db_post_list->id ) {
  1342. $overwrite_apl_post_list[] = $v2_post_list;
  1343. $data_overwrite_post_list[] = $v2_post_list->slug;
  1344. // DESIGNS.
  1345. foreach ( $v1_content['apl_design_arr'] as $k3_design => $v3_design ) {
  1346. if ( $v3_design->slug === $v2_post_list->pl_apl_design ) {
  1347. $overwrite_apl_design[] = $v3_design;
  1348. $data_overwrite_design[] = $v3_design->slug;
  1349. unset( $v1_content['apl_design_arr'][ $k3_design ] );
  1350. break;
  1351. }
  1352. }
  1353. } else {
  1354. // DESIGNS.
  1355. foreach ( $v1_content['apl_design_arr'] as $k3_design => $v3_design ) {
  1356. if ( $v3_design->slug === $v2_post_list->pl_apl_design ) {
  1357. // Uses slug instead of ID.
  1358. $db_design = new APL_Design( $v3_design->slug );
  1359. if ( 0 !== $db_design->id ) {
  1360. // Add Variable to Database.
  1361. //$v2_post_list->pl_apl_design_id = $v3_design->id;
  1362. //$v2_post_list->pl_apl_design_slug = $v3_design->slug;
  1363. //$this->import_process_post_list( $v2_post_list );
  1364. $overwrite_apl_post_list[] = $v2_post_list;
  1365. $data_overwrite_post_list[] = $v2_post_list->slug;
  1366. $overwrite_apl_design[] = $v3_design;
  1367. $data_overwrite_design[] = $v3_design->slug;
  1368. } else {
  1369. // Add Variable to Database.
  1370. //$db_design = $this->import_process_design( $v3_design );
  1371. $db_design = $v3_design;
  1372. $this->import_process_post_list_design( $v2_post_list, $db_design );
  1373. }
  1374. unset( $v1_content['apl_design_arr'][ $k3_design ] );
  1375. break;
  1376. }
  1377. }
  1378. // Add Variable to Database.
  1379. //$this->import_process_post_list( $v2_post_list, $db_design );
  1380. }
  1381. }
  1382. // DESIGNS.
  1383. // Catch any remaining designs that may be left.
  1384. foreach ( $v1_content['apl_design_arr'] as $v2_design ) {
  1385. // Uses slug instead of ID.
  1386. $db_design = new APL_Design( $v2_design->slug );
  1387. if ( 0 !== $db_design->id ) {
  1388. $overwrite_apl_design[] = $v2_design;
  1389. $data_overwrite_design[] = $v2_design->slug;
  1390. } else {
  1391. // Add Variable to Database.
  1392. $this->import_process_design( $v2_design );
  1393. }
  1394. }
  1395. }
  1396. update_option( 'apl_import_overwrite_post_list', $overwrite_apl_post_list );
  1397. update_option( 'apl_import_overwrite_design', $overwrite_apl_design );
  1398. $rtn_data = array(
  1399. 'action' => 'apl_import',
  1400. '_ajax_nonce' => wp_create_nonce( 'apl_import' ),
  1401. 'overwrite_post_list' => $data_overwrite_post_list,
  1402. 'overwrite_design' => $data_overwrite_design,
  1403. );
  1404. echo json_encode( $rtn_data );
  1405. die();
  1406. }
  1407. /**
  1408. * AJAX - Restore Defaults
  1409. *
  1410. * @since 0.5
  1411. *
  1412. * @return void
  1413. */
  1414. public function ajax__restore_defaults() {
  1415. check_ajax_referer( 'apl_settings_restore_defaults' );
  1416. $this->restore_default_presets();
  1417. wp_send_json_success( 'Success' );
  1418. }
  1419. /**
  1420. * Restore Default Presets
  1421. *
  1422. * @since 0.5
  1423. */
  1424. public function restore_default_presets() {
  1425. include_once APL_DIR . 'admin/includes/default-presets.php';
  1426. $apl_post_list_default = apl_restore_post_list_default();
  1427. $apl_design_excerpt_divided = apl_restore_design_excerpt_divided();
  1428. $apl_design_page_content_divided = apl_restore_design_page_content_divided();
  1429. $apl_design_footer_list = apl_restore_design_footer_list();
  1430. $apl_post_list_default->title = 'Excerpt Divided';
  1431. $apl_post_list_default->slug = 'excerpt-divided';
  1432. $apl_post_list_default->pl_apl_design = 'excerpt-divided';
  1433. $this->import_process_post_list_design( $apl_post_list_default, $apl_design_excerpt_divided );
  1434. $apl_post_list_default->title = 'Page Content Divided';
  1435. $apl_post_list_default->slug = 'page-content-divided';
  1436. $apl_post_list_default->pl_apl_design = 'page-content-divided';
  1437. $this->import_process_post_list_design( $apl_post_list_default, $apl_design_page_content_divided );
  1438. $apl_post_list_default->title = 'Footer List';
  1439. $apl_post_list_default->slug = 'footer-list';
  1440. $apl_post_list_default->pl_apl_design = 'footer-list';
  1441. $this->import_process_post_list_design( $apl_post_list_default, $apl_design_footer_list );
  1442. }
  1443. /**
  1444. * Process Import for Post Lists
  1445. *
  1446. * @ignore
  1447. * @since 0.4.0
  1448. * @since 0.4.4 Added APL…

Large files files are truncated, but you can click here to view the full file