Completed
Branch EDTR/gql-server-side (8c11b8)
by
unknown
25:44 queued 17:18
created

DatetimeConnectionResolver   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 207
Duplicated Lines 27.05 %

Coupling/Cohesion

Components 0
Dependencies 4

Importance

Changes 0
Metric Value
dl 56
loc 207
rs 9.84
c 0
b 0
f 0
wmc 32
lcom 0
cbo 4

5 Methods

Rating   Name   Duplication   Size   Complexity  
A get_query() 0 4 1
A get_items() 0 6 2
A should_execute() 0 8 2
F get_query_args() 21 106 18
B sanitizeInputFields() 35 35 9

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace EventEspresso\core\domain\services\graphql\connection_resolvers;
4
5
use EE_Error;
6
use EEM_Datetime;
7
use EE_Event;
8
use EE_Ticket;
9
use EE_Checkin;
10
use EventEspresso\core\exceptions\InvalidDataTypeException;
11
use EventEspresso\core\exceptions\InvalidInterfaceException;
12
use InvalidArgumentException;
13
use WPGraphQL\Data\Connection\AbstractConnectionResolver;
14
use WPGraphQL\Model\Post;
15
use WPGraphQL\Types;
16
17
/**
18
 * Class DatetimeConnectionResolver
19
 *
20
 */
21
class DatetimeConnectionResolver extends AbstractConnectionResolver
22
{
23
24
    /**
25
     * @return EEM_Datetime
26
     * @throws EE_Error
27
     * @throws InvalidArgumentException
28
     * @throws InvalidDataTypeException
29
     * @throws InvalidInterfaceException
30
     */
31
    // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps
32
    public function get_query()
33
    {
34
        return EEM_Datetime::instance();
35
    }
36
37
    /**
38
     * Return an array of items from the query
39
     *
40
     * @return array
41
     */
42
    // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps
43
    public function get_items()
44
    {
45
        $results = $this->query->get_col($this->query_args);
46
47
        return ! empty($results) ? $results : [];
48
    }
49
50
    /**
51
     * Determine whether the Query should execute. If it's determined that the query should
52
     * not be run based on context such as, but not limited to, who the user is, where in the
53
     * ResolveTree the Query is, the relation to the node the Query is connected to, etc
54
     *
55
     * Return false to prevent the query from executing.
56
     *
57
     * @return bool
58
     */
59
    // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps
60
    public function should_execute()
61
    {
62
        if (false === $this->should_execute) {
63
            return false;
64
        }
65
66
        return $this->should_execute;
67
    }
68
69
    /**
70
     * Here, we map the args from the input, then we make sure that we're only querying
71
     * for IDs. The IDs are then passed down the resolve tree, and deferred resolvers
72
     * handle batch resolution of the posts.
73
     *
74
     * @return array
75
     */
76
    // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps
77
    public function get_query_args()
78
    {
79
        $where_params = [];
80
        $query_args   = [];
81
        /**
82
         * Prepare for later use
83
         */
84
        $last  = ! empty($this->args['last']) ? $this->args['last'] : null;
85
        $first = ! empty($this->args['first']) ? $this->args['first'] : null;
86
87
        /**
88
         * Set limit the highest value of $first and $last, with a (filterable) max of 100
89
         */
90
        $query_args['limit'] = min(
91
            max(absint($first), absint($last), 10),
92
            $this->query_amount
93
        ) + 1;
94
95
        /**
96
         * Collect the input_fields and sanitize them to prepare them for sending to the Query
97
         */
98
        $input_fields = [];
99
        if (! empty($this->args['where'])) {
100
            $input_fields = $this->sanitizeInputFields($this->args['where']);
101
        }
102
103
        /**
104
         * Determine where we're at in the Graph and adjust the query context appropriately.
105
         *
106
         * For example, if we're querying for datetime as a field of event query, this will automatically
107
         * set the query to pull datetimes that belong to that event.
108
         * We can set more cases for other source types.
109
         */
110
        if (is_object($this->source)) {
111
            switch (true) {
112
                // It's surely an event
113
                case $this->source instanceof Post:
114
                    $where_params['EVT_ID'] = $this->source->ID;
115
                    break;
116
                case $this->source instanceof EE_Event:
117
                    $where_params['EVT_ID'] = $this->source->ID();
118
                    break;
119
                case $this->source instanceof EE_Ticket:
120
                    $where_params['Ticket.TKT_ID'] = $this->source->ID();
121
                    break;
122
                case $this->source instanceof EE_Checkin:
123
                    $where_params['Checkin.CHK_ID'] = $this->source->ID();
124
                    break;
125
            }
126
        }
127
128
        /**
129
         * Merge the input_fields with the default query_args
130
         */
131
        if (! empty($input_fields)) {
132
            $where_params = array_merge($where_params, $input_fields);
133
        }
134
135
        // ID of the offset datetime.
136
        $offset = $this->get_offset();
137
138
        /**
139
         * Map the orderby inputArgs to the WP_Query
140
         */
141 View Code Duplication
        if (! empty($this->args['where']['orderby']) && is_array($this->args['where']['orderby'])) {
142
            $query_args['order_by'] = [];
143
            foreach ($this->args['where']['orderby'] as $orderby_input) {
144
                $query_args['order_by'][ $orderby_input['field'] ] = $orderby_input['order'];
145
            }
146
        } elseif ($offset) {
147
            $compare = ! empty($last) ? '<' : '>';
148
            $where_params['DTT_ID'] = array($compare, $offset);
149
        }
150
151 View Code Duplication
        if (! empty($this->args['where']['upcoming'])) {
152
            $where_params['DTT_EVT_start'] = array(
153
                '>',
154
                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start')
155
            );
156
        }
157
158
        if (! empty($this->args['where']['active'])) {
159
            $where_params['DTT_EVT_start'] = array(
160
                '<',
161
                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start')
162
            );
163
            $where_params['DTT_EVT_end'] = array(
164
                '>',
165
                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end')
166
            );
167
        }
168
169 View Code Duplication
        if (! empty($this->args['where']['expired'])) {
170
            $where_params['DTT_EVT_end'] = array(
171
                '<',
172
                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end')
173
            );
174
        }
175
176
        $query_args[] = $where_params;
177
        
178
        /**
179
         * Return the $query_args
180
         */
181
        return $query_args;
182
    }
183
184
185
    /**
186
     * This sets up the "allowed" args, and translates the GraphQL-friendly keys to model
187
     * friendly keys.
188
     *
189
     * @param array $where_args
190
     * @return array
191
     */
192 View Code Duplication
    public function sanitizeInputFields(array $where_args)
193
    {
194
        $arg_mapping = [
195
            'eventId'   => 'EVT_ID',
196
            'ticketId'  => 'Ticket.TKT_ID',
197
        ];
198
199
        $query_args = [];
200
201
        foreach ($where_args as $arg => $value) {
202
            if (! array_key_exists($arg, $arg_mapping)) {
203
                continue;
204
            }
205
206
            if (is_array($value) && ! empty($value)) {
207
                $value = array_map(
208
                    function ($value) {
209
                        if (is_string($value)) {
210
                            $value = sanitize_text_field($value);
211
                        }
212
                        return $value;
213
                    },
214
                    $value
215
                );
216
            } elseif (is_string($value)) {
217
                $value = sanitize_text_field($value);
218
            }
219
            $query_args[ $arg_mapping[ $arg ] ] = $value;
220
        }
221
222
        /**
223
         * Return the Query Args
224
         */
225
        return ! empty($query_args) && is_array($query_args) ? $query_args : [];
226
    }
227
}
228