Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
92.16% covered (success)
92.16%
47 / 51
50.00% covered (danger)
50.00%
2 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
Updater
92.16% covered (success)
92.16%
47 / 51
50.00% covered (danger)
50.00%
2 / 4
26.33
0.00% covered (danger)
0.00%
0 / 1
 run
66.67% covered (warning)
66.67%
6 / 9
0.00% covered (danger)
0.00%
0 / 1
5.93
 migrateSettings
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
7
 constructPreselectSetting
93.75% covered (success)
93.75%
15 / 16
0.00% covered (danger)
0.00%
0 / 1
9.02
 renamePluginSettings
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
5
1<?php
2
3declare(strict_types=1);
4
5/**
6 * BeyondWords updater.
7 *
8 * @package Beyondwords\Wordpress
9 * @author  Stuart McAlpine <stu@beyondwords.io>
10 * @since   3.0.0
11 */
12
13namespace Beyondwords\Wordpress\Core;
14
15/**
16 * BeyondWords updater.
17 *
18 * @since 3.7.0
19 */
20defined('ABSPATH') || exit;
21
22class Updater
23{
24    /**
25     * Run
26     *
27     * @since 4.0.0
28     * @since 5.4.0 Add beyondwords_date_activated option.
29     * @since 6.0.0 Make static.
30     */
31    public static function run()
32    {
33        $version = get_option('beyondwords_version', '1.0.0');
34
35        if (version_compare($version, '5.0.0', '<') && get_option('beyondwords_api_key')) {
36            wp_cache_set('beyondwords_sync_to_wordpress', ['all'], 'beyondwords', 60);
37        }
38
39        if (version_compare($version, '3.0.0', '<')) {
40            self::migrateSettings();
41        }
42
43        if (version_compare($version, '3.7.0', '<')) {
44            self::renamePluginSettings();
45        }
46
47        // Record the date activated so we can track how long users have been using the plugin.
48        add_option('beyondwords_date_activated', gmdate(\DateTime::ATOM), '', false);
49
50        // Always update the plugin version, to handle e.g. FTP plugin updates
51        update_option('beyondwords_version', BEYONDWORDS__PLUGIN_VERSION);
52    }
53
54    /**
55     * Migrate settings.
56     *
57     * In v3.0.0 the locations for plugin settings changed. This method migrates settings from the
58     * old location to the new. e.g. from speechkit_settings.speechkit_api_key to beyondwords_api_key.
59     *
60     * @since 3.0.0
61     * @since 3.5.0 Refactored, adding self::constructPreselectSetting().
62     * @since 6.0.0 Make static.
63     *
64     * @return void
65     */
66    public static function migrateSettings()
67    {
68        $oldSettings = get_option('speechkit_settings', []);
69
70        if (! is_array($oldSettings) || empty($oldSettings)) {
71            return;
72        }
73
74        $settingsMap = [
75            'speechkit_api_key'       => 'speechkit_api_key',
76            'speechkit_id'            => 'speechkit_project_id',
77            'speechkit_merge_excerpt' => 'speechkit_prepend_excerpt',
78        ];
79
80        // Simple mapping of 'old key' :: 'new key'
81        foreach ($settingsMap as $oldKey => $newKey) {
82            if (array_key_exists($oldKey, $oldSettings) && ! get_option($newKey)) {
83                add_option($newKey, $oldSettings[$oldKey]);
84            }
85        }
86
87        if (get_option('speechkit_preselect') === false) {
88            $preselectSetting = self::constructPreselectSetting();
89
90            add_option('speechkit_preselect', $preselectSetting);
91        }
92    }
93
94    /**
95     * Construct 'beyondwords_preselect' setting.
96     *
97     * The v3 `beyondwords_preselect` setting is constructed from the data contained in the v2
98     * `speechkit_select_post_types` and `speechkit_selected_categories` fields.
99     *
100     * @since 3.5.0
101     * @since 6.0.0 Make static.
102     *
103     * @return array `beyondwords_preselect` setting.
104     */
105    public static function constructPreselectSetting()
106    {
107        $oldSettings = get_option('speechkit_settings', []);
108
109        if (! is_array($oldSettings) || empty($oldSettings)) {
110            return false;
111        }
112
113        $preselect = [];
114
115        // Build the top level of beyondwords_preselect, for post types
116        if (
117            array_key_exists('speechkit_select_post_types', $oldSettings) &&
118            ! empty($oldSettings['speechkit_select_post_types'])
119        ) {
120            $preselect = array_fill_keys($oldSettings['speechkit_select_post_types'], '1');
121        }
122
123        // Build the taxonomy level of beyondwords_preselect
124        if (
125            array_key_exists('speechkit_selected_categories', $oldSettings) &&
126            ! empty($oldSettings['speechkit_selected_categories'])
127        ) {
128            // Categories can be assigned to multiple post types
129            $taxonomy = get_taxonomy('category');
130
131            if (is_array($taxonomy->object_type)) {
132                foreach ($taxonomy->object_type as $postType) {
133                    // Post type: e.g. "post"
134                    $preselect[$postType] = [
135                        // Taxonomy: "category"
136                        'category' => $oldSettings['speechkit_selected_categories'],
137                    ];
138                }
139            }
140        }
141
142        return $preselect;
143    }
144
145    /**
146     * Rename plugin settings.
147     *
148     * In v3.7.0 the plugin settings change from `speechkit_*` to `beyondwords_*`.
149     *
150     * For now, we will leave `speechkit_*` settings in the db, to support plugin downgrades.
151     *
152     * @since 3.7.0
153     * @since 6.0.0 Make static.
154     *
155     * @return void
156     */
157    public static function renamePluginSettings()
158    {
159        $apiKey         = get_option('speechkit_api_key');
160        $projectId      = get_option('speechkit_project_id');
161        $prependExcerpt = get_option('speechkit_prepend_excerpt');
162        $preselect      = get_option('speechkit_preselect');
163
164        if ($apiKey) {
165            update_option('beyondwords_api_key', $apiKey, false);
166        }
167
168        if ($projectId) {
169            update_option('beyondwords_project_id', $projectId, false);
170        }
171
172        if ($prependExcerpt) {
173            update_option('beyondwords_prepend_excerpt', $prependExcerpt, false);
174        }
175
176        if ($preselect) {
177            update_option('beyondwords_preselect', $preselect, false);
178        }
179    }
180}