PluginProbe
BeyondWords – AI audio for publishers / 4.7.0
BeyondWords – AI audio for publishers v4.7.0
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 / Post / Panel / Inspect / Inspect.php

Inspect.php in BeyondWords – AI audio for publishers 4.7.0, at src/Component/Post/Panel/Inspect/Inspect.php

325 lines 10.3 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 Post Inspect Panel.
7 *
8 * @package Beyondwords\Wordpress
9 * @author Stuart McAlpine <stu@beyondwords.io>
10 * @since 3.0.0
11 */
12
13 namespace Beyondwords\Wordpress\Component\Post\Panel\Inspect;
14
15 use Beyondwords\Wordpress\Component\Post\PostMetaUtils;
16 use Beyondwords\Wordpress\Component\Settings\SettingsUtils;
17
18 /**
19 * Inspect setup
20 *
21 * @since 3.0.0
22 */
23 class Inspect
24 {
25 /**
26 * Constructor
27 */
28 public function init()
29 {
30 add_action('admin_enqueue_scripts', array($this, 'adminEnqueueScripts'));
31 add_action("add_meta_boxes", array($this, 'addMetaBox'));
32
33 add_filter('default_hidden_meta_boxes', array($this, 'hideMetaBox'));
34
35 add_action('wp_loaded', function () {
36 $postTypes = SettingsUtils::getCompatiblePostTypes();
37
38 if (is_array($postTypes)) {
39 foreach ($postTypes as $postType) {
40 add_action("save_post_{$postType}", array($this, 'save'), 5);
41 }
42 }
43 });
44 }
45
46 /**
47 * Enqueue JS for Inspect feature.
48 */
49 public function adminEnqueueScripts($hook)
50 {
51 // Only enqueue for Post screens
52 if ($hook === 'post.php' || $hook === 'post-new.php') {
53 // Clipboard.js dependency
54 wp_enqueue_script(
55 'clipboard',
56 'https://cdn.jsdelivr.net/npm/clipboard@2.0.10/dist/clipboard.min.js',
57 array('jquery'),
58 '2.0.10',
59 true
60 );
61
62 // Our script for the "Copy" button
63 wp_enqueue_script(
64 'beyondwords-inspect',
65 BEYONDWORDS__PLUGIN_URI . 'src/Component/Post/Panel/Inspect/js/inspect.js',
66 array('jquery', 'clipboard'),
67 BEYONDWORDS__PLUGIN_VERSION,
68 true
69 );
70 }
71 }
72
73 /**
74 * Hides the metabox by default.
75 *
76 * @param string[] $hidden An array of IDs of meta boxes hidden by default.
77 */
78 public function hideMetaBox($hidden)
79 {
80 $hidden[] = 'beyondwords__inspect';
81 return $hidden;
82 }
83
84 /**
85 * Adds the meta box container for the Classic Editor.
86 *
87 * The Block Editor UI is handled using JavaScript.
88 *
89 * @param string $postType
90 */
91 public function addMetaBox($postType)
92 {
93 $postTypes = SettingsUtils::getCompatiblePostTypes();
94
95 if (is_array($postTypes) && ! in_array($postType, $postTypes)) {
96 return;
97 }
98
99 add_meta_box(
100 'beyondwords__inspect',
101 __('BeyondWords', 'speechkit') . ': ' . __('Inspect', 'speechkit'),
102 array($this, 'renderMetaBoxContent'),
103 $postType,
104 'advanced',
105 'low',
106 [
107 '__back_compat_meta_box' => true,
108 ]
109 );
110 }
111
112 /**
113 * Render Meta Box content.
114 *
115 * @param WP_Post $post The post object.
116 */
117 public function renderMetaBoxContent($post)
118 {
119 $metadata = PostMetaUtils::getAllBeyondwordsMetadata($post->ID);
120
121 $this->postMetaTable($metadata);
122 ?>
123 <button
124 type="button"
125 id="beyondwords__inspect--copy"
126 class="button button-large"
127 style="margin: 10px 0 0;"
128 data-clipboard-text="<?php echo esc_attr($this->getClipboardText($metadata)); ?>"
129 >
130 <?php esc_html_e('Copy', 'speechkit'); ?>
131 <span
132 id="beyondwords__inspect--copy-confirm"
133 style="display: none; margin: 5px 0 0;"
134 class="dashicons dashicons-yes"
135 ></span>
136 </button>
137
138 <button
139 type="button"
140 id="beyondwords__inspect--remove"
141 class="button button-large button-link-delete"
142 style="margin: 10px 0 0; float: right;"
143 >
144 <?php esc_html_e('Remove', 'speechkit'); ?>
145 <span
146 id="beyondwords__inspect--remove"
147 style="display: none; margin: 5px 0 0;"
148 class="dashicons dashicons-yes"
149 ></span>
150 </button>
151
152 <?php
153 }
154
155 /**
156 * Render Meta Box table.
157 *
158 * @param array $metadata The metadata returned by has_meta.
159 *
160 * @since v3.0.0
161 * @since v3.9.0 Change $postMetaKeys param to $metadata, to support meta_ids.
162 */
163 public function postMetaTable($metadata)
164 {
165 if (! is_array($metadata)) {
166 return;
167 }
168 ?>
169 <div id="postcustomstuff">
170 <table id="inspect-table">
171 <thead>
172 <tr>
173 <th class="left"><?php esc_html_e('Name', 'speechkkit'); ?></th>
174 <th><?php esc_html_e('Value', 'speechkit'); ?></th>
175 </tr>
176 </thead>
177 <tbody id="inspect-table-list">
178 <?php
179 foreach ($metadata as $item) :
180 if (
181 ! is_array($item) ||
182 ! array_key_exists('meta_id', $item) ||
183 ! array_key_exists('meta_key', $item) ||
184 ! array_key_exists('meta_value', $item)
185 ) {
186 continue;
187 }
188
189 $metaId = $item['meta_id'] ? $item['meta_id'] : $item['meta_key'];
190 $metaKey = $item['meta_key'];
191 $metaValue = $this->formatPostMetaValue($item['meta_value']);
192 ?>
193 <tr id="beyondwords-inspect-<?php echo esc_attr($metaId); ?>" class="alternate">
194 <td class="left">
195 <label
196 class="screen-reader-text"
197 for="beyondwords-inspect-<?php echo esc_attr($metaId); ?>-key"
198 >
199 <?php esc_html_e('Key', 'speechkit'); ?>
200 </label>
201 <input
202 id="beyondwords-inspect-<?php echo esc_attr($metaId); ?>-key"
203 type="text"
204 size="20"
205 value="<?php echo esc_attr($metaKey); ?>"
206 readonly
207 />
208 </td>
209 <td>
210 <label
211 class="screen-reader-text"
212 for="beyondwords-inspect-<?php echo esc_attr($metaId); ?>-value"
213 >
214 <?php esc_html_e('Value', 'speechkit'); ?>
215 </label>
216 <textarea
217 id="beyondwords-inspect-<?php echo esc_attr($metaId); ?>-value"
218 rows="2"
219 cols="30"
220 data-beyondwords-metavalue="true"
221 readonly
222 ><?php echo esc_html($metaValue); ?></textarea>
223 </td>
224 </tr>
225 <?php
226 endforeach;
227
228 wp_nonce_field('beyondwords_delete_content', 'beyondwords_delete_content_nonce');
229 ?>
230 <input
231 type="hidden"
232 id="beyondwords_delete_content"
233 name="beyondwords_delete_content"
234 value="1"
235 disabled
236 />
237 </tbody>
238 </table>
239 </div>
240 <?php
241 }
242
243 /**
244 * Format post meta value.
245 *
246 * @param mixed $value The metadata value.
247 *
248 * @since v3.9.0
249 */
250 public function formatPostMetaValue($value)
251 {
252 if (is_numeric($value) || is_string($value)) {
253 return $value;
254 }
255
256 return wp_json_encode($value);
257 }
258
259 /**
260 * Get Clipboard Text.
261 *
262 * @param array $metadata Post metadata.
263 *
264 * @since 3.0.0
265 * @since 3.9.0 Output all post meta data from the earlier has_meta() call instead of
266 * the previous multiple get_post_meta() calls.
267 *
268 * @return string
269 */
270 public function getClipboardText($metadata)
271 {
272 $lines = [];
273
274 foreach ($metadata as $m) {
275 $lines[] = $m['meta_key'] . "\r\n" . $this->formatPostMetaValue($m['meta_value']);
276 }
277
278 $lines[] = "=== " . __('Copied using the Classic Editor', 'speechkit') . " ===\r\n\r\n";
279
280 return implode("\r\n\r\n", $lines);
281 }
282
283 /**
284 * Runs when a post is saved.
285 *
286 * If "Remove" has been pressed in the Classic Editor we set the `beyondwords_delete_content`
287 * custom field. At a later priority we check for this custom field and if it's set
288 * we make a DELETE request to the BeyondWords REST API, keeping WordPress and the
289 * REST API in sync.
290 *
291 * If we don't perform a DELETE REST API request to keep them in sync then the
292 * API will respond with a "source_id is already in use" error message whenver we
293 * attempt to regenerate audio for a post that has audio content "Removed" in
294 * WordPress but still exists in the REST API.
295 *
296 * @since 4.0.7
297 *
298 * @param int $postId The ID of the post being saved.
299 */
300 public function save($postId)
301 {
302 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
303 return $postId;
304 }
305
306 // "save_post" can be triggered at other times, so verify this request came from the our component
307 if (
308 ! isset($_POST['beyondwords_delete_content_nonce']) ||
309 ! wp_verify_nonce(
310 sanitize_text_field($_POST['beyondwords_delete_content_nonce']),
311 'beyondwords_delete_content'
312 )
313 ) {
314 return $postId;
315 }
316
317 if (isset($_POST['beyondwords_delete_content'])) {
318 // Set the flag - the DELETE request is performed at a later priority
319 update_post_meta($postId, 'beyondwords_delete_content', '1');
320 }
321
322 return $postId;
323 }
324 }
325