Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
76.19% |
80 / 105 |
|
55.56% |
5 / 9 |
CRAP | |
0.00% |
0 / 1 |
| Metabox | |
76.19% |
80 / 105 |
|
55.56% |
5 / 9 |
26.95 | |
0.00% |
0 / 1 |
| init | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
| adminEnqueueScripts | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
3 | |||
| addMetaBox | |
92.86% |
13 / 14 |
|
0.00% |
0 / 1 |
2.00 | |||
| renderMetaBoxContent | |
94.44% |
17 / 18 |
|
0.00% |
0 / 1 |
4.00 | |||
| pendingReviewNotice | |
0.00% |
0 / 20 |
|
0.00% |
0 / 1 |
6 | |||
| playerEmbed | |
81.25% |
13 / 16 |
|
0.00% |
0 / 1 |
5.16 | |||
| errors | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
2 | |||
| help | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
1 | |||
| regenerateInstructions | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
1 | |||
| 1 | <?php |
| 2 | |
| 3 | declare(strict_types=1); |
| 4 | |
| 5 | /** |
| 6 | * BeyondWords Post Metabox. |
| 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\Metabox; |
| 14 | |
| 15 | use Beyondwords\Wordpress\Component\Post\GenerateAudio\GenerateAudio; |
| 16 | use Beyondwords\Wordpress\Component\Post\DisplayPlayer\DisplayPlayer; |
| 17 | use Beyondwords\Wordpress\Component\Post\PostMetaUtils; |
| 18 | use Beyondwords\Wordpress\Component\Post\SelectVoice\SelectVoice; |
| 19 | use Beyondwords\Wordpress\Component\Post\PlayerContent\PlayerContent; |
| 20 | use Beyondwords\Wordpress\Component\Post\PlayerStyle\PlayerStyle; |
| 21 | use Beyondwords\Wordpress\Component\Settings\SettingsUtils; |
| 22 | use Beyondwords\Wordpress\Core\Environment; |
| 23 | |
| 24 | /** |
| 25 | * PostMetabox |
| 26 | * |
| 27 | * @since 3.0.0 |
| 28 | */ |
| 29 | class Metabox |
| 30 | { |
| 31 | /** |
| 32 | * Init. |
| 33 | * |
| 34 | * @since 4.0.0 |
| 35 | * @since 6.0.0 Make static. |
| 36 | */ |
| 37 | public static function init() |
| 38 | { |
| 39 | add_action('admin_enqueue_scripts', [self::class, 'adminEnqueueScripts']); |
| 40 | add_action("add_meta_boxes", [self::class, 'addMetaBox']); |
| 41 | } |
| 42 | |
| 43 | /** |
| 44 | * Enque JS for Bulk Edit feature. |
| 45 | * |
| 46 | * @since 6.0.0 Make static. |
| 47 | */ |
| 48 | public static function adminEnqueueScripts($hook) |
| 49 | { |
| 50 | // Only enqueue for Post screens |
| 51 | if ($hook === 'post.php' || $hook === 'post-new.php') { |
| 52 | // Register the Classic Editor "Metabox" CSS |
| 53 | wp_enqueue_style( |
| 54 | 'beyondwords-Metabox', |
| 55 | BEYONDWORDS__PLUGIN_URI . 'src/Component/Post/Metabox/Metabox.css', |
| 56 | false, |
| 57 | BEYONDWORDS__PLUGIN_VERSION |
| 58 | ); |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | /** |
| 63 | * Adds the meta box container. |
| 64 | * |
| 65 | * @since 6.0.0 Make static. |
| 66 | * |
| 67 | * @param string $postType |
| 68 | */ |
| 69 | public static function addMetaBox($postType) |
| 70 | { |
| 71 | $postTypes = SettingsUtils::getCompatiblePostTypes(); |
| 72 | |
| 73 | if (! in_array($postType, $postTypes)) { |
| 74 | return; |
| 75 | } |
| 76 | |
| 77 | add_meta_box( |
| 78 | 'beyondwords', |
| 79 | __('BeyondWords', 'speechkit'), |
| 80 | [self::class, 'renderMetaBoxContent'], |
| 81 | $postType, |
| 82 | 'side', |
| 83 | 'default', |
| 84 | [ |
| 85 | '__back_compat_meta_box' => true, |
| 86 | ] |
| 87 | ); |
| 88 | } |
| 89 | |
| 90 | /** |
| 91 | * Render Meta Box content. |
| 92 | * |
| 93 | * @param int|WP_Post $post The WordPress post ID, or post object. |
| 94 | * |
| 95 | * @since 3.0.0 |
| 96 | * @since 3.7.0 Show "Pending review" notice for posts with status of "pending" |
| 97 | * @since 4.0.0 Content ID is no longer an int |
| 98 | * @since 4.1.0 Add "Player style" and update component display conditions |
| 99 | * @since 6.0.0 Make static and add Magic Embed support. |
| 100 | */ |
| 101 | public static function renderMetaBoxContent($post) |
| 102 | { |
| 103 | $post = get_post($post); |
| 104 | |
| 105 | if (!($post instanceof \WP_Post)) { |
| 106 | return; |
| 107 | } |
| 108 | |
| 109 | // Show errors for posts with/without audio |
| 110 | self::errors($post); |
| 111 | |
| 112 | $hasContent = PostMetaUtils::hasContent($post->ID); |
| 113 | |
| 114 | if ($hasContent) { |
| 115 | // Enable these components for posts with audio |
| 116 | if (get_post_status($post) === 'pending') { |
| 117 | self::pendingReviewNotice($post); |
| 118 | } else { |
| 119 | self::playerEmbed($post); |
| 120 | } |
| 121 | echo '<hr />'; |
| 122 | (new DisplayPlayer())::element($post); |
| 123 | } else { |
| 124 | self::errors($post); |
| 125 | // Enable these components for posts without audio |
| 126 | (new GenerateAudio())::element($post); |
| 127 | } |
| 128 | |
| 129 | // Enable these components for posts with/without audio |
| 130 | (new SelectVoice())::element($post); |
| 131 | (new PlayerStyle())::element($post); |
| 132 | (new PlayerContent())::element($post); |
| 133 | |
| 134 | echo '<hr />'; |
| 135 | self::help(); |
| 136 | } |
| 137 | |
| 138 | |
| 139 | /** |
| 140 | * The "Pending review" message, shown instead of the audio player |
| 141 | * if the post status in WordPress is "pending". |
| 142 | * |
| 143 | * This message is displayed instead of the player because the player |
| 144 | * cannot be rendered for audio which has been created |
| 145 | * with { published: false }. |
| 146 | * |
| 147 | * @since 3.7.0 |
| 148 | * @since 6.0.0 Make static. |
| 149 | * |
| 150 | * @var int|\WP_Post $post The WordPress post ID, or post object. |
| 151 | */ |
| 152 | public static function pendingReviewNotice($post) |
| 153 | { |
| 154 | $post = get_post($post); |
| 155 | |
| 156 | if (!($post instanceof \WP_Post)) { |
| 157 | return; |
| 158 | } |
| 159 | |
| 160 | $projectUrl = sprintf( |
| 161 | '%s/dashboard/project/%d/content', |
| 162 | Environment::getDashboardUrl(), |
| 163 | PostMetaUtils::getProjectId($post->ID) |
| 164 | ); |
| 165 | |
| 166 | ?> |
| 167 | <div id="beyondwords-pending-review-message"> |
| 168 | <?php |
| 169 | printf( |
| 170 | /* translators: %s is replaced with the link to the BeyondWords dashboard */ |
| 171 | esc_html__('Listen to content saved as “Pending” in the %s.', 'speechkit'), |
| 172 | sprintf( |
| 173 | '<a href="%s" target="_blank" rel="nofollow">%s</a>', |
| 174 | esc_url($projectUrl), |
| 175 | esc_html__('BeyondWords dashboard', 'speechkit') |
| 176 | ) |
| 177 | ); |
| 178 | ?> |
| 179 | </div> |
| 180 | <?php |
| 181 | } |
| 182 | |
| 183 | /** |
| 184 | * Embed a player for a WordPress post. |
| 185 | * |
| 186 | * @param int|WP_Post (Optional) Post ID or WP_Post object. Default is global $post. |
| 187 | * |
| 188 | * @since 3.x Introduced |
| 189 | * @since 4.0.1 Admin player init is now all in this one function. |
| 190 | * @since 6.0.0 Make static and add Magic Embed support. |
| 191 | */ |
| 192 | public static function playerEmbed($post = null) |
| 193 | { |
| 194 | $post = get_post($post); |
| 195 | |
| 196 | if (!($post instanceof \WP_Post)) { |
| 197 | return; |
| 198 | } |
| 199 | |
| 200 | $projectId = PostMetaUtils::getProjectId($post->ID); |
| 201 | $hasContent = PostMetaUtils::hasContent($post->ID); |
| 202 | |
| 203 | if (! $projectId || ! $hasContent) { |
| 204 | return; |
| 205 | } |
| 206 | |
| 207 | $contentId = PostMetaUtils::getContentId($post->ID); |
| 208 | $previewToken = PostMetaUtils::getPreviewToken($post->ID); |
| 209 | |
| 210 | // phpcs:disable WordPress.WP.EnqueuedResources.NonEnqueuedScript |
| 211 | ?> |
| 212 | <script async defer |
| 213 | src='<?php echo esc_url(Environment::getJsSdkUrl()); ?>' |
| 214 | onload='const player = new BeyondWords.Player({ |
| 215 | target: this, |
| 216 | projectId: <?php echo esc_attr($projectId); ?>, |
| 217 | <?php if (! empty($contentId)) : ?> |
| 218 | contentId: "<?php echo esc_attr($contentId); ?>", |
| 219 | <?php else : ?> |
| 220 | sourceId: "<?php echo esc_attr($post->ID); ?>", |
| 221 | <?php endif; ?> |
| 222 | previewToken: "<?php echo esc_attr($previewToken); ?>", |
| 223 | adverts: [], |
| 224 | analyticsConsent: "none", |
| 225 | introsOutros: [], |
| 226 | playerStyle: "small", |
| 227 | widgetStyle: "none", |
| 228 | });' |
| 229 | > |
| 230 | </script> |
| 231 | <?php |
| 232 | // phpcs:enable WordPress.WP.EnqueuedResources.NonEnqueuedScript |
| 233 | } |
| 234 | |
| 235 | /** |
| 236 | * Display errors for the post. |
| 237 | * |
| 238 | * @since 6.0.0 Make static. |
| 239 | */ |
| 240 | public static function errors($post) |
| 241 | { |
| 242 | $error = PostMetaUtils::getErrorMessage($post->ID); |
| 243 | |
| 244 | if ($error) : |
| 245 | ?> |
| 246 | <div id="beyondwords-metabox-errors"> |
| 247 | <div class="beyondwords-error"> |
| 248 | <p> |
| 249 | <?php echo esc_html($error); ?> |
| 250 | </p> |
| 251 | </div> |
| 252 | <?php self::regenerateInstructions(); ?> |
| 253 | </div> |
| 254 | <?php |
| 255 | endif; |
| 256 | } |
| 257 | |
| 258 | /** |
| 259 | * Display help text for the metabox. |
| 260 | * |
| 261 | * @since 6.0.0 Make static. |
| 262 | */ |
| 263 | public static function help() |
| 264 | { |
| 265 | ?> |
| 266 | <p id="beyondwords-metabox-help"> |
| 267 | <?php |
| 268 | printf( |
| 269 | /* translators: %s is replaced with the link to the support email address */ |
| 270 | esc_html__('Need help? Email our support team on %s', 'speechkit'), |
| 271 | sprintf('<a href="%s">%s</a>', 'mailto:support@beyondwords.io', 'support@beyondwords.io') |
| 272 | ); |
| 273 | ?> |
| 274 | </p> |
| 275 | <?php |
| 276 | } |
| 277 | |
| 278 | /** |
| 279 | * Display instructions for regenerating audio. |
| 280 | * |
| 281 | * @since 6.0.0 Make static. |
| 282 | */ |
| 283 | public static function regenerateInstructions() |
| 284 | { |
| 285 | ?> |
| 286 | <!-- Update/regenerate --> |
| 287 | <p> |
| 288 | <?php |
| 289 | esc_html_e( |
| 290 | 'To create audio, resolve the error above then select ‘Update’ with ‘Generate audio’ checked.', // phpcs:ignore Generic.Files.LineLength.TooLong |
| 291 | 'speechkit' |
| 292 | ); |
| 293 | ?> |
| 294 | </p> |
| 295 | <?php |
| 296 | } |
| 297 | } |