Completed
Push — develop ( f7632c...dc861e )
by Nate
09:06
created

ObjectsField::getItemActions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 14
ccs 0
cts 8
cp 0
rs 9.7998
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 2
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://flipboxfactory.com/software/hubspot/license
6
 * @link       https://www.flipboxfactory.com/software/hubspot/
7
 */
8
9
namespace flipbox\hubspot\services;
10
11
use Craft;
12
use craft\base\ElementInterface;
13
use craft\base\FieldInterface;
14
use craft\helpers\Component as ComponentHelper;
15
use craft\helpers\StringHelper;
16
use flipbox\craft\sortable\associations\db\SortableAssociationQueryInterface;
17
use flipbox\craft\sortable\associations\records\SortableAssociationInterface;
18
use flipbox\craft\sortable\associations\services\SortableFields;
19
use flipbox\hubspot\db\ObjectAssociationQuery;
20
use flipbox\hubspot\events\RegisterResourceFieldActionsEvent;
21
use flipbox\hubspot\fields\actions\ObjectActionInterface;
22
use flipbox\hubspot\fields\actions\ObjectItemActionInterface;
23
use flipbox\hubspot\fields\actions\SyncItemFrom;
24
use flipbox\hubspot\fields\actions\SyncItemTo;
25
use flipbox\hubspot\fields\Objects;
26
use flipbox\hubspot\HubSpot;
27
use flipbox\hubspot\records\ObjectAssociation;
28
use flipbox\hubspot\web\assets\objects\Objects as ObjectsFieldAsset;
29
use yii\base\Exception;
30
31
/**
32
 * @author Flipbox Factory <[email protected]>
33
 * @since 1.0.0
34
 */
