Test Failed
Push — develop ( 444e5e...4db3e8 )
by Paul
07:08
created

MenuController::renderPremiumMenuCallback()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 26
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
eloc 20
c 0
b 0
f 0
dl 0
loc 26
ccs 0
cts 19
cp 0
rs 9.6
cc 4
nc 4
nop 0
crap 20
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Controllers;
4
5
use GeminiLabs\SiteReviews\Api;
6
use GeminiLabs\SiteReviews\Database\Cache;
7
use GeminiLabs\SiteReviews\Database\Tables;
8
use GeminiLabs\SiteReviews\Defaults\AddonDefaults;
9
use GeminiLabs\SiteReviews\Defaults\FeatureDefaults;
10
use GeminiLabs\SiteReviews\Helper;
11
use GeminiLabs\SiteReviews\Helpers\Arr;
12
use GeminiLabs\SiteReviews\Helpers\Str;
13
use GeminiLabs\SiteReviews\License;
14
use GeminiLabs\SiteReviews\Modules\Console;
15
use GeminiLabs\SiteReviews\Modules\Html\Builder;
16
use GeminiLabs\SiteReviews\Modules\Html\SettingForm;
17
use GeminiLabs\SiteReviews\Modules\Notice;
18
19
class MenuController extends AbstractController
20
{
21
    /**
22
     * @action admin_menu
23
     */
24
    public function registerMenuCount(): void
25
    {
26
        global $menu, $typenow;
27
        foreach ($menu as $key => $value) {
28
            if (!isset($value[2]) || $value[2] != 'edit.php?post_type='.glsr()->post_type) {
29
                continue;
30
            }
31
            $postCount = wp_count_posts(glsr()->post_type);
32
            $pendingCount = glsr(Builder::class)->span(number_format_i18n($postCount->pending), [
33
                'class' => 'unapproved-count',
34
            ]);
35
            $awaitingModeration = glsr(Builder::class)->span($pendingCount, [
36
                'class' => "awaiting-mod count-{$postCount->pending}",
37
            ]);
38
            $menu[$key][0] .= " {$awaitingModeration}";
39
            if (glsr()->post_type === $typenow) {
40
                $menu[$key][4] .= ' current';
41
            }
42
            break;
43
        }
44
    }
45
46
    /**
47
     * @action admin_menu
48
     */
49
    public function registerSubMenus(): void
50
    {
51
        $pages = $this->parseWithFilter('submenu/pages', [
52
            'settings' => _x('Settings', 'admin-text', 'site-reviews'),
53
            'tools' => _x('Tools', 'admin-text', 'site-reviews'),
54
            'documentation' => _x('Help & Support', 'admin-text', 'site-reviews'),
55
            'premium' => _x('Upgrade to Premium', 'admin-text', 'site-reviews'),
56
        ]);
57
        foreach ($pages as $slug => $title) {
58
            $method = Helper::buildMethodName('render', $slug, 'menu', 'callback');
59
            if (!method_exists($this, $method)) {
60
                continue;
61
            }
62
            $callback = glsr()->filter('addon/submenu/callback', [$this, $method], $slug);
63
            if (!is_callable($callback)) {
64
                continue;
65
            }
66
            add_submenu_page('edit.php?post_type='.glsr()->post_type, $title, $title, glsr()->getPermission($slug), Str::dashCase(glsr()->prefix).$slug, $callback);
67
        }
68
    }
69
70
    /**
71
     * We don't use admin_menu because it breaks the privilege check which runs
72
     * after the admin_menu hook is triggered in wp-admin/includes/menu.php.
73
     *
74 8
     * @action admin_init
75
     */
76 8
    public function removeSubMenu(): void
77
    {
78
        if (!function_exists('remove_submenu_page')) {
79 8
            require_once ABSPATH.'wp-admin/includes/plugin.php';
80 8
        }
81 8
        remove_submenu_page(
82 8
            'edit.php?post_type='.glsr()->post_type,
83
            'post-new.php?post_type='.glsr()->post_type
84
        );
85
    }
86
87
    /**
88
     * @see registerSubMenus
89
     */
90
    public function renderDocumentationMenuCallback(): void
91
    {
92
        $tabs = $this->parseWithFilter('documentation/tabs', [
93
            'support' => _x('Support', 'admin-text', 'site-reviews'),
94
            'faq' => _x('FAQ', 'admin-text', 'site-reviews'),
95
            'shortcodes' => _x('Shortcodes', 'admin-text', 'site-reviews'),
96
            'hooks' => _x('Hooks', 'admin-text', 'site-reviews'),
97
            'functions' => _x('Functions', 'admin-text', 'site-reviews'),
98
            'api' => _x('API', 'admin-text', 'site-reviews'),
99
            'addons' => _x('Addons', 'admin-text', 'site-reviews'),
100
        ]);
101
        $addons = glsr()->filterArray('addon/documentation', []);
102
        uksort($addons, fn ($a, $b) => strnatcasecmp(glsr($a)->name, glsr($b)->name));
103
        if (empty($addons)) {
104
            unset($tabs['addons']);
105
        }
106
        $this->renderPage('documentation', [
107
            'addons' => $addons,
108
            'tabs' => $tabs,
109
        ]);
110
    }
111
112
    /**
113
     * @see registerSubMenus
114
     */
115
    public function renderPremiumMenuCallback(): void
116
    {
117
        $addons = [];
118
        $features = [];
119
        $isPremium = glsr(License::class)->isPremium();
120
        if ($isPremium) {
121
            $data = glsr(Api::class)->get('addons')->data();
122
            foreach ($data as $values) {
123
                $context = glsr(AddonDefaults::class)->restrict($values);
124
                $addons[] = array_merge($context, compact('context'));
125
            }
126
        } else {
127
            $data = glsr(Api::class)->get('features')->data();
128
            foreach ($data as $values) {
129
                $features[] = glsr(FeatureDefaults::class)->restrict($values);
130
            }
131
            array_multisort(
132
                array_column($features, 'premium'), SORT_DESC,
0 ignored issues
show
Bug introduced by
GeminiLabs\SiteReviews\Controllers\SORT_DESC cannot be passed to array_multisort() as the parameter $rest expects a reference. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

132
                array_column($features, 'premium'), /** @scrutinizer ignore-type */ SORT_DESC,
Loading history...
Bug introduced by
array_column($features, 'premium') cannot be passed to array_multisort() as the parameter $array expects a reference. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

132
                /** @scrutinizer ignore-type */ array_column($features, 'premium'), SORT_DESC,
Loading history...
133
                array_column($features, 'feature'), SORT_ASC | SORT_NATURAL,
0 ignored issues
show
Bug introduced by
array_column($features, 'feature') cannot be passed to array_multisort() as the parameter $rest expects a reference. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

133
                /** @scrutinizer ignore-type */ array_column($features, 'feature'), SORT_ASC | SORT_NATURAL,
Loading history...
Bug introduced by
GeminiLabs\SiteReviews\C...ontrollers\SORT_NATURAL cannot be passed to array_multisort() as the parameter $rest expects a reference. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

133
                array_column($features, 'feature'), /** @scrutinizer ignore-type */ SORT_ASC | SORT_NATURAL,
Loading history...
134
                $features
135
            );
136
        }
137
        $this->renderPage('premium', [
138
            'addons' => $addons,
139
            'features' => $features,
140
            'is_premium' => $isPremium,
141
        ]);
142
    }
143
144
    /**
145
     * @see registerSubMenus
146
     */
147
    public function renderSettingsMenuCallback(): void
148
    {
149
        $tabs = $this->parseWithFilter('settings/tabs', [ // order is intentional
150
            'general' => _x('General', 'admin-text', 'site-reviews'),
151
            'reviews' => _x('Reviews', 'admin-text', 'site-reviews'),
152
            'forms' => _x('Forms', 'admin-text', 'site-reviews'),
153
            'schema' => _x('Schema', 'admin-text', 'site-reviews'),
154
            'strings' => _x('Strings', 'admin-text', 'site-reviews'),
155
            'integrations' => _x('Integrations', 'admin-text', 'site-reviews'),
156
            'addons' => _x('Addons', 'admin-text', 'site-reviews'),
157
            'licenses' => _x('Licenses', 'admin-text', 'site-reviews'),
158
        ]);
159
        if (empty(Arr::get(glsr()->defaults(), 'settings.addons'))) {
160
            unset($tabs['addons']);
161
        }
162
        if (empty(Arr::get(glsr()->defaults(), 'settings.licenses'))) {
163
            unset($tabs['licenses']);
164
        }
165
        $this->renderPage('settings', [
166
            'fields' => glsr(SettingForm::class, ['groups' => $tabs])->build(),
167
            'tabs' => $tabs,
168
        ]);
169
    }
170
171
    /**
172
     * @see registerSubMenus
173
     */
174
    public function renderToolsMenuCallback(): void
175
    {
176
        $tabs = $this->parseWithFilter('tools/tabs', [
177
            'general' => _x('General', 'admin-text', 'site-reviews'),
178
            'scheduled' => _x('Scheduled Actions', 'admin-text', 'site-reviews'),
179
            'sync' => _x('Sync Reviews', 'admin-text', 'site-reviews'),
180
            'console' => _x('Console', 'admin-text', 'site-reviews'),
181
            'system-info' => _x('System Info', 'admin-text', 'site-reviews'),
182
        ]);
183
        if (!glsr()->filterBool('addon/sync/enable', false)) {
184
            unset($tabs['sync']);
185
        }
186
        $this->renderPage('tools', [
187 8
            'data' => [
188
                'console_level' => glsr(Console::class)->getLevel(),
189 8
                'context' => [
190 8
                    'base_url' => glsr_admin_url(),
191
                    'console' => glsr(Console::class)->get(),
192
                    'id' => glsr()->id,
193
                ],
194
                'myisam_tables' => Arr::get(glsr(Tables::class)->tableEngines(), 'MyISAM', []),
195
                'rollback_script' => file_get_contents(glsr()->path('assets/scripts/rollback.js')),
196
                'rollback_versions' => glsr(Cache::class)->getPluginVersions(),
197
                'services' => glsr()->filterArray('addon/sync/services', []),
198
            ],
199
            'tabs' => $tabs,
200
        ]);
201
    }
202
203
    /**
204
     * @action admin_init
205
     */
206
    public function setCustomPermissions(): void
207
    {
208
        foreach (wp_roles()->roles as $role => $value) {
209
            wp_roles()->remove_cap($role, 'create_'.glsr()->post_type);
210
        }
211
    }
212
213
    protected function getNotices(): string
214
    {
215
        return glsr(Builder::class)->div(glsr(Notice::class)->get(), [
216
            'id' => 'glsr-notices',
217
        ]);
218
    }
219
220
    protected function parseWithFilter(string $hookSuffix, array $args = []): array
221
    {
222
        if (str_ends_with($hookSuffix, '/tabs')) {
223
            $page = str_replace('/tabs', '', $hookSuffix);
224
            foreach ($args as $tab => $title) {
225
                if (!glsr()->hasPermission($page, $tab)) {
226
                    unset($args[$tab]);
227
                }
228
            }
229
        } elseif (array_key_exists('premium', $args) && glsr(License::class)->isPremium()) {
230
            $args['premium'] = _x('Premium Addons', 'admin-text', 'site-reviews');
231
        }
232
        return glsr()->filterArray("addon/{$hookSuffix}", $args);
233
    }
234
235
    protected function renderPage(string $page, array $data = []): void
236
    {
237
        $data['http_referer'] = (string) wp_get_referer();
238
        $data['notices'] = $this->getNotices();
239
        glsr()->render("pages/{$page}/index", $data);
240
    }
241
}
242