Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
72.31% covered (warning)
72.31%
47 / 65
50.00% covered (danger)
50.00%
2 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
ContentId
71.88% covered (warning)
71.88%
46 / 64
50.00% covered (danger)
50.00%
2 / 4
27.03
0.00% covered (danger)
0.00%
0 / 1
 init
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 element
100.00% covered (success)
100.00%
25 / 25
100.00% covered (success)
100.00%
1 / 1
6
 adminEnqueueScripts
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
20
 save
93.33% covered (success)
93.33%
14 / 15
0.00% covered (danger)
0.00%
0 / 1
6.01
1<?php
2
3declare(strict_types=1);
4
5/**
6 * BeyondWords Component: Content ID
7 *
8 * @package Beyondwords\Wordpress
9 * @author  Stuart McAlpine <stu@beyondwords.io>
10 * @since   6.3.0
11 */
12
13namespace Beyondwords\Wordpress\Component\Post\ContentId;
14
15use Beyondwords\Wordpress\Component\Post\PostMetaUtils;
16use Beyondwords\Wordpress\Component\Settings\SettingsUtils;
17use Beyondwords\Wordpress\Core\CoreUtils;
18
19/**
20 * ContentId
21 *
22 * @since 6.3.0
23 */
24defined('ABSPATH') || exit;
25
26class ContentId
27{
28    /**
29     * Init.
30     *
31     * @since 6.3.0
32     */
33    public static function init()
34    {
35        add_action('admin_enqueue_scripts', [self::class, 'adminEnqueueScripts']);
36
37        add_action('wp_loaded', function (): void {
38            $postTypes = SettingsUtils::getCompatiblePostTypes();
39
40            if (is_array($postTypes)) {
41                foreach ($postTypes as $postType) {
42                    add_action("save_post_{$postType}", [self::class, 'save'], 10);
43                }
44            }
45        });
46    }
47
48    /**
49     * HTML output for this component.
50     *
51     * @since 6.3.0
52     *
53     * @param \WP_Post $post The post object.
54     */
55    public static function element($post)
56    {
57        $contentId = PostMetaUtils::getContentId($post->ID) ?: '';
58        $projectId = PostMetaUtils::getProjectId($post->ID) ?: get_option('beyondwords_project_id', '');
59        $postType = get_post_type($post);
60        $postTypeObj = $postType ? get_post_type_object($postType) : null;
61        $restBase = ($postTypeObj && ! empty($postTypeObj->rest_base)) ? $postTypeObj->rest_base : $postType;
62
63        wp_nonce_field('beyondwords_content_id', 'beyondwords_content_id_nonce');
64        ?>
65        <div id="beyondwords-metabox-content-id" style="margin: 8px 0 13px;">
66            <p class="post-attributes-label-wrapper">
67                <label for="beyondwords_content_id" class="post-attributes-label">
68                    <?php esc_html_e('Content ID', 'speechkit'); ?>
69                </label>
70            </p>
71            <div style="display: flex; gap: 4px; align-items: center;">
72                <input
73                    type="text"
74                    id="beyondwords_content_id"
75                    name="beyondwords_content_id"
76                    value="<?php echo esc_attr($contentId); ?>"
77                    style="flex: 1;"
78                />
79                <button
80                    type="button"
81                    id="beyondwords__content-id--fetch"
82                    class="button"
83                    data-project-id="<?php echo esc_attr($projectId); ?>"
84                    data-rest-base="<?php echo esc_attr($restBase); ?>"
85                >
86                    <?php esc_html_e('Fetch', 'speechkit'); ?>
87                </button>
88            </div>
89        </div>
90        <?php
91    }
92
93    /**
94     * Register the component scripts.
95     *
96     * @since 6.3.0
97     *
98     * @param string $hook Page hook
99     */
100    public static function adminEnqueueScripts($hook)
101    {
102        if (! CoreUtils::isGutenbergPage() && ($hook === 'post.php' || $hook === 'post-new.php')) {
103            wp_register_script(
104                'beyondwords-metabox--content-id',
105                BEYONDWORDS__PLUGIN_URI . 'src/Component/Post/ContentId/classic-metabox.js',
106                ['wp-i18n'],
107                BEYONDWORDS__PLUGIN_VERSION,
108                true
109            );
110
111            wp_localize_script(
112                'beyondwords-metabox--content-id',
113                'beyondwordsData',
114                [
115                    'nonce' => wp_create_nonce('wp_rest'),
116                    'root' => esc_url_raw(rest_url()),
117                ]
118            );
119
120            wp_enqueue_script('beyondwords-metabox--content-id');
121        }
122    }
123
124    /**
125     * Save the meta when the post is saved.
126     *
127     * @since 6.3.0
128     *
129     * @param int $postId The ID of the post being saved.
130     */
131    public static function save($postId)
132    {
133        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
134            return $postId;
135        }
136
137        if (
138            ! isset($_POST['beyondwords_content_id_nonce']) ||
139            ! wp_verify_nonce(
140                sanitize_key($_POST['beyondwords_content_id_nonce']),
141                'beyondwords_content_id'
142            )
143        ) {
144            return $postId;
145        }
146
147        if (isset($_POST['beyondwords_content_id'])) {
148            update_post_meta(
149                $postId,
150                'beyondwords_content_id',
151                sanitize_text_field(wp_unslash($_POST['beyondwords_content_id']))
152            );
153        }
154
155        return $postId;
156    }
157}