Skip to content

Commit

Permalink
Bulk edit functionality
Browse files Browse the repository at this point in the history
Fixes #171
  • Loading branch information
ajaydsouza committed Oct 10, 2023
1 parent d81c4bf commit e100b0f
Show file tree
Hide file tree
Showing 6 changed files with 354 additions and 1 deletion.
1 change: 1 addition & 0 deletions contextual-related-posts.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@
require_once CRP_PLUGIN_DIR . 'includes/admin/modules/tools.php';
require_once CRP_PLUGIN_DIR . 'includes/admin/modules/loader.php';
require_once CRP_PLUGIN_DIR . 'includes/admin/modules/metabox.php';
require_once CRP_PLUGIN_DIR . 'includes/admin/modules/class-bulk-edit.php';
} // End if.


Expand Down
70 changes: 70 additions & 0 deletions includes/admin/js/bulk-edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
jQuery(document).ready(function ($) {

// we create a copy of the WP inline edit post function
const wp_inline_edit = inlineEditPost.edit;

// and then we overwrite the function with our own code
inlineEditPost.edit = function (post_id) {

// "call" the original WP edit function
// we don't want to leave WordPress hanging
wp_inline_edit.apply(this, arguments);

// now we take care of our business

// get the post ID from the argument
if (typeof (post_id) == 'object') { // if it is object, get the ID number
post_id = parseInt(this.getId(post_id));
}

if (post_id > 0) {
// define the edit row
const edit_row = $('#edit-' + post_id);
const post_row = $('#post-' + post_id);

// get the data
const crp_manual_related = $('.crp_manual_related', post_row).text();
const crp_exclude_this_post = 1 == $('.crp_exclude_this_post', post_row).val() ? true : false;

// populate the data
$(':input[name="crp_manual_related"]', edit_row).val(crp_manual_related);
$(':input[name="crp_exclude_this_post"]', edit_row).prop('checked', crp_exclude_this_post);
}
};

$('#bulk_edit').on('click', function () {
const bulk_row = $('#bulk-edit');

// get the selected post ids that are being edited
const post_ids = [];

// get the data
const crp_manual_related = $(':input[name="crp_manual_related"]', bulk_row).val();
const crp_exclude_this_post = $('select[name="crp_exclude_this_post"]', bulk_row).val();

// get post ids from bulk_edit
bulk_row.find('#bulk-titles-list .ntdelbutton').each(function () {
post_ids.push($(this).attr('id').replace(/^(_)/i, ''));
});
// convert all post_ids to integer
post_ids.map(function (value, index, array) {
array[index] = parseInt(value);
});

// save the data
$.ajax({
url: ajaxurl, // this is a variable that WordPress has already defined for us
type: 'POST',
async: false,
cache: false,
data: {
action: 'crp_save_bulk_edit', // this is the name of our WP AJAX function that we'll set up next
post_ids: post_ids, // and these are the 2 parameters we're passing to our function
crp_manual_related: crp_manual_related,
crp_exclude_this_post: crp_exclude_this_post,
crp_bulk_edit_nonce: crp_bulk_edit.nonce
}
});
});

});
1 change: 1 addition & 0 deletions includes/admin/js/bulk-edit.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

273 changes: 273 additions & 0 deletions includes/admin/modules/class-bulk-edit.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
<?php
/**
* Contextual Related Posts Bulk Edit functionality.
*
* @package Contextual_Related_Posts
*/

namespace WebberZone\Contextual_Related_Posts;

if ( ! defined( 'WPINC' ) ) {
die;
}

