# speechkit/4.0.0/src/Component/Posts/BulkEdit/BulkEdit.php

BeyondWords – AI audio for publishers, version 4.0.0. 279 lines.

- Page: https://pluginprobe.com/plugins/speechkit/4.0.0/code/src/Component/Posts/BulkEdit/BulkEdit.php
- Raw: https://pluginprobe.com/plugins/speechkit/4.0.0/raw/src/Component/Posts/BulkEdit/BulkEdit.php
- Modified: 2023-07-26T14:25:00+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/speechkit/4.0.0/code/src/Component/Posts/BulkEdit/BulkEdit.php#L10-L20`.

```php
<?php

declare(strict_types=1);

/**
 * BeyondWords Bulk Edit.
 *
 * Text Domain: beyondwords
 *
 * @package Beyondwords\Wordpress
 * @author  Stuart McAlpine <stu@beyondwords.io>
 * @since   3.0.0
 */

namespace Beyondwords\Wordpress\Component\Posts\BulkEdit;

use Beyondwords\Wordpress\Core\Core;
use Beyondwords\Wordpress\Component\Settings\SettingsUtils;
use Beyondwords\Wordpress\Plugin;

/**
 * BulkEdit setup
 *
 * @since 3.0.0
 */
class BulkEdit
{
    /**
     * Constructor
     */
    public function __construct()
    {
        add_action('admin_enqueue_scripts', array($this, 'adminEnqueueScripts'));
        add_action('bulk_edit_custom_box', array($this, 'bulkEditCustomBox'), 10, 2);
        add_action('wp_ajax_save_bulk_edit_beyondwords', array($this, 'saveBulkEdit'));
        add_action('admin_notices', array($this, 'adminNotices'));

        add_action('wp_loaded', function () {
            $postTypes = SettingsUtils::getSupportedPostTypes();

            if (is_array($postTypes)) {
                foreach ($postTypes as $postType) {
                    add_filter("bulk_actions-edit-{$postType}", array($this, 'bulkActionsEdit'), 10, 1);
                    add_filter("handle_bulk_actions-edit-{$postType}", array($this, 'handleBulkActions'), 10, 3);
                }
            }
        });
    }

    /**
     * Enqueue JS for Bulk Edit feature.
     */
    public function adminEnqueueScripts($hook)
    {
        // Only enqueue for Edit screen
        if ($hook === 'edit.php') {
            wp_enqueue_script(
                'beyondwords_bulk_edit',
                BEYONDWORDS__PLUGIN_URI . 'src/Component/Posts/BulkEdit/js/bulk-edit.js',
                array('jquery'),
                BEYONDWORDS__PLUGIN_VERSION,
                true
            );
        }
    }

    /**
     * Adds the meta box container.
     */
    public function bulkEditCustomBox($columnName, $postType)
    {
        if ($columnName !== 'beyondwords') {
            return;
        }

        $postTypes = SettingsUtils::getSupportedPostTypes();

        if (! in_array($postType, $postTypes)) {
            return;
        }

        wp_nonce_field('beyondwords_nonce', 'beyondwords_bulk_edit');

        ?>
        <fieldset class="inline-edit-col-right">
            <div class="inline-edit-col">
                <div class="inline-edit-group wp-clearfix">
                    <label class="alignleft">
                        <span class="title"><?php _e('BeyondWords', 'speechkit'); ?></span>
                        <select name="beyondwords_generate_audio">
                            <option value="-1"><?php _e('— No change —', 'speechkit'); ?></option>
                            <option value="new"><?php _e('Generate audio', 'speechkit'); ?></option>
                        </select>
                    </label>
                </div>
            </div>
        </fieldset>
        <?php
    }

    /**
     * Save Bulk Edit updates.
     *
     * @link https://rudrastyh.com/wordpress/bulk-edit.html
     */
    public function saveBulkEdit()
    {
        /*
         * We need to verify this came from the our screen and with proper authorization,
         * because save_post can be triggered at other times.
         */
        if (
            ! isset($_POST['beyondwords_nonce']) ||
            ! wp_verify_nonce(sanitize_text_field($_POST['beyondwords_nonce']), 'beyondwords_bulk_edit')
        ) {
            wp_nonce_ays('');
        }

        /* OK, it's safe for us to save the data now. */
        $generate_audio = (
            ! empty($_POST[ 'beyondwords_generate_audio' ]) &&
            $_POST[ 'beyondwords_generate_audio' ] === 'new'
        );

        if (! $generate_audio) {
            return [];
        }

        if (isset($_POST['post_ids'])) {
            $post_ids = filter_var($_POST['post_ids'], FILTER_VALIDATE_INT, FILTER_REQUIRE_ARRAY);

            return $this->generateAudioForPosts($post_ids);
        }

        return [];
    }

    public function generateAudioForPosts($postIds)
    {
        if (!is_array($postIds)) {
            return false;
        }

        $updatedPostIds = [];

        foreach ($postIds as $postId) {
            if (! get_post_meta($postId, 'beyondwords_content_id', true)) {
                update_post_meta($postId, 'beyondwords_generate_audio', '1');
            }
            $updatedPostIds[] = $postId;
        }

        return $updatedPostIds;
    }

    /**
     *
     */
    public function bulkActionsEdit($bulk_array)
    {
        $bulk_array['beyondwords_generate_audio'] = __('Generate audio', 'speechkit');
        return $bulk_array;
    }

    /**
     * @SuppressWarnings(PHPMD.LongVariable)
     */
    public function handleBulkActions($redirect, $doaction, $object_ids)
    {
        global $beyondwords_wordpress_plugin;

        // Remove query args
        $redirect = remove_query_arg(['beyondwords_bulk_processed'], $redirect);

        // Handle "Generate audio" bulk action
        if ($doaction === 'beyondwords_generate_audio') {
            $processed = 0;
            $failed = 0;

            // Order batch by Post ID asc
            sort($object_ids);

            try {
                // Update all custom fields before attempting any processing
                foreach ($object_ids as $post_id) {
                    update_post_meta($post_id, 'beyondwords_generate_audio', '1');
                }

                // Now process all posts
                foreach ($object_ids as $post_id) {
                    if (
                        $beyondwords_wordpress_plugin instanceof Plugin
                        && $beyondwords_wordpress_plugin->core instanceof Core
                    ) {
                        $response = $beyondwords_wordpress_plugin->core->generateAudioForPost($post_id);

                        if ($response) {
                            $processed++;
                        } else {
                            $failed++;
                        }
                    } else {
                        throw new \Exception('Error while bulk generating audio. Please contact support with reference BULK-NO-PLUGIN.'); // phpcs:ignore
                    }
                }
            } catch (\Exception $e) {
                $redirect = add_query_arg('beyondwords_bulk_error', $e->getMessage(), $redirect);
            }

            // Add $processed query arg into redirect
            $redirect = add_query_arg('beyondwords_bulk_processed', $processed, $redirect);

            if ($failed) {
                $redirect = add_query_arg('beyondwords_bulk_failed', $failed, $redirect);
            }

            // Add $nonce query arg into redirect
            $nonce = wp_create_nonce('beyondwords_bulk_edit');
            $redirect = add_query_arg('beyondwords_nonce', $nonce, $redirect);
        }

        return $redirect;
    }

    /**
     *
     */
    public function adminNotices()
    {
        if (! isset($_REQUEST['beyondwords_nonce']) || ! isset($_REQUEST['beyondwords_bulk_processed'])) {
            return '';
        }

        if (! wp_verify_nonce(sanitize_text_field($_REQUEST['beyondwords_nonce']), 'beyondwords_bulk_edit')) {
            wp_nonce_ays('');
        }

        $processedCount = intval($_REQUEST['beyondwords_bulk_processed']);
        $failedCount = intval($_REQUEST['beyondwords_bulk_failed'] ?? 0);

        $processedMessage = sprintf(
            /* translators: %d is replaced with the number of posts processed */
            _n(
                'Audio requested for %d post.',
                'Audio requested for %d posts.',
                $processedCount,
                'speechkit'
            ),
            $processedCount
        );
        ?>
        <div id="beyondwords-bulk-edit-notice" class="notice notice-info is-dismissible">
            <p>
                <?php echo esc_html($processedMessage); ?>
            </p>
            <?php
            if ($failedCount) {
                $failedMessage = sprintf(
                    /* translators: %d is replaced with the number of posts that were skipped */
                    _n(
                        '%d post failed, check for errors in the BeyondWords column below.',
                        '%d posts failed, check for errors in the BeyondWords column below.',
                        $failedCount,
                        'speechkit'
                    ),
                    $failedCount
                );
                ?>
                <p>
                    <?php echo esc_html($failedMessage); ?>
                </p>
                <?php
            }
            ?>
        </div>
        <?php
    }
}

```
