Passed
Push — develop ( afff43...70b7ee )
by Paul
14:29
created

ReviewsDefaults::finalizeBoolValue()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 6
ccs 3
cts 4
cp 0.75
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2.0625
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Defaults;
4
5
use GeminiLabs\SiteReviews\Helpers\Arr;
6
use GeminiLabs\SiteReviews\Helpers\Cast;
7
use GeminiLabs\SiteReviews\Helpers\Str;
8
use GeminiLabs\SiteReviews\Modules\Multilingual;
9
use GeminiLabs\SiteReviews\Modules\Sanitizer;
10
11
class ReviewsDefaults extends DefaultsAbstract
12
{
13
    /**
14
     * The values that should be cast before sanitization is run.
15
     * This is done before $sanitize and $enums.
16
     */
17
    public array $casts = [
18
        'terms' => 'string',
19
        'verified' => 'string',
20
    ];
21
22
    /**
23
     * The values that should be constrained after sanitization is run.
24
     * This is done after $casts and $sanitize.
25
     */
26
    public array $enums = [
27
        'order' => ['asc', 'desc'],
28
        'orderby' => [
29
            'author',
30
            'comment_count',
31
            'date',
32
            'date_gmt',
33
            'id',
34
            'menu_order',
35
            'none',
36
            'random',
37
            'rating',
38
        ],
39
        'status' => ['all', 'approved', 'hold', 'pending', 'publish', 'unapproved'],
40
        'terms' => ['0', 'false', '1', 'true'],
41
        'verified' => ['0', 'false', '1', 'true'],
42
    ];
43
44
    /**
45
     * The keys that should be mapped to other keys.
46
     * Keys are mapped before the values are normalized and sanitized.
47
     * Note: Mapped keys should not be included in the defaults!
48
     */
49
    public array $mapped = [
50
        'assigned_to' => 'assigned_posts',
51
        'author' => 'user__in',
52
        'author_id' => 'user__in',
53
        'category' => 'assigned_terms',
54
        'display' => 'per_page',
55
        'exclude' => 'post__not_in',
56
        'include' => 'post__in',
57
        'user' => 'assigned_users',
58
    ];
59
60
    /**
61
     * The values that should be sanitized.
62
     * This is done after $casts and before $enums.
63
     */
64
    public array $sanitize = [
65
        'assigned_posts' => 'post-ids',
66
        'assigned_posts_types' => 'array-string',
67
        'assigned_terms' => 'term-ids',
68
        'assigned_users' => 'user-ids',
69
        'content' => 'text-multiline',
70
        'email' => 'email',
71
        'integration' => 'slug',
72
        'ip_address' => 'ip-address',
73
        'offset' => 'min:0',
74
        'order' => 'name',
75
        'orderby' => 'name',
76
        'page' => 'min:1',
77
        'per_page' => 'min:-1', // -1 means unlimited
78
        'post__in' => 'array-int',
79
        'post__not_in' => 'array-int',
80
        'rating' => 'rating',
81
        'rating_field' => 'name',
82
        'status' => 'name',
83
        'type' => 'slug',
84
        'user__in' => 'user-ids',
85
        'user__not_in' => 'user-ids',
86
    ];
87
88 51
    protected function defaults(): array
89
    {
90 51
        return [
91 51
            'assigned_posts' => '',
92 51
            'assigned_posts_types' => [],
93 51
            'assigned_terms' => '',
94 51
            'assigned_users' => '',
95 51
            'content' => '',
96 51
            'date' => '', // can be an array or string
97 51
            'email' => '',
98 51
            'integration' => '', // the slug of the integration querying the reviews
99 51
            'ip_address' => '',
100 51
            'offset' => 0,
101 51
            'order' => 'desc',
102 51
            'orderby' => 'date',
103 51
            'page' => 1,
104 51
            'per_page' => 10,
105 51
            'post__in' => [],
106 51
            'post__not_in' => [],
107 51
            'rating' => '',
108 51
            'rating_field' => 'rating', // used for custom rating fields
109 51
            'status' => 'approved',
110 51
            'terms' => '',
111 51
            'type' => '',
112 51
            'user__in' => [],
113 51
            'user__not_in' => [],
114 51
            'verified' => '',
115 51
        ];
116
    }
117
118
    /**
119
     * Normalize provided values, this always runs first.
120
     */
121 51
    protected function normalize(array $values = []): array
122
    {
123 51
        if ($postIds = Arr::getAs('array', $values, 'assigned_posts')) {
124 4
            $values['assigned_posts_types'] = [];
125 4
            foreach ($postIds as $postType) {
126 4
                if (!is_numeric($postType) && post_type_exists($postType)) {
127
                    $values['assigned_posts'] = []; // query only by assigned post types!
128
                    $values['assigned_posts_types'][] = $postType;
129
                }
130
            }
131
        } else {
132 50
            $postTypes = glsr(Sanitizer::class)->sanitizeArrayString(Arr::get($values, 'assigned_posts_types'));
133 50
            $values['assigned_posts_types'] = array_filter($postTypes, 'post_type_exists');
134
        }
135 51
        return $values;
136
    }
137
138
    /**
139
     * Finalize provided values, this always runs last.
140
     */
141 51
    protected function finalize(array $values = []): array
142
    {
143 51
        $values['assigned_posts'] = glsr(Multilingual::class)->getPostIdsForAllLanguages($values['assigned_posts']);
144 51
        $values['assigned_terms'] = glsr(Multilingual::class)->getTermIdsForAllLanguages($values['assigned_terms']);
145 51
        $values['date'] = $this->finalizeDate($values['date']);
146 51
        $values['order'] = $this->finalizeOrder($values['order']);
147 51
        $values['orderby'] = $this->finalizeOrderby($values['orderby']);
148 51
        $values['status'] = $this->finalizeStatus($values['status']);
149 51
        $values['terms'] = $this->finalizeBoolValue($values['terms']);
150 51
        $values['verified'] = $this->finalizeBoolValue($values['verified']);
151 51
        return $values;
152
    }
153
154 51
    protected function finalizeBoolValue(string $value): int
155
    {
156 51
        if (!empty($value)) {
157
            return Cast::toInt(Cast::toBool($value));
158
        }
159 51
        return -1;
160
    }
161
162 51
    protected function finalizeDate($value): array
163
    {
164 51
        $date = array_fill_keys(['after', 'before', 'day', 'inclusive', 'month', 'year'], '');
165 51
        $timestamp = strtotime(Cast::toString($value));
166 51
        if (false !== $timestamp) {
167
            $date['year'] = date('Y', $timestamp);
168
            $date['month'] = date('n', $timestamp);
169
            $date['day'] = date('j', $timestamp);
170
            return $date;
171
        }
172 51
        $date['after'] = glsr(Sanitizer::class)->sanitizeDate(Arr::get($value, 'after'));
173 51
        $date['before'] = glsr(Sanitizer::class)->sanitizeDate(Arr::get($value, 'before'));
174 51
        if (!empty(array_filter($date))) {
175 1
            $date['inclusive'] = Arr::getAs('bool', $value, 'inclusive') ? '=' : '';
176
        }
177 51
        return $date;
178
    }
179
180 51
    protected function finalizeOrder(string $value): string
181
    {
182 51
        return strtoupper($value);
183
    }
184
185 51
    protected function finalizeOrderby(string $value): string
186
    {
187 51
        if ('id' === $value) {
188 1
            return 'p.ID';
189
        }
190 51
        if (in_array($value, ['comment_count', 'menu_order'])) {
191 1
            return Str::prefix($value, 'p.');
192
        }
193 51
        if (in_array($value, ['author', 'date', 'date_gmt'])) {
194 51
            return Str::prefix($value, 'p.post_');
195
        }
196 1
        if (in_array($value, ['rating'])) {
197 1
            return Str::prefix($value, 'r.');
198
        }
199 1
        return $value;
200
    }
201
202 51
    protected function finalizeStatus(string $value): int
203
    {
204 51
        $statuses = [
205 51
            'all' => -1,
206 51
            'approved' => 1,
207 51
            'hold' => 0,
208 51
            'pending' => 0,
209 51
            'publish' => 1,
210 51
            'unapproved' => 0,
211 51
        ];
212 51
        return $statuses[$value] ?? 1;
213
    }
214
}
215