Completed
Branch EDTR/master (2c6b27)
by
unknown
33:34 queued 25:23
created

EntityReorder::mutateAndGetPayload()   D

Complexity

Conditions 15
Paths 1

Size

Total Lines 126

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 15
nc 1
nop 0
dl 0
loc 126
rs 4.7333
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace EventEspresso\core\domain\services\graphql\mutators;
4
5
use EE_Registry;
6
use EEM_Base;
7
use EE_Base_Class;
8
9
use EE_Error;
10
use EventEspresso\core\exceptions\ExceptionStackTraceDisplay;
11
use Exception;
12
use InvalidArgumentException;
13
use ReflectionException;
14
use EventEspresso\core\exceptions\InvalidDataTypeException;
15
use EventEspresso\core\exceptions\InvalidInterfaceException;
16
17
use GraphQL\Type\Definition\ResolveInfo;
18
use RuntimeException;
19
use WPGraphQL\AppContext;
20
use GraphQL\Error\UserError;
21
use GraphQLRelay\Relay;
22
23
class EntityReorder
24
{
25
    /**
26
     * Defines the mutation data modification closure.
27
     *
28
     * @return callable
29
     */
30
    public static function mutateAndGetPayload()
31
    {
32
        /**
33
         * Updates an entity.
34
         *
35
         * @param array       $input   The input for the mutation
36
         * @param AppContext  $context The AppContext passed down to all resolvers
37
         * @param ResolveInfo $info    The ResolveInfo passed down to all resolvers
38
         * @return array
39
         * @throws UserError
40
         * @throws ReflectionException
41
         * @throws InvalidArgumentException
42
         * @throws InvalidInterfaceException
43
         * @throws InvalidDataTypeException
44
         * @throws EE_Error
45
         */
46
        return static function ($input, AppContext $context, ResolveInfo $info) {
47
            /**
48
             * Stop now if a user isn't allowed to reorder.
49
             */
50
            if (! current_user_can('ee_edit_events')) {
51
                throw new UserError(
52
                    esc_html__('Sorry, you do not have the required permissions to reorder entities', 'event_espresso')
53
                );
54
            }
55
56
            $entityGuids = ! empty($input['entityIds']) ? array_map('sanitize_text_field', (array) $input['entityIds']) : [];
57
            $entityType  = ! empty($input['entityType']) ? sanitize_text_field($input['entityType']) : null;
58
59
            /**
60
             * Make sure we have the IDs and entity type
61
             */
62
            if (empty($entityGuids) || empty($entityType)) {
63
                throw new UserError(
64
                    // translators: the placeholders are the names of the fields
65
                    sprintf(esc_html__('%1$s and %2$s are required.', 'event_espresso'), 'entityIds', 'entityType')
66
                );
67
            }
68
69
            $model = EE_Registry::instance()->load_model($entityType);
70
71
            if (!($model instanceof EEM_Base)) {
72
                throw new UserError(
73
                    esc_html__(
74
                        'A valid data model could not be obtained. Did you supply a valid entity type?',
75
                        'event_espresso'
76
                    )
77
                );
78
            }
79
80
            // convert GUIDs to DB IDs
81
            $entityDbids = array_map(function ($entityGuid) {
82
                $id_parts = Relay::fromGlobalId($entityGuid);
83
                return ! empty($id_parts['id']) ? absint($id_parts['id']) : 0;
84
            }, (array) $entityGuids);
85
            // remove 0 values
86
            $entityDbids = array_filter($entityDbids);
87
88
            /**
89
             * If we could not get DB IDs for some GUIDs
90
             */
91
            if (count($entityDbids) !== count($entityGuids)) {
92
                throw new UserError(
93
                    esc_html__('Sorry, update cancelled due to missing or invalid entity IDs.', 'event_espresso')
94
                );
95
            }
96
97
            // e.g. DTT_ID, TKT_ID
98
            $primaryKey = $model->get_primary_key_field()->get_name();
99
            // e.g. "DTT_ID" will give us "DTT"
100
            $keyPrefix = explode('_', $primaryKey)[0];
101
            $deletedKey  = $keyPrefix . '_deleted'; // e.g. "TKT_deleted"
102
103
            $entities = $model::instance()->get_all([
104
                [
105
                    $primaryKey => ['IN', $entityDbids],
106
                    $deletedKey => ['IN', [true, false]],
107
                ],
108
            ]);
109
110
            /**
111
             * If we could not get exactly same number of entities for the given DB IDs
112
             */
113
            if (count($entityDbids) !== count($entities)) {
114
                throw new UserError(esc_html__('Sorry, update cancelled due to missing entities.', 'event_espresso'));
115
            }
116
117
            // Make sure we have an instance for every ID.
118
            foreach ($entityDbids as $entityDbid) {
119
                if (isset($entities[ $entityDbid ]) && $entities[ $entityDbid ] instanceof EE_Base_Class) {
120
                    continue;
121
                }
122
                throw new UserError(esc_html__('Sorry, update cancelled due to invalid entities.', 'event_espresso'));
123
            }
124
125
            $orderKey  = $keyPrefix . '_order'; // e.g. "TKT_order"
126
127
            $ok = false;
128
129
            // We do not want to continue reorder if one fails.
130
            // Thus wrap whole loop in try-catch
131
            try {
132
                foreach ($entityDbids as $order => $entityDbid) {
133
                    $args = [
134
                        $orderKey => $order + 1,
135
                    ];
136
                    $entities[ $entityDbid ]->save($args);
137
                }
138
                $ok = true;
139
            } catch (Exception $exception) {
140
                new ExceptionStackTraceDisplay(
141
                    new RuntimeException(
142
                        sprintf(
143
                            esc_html__(
144
                                'Failed to update order because of the following error(s): %1$s',
145
                                'event_espresso'
146
                            ),
147
                            $exception->getMessage()
148
                        )
149
                    )
150
                );
151
            }
152
153
            return compact('ok');
154
        };
155
    }
156
}
157