Passed
Push — master ( d46765...078281 )
by Paul
05:16
created

EditorController::canModifyTranslation()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 4
nc 3
nop 1
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Controllers;
4
5
use GeminiLabs\SiteReviews\Application;
6
use GeminiLabs\SiteReviews\Controllers\EditorController\Customization;
7
use GeminiLabs\SiteReviews\Controllers\EditorController\Labels;
8
use GeminiLabs\SiteReviews\Controllers\EditorController\Metaboxes;
9
use GeminiLabs\SiteReviews\Controllers\ListTableController\Columns;
10
use GeminiLabs\SiteReviews\Database;
11
use GeminiLabs\SiteReviews\Database\ReviewManager;
12
use GeminiLabs\SiteReviews\Defaults\CreateReviewDefaults;
13
use GeminiLabs\SiteReviews\Helpers\Arr;
14
use GeminiLabs\SiteReviews\Modules\Html\Builder;
15
use GeminiLabs\SiteReviews\Modules\Html\Template;
16
use GeminiLabs\SiteReviews\Modules\Notice;
17
use GeminiLabs\SiteReviews\Review;
18
use WP_Post;
19
20
class EditorController extends Controller
21
{
22
    /**
23
     * @return void
24
     * @action admin_enqueue_scripts
25
     */
26
    public function customizePostStatusLabels()
27
    {
28
        if ($this->canModifyTranslation()) {
29
            glsr(Labels::class)->customizePostStatusLabels();
30
        }
31
    }
32
33
    /**
34
     * @param array $settings
35
     * @return array
36
     * @filter wp_editor_settings
37
     */
38
    public function filterEditorSettings($settings)
39
    {
40
        return glsr(Customization::class)->filterEditorSettings(
41
            Arr::consolidateArray($settings)
42
        );
43
    }
44
45
    /**
46
     * Modify the WP_Editor html to allow autosizing without breaking the `editor-expand` script.
47
     * @param string $html
48
     * @return string
49
     * @filter the_editor
50
     */
51
    public function filterEditorTextarea($html)
52
    {
53
        return glsr(Customization::class)->filterEditorTextarea($html);
54
    }
55
56
    /**
57
     * @param bool $protected
58
     * @param string $metaKey
59
     * @param string $metaType
60
     * @return bool
61
     * @filter is_protected_meta
62
     */
63
    public function filterIsProtectedMeta($protected, $metaKey, $metaType)
64
    {
65
        if ('post' == $metaType && Application::POST_TYPE == get_post_type()) {
66
            $values = glsr(CreateReviewDefaults::class)->unguarded();
67
            $values = Arr::prefixArrayKeys($values);
68
            if (array_key_exists($metaKey, $values)) {
69
                $protected = false;
70
            }
71
        }
72
        return $protected;
73
    }
74
75
    /**
76
     * @param string $translation
77
     * @param string $test
78
     * @param string $domain
79
     * @return string
80
     * @filter gettext
81
     */
82 7
    public function filterPostStatusLabels($translation, $text, $domain)
83
    {
84 7
        return $this->canModifyTranslation($domain)
85
            ? glsr(Labels::class)->filterPostStatusLabels($translation, $text)
86 7
            : $translation;
87
    }
88
89
    /**
90
     * @param string $translation
91
     * @param string $test
92
     * @param string $domain
93
     * @return string
94
     * @filter gettext_with_context
95
     */
96 2
    public function filterPostStatusLabelsWithContext($translation, $text, $context, $domain)
97
    {
98 2
        return $this->canModifyTranslation($domain)
99
            ? glsr(Labels::class)->filterPostStatusLabels($translation, $text)
100 2
            : $translation;
101
    }
102
103
    /**
104
     * @param array $messages
105
     * @return array
106
     * @filter post_updated_messages
107
     */
108
    public function filterUpdateMessages($messages)
109
    {
110
        return glsr(Labels::class)->filterUpdateMessages(
111
            Arr::consolidateArray($messages)
112
        );
113
    }
114
115
    /**
116
     * @return void
117
     * @action add_meta_boxes_{Application::POST_TYPE}
118
     */
119
    public function registerMetaBoxes($post)
120
    {
121
        add_meta_box(Application::ID.'_assigned_to', __('Assigned To', 'site-reviews'), [$this, 'renderAssignedToMetabox'], null, 'side');
122
        add_meta_box(Application::ID.'_review', __('Details', 'site-reviews'), [$this, 'renderDetailsMetaBox'], null, 'side');
123
        if ('local' != glsr(Database::class)->get($post->ID, 'review_type')) {
124
            return;
125
        }
126
        add_meta_box(Application::ID.'_response', __('Respond Publicly', 'site-reviews'), [$this, 'renderResponseMetaBox'], null, 'normal');
127
    }
128
129
    /**
130
     * @return void
131
     * @action admin_print_scripts
132
     */
133
    public function removeAutosave()
134
    {
135
        glsr(Customization::class)->removeAutosave();
136
    }
137
138
    /**
139
     * @return void
140
     * @action admin_menu
141
     */
142
    public function removeMetaBoxes()
143
    {
144
        glsr(Customization::class)->removeMetaBoxes();
145
    }
146
147
    /**
148
     * @return void
149
     */
150 1
    public function removePostTypeSupport()
151
    {
152 1
        glsr(Customization::class)->removePostTypeSupport();
153 1
    }
154
155
    /**
156
     * @param WP_Post $post
157
     * @return void
158
     * @callback add_meta_box
159
     */
160
    public function renderAssignedToMetabox($post)
161
    {
162
        if (!$this->isReviewPostType($post)) {
163
            return;
164
        }
165
        $assignedTo = (string) glsr(Database::class)->get($post->ID, 'assigned_to');
166
        wp_nonce_field('assigned_to', '_nonce-assigned-to', false);
167
        glsr()->render('partials/editor/metabox-assigned-to', [
168
            'id' => $assignedTo,
169
            'template' => $this->buildAssignedToTemplate($assignedTo, $post),
170
        ]);
171
    }
172
173
    /**
174
     * @param WP_Post $post
175
     * @return void
176
     * @callback add_meta_box
177
     */
178
    public function renderDetailsMetaBox($post)
179
    {
180
        if (!$this->isReviewPostType($post)) {
181
            return;
182
        }
183
        $review = glsr_get_review($post);
184
        glsr()->render('partials/editor/metabox-details', [
185
            'button' => $this->buildDetailsMetaBoxRevertButton($review, $post),
186
            'metabox' => $this->normalizeDetailsMetaBox($review),
187
        ]);
188
    }
189
190
    /**
191
     * @return void
192
     * @action post_submitbox_misc_actions
193
     */
194
    public function renderPinnedInPublishMetaBox()
195
    {
196
        if (!$this->isReviewPostType(get_post())) {
197
            return;
198
        }
199
        glsr(Template::class)->render('partials/editor/pinned', [
200
            'context' => [
201
                'no' => __('No', 'site-reviews'),
202
                'yes' => __('Yes', 'site-reviews'),
203
            ],
204
            'pinned' => wp_validate_boolean(glsr(Database::class)->get(get_the_ID(), 'pinned')),
205
        ]);
206
    }
207
208
    /**
209
     * @param WP_Post $post
210
     * @return void
211
     * @callback add_meta_box
212
     */
213
    public function renderResponseMetaBox($post)
214
    {
215
        if (!$this->isReviewPostType($post)) {
216
            return;
217
        }
218
        wp_nonce_field('response', '_nonce-response', false);
219
        glsr()->render('partials/editor/metabox-response', [
220
            'response' => glsr(Database::class)->get($post->ID, 'response'),
221
        ]);
222
    }
223
224
    /**
225
     * @param WP_Post $post
226
     * @return void
227
     * @action edit_form_after_title
228
     */
229
    public function renderReviewEditor($post)
230
    {
231
        if (!$this->isReviewPostType($post) || $this->isReviewEditable($post)) {
232
            return;
233
        }
234
        glsr()->render('partials/editor/review', [
235
            'post' => $post,
236
            'response' => glsr(Database::class)->get($post->ID, 'response'),
237
        ]);
238
    }
239
240
    /**
241
     * @return void
242
     * @action admin_head
243
     */
244
    public function renderReviewFields()
245
    {
246
        $screen = glsr_current_screen();
247
        if ('post' != $screen->base || Application::POST_TYPE != $screen->post_type) {
248
            return;
249
        }
250
        add_action('edit_form_after_title', [$this, 'renderReviewEditor']);
251
        add_action('edit_form_top', [$this, 'renderReviewNotice']);
252
    }
253
254
    /**
255
     * @param WP_Post $post
256
     * @return void
257
     * @action edit_form_top
258
     */
259
    public function renderReviewNotice($post)
260
    {
261
        if (!$this->isReviewPostType($post) || $this->isReviewEditable($post)) {
262
            return;
263
        }
264
        glsr(Notice::class)->addWarning(sprintf(
265
            __('%s reviews are read-only.', 'site-reviews'),
266
            glsr(Columns::class)->buildColumnReviewType($post->ID)
267
        ));
268
        glsr(Template::class)->render('partials/editor/notice', [
269
            'context' => [
270
                'notices' => glsr(Notice::class)->get(),
271
            ],
272
        ]);
273
    }
274
275
    /**
276
     * @param WP_Post $post
277
     * @return void
278
     * @see glsr_categories_meta_box()
279
     * @callback register_taxonomy
280
     */
281
    public function renderTaxonomyMetabox($post)
282
    {
283
        if (!$this->isReviewPostType($post)) {
284
            return;
285
        }
286
        glsr()->render('partials/editor/metabox-categories', [
287
            'post' => $post,
288
            'tax_name' => Application::TAXONOMY,
289
            'taxonomy' => get_taxonomy(Application::TAXONOMY),
290
        ]);
291
    }
292
293
    /**
294
     * @return void
295
     * @see $this->filterUpdateMessages()
296
     * @action admin_action_revert
297
     */
298
    public function revertReview()
299
    {
300
        if (Application::ID != filter_input(INPUT_GET, 'plugin')) {
301
            return;
302
        }
303
        check_admin_referer('revert-review_'.($postId = $this->getPostId()));
304
        glsr(ReviewManager::class)->revert($postId);
305
        $this->redirect($postId, 52);
306
    }
307
308
    /**
309
     * @param int $postId
310
     * @param \WP_Post $post
311
     * @param bool $isUpdate
312
     * @return void
313
     * @action save_post_.Application::POST_TYPE
314
     */
315 1
    public function saveMetaboxes($postId, $post, $isUpdating)
316
    {
317 1
        glsr(Metaboxes::class)->saveAssignedToMetabox($postId);
318 1
        glsr(Metaboxes::class)->saveResponseMetabox($postId);
319 1
        if ($isUpdating) {
320
            do_action('site-reviews/review/saved', glsr_get_review($postId));
321
        }
322 1
    }
323
324
    /**
325
     * @param string $assignedTo
326
     * @return string
327
     */
328
    protected function buildAssignedToTemplate($assignedTo, WP_Post $post)
329
    {
330
        $assignedPost = glsr(Database::class)->getAssignedToPost($post->ID, $assignedTo);
331
        if (!($assignedPost instanceof WP_Post)) {
332
            return;
333
        }
334
        return glsr(Template::class)->build('partials/editor/assigned-post', [
335
            'context' => [
336
                'data.url' => (string) get_permalink($assignedPost),
337
                'data.title' => get_the_title($assignedPost),
338
            ],
339
        ]);
340
    }
341
342
    /**
343
     * @return string
344
     */
345
    protected function buildDetailsMetaBoxRevertButton(Review $review, WP_Post $post)
346
    {
347
        $isModified = !Arr::compareArrays(
348
            [$review->title, $review->content, $review->date],
349
            [
350
                glsr(Database::class)->get($post->ID, 'title'),
351
                glsr(Database::class)->get($post->ID, 'content'),
352
                glsr(Database::class)->get($post->ID, 'date'),
353
            ]
354
        );
355
        if ($isModified) {
356
            $revertUrl = wp_nonce_url(
357
                admin_url('post.php?post='.$post->ID.'&action=revert&plugin='.Application::ID),
358
                'revert-review_'.$post->ID
359
            );
360
            return glsr(Builder::class)->a(__('Revert Changes', 'site-reviews'), [
361
                'class' => 'button button-large',
362
                'href' => $revertUrl,
363
                'id' => 'revert',
364
            ]);
365
        }
366
        return glsr(Builder::class)->button(__('Nothing to Revert', 'site-reviews'), [
367
            'class' => 'button-large',
368
            'disabled' => true,
369
            'id' => 'revert',
370
        ]);
371
    }
372
373
    /**
374
     * @param string $domain
375
     * @return bool
376
     */
377 7
    protected function canModifyTranslation($domain = 'default')
378
    {
379 7
        if ('default' != $domain || empty(glsr_current_screen()->base)) {
380 7
            return false;
381
        }
382 7
        return Application::POST_TYPE == glsr_current_screen()->post_type
383 7
            && in_array(glsr_current_screen()->base, ['edit', 'post']);
384
    }
385
386
    /**
387
     * @param object $review
388
     * @return string|void
389
     */
390
    protected function getReviewType($review)
391
    {
392
        if (count(glsr()->reviewTypes) < 2) {
393
            return;
394
        }
395
        $reviewType = array_key_exists($review->review_type, glsr()->reviewTypes)
396
            ? glsr()->reviewTypes[$review->review_type]
397
            : __('Unknown', 'site-reviews');
398
        if (!empty($review->url)) {
399
            $reviewType = glsr(Builder::class)->a($reviewType, [
400
                'href' => $review->url,
401
                'target' => '_blank',
402
            ]);
403
        }
404
        return $reviewType;
405
    }
406
407
    /**
408
     * @return bool
409
     */
410
    protected function isReviewEditable($post)
411
    {
412
        return $this->isReviewPostType($post)
413
            && post_type_supports(Application::POST_TYPE, 'title')
414
            && 'local' == glsr(Database::class)->get($post->ID, 'review_type');
415
    }
416
417
    /**
418
     * @param mixed $post
419
     * @return bool
420
     */
421
    protected function isReviewPostType($post)
422
    {
423
        return $post instanceof WP_Post && Application::POST_TYPE == $post->post_type;
424
    }
425
426
    /**
427
     * @return array
428
     */
429
    protected function normalizeDetailsMetaBox(Review $review)
430
    {
431
        $user = empty($review->user_id)
432
            ? __('Unregistered user', 'site-reviews')
433
            : glsr(Builder::class)->a(get_the_author_meta('display_name', $review->user_id), [
434
                'href' => get_author_posts_url($review->user_id),
435
            ]);
436
        $email = empty($review->email)
437
            ? '&mdash;'
438
            : glsr(Builder::class)->a($review->email, [
439
                'href' => 'mailto:'.$review->email.'?subject='.esc_attr(__('RE:', 'site-reviews').' '.$review->title),
440
            ]);
441
        $metabox = [
442
            __('Rating', 'site-reviews') => glsr_star_rating($review->rating),
443
            __('Type', 'site-reviews') => $this->getReviewType($review),
444
            __('Date', 'site-reviews') => get_date_from_gmt($review->date, 'F j, Y'),
445
            __('Name', 'site-reviews') => $review->author,
446
            __('Email', 'site-reviews') => $email,
447
            __('User', 'site-reviews') => $user,
448
            __('IP Address', 'site-reviews') => $review->ip_address,
449
            __('Avatar', 'site-reviews') => sprintf('<img src="%s" width="96">', $review->avatar),
450
        ];
451
        return array_filter(apply_filters('site-reviews/metabox/details', $metabox, $review));
452
    }
453
454
    /**
455
     * @param int $postId
456
     * @param int $messageIndex
457
     * @return void
458
     */
459
    protected function redirect($postId, $messageIndex)
460
    {
461
        $referer = wp_get_referer();
462
        $hasReferer = !$referer
463
            || false !== strpos($referer, 'post.php')
464
            || false !== strpos($referer, 'post-new.php');
465
        $redirectUri = $hasReferer
466
            ? remove_query_arg(['deleted', 'ids', 'trashed', 'untrashed'], $referer)
467
            : get_edit_post_link($postId);
468
        wp_safe_redirect(add_query_arg(['message' => $messageIndex], $redirectUri));
469
        exit;
470
    }
471
}
472