/**
* Class Bulk Edit functionality.
*
* @since 3.4.0
*/
class Bulk_Edit {

/**
* CRP_Bulk_Edit constructor.
*/
public function __construct() {
add_action( 'init', array( $this, 'add_custom_columns' ), 99 );
add_action( 'bulk_edit_custom_box', array( $this, 'quick_edit_custom_box' ) );
add_action( 'quick_edit_custom_box', array( $this, 'quick_edit_custom_box' ) );
add_action( 'save_post', array( $this, 'save_post_meta' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
add_action( 'wp_ajax_crp_save_bulk_edit', array( $this, 'save_bulk_edit' ) );
}

/**
* Enqueue scripts and styles.
*
* @param string $hook The current admin page.
*/
public function enqueue_scripts( $hook ) {
if ( 'edit.php' !== $hook ) {
return;
}

$file_prefix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';

wp_enqueue_script(
'crp-bulk-edit',
CRP_PLUGIN_URL . "includes/admin/js/bulk-edit{$file_prefix}.js",
array( 'jquery' ),
CRP_VERSION,
true
);
wp_localize_script(
'crp-bulk-edit',
'crp_bulk_edit',
array(
'nonce' => wp_create_nonce( 'crp_bulk_edit_nonce' ),
)
);
}

/**
* Add custom columns to the posts list table.
*/
public function add_custom_columns() {
// Get all post types present on the site.
$post_types = get_post_types( array( 'public' => true ) );

// For each post type, add the bulk edit functionality and the columns.
foreach ( $post_types as $post_type ) {
add_filter( 'manage_' . $post_type . '_posts_columns', array( $this, 'add_admin_columns' ) );
add_action( 'manage_' . $post_type . '_posts_custom_column', array( $this, 'populate_custom_columns' ), 10, 2 );
}
}

/**
* Add custom columns to the posts list table.
*
* @param array $columns The existing columns.
* @return array The modified columns.
*/
public function add_admin_columns( $columns ) {
$columns['crp_columns'] = __( 'Contextual Related Posts', 'contextual-related-posts' );
return $columns;
}

/**
* Populate the custom columns with data.
*
* @param string $column_name The name of the column.
* @param int $post_id The ID of the post.
*/
public function populate_custom_columns( $column_name, $post_id ) {
switch ( $column_name ) {
case 'crp_columns':
// Get related posts specific meta.
$post_meta = get_post_meta( $post_id, 'crp_post_meta', true );

// Manual related.
$manual_related = isset( $post_meta['manual_related'] ) ? $post_meta['manual_related'] : '';
$manual_related_array = wp_parse_id_list( $manual_related );

// For each of the manual related posts, display the post ID with a link to open this in a new tab.
if ( ! empty( $manual_related_array ) ) {
$html = '<p>' . __( 'Manual related posts:', 'contextual-related-posts' );
foreach ( $manual_related_array as $related_post_id ) {
$html .= ' <a href="' . esc_url( get_permalink( $related_post_id ) ) . '" target="_blank">' . esc_html( (string) $related_post_id ) . '</a>,';
}
$html = rtrim( $html, ',' );
$html .= '<div class="crp_manual_related hidden">' . $manual_related . '</div>';
$html .= '</p>';

echo wp_kses_post( $html );
}

// Exclude this post.
$exclude_this_post = isset( $post_meta['exclude_this_post'] ) ? $post_meta['exclude_this_post'] : 0;

// Display the checkbox.
echo '<p>';
esc_html_e( 'Exclude from list:', 'contextual-related-posts' );
echo wp_kses_post( $exclude_this_post ? '<span class="dashicons dashicons-yes" style="color:green"></span>' : '<span class="dashicons dashicons-no" style="color:red"></span>' );
echo '<input type="hidden" name="crp_exclude_this_post" class="crp_exclude_this_post" value="' . esc_attr( $exclude_this_post ) . '">';
echo '</p>';

break;
}
}

/**
* Add custom field to quick edit screen.
*
* @param string $column_name The name of the column.
*/
public function quick_edit_custom_box( $column_name ) {

switch ( $column_name ) {
case 'crp_columns':
if ( current_filter() === 'quick_edit_custom_box' ) {
wp_nonce_field( 'crp_quick_edit_nonce', 'crp_quick_edit_nonce' );
} else {
wp_nonce_field( 'crp_bulk_edit_nonce', 'crp_bulk_edit_nonce' );
}
?>
<fieldset class="inline-edit-col-left inline-edit-crp">
<div class="inline-edit-col column-<?php echo esc_attr( $column_name ); ?>">
<label class="inline-edit-group">
<?php esc_html_e( 'Manual Related Posts', 'contextual-related-posts' ); ?>
<?php
if ( current_filter() === 'bulk_edit_custom_box' ) {
' ' . esc_html_e( '(0 to clear the manual posts)', 'contextual-related-posts' );
}
?>
<input type="text" name="crp_manual_related" class="widefat" value="">
</label>
<label class="inline-edit-group">
<?php if ( current_filter() === 'quick_edit_custom_box' ) { ?>
<input type="checkbox" name="crp_exclude_this_post"><?php esc_html_e( 'Exclude this post from related posts', 'contextual-related-posts' ); ?>
<?php } else { ?>
<?php esc_html_e( 'Exclude from related posts', 'contextual-related-posts' ); ?>
<select name="crp_exclude_this_post">
<option value="-1"><?php esc_html_e( '&mdash; No Change &mdash;' ); ?></option>
<option value="1"><?php esc_html_e( 'Exclude' ); ?></option>
<option value="0"><?php esc_html_e( 'Include' ); ?></option>
</select>
<?php } ?>
</label>
</div>
</fieldset>
<?php
break;
}
}

/**
* Save custom field data.
*
* @param int $post_id The post ID.
*/
public function save_post_meta( $post_id ) {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
if ( ! isset( $_REQUEST['crp_quick_edit_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['crp_quick_edit_nonce'] ) ), 'crp_quick_edit_nonce' ) ) {
return;
}

$post_meta = array();

if ( isset( $_REQUEST['crp_manual_related'] ) ) {
$manual_related_array = wp_parse_id_list( sanitize_text_field( wp_unslash( $_REQUEST['crp_manual_related'] ) ) );

foreach ( $manual_related_array as $key => $value ) {
if ( 'publish' !== get_post_status( $value ) ) {
unset( $manual_related_array[ $key ] );
}
}
$manual_related = implode( ',', $manual_related_array );
$post_meta['manual_related'] = $manual_related;
}

if ( isset( $_REQUEST['crp_exclude_this_post'] ) ) {
$post_meta['exclude_this_post'] = 1;
} else {
$post_meta['exclude_this_post'] = 0;
}

$meta = get_post_meta( $post_id, 'crp_post_meta', true );
if ( $meta ) {
$post_meta = array_merge( $meta, $post_meta );
}

$post_meta_filtered = array_filter( $post_meta );

/**** Now we can start saving */
if ( empty( $post_meta_filtered ) ) { // Checks if all the array items are 0 or empty.
delete_post_meta( $post_id, 'crp_post_meta' ); // Delete the post meta if no options are set.
} else {
update_post_meta( $post_id, 'crp_post_meta', $post_meta_filtered );
}
}

/**
* Save bulk edit data.
*/
public function save_bulk_edit() {
// Security check.
check_ajax_referer( 'crp_bulk_edit_nonce', 'crp_bulk_edit_nonce' );

// Get the post IDs.
$post_ids = isset( $_POST['post_ids'] ) ? wp_parse_id_list( wp_unslash( $_POST['post_ids'] ) ) : array();

// Get the post meta.
$post_meta = array();

if ( isset( $_POST['crp_manual_related'] ) ) {
$manual_related_array = wp_parse_id_list( wp_unslash( $_POST['crp_manual_related'] ) );

if ( ! empty( $manual_related_array ) ) {
foreach ( $manual_related_array as $key => $value ) {
if ( 'publish' !== get_post_status( $value ) ) {
unset( $manual_related_array[ $key ] );
}
}
$manual_related = implode( ',', $manual_related_array );
$post_meta['manual_related'] = $manual_related;
}
}

if ( isset( $_POST['crp_exclude_this_post'] ) && -1 !== (int) $_POST['crp_exclude_this_post'] ) {
$post_meta['exclude_this_post'] = intval( wp_unslash( $_POST['crp_exclude_this_post'] ) );
}

// Now we can start saving.
foreach ( $post_ids as $post_id ) {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
continue;
}
$meta = get_post_meta( $post_id, 'crp_post_meta', true );
$meta = $meta ? array_merge( $meta, $post_meta ) : $post_meta;
$meta_filtered = array_filter( $meta );

if ( empty( $meta_filtered ) ) { // Checks if all the array items are 0 or empty.
delete_post_meta( $post_id, 'crp_post_meta' ); // Delete the post meta if no options are set.
} else {
update_post_meta( $post_id, 'crp_post_meta', $meta_filtered );
}
}

wp_send_json_success();
}
}

new Bulk_Edit();
7 changes: 6 additions & 1 deletion phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ parameters:
count: 1
path: includes/admin/default-settings.php

-
message: "#^Constant CRP_PLUGIN_URL not found\\.$#"
count: 1
path: includes/admin/modules/class-bulk-edit.php

-
message: "#^Constant CRP_PLUGIN_DIR not found\\.$#"
count: 1
Expand All @@ -32,7 +37,7 @@ parameters:

-
message: "#^Variable \\$meta_key might not be defined\\.$#"
count: 3
count: 2
path: includes/main-query.php

-
Expand Down
3 changes: 3 additions & 0 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ Contextual Related Posts is one of the many plugins developed by WebberZone. Che

= 3.4.0 =

Features:
* Bulk edit posts, pages and custom post types to add the manual relatd posts and/or exclude posts from the related posts list

* Enhancements/Modifications:
* Caching of the entire HTML output is enabled by default. You can disable it in the settings page. This will reduce the number of database queries and improve performance. If you have customised the output, you will need to clear the cache for the changes to take effect. Applies to new installs and when you reset the settings
* The plugin no longer check for pre v2.5 settings key
Expand Down

0 comments on commit e100b0f

Please sign in to comment.