Passed
Push — develop ( c25d3a...0b5f25 )
by Paul
16:59
created

MainController::filterRatingOption()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Integrations\WooCommerce\Controllers;
4
5
use GeminiLabs\SiteReviews\Controllers\AbstractController;
6
use GeminiLabs\SiteReviews\Database\PostMeta;
7
use GeminiLabs\SiteReviews\Helpers\Arr;
8
use GeminiLabs\SiteReviews\Helpers\Cast;
9
use GeminiLabs\SiteReviews\Integrations\WooCommerce\Elementor\Widgets\ProductRating;
10
use GeminiLabs\SiteReviews\Integrations\WooCommerce\Widgets\WidgetRatingFilter;
11
use GeminiLabs\SiteReviews\Integrations\WooCommerce\Widgets\WidgetRecentReviews;
12
use GeminiLabs\SiteReviews\Modules\SchemaParser;
13
use GeminiLabs\SiteReviews\Review;
14
15
class MainController extends AbstractController
16
{
17
    /**
18
     * @action admin_enqueue_scripts
19
     */
20
    public function enqueueInlineAdminStyles(): void
21
    {
22
        $css = '.woocommerce-review-activity-card .woocommerce-activity-card__actions button.is-tertiary:not(.is-destructive) {display:none}';
23
        wp_add_inline_style('wc-admin-app', $css);
24
    }
25
26
    /**
27
     * @filter site-reviews/enqueue/public/inline-styles
28
     */
29
    public function filterInlineStyles(string $css): string
30
    {
31
        $css .= 'ul.glsr li a{display:flex;justify-content:space-between;}'; // fix rating filter widget
32
        $css .= '.glsr.woocommerce-product-rating{align-items:center;display:inline-flex;gap:.5em;&::before{display:none!important;}}';
33
        $css .= '.glsr.woocommerce-product-rating .woocommerce-review-link{top:-1px!important;}'; // fix product title rating position
34
        $style = glsr_get_option('integrations.woocommerce.style');
35
        $colors = [
36
            'black' => '#212121',
37
            'woocommerce' => '#96588A',
38
        ];
39
        if (!array_key_exists($style, $colors)) {
40
            return $css;
41
        }
42
        $css = str_replace('assets/images/stars/default/', "assets/images/stars/{$style}/", $css);
43
        $css .= ".glsr:not([data-theme]) .glsr-bar-background-percent{--glsr-bar-bg:{$colors[$style]};}";
44
        return $css;
45
    }
46
47
    /**
48
     * @return int
49
     *
50
     * @filter woocommerce_product_reviews_pending_count
51
     */
52
    public function filterMenuPendingCount()
53
    {
54
        return 0;
55
    }
56
57
    /**
58
     * @param string $status
59
     * @param string $postType
60
     * @param string $commentType
61
     *
62
     * @return string
63
     *
64
     * @filter get_default_comment_status
65
     */
66
    public function filterProductCommentStatus($status, $postType, $commentType)
67
    {
68
        if ('product' === $postType && 'comment' === $commentType) {
69
            return 'open';
70
        }
71
        return $status;
72
    }
73
74
    /**
75
     * @param array  $settings
76
     * @param string $section
77
     *
78
     * @return array
79
     *
80
     * @filter woocommerce_get_settings_products
81
     */
82
    public function filterProductSettings($settings, $section)
83
    {
84
        if (!empty($section)) {
85
            return $settings;
86
        }
87
        $disabled = ['woocommerce_enable_review_rating', 'woocommerce_review_rating_required'];
88
        foreach ($settings as &$setting) {
89
            if (in_array(Arr::get($setting, 'id'), $disabled)) {
90
                $setting = Arr::set($setting, 'custom_attributes.disabled', true);
91
                $setting['desc'] = sprintf('%s <span class="required">(%s)</span>',
92
                    $setting['desc'],
93
                    _x('managed by Site Reviews', 'admin-text', 'site-reviews')
94
                );
95
            }
96
        }
97
        return $settings;
98
    }
99
100
    /**
101
     * @filter site-reviews/enqueue/public/inline-script/after
102
     */
103
    public function filterPublicInlineScript(string $script): string
104
    {
105
        $script .= '"undefined"!==typeof jQuery&&(jQuery(".wc-tabs .reviews_tab a").on("click",function(){setTimeout(function(){GLSR.Event.trigger("site-reviews-themes/swiper/resize")},25)}));';
106
        return $script;
107
    }
108
109
    /**
110
     * @filter site-reviews/schema/generate
111
     */
112
    public function filterRankmathSchemaPreview(array $data, SchemaParser $parser): array
113
    {
114
        if (!did_action('rank_math/json_ld/preview')) {
115
            return $data; // only run this for the preview
116
        }
117
        if (!$url = wp_get_referer()) {
118
            return $data;
119
        }
120
        $urlQuery = (string) wp_parse_url($url, \PHP_URL_QUERY);
121
        $query = wp_parse_args($urlQuery);
122
        $postId = Cast::toInt($query['post'] ?? 0);
123
        if (!$product = wc_get_product($postId)) {
124
            return $data;
125
        }
126
        if (!$product->get_reviews_allowed()) {
127
            return $data;
128
        }
129
        return $parser->buildReviewSchema([
130
            'assigned_posts' => $postId,
131
        ]);
132
    }
133
134
    /**
135
     * @return string
136
     *
137
     * @filter option_woocommerce_enable_review_rating
138
     * @filter option_woocommerce_review_rating_required
139
     */
140
    public function filterRatingOption()
141
    {
142
        return 'yes';
143
    }
144
145
    /**
146
     * @param \GeminiLabs\SiteReviews\Modules\Html\Tags\ReviewAuthorTag $tag
147
     *
148
     * @filter site-reviews/review/value/author
149
     */
150
    public function filterReviewAuthorTagValue(string $value, $tag): string
151
    {
152
        if ($tag->review->hasVerifiedOwner() && 'yes' === get_option('woocommerce_review_rating_verification_label')) { // @phpstan-ignore-line
153
            $text = esc_attr__('verified owner', 'site-reviews');
154
            $value = sprintf('%s <em class="woocommerce-review__verified verified">(%s)</em>', $value, $text);
155
        }
156
        return $value;
157
    }
158
159
    /**
160
     * @filter site-reviews/review/call/hasVerifiedOwner
161
     */
162
    public function filterReviewCallbackHasVerifiedOwner(Review $review): bool
163
    {
164
        $verified = glsr(PostMeta::class)->get($review->ID, 'verified');
165
        if ('' !== $verified) {
166
            return (bool) $verified;
167
        }
168
        $review->refresh(); // refresh the review first!
169
        $verified = false;
170
        foreach ($review->assigned_posts as $postId) {
171
            if ('product' === get_post_type($postId)) {
172
                $verified = wc_customer_bought_product($review->email, $review->author_id, $postId);
173
                break; // only check the first product
174
            }
175
        }
176
        glsr(PostMeta::class)->set($review->ID, 'verified', (int) $verified);
177
        return $verified;
178
    }
179
180
    /**
181
     * @filter site-reviews/review/call/product
182
     */
183
    public function filterReviewCallbackProduct(Review $review): ?\WC_Product
184
    {
185
        foreach ($review->assigned_posts as $postId) {
186
            if ('product' !== get_post_type($postId)) {
187
                continue;
188
            }
189
            if ($product = wc_get_product($postId)) {
190
                return $product; // only return the first found product
191
            }
192
        }
193
        return null;
194
    }
195
196
    /**
197
     * @action admin_init
198
     */
199
    public function redirectProductReviews(): void
200
    {
201
        global $pagenow;
202
        if ('edit.php' === $pagenow
203
            && 'product' === filter_input(INPUT_GET, 'post_type')
204
            && 'product-reviews' === filter_input(INPUT_GET, 'page')) {
205
            wp_redirect(add_query_arg('notice', 'product-reviews', glsr_admin_url()), 301);
206
            exit;
207
        }
208
    }
209
210
    /**
211
     * @action elementor/widgets/register
212
     */
213
    public function registerElementorWidgets(): void
214
    {
215
        $widgets = \Elementor\Plugin::instance()->widgets_manager;
216
        $widgets->unregister('woocommerce-product-rating');
217
        if (class_exists('ElementorPro\Modules\Woocommerce\Widgets\Product_Rating')) {
218
            $widgets->register(new ProductRating());
219
        }
220
    }
221
222
    /**
223
     * @action widgets_init
224
     */
225
    public function registerWidgets(): void
226
    {
227
        unregister_widget('WC_Widget_Recent_Reviews');
228
        unregister_widget('WC_Widget_Rating_Filter');
229
        register_widget(WidgetRecentReviews::class);
230
        register_widget(WidgetRatingFilter::class);
231
    }
232
233
    /**
234
     * This is only done on the admin side because otherwise it breaks product
235
     * ratings on Divi product pages (and possibly on other page builder product pages).
236
     *
237
     * @action admin_init
238
     */
239
    public function removeCommentSupport(): void
240
    {
241
        remove_post_type_support('product', 'comments');
242
    }
243
244
    /**
245
     * @action admin_notices
246
     */
247
    public function renderNotice(): void
248
    {
249
        $screen = glsr_current_screen();
250
        if ('edit' !== $screen->base || 'edit-site-review' !== $screen->id) {
251
            return;
252
        }
253
        if ('product-reviews' !== filter_input(INPUT_GET, 'notice')) {
254
            return;
255
        }
256
        glsr()->render('integrations/woocommerce/notices/reviews');
257
    }
258
259
    /**
260
     * @action site-reviews/review/created
261
     */
262
    public function verifyProductOwner(Review $review): void
263
    {
264
        $review->hasVerifiedOwner();
265
    }
266
}
267