Test Failed
Push — develop ( 6a684d...5c54e5 )
by Paul
08:51
created

ProfileController   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 227
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 43
eloc 107
c 1
b 0
f 1
dl 0
loc 227
rs 8.96

15 Methods

Rating   Name   Duplication   Size   Complexity  
A shortcodeForm() 0 20 4
A shortcodeSummary() 0 10 1
A renderReviewsTab() 0 10 2
A filterProfileTabs() 0 10 2
A filterInlineStyles() 0 7 1
C hasVisibilityPermission() 0 29 14
A filterInlineScript() 0 13 2
A filterSummaryTextValue() 0 9 3
A filterSavedTabs() 0 7 2
A filterReviewsFallback() 0 11 3
A filterSummaryPercentagesValue() 0 6 2
A currentProfileId() 0 4 1
A filterReviewAuthorValue() 0 8 3
A filterSummaryRatingValue() 0 6 2
A shortcodeReviews() 0 8 1

How to fix   Complexity   

Complex Class

Complex classes like ProfileController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ProfileController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace GeminiLabs\SiteReviews\Integrations\ProfilePress\Controllers;
4
5
use GeminiLabs\SiteReviews\Contracts\TagContract;
6
use GeminiLabs\SiteReviews\Controllers\AbstractController;
7
use GeminiLabs\SiteReviews\Modules\Html\Builder;
8
use GeminiLabs\SiteReviews\Modules\Html\Template;
9
use GeminiLabs\SiteReviews\Shortcodes\SiteReviewsFormShortcode;
10
11
class ProfileController extends AbstractController
12
{
13
    public const REVIEWS_TAB = 'member_reviews';
14
15
    /**
16
     * @filter site-reviews/enqueue/public/inline-script/after
17
     */
18
    public function filterInlineScript(string $javascript): string
19
    {
20
        if (!$this->hasVisibilityPermission()) {
21
            return $javascript;
22
        }
23
        return $javascript.'document.addEventListener("DOMContentLoaded", () => {'.
24
            'GLSR.Event.on("site-reviews/form/handle", (response, form) => {'.
25
                'if (true !== response.success || "undefined" === typeof response.html) return;'.
26
                'form.classList.add("glsr-hide-form");'.
27
                'form.insertAdjacentHTML("afterend", "<p class=\"glsr-no-margins glsr-form-success\">"+response.message+"</p>");'.
28
                'form.remove()'.
29
            '})'.
30
        '})';
31
    }
32
33
    /**
34
     * @filter site-reviews/enqueue/public/inline-styles
35
     */
36
    public function filterInlineStyles(string $css): string
37
    {
38
        $css .= '.pp-reviews:has(.glsr-reviews) {border-top: 3px solid #eee; padding-top:var(--glsr-gap-xl);}';
39
        $css .= '.pp-reviews-form:has(div) {border-top: 3px solid #eee; padding:var(--glsr-gap-xl) 0;}';
40
        $css .= '.pp-reviews-summary .glsr-summary-text {--glsr-summary-text: var(--glsr-text-base);}';
41
        $css .= '.pp-reviews-summary {padding-top:var(--glsr-gap-lg); padding-bottom:var(--glsr-gap-xl);}';
42
        return $css;
43
    }
44
45
    /**
46
     * @filter ppress_profile_tabs
47
     */
48
    public function filterProfileTabs(array $tabs): array
49
    {
50
        if (!$this->hasVisibilityPermission()) {
51
            return $tabs;
52
        }
53
        $tabs[static::REVIEWS_TAB] = [
54
            'icon' => 'star',
55
            'title' => __('Reviews', 'site-reviews'),
56
        ];
57
        return $tabs;
58
    }
59
60
    /**
61
     * @see $this->shortcodeReviews()
62
     *
63
     * @filter site-reviews/review/value/author
64
     */
65
    public function filterReviewAuthorValue(string $value, TagContract $tag): string
66
    {
67
        if ($user = $tag->review->user()) { // @phpstan-ignore-line
0 ignored issues
show
Bug introduced by
Accessing review on the interface GeminiLabs\SiteReviews\Contracts\TagContract suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
68
            if ($url = ppress_get_frontend_profile_url($user->ID)) {
0 ignored issues
show
Bug introduced by
The function ppress_get_frontend_profile_url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

68
            if ($url = /** @scrutinizer ignore-call */ ppress_get_frontend_profile_url($user->ID)) {
Loading history...
69
                return sprintf('<a href="%s">%s</a>', $url, $value);
70
            }
71
        }
72
        return $value;
73
    }
74
75
    /**
76
     * @see $this->shortcodeReviews()
77
     *
78
     * @filter site-reviews/reviews/fallback
79
     */
80
    public function filterReviewsFallback(string $fallback, array $args): string
81
    {
82
        if ($args['fallback'] !== __('There are no reviews yet. Be the first one to write one.', 'site-reviews')) {
83
            return $fallback;
84
        }
85
        $value = get_current_user_id() === $this->currentProfileId()
86
            ? __('You have not received any reviews.', 'site-reviews')
87
            : __('This person has not received any reviews.', 'site-reviews');
88
        return glsr(Builder::class)->p([
89
            'class' => 'glsr-no-margins',
90
            'text' => $value,
91
        ]);
92
    }
93
94
    /**
95
     * @filter ppress_dpf_saved_tabs
96
     */
97
    public function filterSavedTabs(array $tabs): array
98
    {
99
        if (!$this->hasVisibilityPermission()) {
100
            return $tabs;
101
        }
102
        $tabs[] = static::REVIEWS_TAB;
103
        return array_values(array_unique($tabs));
104
    }
105
106
    /**
107
     * @filter site-reviews/summary/value/percentages
108
     */
109
    public function filterSummaryPercentagesValue(string $value, TagContract $tag): string
110
    {
111
        if (!empty(array_sum($tag->ratings))) { // @phpstan-ignore-line
0 ignored issues
show
Bug introduced by
Accessing ratings on the interface GeminiLabs\SiteReviews\Contracts\TagContract suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
112
            return $value;
113
        }
114
        return '';
115
    }
116
117
    /**
118
     * @filter site-reviews/summary/value/text
119
     */
120
    public function filterSummaryRatingValue(): string
121
    {
122
        $value = get_current_user_id() === $this->currentProfileId()
123
            ? __('Your rating', 'site-reviews')
124
            : __('User rating', 'site-reviews');
125
        return glsr(Builder::class)->h4($value);
126
    }
127
128
    /**
129
     * @filter site-reviews/summary/value/rating
130
     */
131
    public function filterSummaryTextValue(string $value, TagContract $tag): string
132
    {
133
        if (!empty(array_sum($tag->ratings))) { // @phpstan-ignore-line
0 ignored issues
show
Bug introduced by
Accessing ratings on the interface GeminiLabs\SiteReviews\Contracts\TagContract suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
134
            return $value;
135
        }
136
        if (get_current_user_id() === $this->currentProfileId()) {
137
            return __('No one has reviewed you yet.', 'site-reviews');
138
        }
139
        return __('No one has reviewed this person yet.', 'site-reviews');
140
    }
141
142
    /**
143
     * @action ppress_profile_tab_content_{static::REVIEWS_TAB}
144
     */
145
    public function renderReviewsTab(): void
146
    {
147
        if (!$this->hasVisibilityPermission()) {
148
            return;
149
        }
150
        glsr(Template::class)->render('templates/profilepress/profile-reviews', [
151
            'context' => [
152
                'form' => $this->shortcodeForm(),
153
                'reviews' => $this->shortcodeReviews(),
154
                'summary' => $this->shortcodeSummary(),
155
            ],
156
        ]);
157
    }
158
159
    protected function currentProfileId(): int
160
    {
161
        global $ppress_frontend_profile_user_obj;
162
        return ppress_var_obj($ppress_frontend_profile_user_obj, 'ID', 0);
0 ignored issues
show
Bug introduced by
The function ppress_var_obj was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

162
        return /** @scrutinizer ignore-call */ ppress_var_obj($ppress_frontend_profile_user_obj, 'ID', 0);
Loading history...
163
    }
164
165
    protected function hasVisibilityPermission(): bool
166
    {
167
        if (!glsr_get_option('integrations.profilepress.display_profile_tab', false, 'bool')) {
168
            return false;
169
        }
170
        if (!ppress_post_content_has_shortcode('profilepress-user-profile')) {
0 ignored issues
show
Bug introduced by
The function ppress_post_content_has_shortcode was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

170
        if (!/** @scrutinizer ignore-call */ ppress_post_content_has_shortcode('profilepress-user-profile')) {
Loading history...
171
            return false;
172
        }
173
        $roles = glsr_get_option('integrations.profilepress.profile_tab_roles');
174
        $visibility = glsr_get_option('integrations.profilepress.profile_tab_visibility');
175
        $user = wp_get_current_user();
176
        $userHasRole = !empty(array_intersect($roles, (array) $user->roles));
177
        $userIsOwner = $user->ID === $this->currentProfileId();
178
        if ('guest' === $visibility && $user->ID) {
179
            return false;
180
        }
181
        if ('member' === $visibility && !$user->ID) {
182
            return false;
183
        }
184
        if ('owner' === $visibility && !$userIsOwner) {
185
            return false;
186
        }
187
        if ('roles' === $visibility && !$userHasRole) {
188
            return false;
189
        }
190
        if ('owner_roles' === $visibility && !$userIsOwner && !$userHasRole) {
191
            return false;
192
        }
193
        return true;
194
    }
195
196
    protected function shortcodeForm(): string
197
    {
198
        if (!is_user_logged_in()) {
199
            $text = sprintf(__('You must be %s to review this person.', 'site-reviews'), glsr(SiteReviewsFormShortcode::class)->loginLink());
200
            return glsr(Template::class)->build('templates/login-register', [
201
                'context' => compact('text'),
202
            ]);
203
        }
204
        if (get_current_user_id() === $this->currentProfileId()) {
205
            return '';
206
        }
207
        $ratings = glsr_get_ratings([
208
            'assigned_users' => $this->currentProfileId(),
209
            'status' => 'all',
210
            'user__in' => get_current_user_id(),
211
        ]);
212
        if (0 < $ratings->reviews) {
213
            return '';
214
        }
215
        return do_shortcode(glsr_get_option('integrations.profilepress.profile_tab_form'));
216
    }
217
218
    protected function shortcodeReviews(): string
219
    {
220
        add_filter('site-reviews/review/value/author', [$this, 'filterReviewAuthorValue'], 20, 2);
221
        add_filter('site-reviews/reviews/fallback', [$this, 'filterReviewsFallback'], 20, 2);
222
        $shortcode = do_shortcode(glsr_get_option('integrations.profilepress.profile_tab_reviews'));
223
        remove_filter('site-reviews/review/value/author', [$this, 'filterReviewAuthorValue'], 20);
224
        remove_filter('site-reviews/reviews/fallback', [$this, 'filterReviewsFallback'], 20);
225
        return $shortcode;
226
    }
227
228
    protected function shortcodeSummary(): string
229
    {
230
        add_filter('site-reviews/summary/value/percentages', [$this, 'filterSummaryPercentagesValue'], 20, 2);
231
        add_filter('site-reviews/summary/value/rating', [$this, 'filterSummaryRatingValue'], 20);
232
        add_filter('site-reviews/summary/value/text', [$this, 'filterSummaryTextValue'], 20, 2);
233
        $shortcode = do_shortcode(glsr_get_option('integrations.profilepress.profile_tab_summary'));
234
        remove_filter('site-reviews/summary/value/percentages', [$this, 'filterSummaryPercentagesValue'], 20);
235
        remove_filter('site-reviews/summary/value/rating', [$this, 'filterSummaryRatingValue'], 20);
236
        remove_filter('site-reviews/summary/value/text', [$this, 'filterSummaryTextValue'], 20);
237
        return $shortcode;
238
    }
239
}
240