35
class ObjectsField extends SortableFields
36
{
37
    /**
38
     * @inheritdoc
39
     */
40
    const SOURCE_ATTRIBUTE = ObjectAssociation::SOURCE_ATTRIBUTE;
41
42
    /**
43
     * @inheritdoc
44
     */
45
    const TARGET_ATTRIBUTE = ObjectAssociation::TARGET_ATTRIBUTE;
46
47
    /**
48
     * HubSpot Object Association fields, indexed by their Id.
49
     *
50
     * @var Objects[]
51
     */
52
    private $fields = [];
53
54
    /**
55
     * @inheritdoc
56
     */
57
    protected static function tableAlias(): string
58
    {
59
        return ObjectAssociation::tableAlias();
60
    }
61
62
    /**
63
     * @param int $id
64
     * @return Objects|null
65
     */
66
    public function findById(int $id)
67
    {
68
        if (!array_key_exists($id, $this->fields)) {
69
            $field = Craft::$app->getFields()->getFieldById($id);
70
            if (!$field instanceof Objects) {
71
                $field = null;
72
            }
73
74
            $this->fields[$id] = $field;
75
        }
76
77
        return $this->fields[$id];
78
    }
79
80
    /**
81
     * @inheritdoc
82
     * @return ObjectAssociationQuery
83
     * @throws Exception
84
     */
85
    protected function getQuery(
86
        FieldInterface $field,
87
        ElementInterface $element = null
88
    ): SortableAssociationQueryInterface {
89
        $query = $this->baseQuery($field, $element);
90
91
        /** @var Objects $field */
92
93
        if ($field->max !== null) {
94
            $query->limit($field->max);
95
        }
96
97
        return $query;
98
    }
99
100
    /**
101
     * @param FieldInterface $field
102
     * @param ElementInterface|null $element
103
     * @return ObjectAssociationQuery
104
     * @throws Exception
105
     */
106
    private function baseQuery(
107
        FieldInterface $field,
108
        ElementInterface $element = null
109
    ): ObjectAssociationQuery {
110
        /** @var Objects $field */
111
        $this->ensureField($field);
112
113
        $query = HubSpot::getInstance()->getObjectAssociations()->getQuery()
114
            ->field($field->id)
115
            ->site($this->targetSiteId($element));
116
117
        $query->{ObjectAssociation::SOURCE_ATTRIBUTE} = $element === null ? null : $element->getId();
118
119
        return $query;
120
    }
121
122
    /*******************************************
123
     * NORMALIZE VALUE
124
     *******************************************/
125
126
    /**
127
     * @inheritdoc
128
     * @throws Exception
129
     */
130
    protected function normalizeQueryInputValue(
131
        FieldInterface $field,
132
        $value,
133
        int &$sortOrder,
134
        ElementInterface $element = null
135
    ): SortableAssociationInterface {
136
        if (is_array($value)) {
137
            $value = StringHelper::toString($value);
138
        }
139
140
        $query = $this->baseQuery($field, $element)
141
            ->sortOrder($sortOrder++);
142
143
        $query->{ObjectAssociation::TARGET_ATTRIBUTE} = $value;
144
145
        return $query;
146
    }
147
148
    /**
149
     * @param FieldInterface $field
150
     * @throws Exception
151
     */
152
    private function ensureField(FieldInterface $field)
153
    {
154
        if (!$field instanceof Objects) {
155
            throw new Exception(sprintf(
156
                "The field must be an instance of '%s', '%s' given.",
157
                (string)Objects::class,
158
                (string)get_class($field)
159
            ));
160
        }
161
    }
162
163
164
    /**
165
     * @param Objects $field
166
     * @param ObjectAssociationQuery $query
167
     * @param ElementInterface|null $element
168
     * @param bool $static
169
     * @return null|string
170
     * @throws Exception
171
     * @throws \Twig_Error_Loader
172
     */
173
    public function getInputHtml(
174
        Objects $field,
175
        ObjectAssociationQuery $query,
176
        ElementInterface $element = null,
177
        bool $static = false
178
    ) {
179
        Craft::$app->getView()->registerAssetBundle(ObjectsFieldAsset::class);
180
181
        return Craft::$app->getView()->renderTemplate(
182
            $field::INPUT_TEMPLATE_PATH,
183
            [
184
                'field' => $field,
185
                'element' => $element,
186
                'value' => $query,
187
                'actions' => $this->getActionHtml($field, $element),
188
                'itemActions' => $this->getItemActionHtml($field, $element),
189
                'static' => $static
190
            ]
191
        );
192
    }
193
194
    /**
195
     * @param Objects $field
196
     * @return null|string
197
     * @throws Exception
198
     * @throws \Twig_Error_Loader
199
     */
200
    public function getSettingsHtml(
201
        Objects $field
202
    ) {
203
        return Craft::$app->getView()->renderTemplate(
204
            'hubspot/_components/fieldtypes/Objects/settings',
205
            [
206
                'field' => $field,
207
                'availableActions' => $this->getAvailableActions($field),
208
                'availableItemActions' => $this->getAvailableItemActions($field)
209
            ]
210
        );
211
    }
212
213
214
    /*******************************************
215
     * ACTIONS
216
     *******************************************/
217
218
    /**
219
     * @param Objects $field
220
     * @return ObjectActionInterface[]
221
     * @throws \craft\errors\MissingComponentException
222
     * @throws \yii\base\InvalidConfigException
223
     */
224
    public function getAvailableActions(Objects $field): array
225
    {
226
        $event = new RegisterResourceFieldActionsEvent([
227
            'actions' => []
228
        ]);
229
230
        $field->trigger(
231
            $field::EVENT_REGISTER_AVAILABLE_ACTIONS,
232
            $event
233
        );
234
        return $this->resolveActions($event->actions, ObjectActionInterface::class);
235
    }
236
237
    /**
238
     * @param Objects $field
239
     * @param ElementInterface|null $element
240
     * @return ObjectActionInterface[]
241
     * @throws \craft\errors\MissingComponentException
242
     * @throws \yii\base\InvalidConfigException
243
     */
244
    public function getActions(Objects $field, ElementInterface $element = null): array
245
    {
246
        $actions = [];
0 ignored issues
show
Unused Code introduced by
$actions is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
247
248
        $event = new RegisterResourceFieldActionsEvent([
249
            'actions' => $field->selectedActions,
250
            'element' => $element
251
        ]);
252
253
        $field->trigger(
254
            $field::EVENT_REGISTER_ACTIONS,
255
            $event
256
        );
257
258
        return $this->resolveActions($event->actions, ObjectActionInterface::class);
259
    }
260
261
    /**
262
     * @param Objects $field
263
     * @return ObjectActionInterface[]
264
     * @throws \craft\errors\MissingComponentException
265
     * @throws \yii\base\InvalidConfigException
266
     */
267
    public function getAvailableItemActions(Objects $field): array
268
    {
269
        $event = new RegisterResourceFieldActionsEvent([
270
            'actions' => [
271
                SyncItemFrom::class,
272
                SyncItemTo::class,
273
            ]
274
        ]);
275
276
        $field->trigger(
277
            $field::EVENT_REGISTER_AVAILABLE_ITEM_ACTIONS,
278
            $event
279
        );
280
281
        return $this->resolveActions($event->actions, ObjectItemActionInterface::class);
282
    }
283
284
    /**
285
     * @param Objects $field
286
     * @param ElementInterface|null $element
287
     * @return ObjectItemActionInterface[]
288
     * @throws \craft\errors\MissingComponentException
289
     * @throws \yii\base\InvalidConfigException
290
     */
291
    public function getItemActions(Objects $field, ElementInterface $element = null): array
292
    {
293
        $event = new RegisterResourceFieldActionsEvent([
294
            'actions' => $field->selectedItemActions,
295
            'element' => $element
296
        ]);
297
298
        $field->trigger(
299
            $field::EVENT_REGISTER_ITEM_ACTIONS,
300
            $event
301
        );
302
303
        return $this->resolveActions($event->actions, ObjectItemActionInterface::class);
304
    }
305
306
    /**
307
     * @param array $actions
308
     * @param string $instance
309
     * @return array
310
     * @throws \craft\errors\MissingComponentException
311
     * @throws \yii\base\InvalidConfigException
312
     */
313
    protected function resolveActions(array $actions, string $instance)
314
    {
315
        foreach ($actions as $i => $action) {
316
            // $action could be a string or config array
317
            if (!$action instanceof $instance) {
318
                $actions[$i] = $action = ComponentHelper::createComponent($action, $instance);
319
320
                if ($actions[$i] === null) {
321
                    unset($actions[$i]);
322
                }
323
            }
324
        }
325
326
        return array_values($actions);
327
    }
328
329
    /**
330
     * @param Objects $field
331
     * @param ElementInterface|null $element
332
     * @return array
333
     * @throws \craft\errors\MissingComponentException
334
     * @throws \yii\base\InvalidConfigException
335
     */
336
    protected function getActionHtml(Objects $field, ElementInterface $element = null): array
337
    {
338
        $actionData = [];
339
340
        foreach ($this->getActions($field, $element) as $action) {
341
            $actionData[] = [
342
                'type' => get_class($action),
343
                'destructive' => $action->isDestructive(),
344
                'params' => [],
345
                'name' => $action->getTriggerLabel(),
346
                'trigger' => $action->getTriggerHtml(),
347
                'confirm' => $action->getConfirmationMessage(),
348
            ];
349
        }
350
351
        return $actionData;
352
    }
353
354
    /**
355
     * @param Objects $field
356
     * @param ElementInterface|null $element
357
     * @return array
358
     * @throws \craft\errors\MissingComponentException
359
     * @throws \yii\base\InvalidConfigException
360
     */
361
    protected function getItemActionHtml(Objects $field, ElementInterface $element = null): array
362
    {
363
        $actionData = [];
364
365
        foreach ($this->getItemActions($field, $element) as $action) {
366
            $actionData[] = [
367
                'type' => get_class($action),
368
                'destructive' => $action->isDestructive(),
369
                'params' => [],
370
                'name' => $action->getTriggerLabel(),
371
                'trigger' => $action->getTriggerHtml(),
372
                'confirm' => $action->getConfirmationMessage(),
373
            ];
374
        }
375
376
        return $actionData;
377
    }
378
}
379