PluginProbe
BeyondWords – AI audio for publishers / 4.0.6
BeyondWords – AI audio for publishers v4.0.6
7.1.0 trunk 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.1.0 4.1.1 4.1.2 4.2.0 4.2.1 4.2.2 4.2.3 4.2.4 4.3.0 4.4.0 4.5.0 4.5.1 4.6.0 4.6.1 4.6.2 4.7.0 All 43 releases
speechkit / src / Component / Posts / BulkEdit / BulkEdit.php

BulkEdit.php in BeyondWords – AI audio for publishers 4.0.6, at src/Component/Posts/BulkEdit/BulkEdit.php

279 lines 8.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 /**
6 * BeyondWords Bulk Edit.
7 *
8 * Text Domain: beyondwords
9 *
10 * @package Beyondwords\Wordpress
11 * @author Stuart McAlpine <stu@beyondwords.io>
12 * @since 3.0.0
13 */
14
15 namespace Beyondwords\Wordpress\Component\Posts\BulkEdit;
16
17 use Beyondwords\Wordpress\Core\Core;
18 use Beyondwords\Wordpress\Component\Settings\SettingsUtils;
19 use Beyondwords\Wordpress\Plugin;
20
21 /**
22 * BulkEdit setup
23 *
24 * @since 3.0.0
25 */
26 class BulkEdit
27 {
28 /**
29 * Constructor
30 */
31 public function __construct()
32 {
33 add_action('admin_enqueue_scripts', array($this, 'adminEnqueueScripts'));
34 add_action('bulk_edit_custom_box', array($this, 'bulkEditCustomBox'), 10, 2);
35 add_action('wp_ajax_save_bulk_edit_beyondwords', array($this, 'saveBulkEdit'));
36 add_action('admin_notices', array($this, 'adminNotices'));
37
38 add_action('wp_loaded', function () {
39 $postTypes = SettingsUtils::getSupportedPostTypes();
40
41 if (is_array($postTypes)) {
42 foreach ($postTypes as $postType) {
43 add_filter("bulk_actions-edit-{$postType}", array($this, 'bulkActionsEdit'), 10, 1);
44 add_filter("handle_bulk_actions-edit-{$postType}", array($this, 'handleBulkActions'), 10, 3);
45 }
46 }
47 });
48 }
49
50 /**
51 * Enqueue JS for Bulk Edit feature.
52 */
53 public function adminEnqueueScripts($hook)
54 {
55 // Only enqueue for Edit screen
56 if ($hook === 'edit.php') {
57 wp_enqueue_script(
58 'beyondwords_bulk_edit',
59 BEYONDWORDS__PLUGIN_URI . 'src/Component/Posts/BulkEdit/js/bulk-edit.js',
60 array('jquery'),
61 BEYONDWORDS__PLUGIN_VERSION,
62 true
63 );
64 }
65 }
66
67 /**
68 * Adds the meta box container.
69 */
70 public function bulkEditCustomBox($columnName, $postType)
71 {
72 if ($columnName !== 'beyondwords') {
73 return;
74 }
75
76 $postTypes = SettingsUtils::getSupportedPostTypes();
77
78 if (! in_array($postType, $postTypes)) {
79 return;
80 }
81
82 wp_nonce_field('beyondwords_nonce', 'beyondwords_bulk_edit');
83
84 ?>
85 <fieldset class="inline-edit-col-right">
86 <div class="inline-edit-col">
87 <div class="inline-edit-group wp-clearfix">
88 <label class="alignleft">
89 <span class="title"><?php _e('BeyondWords', 'speechkit'); ?></span>
90 <select name="beyondwords_generate_audio">
91 <option value="-1"><?php _e('— No change —', 'speechkit'); ?></option>
92 <option value="new"><?php _e('Generate audio', 'speechkit'); ?></option>
93 </select>
94 </label>
95 </div>
96 </div>
97 </fieldset>
98 <?php
99 }
100
101 /**
102 * Save Bulk Edit updates.
103 *
104 * @link https://rudrastyh.com/wordpress/bulk-edit.html
105 */
106 public function saveBulkEdit()
107 {
108 /*
109 * We need to verify this came from the our screen and with proper authorization,
110 * because save_post can be triggered at other times.
111 */
112 if (
113 ! isset($_POST['beyondwords_nonce']) ||
114 ! wp_verify_nonce(sanitize_text_field($_POST['beyondwords_nonce']), 'beyondwords_bulk_edit')
115 ) {
116 wp_nonce_ays('');
117 }
118
119 /* OK, it's safe for us to save the data now. */
120 $generate_audio = (
121 ! empty($_POST[ 'beyondwords_generate_audio' ]) &&
122 $_POST[ 'beyondwords_generate_audio' ] === 'new'
123 );
124
125 if (! $generate_audio) {
126 return [];
127 }
128
129 if (isset($_POST['post_ids'])) {
130 $post_ids = filter_var($_POST['post_ids'], FILTER_VALIDATE_INT, FILTER_REQUIRE_ARRAY);
131
132 return $this->generateAudioForPosts($post_ids);
133 }
134
135 return [];
136 }
137
138 public function generateAudioForPosts($postIds)
139 {
140 if (!is_array($postIds)) {
141 return false;
142 }
143
144 $updatedPostIds = [];
145
146 foreach ($postIds as $postId) {
147 if (! get_post_meta($postId, 'beyondwords_content_id', true)) {
148 update_post_meta($postId, 'beyondwords_generate_audio', '1');
149 }
150 $updatedPostIds[] = $postId;
151 }
152
153 return $updatedPostIds;
154 }
155
156 /**
157 *
158 */
159 public function bulkActionsEdit($bulk_array)
160 {
161 $bulk_array['beyondwords_generate_audio'] = __('Generate audio', 'speechkit');
162 return $bulk_array;
163 }
164
165 /**
166 * @SuppressWarnings(PHPMD.LongVariable)
167 */
168 public function handleBulkActions($redirect, $doaction, $object_ids)
169 {
170 global $beyondwords_wordpress_plugin;
171
172 // Remove query args
173 $redirect = remove_query_arg(['beyondwords_bulk_processed'], $redirect);
174
175 // Handle "Generate audio" bulk action
176 if ($doaction === 'beyondwords_generate_audio') {
177 $processed = 0;
178 $failed = 0;
179
180 // Order batch by Post ID asc
181 sort($object_ids);
182
183 try {
184 // Update all custom fields before attempting any processing
185 foreach ($object_ids as $post_id) {
186 update_post_meta($post_id, 'beyondwords_generate_audio', '1');
187 }
188
189 // Now process all posts
190 foreach ($object_ids as $post_id) {
191 if (
192 $beyondwords_wordpress_plugin instanceof Plugin
193 && $beyondwords_wordpress_plugin->core instanceof Core
194 ) {
195 $response = $beyondwords_wordpress_plugin->core->generateAudioForPost($post_id);
196
197 if ($response) {
198 $processed++;
199 } else {
200 $failed++;
201 }
202 } else {
203 throw new \Exception('Error while bulk generating audio. Please contact support with reference BULK-NO-PLUGIN.'); // phpcs:ignore
204 }
205 }
206 } catch (\Exception $e) {
207 $redirect = add_query_arg('beyondwords_bulk_error', $e->getMessage(), $redirect);
208 }
209
210 // Add $processed query arg into redirect
211 $redirect = add_query_arg('beyondwords_bulk_processed', $processed, $redirect);
212
213 if ($failed) {
214 $redirect = add_query_arg('beyondwords_bulk_failed', $failed, $redirect);
215 }
216
217 // Add $nonce query arg into redirect
218 $nonce = wp_create_nonce('beyondwords_bulk_edit');
219 $redirect = add_query_arg('beyondwords_nonce', $nonce, $redirect);
220 }
221
222 return $redirect;
223 }
224
225 /**
226 *
227 */
228 public function adminNotices()
229 {
230 if (! isset($_REQUEST['beyondwords_nonce']) || ! isset($_REQUEST['beyondwords_bulk_processed'])) {
231 return '';
232 }
233
234 if (! wp_verify_nonce(sanitize_text_field($_REQUEST['beyondwords_nonce']), 'beyondwords_bulk_edit')) {
235 wp_nonce_ays('');
236 }
237
238 $processedCount = intval($_REQUEST['beyondwords_bulk_processed']);
239 $failedCount = intval($_REQUEST['beyondwords_bulk_failed'] ?? 0);
240
241 $processedMessage = sprintf(
242 /* translators: %d is replaced with the number of posts processed */
243 _n(
244 'Audio requested for %d post.',
245 'Audio requested for %d posts.',
246 $processedCount,
247 'speechkit'
248 ),
249 $processedCount
250 );
251 ?>
252 <div id="beyondwords-bulk-edit-notice" class="notice notice-info is-dismissible">
253 <p>
254 <?php echo esc_html($processedMessage); ?>
255 </p>
256 <?php
257 if ($failedCount) {
258 $failedMessage = sprintf(
259 /* translators: %d is replaced with the number of posts that were skipped */
260 _n(
261 '%d post failed, check for errors in the BeyondWords column below.',
262 '%d posts failed, check for errors in the BeyondWords column below.',
263 $failedCount,
264 'speechkit'
265 ),
266 $failedCount
267 );
268 ?>
269 <p>
270 <?php echo esc_html($failedMessage); ?>
271 </p>
272 <?php
273 }
274 ?>
275 </div>
276 <?php
277 }
278 }
279