PageRenderTime 66ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/includes/class-custom-bulkquick-edit.php

https://github.com/wp-plugins/custom-bulkquick-edit
PHP | 1351 lines | 954 code | 314 blank | 83 comment | 171 complexity | 9c1b4631d339d1545552165ec98220ae MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /**
  3. * Copyright 2014 Michael Cannon (email: mc@aihr.us)
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License, version 2, as
  6. * published by the Free Software Foundation.
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. * You should have received a copy of the GNU General Public License
  12. * along with this program; if not, write to the Free Software
  13. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  14. */
  15. require_once AIHR_DIR_INC . 'class-aihrus-common.php';
  16. require_once CBQE_DIR_INC . 'class-custom-bulkquick-edit-settings.php';
  17. if ( class_exists( 'Custom_Bulkquick_Edit' ) )
  18. return;
  19. class Custom_Bulkquick_Edit extends Aihrus_Common {
  20. const BASE = CBQE_BASE;
  21. const ID = 'custom-bulkquick-edit';
  22. const SLUG = 'cbqe_';
  23. const VERSION = CBQE_VERSION;
  24. private static $fields_enabled = array();
  25. private static $no_instance = true;
  26. private static $post_fields_ignore = array(
  27. 'ID',
  28. 'comment_count',
  29. 'comment_status',
  30. 'guid',
  31. 'menu_order',
  32. 'ping_status',
  33. 'pinged',
  34. 'post_author',
  35. 'post_category',
  36. 'post_content',
  37. 'post_content_filtered',
  38. 'post_date',
  39. 'post_date_gmt',
  40. 'post_excerpt',
  41. 'post_mime_type',
  42. 'post_modified',
  43. 'post_modified_gmt',
  44. 'post_name',
  45. 'post_parent',
  46. 'post_password',
  47. 'post_status',
  48. 'post_title',
  49. 'post_type',
  50. 'to_ping',
  51. );
  52. private static $post_types_ignore = array(
  53. 'attachment',
  54. );
  55. public static $bulk_edit_save = false;
  56. public static $class = __CLASS__;
  57. public static $notice_key;
  58. public static $plugin_assets;
  59. public static $post_types = array();
  60. public static $post_types_keys = array();
  61. public static $scripts_bulk = array();
  62. public static $scripts_called = false;
  63. public static $scripts_extra = array();
  64. public static $scripts_quick = array();
  65. public static $settings_link = '';
  66. public function __construct() {
  67. parent::__construct();
  68. self::$plugin_assets = plugins_url( '/assets/', dirname( __FILE__ ) );
  69. self::$plugin_assets = self::strip_protocol( self::$plugin_assets );
  70. add_action( 'admin_init', array( __CLASS__, 'admin_init' ) );
  71. add_action( 'init', array( __CLASS__, 'init' ) );
  72. }
  73. public static function admin_init() {
  74. self::$settings_link = '<a href="' . get_admin_url() . 'options-general.php?page=' . Custom_Bulkquick_Edit_Settings::ID . '">' . esc_html__( 'Settings', 'custom-bulkquick-edit' ) . '</a>';
  75. self::update();
  76. add_action( 'admin_footer', array( __CLASS__, 'admin_footer' ) );
  77. add_action( 'bulk_edit_custom_box', array( __CLASS__, 'bulk_edit_custom_box' ), 10, 2 );
  78. add_action( 'quick_edit_custom_box', array( __CLASS__, 'quick_edit_custom_box' ), 10, 2 );
  79. add_action( 'save_post', array( __CLASS__, 'save_post' ), 25 );
  80. add_action( 'wp_ajax_save_post_bulk_edit', array( __CLASS__, 'save_post_bulk_edit' ) );
  81. add_filter( 'plugin_action_links', array( __CLASS__, 'plugin_action_links' ), 10, 2 );
  82. add_filter( 'plugin_row_meta', array( __CLASS__, 'plugin_row_meta' ), 10, 2 );
  83. add_filter( 'pre_update_option_active_plugins', array( __CLASS__, 'pre_update_option_active_plugins' ), 10, 2 );
  84. if ( self::do_load() ) {
  85. self::styles();
  86. }
  87. }
  88. public static function init() {
  89. load_plugin_textdomain( self::ID, false, 'custom-bulkquick-edit/languages' );
  90. }
  91. public static function plugin_action_links( $links, $file ) {
  92. if ( self::BASE == $file ) {
  93. array_unshift( $links, self::$settings_link );
  94. }
  95. return $links;
  96. }
  97. public static function uninstall() {
  98. if ( ! current_user_can( 'activate_plugins' ) ) {
  99. return;
  100. }
  101. global $wpdb;
  102. require_once CBQE_DIR_INC . 'class-custom-bulkquick-edit-settings.php';
  103. $delete_data = cbqe_get_option( 'delete_data', false );
  104. if ( $delete_data ) {
  105. delete_option( Custom_Bulkquick_Edit_Settings::ID );
  106. $wpdb->query( 'OPTIMIZE TABLE `' . $wpdb->options . '`' );
  107. }
  108. }
  109. /**
  110. *
  111. *
  112. * @SuppressWarnings(PHPMD.LongVariable)
  113. */
  114. public static function plugin_row_meta( $input, $file ) {
  115. if ( self::BASE != $file ) {
  116. return $input;
  117. }
  118. $disable_donate = cbqe_get_option( 'disable_donate' );
  119. if ( $disable_donate ) {
  120. return $input;
  121. }
  122. $links = array(
  123. self::$donate_link,
  124. );
  125. global $Custom_Bulkquick_Edit_Premium;
  126. if ( ! isset( $Custom_Bulkquick_Edit_Premium ) ) {
  127. $links[] = CBQE_PREMIUM_LINK;
  128. }
  129. $input = array_merge( $input, $links );
  130. return $input;
  131. }
  132. public static function notice_0_0_1() {
  133. $text = sprintf( __( 'If your Custom Bulk/Quick Edit display has gone to funky town, please <a href="%s">read the FAQ</a> about possible CSS fixes.', 'custom-bulkquick-edit' ), 'https://aihrus.zendesk.com/entries/23722573-Major-Changes-Since-2-10-0' );
  134. aihr_notice_updated( $text );
  135. }
  136. /**
  137. *
  138. *
  139. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  140. */
  141. public static function notice_donate( $disable_donate = null, $item_name = null ) {
  142. $disable_donate = cbqe_get_option( 'disable_donate' );
  143. parent::notice_donate( $disable_donate, CBQE_NAME );
  144. }
  145. public static function update() {
  146. $prior_version = cbqe_get_option( 'admin_notices' );
  147. if ( $prior_version ) {
  148. if ( $prior_version < '0.0.1' ) {
  149. add_action( 'admin_notices', array( __CLASS__, 'notice_0_0_1' ) );
  150. }
  151. if ( $prior_version < self::VERSION ) {
  152. cbqe_requirements_check( true );
  153. do_action( 'custom_bulkquick_edit_update' );
  154. }
  155. cbqe_set_option( 'admin_notices' );
  156. }
  157. // display donate on major/minor version release
  158. $donate_version = cbqe_get_option( 'donate_version', false );
  159. if ( ! $donate_version || ( $donate_version != self::VERSION && preg_match( '#\.0$#', self::VERSION ) ) ) {
  160. self::set_notice( 'notice_donate' );
  161. cbqe_set_option( 'donate_version', self::VERSION );
  162. }
  163. }
  164. /**
  165. *
  166. *
  167. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  168. */
  169. public static function manage_posts_custom_column_precapture( $column, $post_id ) {
  170. ob_start();
  171. }
  172. public static function manage_posts_custom_column_capture( $column, $post_id ) {
  173. $buffer = ob_get_contents();
  174. ob_end_clean();
  175. self::manage_posts_custom_column( $column, $post_id, $buffer );
  176. }
  177. public static function manage_posts_custom_column( $column, $post_id, $buffer = null ) {
  178. global $post;
  179. $field_type = self::is_field_enabled( $post->post_type, $column );
  180. if ( ! $field_type ) {
  181. echo $buffer;
  182. return;
  183. }
  184. if ( 1 == $field_type )
  185. $field_type = self::check_field_type( $field_type, $column );
  186. $details = self::get_field_config( $post->post_type, $column );
  187. $options = explode( "\n", $details );
  188. $result = '';
  189. switch ( $column ) {
  190. case 'post_excerpt':
  191. $result = $post->post_excerpt;
  192. break;
  193. case 'post_title':
  194. $result = $post->post_title;
  195. break;
  196. default:
  197. $current = get_post_meta( $post_id, $column, true );
  198. switch ( $field_type ) {
  199. case 'categories':
  200. $result = self::column_categories( $post_id, $column, $current, $options, $field_type );
  201. break;
  202. case 'show_only':
  203. case 'taxonomy':
  204. $result = self::column_taxonomies( $post_id, $column, $current, $options, $field_type );
  205. break;
  206. case 'input':
  207. case 'textarea':
  208. $result = $current;
  209. if ( is_numeric( $result ) && 0 == $result && 1 == strlen( $result ) ) {
  210. $result = '&Oslash;';
  211. }
  212. break;
  213. case 'checkbox':
  214. case 'radio':
  215. $result = self::column_checkbox_radio( $column, $current, $options, $field_type );
  216. break;
  217. case 'select':
  218. $result = self::column_select( $column, $current, $options, $field_type );
  219. break;
  220. default:
  221. $result = apply_filters( 'cbqe_manage_posts_custom_column_field_type', $current, $field_type, $column, $post_id );
  222. break;
  223. }
  224. }
  225. $result = apply_filters( 'cbqe_posts_custom_column', $result, $column, $post_id );
  226. if ( $result ) {
  227. echo $result;
  228. }
  229. }
  230. public static function manage_columns( $columns ) {
  231. global $post;
  232. if ( is_null( $post ) ) {
  233. return $columns;
  234. }
  235. $fields = self::get_enabled_fields( $post->post_type );
  236. foreach ( $fields as $key => $field_name ) {
  237. $title = Custom_Bulkquick_Edit_Settings::$settings[ $key ]['label'];
  238. $columns[ $field_name ] = $title;
  239. }
  240. $columns = apply_filters( 'cbqe_columns', $columns );
  241. return $columns;
  242. }
  243. public static function get_enabled_fields( $post_type ) {
  244. $fields = array();
  245. $settings = Custom_Bulkquick_Edit_Settings::$settings;
  246. foreach ( $settings as $key => $value ) {
  247. if ( $post_type != $value['section'] ) {
  248. continue;
  249. }
  250. if ( false !== strstr( $key, Custom_Bulkquick_Edit_Settings::CONFIG ) ) {
  251. continue;
  252. }
  253. $field_name = str_replace( $post_type . Custom_Bulkquick_Edit_Settings::ENABLE, '', $key );
  254. $field_type = self::is_field_enabled( $post_type, $field_name );
  255. if ( $field_type ) {
  256. $fields[ $key ] = $field_name;
  257. }
  258. }
  259. return $fields;
  260. }
  261. public static function get_scripts() {
  262. if ( self::$scripts_called ) {
  263. return;
  264. }
  265. echo '
  266. <script type="text/javascript">
  267. jQuery( document ).ready( function() {
  268. var wp_inline_edit = inlineEditPost.edit;
  269. inlineEditPost.edit = function( id ) {
  270. wp_inline_edit.apply( this, arguments );
  271. var post_id = 0;
  272. if ( typeof( id ) == "object" )
  273. post_id = parseInt( this.getId( id ) );
  274. if ( post_id > 0 ) {
  275. // define the edit row
  276. var edit_row = jQuery( "#edit-" + post_id );
  277. var post_row = jQuery( "#post-" + post_id );
  278. ';
  279. $scripts = implode( "\n", self::$scripts_quick );
  280. echo $scripts;
  281. echo '
  282. }
  283. };
  284. ';
  285. $scripts = implode( "\n", self::$scripts_extra );
  286. echo $scripts;
  287. echo '
  288. jQuery( "#bulk_edit" ).on( "click", function() {
  289. var bulk_row = jQuery( "#bulk-edit" );
  290. var post_ids = new Array();
  291. bulk_row.find( "#bulk-titles" ).children().each( function() {
  292. post_ids.push( jQuery( this ).attr( "id" ).replace( /^(ttle)/i, "" ) );
  293. });
  294. jQuery.ajax({
  295. url: ajaxurl,
  296. type: "POST",
  297. async: false,
  298. cache: false,
  299. data: {
  300. action: "save_post_bulk_edit",
  301. post_ids: post_ids,
  302. ';
  303. $scripts = implode( ",\n", self::$scripts_bulk );
  304. echo $scripts;
  305. echo '
  306. }
  307. });
  308. });
  309. });
  310. </script>
  311. ';
  312. self::$scripts_called = true;
  313. }
  314. /**
  315. *
  316. *
  317. * @SuppressWarnings(PHPMD.Superglobals)
  318. * @SuppressWarnings(PHPMD.ExitExpression)
  319. */
  320. public static function save_post_bulk_edit() {
  321. self::$bulk_edit_save = true;
  322. $post_ids = ! empty( $_POST[ 'post_ids' ] ) ? $_POST[ 'post_ids' ] : array();
  323. if ( ! empty( $post_ids ) && is_array( $post_ids ) ) {
  324. remove_action( 'save_post', array( __CLASS__, 'save_post' ), 25 );
  325. foreach ( $post_ids as $post_id ) {
  326. self::save_post_items( $post_id, 'bulk_edit' );
  327. }
  328. }
  329. die();
  330. }
  331. /**
  332. *
  333. *
  334. * @SuppressWarnings(PHPMD.Superglobals)
  335. */
  336. public static function save_post_items( $post_id, $mode = '' ) {
  337. if ( ! preg_match( '#^\d+$#', $post_id ) ) {
  338. return;
  339. }
  340. unset( $_POST['action'] );
  341. unset( $_POST['post_ids'] );
  342. if ( empty( $_POST ) ) {
  343. return;
  344. }
  345. $post = get_post( $post_id );
  346. $post_type = $post->post_type;
  347. if ( empty( $mode ) ) {
  348. // unset unchecked checkboxes from quick edit
  349. $fields = self::get_enabled_fields( $post_type );
  350. foreach ( $fields as $key => $field ) {
  351. $field_type = self::is_field_enabled( $post_type, $field );
  352. if ( 'checkbox' == $field_type ) {
  353. $field_name = self::SLUG . $field;
  354. if ( ! isset( $_POST[ $field_name ] ) ) {
  355. $_POST[ $field_name ] = Custom_Bulkquick_Edit_Settings::RESET;
  356. }
  357. }
  358. }
  359. }
  360. foreach ( $_POST as $field => $value ) {
  361. if ( in_array( $field, self::$post_fields_ignore ) ) {
  362. continue;
  363. } elseif ( '' == $value && 'bulk_edit' == $mode ) {
  364. continue;
  365. }
  366. if ( 'tax_input' != $field ) {
  367. self::save_post_item( $post_id, $post_type, $field, $value );
  368. } else {
  369. foreach ( $value as $key => $val ) {
  370. self::save_post_item( $post_id, $post_type, $key, $val );
  371. }
  372. }
  373. }
  374. do_action( 'cbqe_save_post', $post_id );
  375. }
  376. public static function save_post_item( $post_id, $post_type, $field, $value ) {
  377. $field_name = str_replace( self::SLUG, '', $field );
  378. $field_type = self::is_field_enabled( $post_type, $field_name );
  379. if ( empty( $field_type ) ) {
  380. return;
  381. }
  382. if ( false !== strstr( $field_name, Custom_Bulkquick_Edit_Settings::REMOVE ) ) {
  383. $terms = array_map( 'intval', $value );
  384. $taxonomy = str_replace( Custom_Bulkquick_Edit_Settings::REMOVE, '', $field_name );
  385. wp_remove_object_terms( $post_id, $terms, $taxonomy );
  386. return;
  387. }
  388. if ( false !== strstr( $field_name, Custom_Bulkquick_Edit_Settings::RESET ) ) {
  389. $taxonomy = str_replace( Custom_Bulkquick_Edit_Settings::RESET, '', $field_name );
  390. wp_delete_object_term_relationships( $post_id, $taxonomy );
  391. return;
  392. }
  393. if ( in_array( $field_type, array( 'categories', 'taxonomy' ) ) ) {
  394. $value = stripslashes_deep( $value );
  395. if ( 'taxonomy' == $field_type ) {
  396. // WordPress doesn't keep " enclosed CSV terms together, so don't worry about it here then by using `str_getcsv`
  397. $values = explode( ',', $value );
  398. wp_set_object_terms( $post_id, $values, $field_name );
  399. } else {
  400. $value = array_map( 'intval', $value );
  401. $value = array_unique( $value );
  402. if ( isset( $value[ 0 ] ) && 0 === $value[ 0 ] ) {
  403. unset( $value[ 0 ] );
  404. }
  405. wp_set_object_terms( $post_id, $value, $field_name );
  406. }
  407. return;
  408. }
  409. if ( ! is_array( $value ) ) {
  410. $delete = strstr( $value, Custom_Bulkquick_Edit_Settings::DELETE );
  411. } else {
  412. $delete = in_array( Custom_Bulkquick_Edit_Settings::DELETE, $value );
  413. }
  414. if ( false !== strstr( $field_name, Custom_Bulkquick_Edit_Settings::DELETE ) ) {
  415. $field_name = str_replace( Custom_Bulkquick_Edit_Settings::DELETE, '', $field_name );
  416. $delete = true;
  417. }
  418. $post_save_fields = apply_filters( 'cbqe_post_save_fields', self::$post_fields_ignore );
  419. if ( ! in_array( $field_name, $post_save_fields ) ) {
  420. if ( ! $delete ) {
  421. update_post_meta( $post_id, $field_name, $value );
  422. } else {
  423. delete_post_meta( $post_id, $field_name );
  424. }
  425. } else {
  426. if ( $delete ) {
  427. $value = '';
  428. }
  429. $value = apply_filters( 'cbqe_post_save_value', $value, $post_id, $field_name );
  430. if ( is_null( $value ) ) {
  431. return;
  432. }
  433. $data = array(
  434. 'ID' => $post_id,
  435. $field_name => $value,
  436. );
  437. wp_update_post( $data );
  438. }
  439. }
  440. /**
  441. *
  442. *
  443. * @SuppressWarnings(PHPMD.Superglobals)
  444. */
  445. public static function get_post_types() {
  446. if ( ! empty( self::$post_types ) ) {
  447. return self::$post_types;
  448. }
  449. if ( isset( $_GET['post_type'] ) ) {
  450. $post_type = esc_attr( $_GET['post_type'] );
  451. self::$post_types[ $post_type ] = $post_type;
  452. self::$post_types_keys[] = $post_type;
  453. return self::$post_types;
  454. } else {
  455. self::$post_types_ignore = apply_filters( 'cbqe_post_types_ignore', self::$post_types_ignore );
  456. $args = array(
  457. 'public' => true,
  458. '_builtin' => true,
  459. );
  460. $args = apply_filters( 'cbqe_get_post_types_args', $args );
  461. $post_types = get_post_types( $args, 'objects' );
  462. foreach ( $post_types as $post_type ) {
  463. if ( in_array( $post_type->name, self::$post_types_ignore ) ) {
  464. continue;
  465. }
  466. self::$post_types[ $post_type->name ] = $post_type->label;
  467. self::$post_types_keys[] = $post_type->name;
  468. }
  469. return self::$post_types;
  470. }
  471. }
  472. public static function get_field_config( $post_type = null, $field_name = null ) {
  473. $key = self::get_field_key( $post_type, $field_name );
  474. if ( empty( $key ) ) {
  475. return false;
  476. }
  477. $key .= Custom_Bulkquick_Edit_Settings::CONFIG;
  478. $details = cbqe_get_option( $key );
  479. return $details;
  480. }
  481. public static function get_field_key( $post_type = null, $field_name = null ) {
  482. if ( is_null( $post_type ) ) {
  483. global $post;
  484. if ( is_null( $post ) ) {
  485. return false;
  486. }
  487. $post_type = $post->post_type;
  488. }
  489. if ( false !== strstr( $field_name, self::SLUG ) ) {
  490. $field_name = preg_replace( '#^' . self::SLUG . '#', '', $field_name );
  491. }
  492. $key = $post_type . Custom_Bulkquick_Edit_Settings::ENABLE . $field_name;
  493. return $key;
  494. }
  495. public static function is_field_enabled( $post_type = null, $field_name = null ) {
  496. if ( is_null( $field_name ) ) {
  497. return false;
  498. }
  499. if ( is_null( $post_type ) ) {
  500. global $post;
  501. if ( is_null( $post ) ) {
  502. return false;
  503. }
  504. $post_type = $post->post_type;
  505. }
  506. $key = self::get_field_key( $post_type, $field_name );
  507. if ( isset( self::$fields_enabled[ $key ] ) ) {
  508. return self::$fields_enabled[ $key ];
  509. }
  510. $enable = cbqe_get_option( $key );
  511. if ( ! empty( $enable ) ) {
  512. self::$fields_enabled[ $key ] = $enable;
  513. return $enable;
  514. } else {
  515. self::$fields_enabled[ $key ] = false;
  516. return false;
  517. }
  518. }
  519. public static function bulk_edit_custom_box( $column_name, $post_type ) {
  520. self::quick_edit_custom_box( $column_name, $post_type, true );
  521. }
  522. /**
  523. *
  524. *
  525. * @SuppressWarnings(PHPMD.UnusedLocalVariable)
  526. */
  527. public static function quick_edit_custom_box( $column_name, $post_type, $bulk_mode = false ) {
  528. if ( ! in_array( $post_type, self::$post_types_keys ) ) {
  529. return;
  530. }
  531. $field_type = self::is_field_enabled( $post_type, $column_name );
  532. if ( empty( $field_type ) ) {
  533. return;
  534. }
  535. if ( 'show_only' == $field_type ) {
  536. return;
  537. }
  538. if ( self::$no_instance ) {
  539. self::$no_instance = false;
  540. wp_nonce_field( self::BASE, self::ID );
  541. }
  542. $key = self::get_field_key( $post_type, $column_name );
  543. $field_name = self::SLUG . $column_name;
  544. $open_fieldset = '<fieldset class="inline-edit-col-%1$s cbqe">';
  545. $close_fieldset = '</fieldset>';
  546. $open_div = '<div class="inline-edit-col">';
  547. $close_div = '</div>';
  548. if ( $bulk_mode ) {
  549. $return_now = false;
  550. $ignore_bulk_edit = apply_filters( 'cbqe_ignore_bulk_edit', array() );
  551. if ( in_array( $column_name, $ignore_bulk_edit ) ) {
  552. return;
  553. }
  554. $setting = $post_type . Custom_Bulkquick_Edit_Settings::ENABLE . $column_name;
  555. $enable = cbqe_get_option( $setting );
  556. if ( empty( $enable ) ) {
  557. return;
  558. }
  559. $result = '';
  560. $row = 1;
  561. $valid_delete = strstr( $setting, Custom_Bulkquick_Edit_Settings::DELETE );
  562. if ( $valid_delete ) {
  563. $orig_field = preg_replace( '#(^|' . Custom_Bulkquick_Edit_Settings::ENABLE . '|' . Custom_Bulkquick_Edit_Settings::DELETE . ')#', '', $column_name );
  564. $orig_column = self::SLUG . $orig_field;
  565. $result .= self::custom_box_reset( $orig_column, $orig_field, $setting, true );
  566. $return_now = true;
  567. }
  568. $valid_reset = strstr( $setting, Custom_Bulkquick_Edit_Settings::RESET );
  569. if ( $valid_reset ) {
  570. $orig_field = preg_replace( '#(^|' . Custom_Bulkquick_Edit_Settings::ENABLE . '|' . Custom_Bulkquick_Edit_Settings::RESET . ')#', '', $column_name );
  571. $orig_column = self::SLUG . $orig_field;
  572. $result .= self::custom_box_reset( $orig_column, $orig_field, $setting );
  573. $return_now = true;
  574. }
  575. $valid_remove = strstr( $setting, Custom_Bulkquick_Edit_Settings::REMOVE );
  576. if ( $valid_remove ) {
  577. $field = preg_replace( '#(^' . $post_type . '|' . Custom_Bulkquick_Edit_Settings::ENABLE . ')#', '', $setting );
  578. $result = self::custom_box_remove( $field, $setting );
  579. $row++;
  580. $return_now = true;
  581. }
  582. if ( ! empty( $result ) ) {
  583. echo sprintf( $open_fieldset, 'right' );
  584. echo $open_div;
  585. echo '<div class="inline-edit-group">';
  586. echo $result;
  587. echo $close_div;
  588. echo $close_div;
  589. echo $close_fieldset;
  590. }
  591. // return now otherwise taxonomy entries are duplicated
  592. if ( $return_now || in_array( $field_type, array( 'categories', 'taxonomy' ) ) ) {
  593. $bulk_edit_taxonomy = apply_filters( 'cbqe_bulk_edit_taxonomy', array() );
  594. if ( ! in_array( $column_name, $bulk_edit_taxonomy ) ) {
  595. return;
  596. }
  597. }
  598. } else {
  599. if ( false !== strstr( $key, Custom_Bulkquick_Edit_Settings::DELETE ) ) {
  600. return;
  601. }
  602. if ( false !== strstr( $key, Custom_Bulkquick_Edit_Settings::RESET ) ) {
  603. return;
  604. }
  605. if ( false !== strstr( $key, Custom_Bulkquick_Edit_Settings::REMOVE ) ) {
  606. return;
  607. }
  608. $ignore_quick_edit = array( 'post_title' );
  609. $ignore_quick_edit = apply_filters( 'cbqe_ignore_quick_edit', $ignore_quick_edit );
  610. if ( in_array( $column_name, $ignore_quick_edit ) ) {
  611. return;
  612. }
  613. }
  614. $field_type = self::check_field_type( $field_type, $column_name );
  615. $field_name_var = str_replace( '-', '_', $field_name );
  616. $title = Custom_Bulkquick_Edit_Settings::$settings[ $key ]['label'];
  617. echo sprintf( $open_fieldset, 'left' );
  618. echo $open_div;
  619. $class = '';
  620. if ( 'categories' == $field_type ) {
  621. $class = 'inline-edit-categories-label';
  622. } elseif ( 'taxonomy' != $field_type ) {
  623. echo '<label class="alignleft">';
  624. } else {
  625. echo '<label class="inline-edit-tags">';
  626. }
  627. echo '<span class="title ' . $class . '">' . $title . '</span>';
  628. $details = self::get_field_config( $post_type, $column_name );
  629. $options = explode( "\n", $details );
  630. switch ( $field_type ) {
  631. case 'checkbox':
  632. if ( ! $bulk_mode ) {
  633. $result = self::custom_box_checkbox( $column_name, $field_name, $field_name_var, $options );
  634. } else {
  635. $result = self::custom_box_select_multiple( $column_name, $field_name, $field_name_var, $options, $bulk_mode );
  636. }
  637. break;
  638. case 'radio':
  639. if ( ! $bulk_mode ) {
  640. $result = self::custom_box_radio( $column_name, $field_name, $field_name_var, $options );
  641. } else {
  642. $result = self::custom_box_select( $column_name, $field_name, $field_name_var, $options, $bulk_mode );
  643. }
  644. break;
  645. case 'input':
  646. $result = self::custom_box_input( $column_name, $field_name, $field_name_var );
  647. break;
  648. case 'select':
  649. $result = self::custom_box_select( $column_name, $field_name, $field_name_var, $options, $bulk_mode );
  650. break;
  651. case 'textarea':
  652. $result = self::custom_box_textarea( $column_name, $field_name, $field_name_var );
  653. break;
  654. case 'categories':
  655. $result = self::custom_box_categories( $field_name, $field_name_var, $bulk_mode );
  656. break;
  657. case 'taxonomy':
  658. $warning = esc_html__( 'Use commas to separate your values. Ex: "1,two,Three"', 'custom-bulkquick-edit' );
  659. echo '<span class="warning">' . $warning . '</span>';
  660. $result = self::custom_box_taxonomy( $column_name, $field_name, $field_name_var );
  661. break;
  662. default:
  663. $result = apply_filters( 'cbqe_quick_edit_custom_box_field', '', $field_type, $field_name, $options, $bulk_mode );
  664. self::$scripts_bulk = apply_filters( 'cbqe_quick_scripts_bulk', self::$scripts_bulk, $post_type, $column_name, $field_name, $field_type, $field_name_var );
  665. self::$scripts_quick = apply_filters( 'cbqe_quick_scripts_quick', self::$scripts_quick, $post_type, $column_name, $field_name, $field_type, $field_name_var );
  666. self::$scripts_extra = apply_filters( 'cbqe_quick_scripts_extra', self::$scripts_extra, $post_type, $column_name, $field_name, $field_type, $field_name_var );
  667. break;
  668. }
  669. echo $result;
  670. echo '</label>';
  671. echo $close_div;
  672. echo $close_fieldset;
  673. }
  674. public static function custom_box_checkbox( $column_name, $field_name, $field_name_var, $options ) {
  675. $result = '<div class="inline-edit-group cbqe">';
  676. $multiple = '';
  677. $do_pre_title = true;
  678. if ( 1 < count( $options ) ) {
  679. $multiple = '[]';
  680. } else {
  681. $do_pre_title = false;
  682. }
  683. foreach ( $options as $option ) {
  684. if ( $do_pre_title ) {
  685. $result .= '<label class="alignleft">';
  686. }
  687. $parts = explode( '|', $option );
  688. $value = array_shift( $parts );
  689. if ( empty( $parts ) ) {
  690. $name = $value;
  691. } else {
  692. $name = array_shift( $parts );
  693. }
  694. $result .= '<input type="checkbox" name="' . $field_name . $multiple . '" value="' . $value . '" />';
  695. $result .= ' ' . $name . '&nbsp;';
  696. if ( $do_pre_title ) {
  697. $result .= '</label>';
  698. }
  699. }
  700. $result .= '</div>';
  701. self::$scripts_quick[ $column_name . '1' ] = "var {$field_name_var} = jQuery( '.column-{$column_name} input:checkbox:checked', post_row ).map( function(){ return jQuery( this ).val(); } ).get();";
  702. self::$scripts_quick[ $column_name . '2' ] = "jQuery.each( {$field_name_var}, function( key, value ){ jQuery( ':input[name^={$field_name}]', edit_row ).filter('[value=\"' + value + '\"]').prop('checked', true); } );";
  703. return $result;
  704. }
  705. public static function custom_box_radio( $column_name, $field_name, $field_name_var, $options ) {
  706. $result = '<div class="inline-edit-group cbqe">';
  707. $unset_option = Custom_Bulkquick_Edit_Settings::RESET . '|' . esc_html__( '&mdash; Unset &mdash;', 'custom-bulkquick-edit' );
  708. array_unshift( $options, $unset_option );
  709. foreach ( $options as $option ) {
  710. $result .= '<label class="alignleft">';
  711. $parts = explode( '|', $option );
  712. $value = array_shift( $parts );
  713. if ( empty( $parts ) ) {
  714. $name = $value;
  715. } else {
  716. $name = array_shift( $parts );
  717. }
  718. $result .= '<input type="radio" name="' . $field_name . '" value="' . $value . '" />';
  719. $result .= ' ' . $name . '&nbsp;';
  720. $result .= '</label>';
  721. }
  722. $result .= '</div>';
  723. self::$scripts_quick[ $column_name . '1' ] = "var {$field_name_var} = jQuery( '.column-{$column_name} input:radio:checked', post_row ).val();";
  724. self::$scripts_quick[ $column_name . '2' ] = "jQuery( ':input[name={$field_name}]', edit_row ).filter('[value=' + {$field_name_var} + ']').prop('checked', true);";
  725. return $result;
  726. }
  727. public static function custom_box_select_multiple( $column_name, $field_name, $field_name_var, $options, $bulk_mode ) {
  728. $result = self::custom_box_select( $column_name, $field_name, $field_name_var, $options, $bulk_mode, true );
  729. return $result;
  730. }
  731. public static function custom_box_select( $column_name, $field_name, $field_name_var, $options, $bulk_mode = false, $multiple = false ) {
  732. $result = '<select name="' . $field_name;
  733. if ( $multiple ) {
  734. if ( ! $bulk_mode ) {
  735. $result .= '[]';
  736. }
  737. $result .= '" multiple="multiple';
  738. }
  739. $result .= '">';
  740. $unset_option = Custom_Bulkquick_Edit_Settings::RESET . '|' . esc_html__( '&mdash; Unset &mdash;', 'custom-bulkquick-edit' );
  741. array_unshift( $options, $unset_option );
  742. if ( $bulk_mode && ! $multiple ) {
  743. $no_change_option = '|' . esc_html__( '&mdash; No Change &mdash;', 'custom-bulkquick-edit' );
  744. array_unshift( $options, $no_change_option );
  745. }
  746. foreach ( $options as $option ) {
  747. $parts = explode( '|', $option );
  748. $value = array_shift( $parts );
  749. if ( empty( $parts ) ) {
  750. $name = $value;
  751. } else {
  752. $name = array_shift( $parts );
  753. }
  754. $result .= '<option value="' . $value . '">' . $name . '</option>';
  755. }
  756. $result .= '</select>';
  757. if ( ! $bulk_mode ) {
  758. self::$scripts_quick[ $column_name . '1' ] = "var {$field_name_var} = jQuery( '.column-{$column_name} option:selected', post_row ).map( function(){ return jQuery( this ).val(); } ).get();";
  759. self::$scripts_quick[ $column_name . '2' ] = "jQuery.each( {$field_name_var}, function( key, value ){ jQuery( ':input[name^={$field_name}] option[value=\"' + value + '\"]', edit_row ).prop('selected', true); } );";
  760. } else {
  761. self::$scripts_bulk[ $column_name ] = "'{$field_name}': bulk_row.find( 'select[name={$field_name}]' ).val()";
  762. }
  763. return $result;
  764. }
  765. public static function custom_box_reset( $column_name, $field_name, $key_reset, $delete = false ) {
  766. if ( empty( $delete ) ) {
  767. $field_reset = $field_name . Custom_Bulkquick_Edit_Settings::RESET;
  768. $column_reset = $column_name . Custom_Bulkquick_Edit_Settings::RESET;
  769. } else {
  770. $field_reset = $field_name . Custom_Bulkquick_Edit_Settings::DELETE;
  771. $column_reset = $column_name . Custom_Bulkquick_Edit_Settings::DELETE;
  772. }
  773. $title_reset = Custom_Bulkquick_Edit_Settings::$settings[ $key_reset ]['label'];
  774. $result = '<label>';
  775. $result .= '<input type="checkbox" name="' . $field_reset . '" />';
  776. $result .= ' ';
  777. $result .= '<span class="checkbox-title">' . $title_reset . '</span>';
  778. $result .= '</label>';
  779. self::$scripts_bulk[ $column_reset ] = "'{$field_reset}': bulk_row.find( 'input[name^={$field_reset}]:checkbox:checked' ).map( function(){ return jQuery( this ).val(); } ).get()";
  780. return $result;
  781. }
  782. public static function custom_box_taxonomy( $column_name, $field_name, $field_name_var ) {
  783. $taxonomy = str_replace( self::SLUG, '', $field_name );
  784. $tax_class = 'tax_input_' . $taxonomy;
  785. $result = '<textarea cols="22" rows="1" name="tax_input[' . $taxonomy . ']" class="' . $tax_class . '" autocomplete="off"></textarea>';
  786. self::$scripts_bulk[ $column_name ] = "'{$field_name}': bulk_row.find( '.{$tax_class}' ).val()";
  787. if ( false === strstr( $field_name, '-' ) ) {
  788. self::$scripts_quick[ $column_name . '1' ] = "var {$field_name_var} = jQuery( '.column-{$column_name}', post_row ).text();";
  789. self::$scripts_quick[ $column_name . '2' ] = "jQuery( '.{$tax_class}', edit_row ).val( {$field_name_var} );";
  790. }
  791. return $result;
  792. }
  793. public static function custom_box_categories( $field_name, $field_name_var, $bulk_mode = false ) {
  794. global $post;
  795. $post_id = isset( $post->ID ) && empty( $bulk_mode ) ? $post->ID : null;
  796. $post_id = null;
  797. $taxonomy = str_replace( self::SLUG, '', $field_name );
  798. ob_start();
  799. wp_terms_checklist( $post_id, array( 'taxonomy' => $taxonomy ) );
  800. $terms = ob_get_contents();
  801. ob_end_clean();
  802. $result = '';
  803. $input_name = 'tax_input';
  804. if ( 'category' != $taxonomy ) {
  805. $result .= '<input type="hidden" name="' . $input_name . '[' . $taxonomy . '][]" value="0" />';
  806. self::$scripts_quick[ $field_name . '1' ] = "var {$taxonomy}_terms = jQuery( '#{$taxonomy}_' + post_id ).text();";
  807. self::$scripts_quick[ $field_name . '2' ] = "if ( {$taxonomy}_terms ) {
  808. jQuery( 'ul.{$taxonomy}-checklist :checkbox', edit_row ).val( {$taxonomy}_terms.split(',') );
  809. }
  810. ";
  811. } else {
  812. $input_name = 'post_category';
  813. $result .= '<input type="hidden" name="' . $input_name . '[]" value="0" />';
  814. }
  815. $result .= '<ul class="cat-checklist ' . esc_attr( $taxonomy ) . '-checklist">';
  816. $result .= $terms;
  817. $result .= '</ul>';
  818. return $result;
  819. }
  820. public static function custom_box_remove( $field_name, $key_reset = null ) {
  821. $field_name = str_replace( self::SLUG, '', $field_name );
  822. $taxonomy = str_replace( Custom_Bulkquick_Edit_Settings::REMOVE, '', $field_name );
  823. $title_reset = Custom_Bulkquick_Edit_Settings::$settings[ $key_reset ]['label'];
  824. $result = '<label>';
  825. $result .= '<span class="checkbox-title">' . $title_reset . '</span>';
  826. ob_start();
  827. wp_terms_checklist( null, array( 'taxonomy' => $taxonomy ) );
  828. $terms = ob_get_contents();
  829. ob_end_clean();
  830. $terms = preg_replace( "#(post_category|tax_input\[{$taxonomy}\])#", $field_name, $terms );
  831. $result .= '<input type="hidden" name="' . $field_name . '[]" value="0" />';
  832. $result .= '<ul class="cat-checklist ' . esc_attr( $field_name ) . '-checklist">';
  833. $result .= $terms;
  834. $result .= '</ul>';
  835. $result .= '</label>';
  836. self::$scripts_bulk[ $field_name ] = "'{$field_name}': bulk_row.find( 'input[name^={$field_name}]:checked:checked' ).map( function(){ return jQuery( this ).val(); } ).get()";
  837. return $result;
  838. }
  839. public static function custom_box_textarea( $column_name, $field_name, $field_name_var ) {
  840. $result = '<textarea cols="22" rows="1" name="' . $field_name . '" autocomplete="off"></textarea>';
  841. self::$scripts_bulk[ $column_name ] = "'{$field_name}': bulk_row.find( 'textarea[name={$field_name}]' ).val()";
  842. self::$scripts_quick[ $column_name . '1' ] = "var {$field_name_var} = jQuery( '.column-{$column_name}', post_row ).text();";
  843. self::$scripts_quick[ $column_name . '2' ] = "jQuery( ':input[name={$field_name}]', edit_row ).val( {$field_name_var} );";
  844. return $result;
  845. }
  846. public static function custom_box_input( $column_name, $field_name, $field_name_var ) {
  847. $result = '<input type="text" name="' . $field_name . '" autocomplete="off" />';
  848. self::$scripts_bulk[ $column_name ] = "'{$field_name}': bulk_row.find( 'input[name={$field_name}]' ).val()";
  849. self::$scripts_quick[ $column_name . '1' ] = "var {$field_name_var} = jQuery( '.column-{$column_name}', post_row ).text();";
  850. self::$scripts_quick[ $column_name . '2' ] = "if ( '&Oslash;' == {$field_name_var} || 'Ø' == {$field_name_var} ) {$field_name_var} = 0;";
  851. self::$scripts_quick[ $column_name . '3' ] = "jQuery( ':input[name={$field_name}]', edit_row ).val( {$field_name_var} );";
  852. return $result;
  853. }
  854. /**
  855. *
  856. *
  857. * @SuppressWarnings(PHPMD.Superglobals)
  858. */
  859. public static function save_post( $post_id ) {
  860. $post_type = get_post_type( $post_id );
  861. if ( ! in_array( $post_type, self::$post_types_keys ) ) {
  862. return;
  863. }
  864. if ( ! current_user_can( 'edit_post', $post_id ) ) {
  865. return;
  866. }
  867. if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
  868. return;
  869. }
  870. if ( 'revision' == $post_type ) {
  871. return;
  872. }
  873. if ( isset( $_POST[ self::ID ] ) && ! wp_verify_nonce( $_POST[ self::ID ], self::BASE ) ) {
  874. return;
  875. }
  876. remove_action( 'save_post', array( __CLASS__, 'save_post' ), 25 );
  877. self::save_post_items( $post_id );
  878. }
  879. /**
  880. *
  881. *
  882. * @SuppressWarnings(PHPMD.Superglobals)
  883. */
  884. public static function admin_footer() {
  885. if ( self::$no_instance ) {
  886. return;
  887. }
  888. if ( empty( $_GET['post_type'] ) ) {
  889. global $post;
  890. $_GET['post_type'] = ! empty( $post->post_type ) ? $post->post_type : false;
  891. }
  892. if ( in_array( $_GET['post_type'], self::$post_types_keys ) ) {
  893. self::get_scripts();
  894. }
  895. }
  896. public static function column_checkbox_radio( $column, $current, $options, $field_type ) {
  897. $result = '';
  898. if ( ! is_array( $current ) ) {
  899. $current = array( $current );
  900. }
  901. foreach ( $options as $option ) {
  902. $parts = explode( '|', $option );
  903. $value = array_shift( $parts );
  904. if ( empty( $parts ) ) {
  905. $name = $value;
  906. } else {
  907. $name = array_shift( $parts );
  908. }
  909. if ( in_array( $value, $current ) ) {
  910. $result .= '<input type="' . $field_type . '" name="' . $column . '" value="' . $value . '" checked="checked" disabled="disabled" /> ' . $name . '<br />';
  911. }
  912. }
  913. return $result;
  914. }
  915. public static function column_select( $column, $current, $options, $field_type ) {
  916. $result = '';
  917. if ( ! is_array( $current ) ) {
  918. $current = array( $current );
  919. }
  920. $select_options = '';
  921. foreach ( $options as $option ) {
  922. $parts = explode( '|', $option );
  923. $value = array_shift( $parts );
  924. if ( empty( $parts ) ) {
  925. $name = $value;
  926. } else {
  927. $name = array_shift( $parts );
  928. }
  929. if ( in_array( $value, $current ) ) {
  930. $select_options .= '<option value="' . $value . '" selected="selected">' . $name . '</option>';
  931. }
  932. }
  933. $multiple = '';
  934. if ( 'multiple' == $field_type ) {
  935. $multiple = '" multiple="multiple';
  936. }
  937. if ( $select_options ) {
  938. $result = '<select name="' . $column . $multiple . '" disabled="disabled">';
  939. $result .= $select_options;
  940. $result .= '</select>';
  941. }
  942. return $result;
  943. }
  944. /**
  945. *
  946. *
  947. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  948. */
  949. public static function column_taxonomies( $post_id, $column, $current, $options, $field_type ) {
  950. $taxonomy = $column;
  951. $post_type = get_post_type( $post_id );
  952. $post_terms = array();
  953. $terms = get_the_terms( $post_id, $taxonomy );
  954. if ( ! empty( $terms ) ) {
  955. foreach ( $terms as $term ) {
  956. $post_terms[] = '<a href="edit.php?post_type=' . $post_type . '&' . $taxonomy . '=' . $term->slug . '">' . esc_html( sanitize_term_field( 'name', $term->name, $term->term_id, $taxonomy, 'edit' ) ) . '</a>';
  957. }
  958. }
  959. $result = implode( ', ', $post_terms );
  960. return $result;
  961. }
  962. /**
  963. *
  964. *
  965. * @SuppressWarnings(PHPMD.Superglobals)
  966. */
  967. public static function do_load() {
  968. $do_load = false;
  969. if ( ! empty( $GLOBALS['pagenow'] ) && in_array( $GLOBALS['pagenow'], array( 'edit.php', 'options.php' ) ) ) {
  970. $do_load = true;
  971. } elseif ( ! empty( $_REQUEST['page'] ) && Custom_Bulkquick_Edit_Settings::ID == $_REQUEST['page'] ) {
  972. $do_load = true;
  973. } elseif ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
  974. $do_load = true;
  975. }
  976. return $do_load;
  977. }
  978. public static function check_field_type( $field_type, $column_name ) {
  979. if ( in_array( $column_name, array( 'post_excerpt', 'post_title' ) ) ) {
  980. $field_type = 'textarea';
  981. }
  982. $field_type = apply_filters( 'cbqe_check_field_type', $field_type, $column_name );
  983. return $field_type;
  984. }
  985. /**
  986. *
  987. *
  988. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  989. */
  990. public static function pre_update_option_active_plugins( $plugins, $old_value ) {
  991. if ( ! is_array( $plugins ) ) {
  992. return $plugins;
  993. }
  994. if ( defined( 'CBQEP_BASE' ) ) {
  995. return $plugins;
  996. }
  997. $index = array_search( self::BASE, $plugins );
  998. if ( false !== $index && ! empty( $index ) ) {
  999. unset( $plugins[ $index ] );
  1000. array_unshift( $plugins, self::BASE );
  1001. }
  1002. return $plugins;
  1003. }
  1004. public static function styles() {
  1005. if ( is_admin() ) {
  1006. wp_register_style( __CLASS__, self::$plugin_assets . 'css/custom-bulkquick-edit.css' );
  1007. }
  1008. wp_enqueue_style( __CLASS__ );
  1009. do_action( 'cbqe_styles' );
  1010. }
  1011. /**
  1012. *
  1013. *
  1014. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  1015. */
  1016. public static function column_categories( $post_id, $column, $current, $options, $field_type ) {
  1017. $post_terms = array();
  1018. $post_type = get_post_type( $post_id );
  1019. $taxonomy = $column;
  1020. $term_ids = array();
  1021. $terms = get_the_terms( $post_id, $taxonomy );
  1022. if ( ! empty( $terms ) ) {
  1023. foreach ( $terms as $term ) {
  1024. $post_terms[] = '<a href="edit.php?post_type=' . $post_type . '&' . $taxonomy . '=' . $term->slug . '">' . esc_html( sanitize_term_field( 'name', $term->name, $term->term_id, $taxonomy, 'edit' ) ) . '</a>';
  1025. }
  1026. $term_ids = wp_list_pluck( $terms, 'term_id' );
  1027. }
  1028. $result = implode( ', ', $post_terms );
  1029. $result .= '<div class="hidden" id="' . $taxonomy . '_' . $post_id . '">' . implode( ',', $term_ids ) . '</div>';
  1030. return $result;
  1031. }
  1032. }
  1033. ?>