Passed
Pull Request — main (#41)
by
unknown
04:52
created

Application::storeDefaults()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
eloc 5
c 0
b 0
f 0
dl 0
loc 8
ccs 0
cts 6
cp 0
rs 10
cc 3
nc 4
nop 0
crap 12
1
<?php
2
3
namespace GeminiLabs\SiteReviews;
4
5
use GeminiLabs\SiteReviews\Addons\Updater;
6
use GeminiLabs\SiteReviews\Database\DefaultsManager;
7
use GeminiLabs\SiteReviews\Database\OptionManager;
8
use GeminiLabs\SiteReviews\Defaults\PermissionDefaults;
9
use GeminiLabs\SiteReviews\Helpers\Arr;
10
use GeminiLabs\SiteReviews\Modules\Migrate;
11
12
/**
13
 * @property array $addons
14
 * @property string $capability
15
 * @property string $cron_event
16
 * @property array $db_version
17
 * @property array $defaults
18
 * @property string $export_key
19
 * @property string $file
20
 * @property string $id
21
 * @property string $languages
22
 * @property string $name
23
 * @property string $paged_handle
24
 * @property string $paged_query_var
25
 * @property string $post_type
26
 * @property string $prefix
27
 * @property array $session
28
 * @property \GeminiLabs\SiteReviews\Arguments $storage
29
 * @property string $taxonomy
30
 * @property array $updated
31
 * @property string $version
32
 * @property string $testedTo;
33
 */
34
final class Application extends Container
35
{
36
    use Plugin;
37
    use Session;
38
    use Storage;
39
40
    public const DB_VERSION = '1.2';
41
    public const EXPORT_KEY = '_glsr_export';
42
    public const ID = 'site-reviews';
43
    public const PAGED_HANDLE = 'pagination_request';
44
    public const PAGED_QUERY_VAR = 'reviews-page'; // filtered
45
    public const POST_TYPE = 'site-review';
46
    public const PREFIX = 'glsr_';
47
    public const TAXONOMY = 'site-review-category';
48
49
    /**
50
     * @var array
51
     */
52
    protected $addons = [];
53
54
    /**
55
     * @var array
56
     */
57
    protected $defaults;
58
59
    /**
60
     * @var string
61
     */
62
    protected $name;
63
64
    /**
65
     * @var array
66
     */
67
    protected $settings;
68
69
    /**
70
     * @var array
71
     */
72
    protected $updated = [];
73
74
    /**
75
     * @param string $addonId
76
     * @return false|\GeminiLabs\SiteReviews\Addons\Addon
77
     */
78 30
    public function addon($addonId)
79
    {
80 30
        return $this->addons[$addonId] ?? false;
81
    }
82
83
    /**
84
     * @param string $capability
85
     * @param mixed ...$args
86
     * @return bool
87
     */
88
    public function can($capability, ...$args)
89
    {
90
        return $this->make(Role::class)->can($capability, ...$args);
91
    }
92
93
    /**
94
     * @param bool $networkDeactivating
95
     * @return void
96
     * @callback register_deactivation_hook
97
     */
98
    public function deactivate($networkDeactivating)
99
    {
100
        $this->make(Install::class)->deactivate($networkDeactivating);
101
    }
102
103
    /**
104
     * @param string $page
105
     * @param string $tab
106
     * @return string
107
     */
108
    public function getPermission($page = '', $tab = 'index')
109
    {
110
        $fallback = 'edit_posts';
111
        $permissions = $this->make(PermissionDefaults::class)->defaults();
112
        $permission = Arr::get($permissions, $page, $fallback);
113
        if (is_array($permission)) {
114
            $permission = Arr::get($permission, $tab, $fallback);
115
        }
116
        $capability = empty($permission) || !is_string($permission)
117
            ? $fallback
118
            : $permission;
119
        return $this->make(Role::class)->capability($capability);
120
    }
121
122
    /**
123
     * @param string $page
124
     * @param string $tab
125
     * @return bool
126
     */
127
    public function hasPermission($page = '', $tab = 'index')
128
    {
129
        $isAdmin = $this->isAdmin();
130
        return !$isAdmin || $this->can($this->getPermission($page, $tab));
131
    }
132
133
    /**
134
     * @return void
135
     */
136
    public function init()
137
    {
138
        // Ensure the custom database tables exist, this is needed in cases
139
        // where the plugin has been updated instead of activated.
140
        if (empty(get_option(static::PREFIX.'db_version'))) {
141
            $this->make(Install::class)->run();
142
        }
143
        // If this is a new major version, copy over the previous version settings
144
        if (empty(get_option(OptionManager::databaseKey()))) {
145
            update_option(OptionManager::databaseKey(), $this->make(OptionManager::class)->previous());
146
        }
147
        // Force an immediate plugin migration on database version upgrades
148
        if (static::DB_VERSION !== get_option(static::PREFIX.'db_version')) {
149
            $this->make(Migrate::class)->run();
150
        }
151
        $this->make(Hooks::class)->run();
152
    }
153
154
    /**
155
     * @return bool
156
     */
157 27
    public function isAdmin()
158
    {
159 27
        return (is_admin() || is_network_admin()) && !wp_doing_ajax();
160
    }
161
162
    /**
163
     * @param object|string $addon
164
     * @return void
165
     */
166
    public function license($addon)
167
    {
168
        try {
169
            $settings = $this->settings(); // populate the initial settings
170
            $reflection = new \ReflectionClass($addon);
171
            $id = $reflection->getConstant('ID');
172
            $licensed = $reflection->getConstant('LICENSED');
173
            $name = $reflection->getConstant('NAME');
174
            if (true !== $licensed || 2 !== count(array_filter([$id, $name]))) {
175
                return;
176
            }
177
            $license = [
178
                'settings.licenses.'.$id => [
179
                    'class' => 'glsr-license-key regular-text',
180
                    'default' => '',
181
                    'label' => $name,
182
                    'tooltip' => sprintf(_x('Enter the license key here. Your license can be found on the %s page of your Nifty Plugins account.', 'License Keys (admin-text)', 'site-reviews'),
183
                        sprintf('<a href="https://niftyplugins.com/account/license-keys/" target="_blank">%s</a>', _x('License Keys', 'admin-text', 'site-reviews'))
184
                    ),
185
                    'type' => 'text',
186
                ],
187
            ];
188
            $this->settings = array_merge($license, $settings);
189
        } catch (\ReflectionException $e) {
190
            // Fail silently
191
        }
192
    }
193
194
    /**
195
     * @param string|object $addon
196
     * @return void
197
     */
198
    public function register($addon)
199
    {
200
        try {
201
            $reflection = new \ReflectionClass($addon); // make sure that the class exists
202
            $addon = $reflection->getName();
203
            $this->addons[$addon::ID] = $addon;
204
            $this->singleton($addon); // this goes first!
205
            $this->alias($addon::ID, $this->make($addon)); // @todo for some reason we have to link an alias to an instantiated class
206
            $instance = $this->make($addon)->init();
207
            $this->append('addons', $instance->version, $instance->id);
208
        } catch (\ReflectionException $e) {
209
            glsr_log()->error('Attempted to register an invalid addon.');
210
        }
211
    }
212
213
    /**
214
     * The settings config (these are not the saved settings!).
215
     * @return array
216
     */
217 25
    public function settings()
218
    {
219 25
        if (empty($this->settings)) {
220
            $settings = $this->filterArray('addon/settings', $this->config('settings'));
221
            array_walk($settings, function (&$setting) {
222
                isset($setting['default']) ?: $setting['default'] = '';
223
            });
224
            $this->settings = $settings;
225
        }
226 25
        return $this->settings;
227
    }
228
229
    /**
230
     * The setting defaults (these are not the saved settings!).
231
     * @return void
232
     */
233
    public function storeDefaults()
234
    {
235
        if (empty($this->defaults)) {
236
            $defaults = $this->make(DefaultsManager::class)->get();
237
            $this->defaults = $this->filterArray('get/defaults', $defaults);
238
        }
239
        if (empty(get_option(OptionManager::databaseKey()))) {
240
            update_option(OptionManager::databaseKey(), $this->defaults);
241
        }
242
    }
243
244
    /**
245
     * @param object|string $addon
246
     * @param string $file
247
     * @return void
248
     */
249
    public function update($addon, $file)
250
    {
251
        if (!current_user_can('manage_options') && !(defined('DOING_CRON') && DOING_CRON)) {
252
            return;
253
        }
254
        if (!file_exists($file)) {
255
            glsr_log()->error("Add-on does not exist: $file")->debug($addon);
256
        }
257
        try {
258
            $reflection = new \ReflectionClass($addon);
259
            $addonId = $reflection->getConstant('ID');
260
            $licensed = $reflection->getConstant('LICENSED');
261
            $updateUrl = $reflection->getConstant('UPDATE_URL');
262
            if ($addonId && $updateUrl && !array_key_exists($addonId, $this->updated)) {
263
                $this->license($addon);
264
                $license = glsr_get_option('licenses.'.$addonId);
265
                $updater = new Updater($updateUrl, $file, $addonId, compact('license'));
266
                $updater->init();
267
                $this->updated[$addonId] = compact('file', 'licensed', 'updateUrl'); // store details for license verification in settings
268
            }
269
        } catch (\ReflectionException $e) {
270
            // We don't need to log an error here.
271
        }
272
    }
273
}
274