Completed
Push — develop ( 422da7...0b9ba8 )
by Nate
03:22
created

ObjectAssociations   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 300
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 13

Test Coverage

Coverage 18.45%

Importance

Changes 0
Metric Value
wmc 33
lcom 2
cbo 13
dl 0
loc 300
ccs 19
cts 103
cp 0.1845
rs 9.76
c 0
b 0
f 0

18 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 10 1
A ensureTableExists() 0 10 2
A createTable() 0 8 1
A findObjectIdByElement() 0 5 1
A findObjectId() 0 11 2
A findElementId() 0 11 2
A getQuery() 0 4 1
A associationQuery() 0 10 1
A existingAssociations() 0 13 4
A getElementByObjectId() 0 11 2
A findElementByObjectId() 0 12 2
A findObjectIdByElementId() 0 13 2
A query() 0 13 1
A associations() 0 9 1
B save() 0 22 6
A resolveFieldFromQuery() 0 9 2
A tableAlias() 0 4 1
A recordClass() 0 4 1
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\Element;
13
use craft\base\ElementInterface;
14
use craft\errors\ElementNotFoundException;
15
use craft\helpers\Json;
16
use flipbox\craft\sortable\associations\db\SortableAssociationQueryInterface;
17
use flipbox\craft\sortable\associations\records\SortableAssociationInterface;
18
use flipbox\craft\sortable\associations\services\SortableAssociations;
19
use flipbox\ember\helpers\SiteHelper;
20
use flipbox\ember\services\traits\records\Accessor;
21
use flipbox\ember\validators\MinMaxValidator;
22
use flipbox\hubspot\db\ObjectAssociationQuery;
23
use flipbox\hubspot\fields\Objects;
24
use flipbox\hubspot\HubSpot;
25
use flipbox\hubspot\records\ObjectAssociation;
26
use flipbox\hubspot\migrations\ObjectAssociation as ObjectAssociationMigration;
27
28
/**
29
 * @author Flipbox Factory <[email protected]>
30
 * @since 1.0.0
31
 *
32
 * @method ObjectAssociationQuery parentGetQuery($config = [])
33
 * @method ObjectAssociation create(array $attributes = [])
34
 * @method ObjectAssociation find($identifier)
35
 * @method ObjectAssociation get($identifier)
36
 * @method ObjectAssociation findByCondition($condition = [])
37
 * @method ObjectAssociation getByCondition($condition = [])
38
 * @method ObjectAssociation findByCriteria($criteria = [])
39
 * @method ObjectAssociation getByCriteria($criteria = [])
40
 * @method ObjectAssociation[] findAllByCondition($condition = [])
41
 * @method ObjectAssociation[] getAllByCondition($condition = [])
42
 * @method ObjectAssociation[] findAllByCriteria($criteria = [])
43
 * @method ObjectAssociation[] getAllByCriteria($criteria = [])
44
 */
45
class ObjectAssociations extends SortableAssociations
46
{
47
    use Accessor {
48
        getQuery as parentGetQuery;
49
    }
50
51
    /**
52
     * @inheritdoc
53
     */
54
    const SOURCE_ATTRIBUTE = ObjectAssociation::SOURCE_ATTRIBUTE;
55
56
    /**
57
     * @inheritdoc
58
     */
59
    const TARGET_ATTRIBUTE = ObjectAssociation::TARGET_ATTRIBUTE;
60
61
    /**
62
     * @inheritdoc
63
     */
64 3
    public function init()
65
    {
66 3
        $settings = HubSpot::getInstance()->getSettings();
67 3
        $this->cacheDuration = $settings->associationsCacheDuration;
68 3
        $this->cacheDependency = $settings->associationsCacheDependency;
69
70 3
        parent::init();
71
72 3
        $this->ensureTableExists();
73 3
    }
74
75
    /**
76
     * @throws \Throwable
77
     */
78 3
    public function ensureTableExists()
79
    {
80 3
        if (!in_array(
81 3
            Craft::$app->getDb()->tablePrefix . ObjectAssociation::tableAlias(),
82 3
            Craft::$app->getDb()->getSchema()->tableNames,
83 3
            true
84
        )) {
85 3
            $this->createTable();
86
        }
87 3
    }
88
89
    /**
90
     * @return bool
91
     * @throws \Throwable
92
     */
93 3
    private function createTable(): bool
94
    {
95 3
        ob_start();
96 3
            (new ObjectAssociationMigration())->up();
97 3
        ob_end_clean();
98
99 3
        return true;
100
    }
101
    
102
    /**
103
     * @param ElementInterface $element
104
     * @param Objects $field
105
     * @return string|null
106
     */
107
    public function findObjectIdByElement(ElementInterface $element, Objects $field)
108
    {
109
        /** @var Element $element */
110
        return $this->findObjectId($field->id, $element->getId(), $element->siteId);
111
    }
112
113
    /**
114
     * @noinspection PhpDocMissingThrowsInspection
115
     *
116
     * @param string $fieldId
117
     * @param string $elementId
118
     * @param string|null $siteId
119
     * @return null|string
120
     */
121
    public function findObjectId(string $fieldId, string $elementId, string $siteId = null)
122
    {
123
        $objectId = HubSpot::getInstance()->getObjectAssociations()->getQuery([
124
            'select' => ['objectId'],
125
            'elementId' => $elementId,
126
            'siteId' => SiteHelper::ensureSiteId($siteId),
127
            'fieldId' => $fieldId
128
        ])->scalar();
129
130
        return is_string($objectId) ? $objectId : null;
131
    }
132
133
    /**
134
     * @noinspection PhpDocMissingThrowsInspection
135
     *
136
     * @param string $fieldId
137
     * @param string $elementId
138
     * @param string|null $siteId
139
     * @return null|string
140
     */
141
    public function findElementId(string $fieldId, string $elementId, string $siteId = null)
142
    {
143
        $elementId = HubSpot::getInstance()->getObjectAssociations()->getQuery([
144
            'select' => ['elementId'],
145
            'objectId' => $elementId,
146
            'siteId' => SiteHelper::ensureSiteId($siteId),
147
            'fieldId' => $fieldId
148
        ])->scalar();
149
150
        return is_string($elementId) ? $elementId : null;
151
    }
152
153
    /**
154
     * @inheritdoc
155
     * @return ObjectAssociationQuery
156
     */
157
    public function getQuery($config = []): SortableAssociationQueryInterface
158
    {
159
        return $this->parentGetQuery($config);
160
    }
161
162
    /**
163
     * @inheritdoc
164
     * @return ObjectAssociationQuery
165
     */
166
    protected function associationQuery(
167
        SortableAssociationInterface $record
168
    ): SortableAssociationQueryInterface {
169
        /** @var ObjectAssociation $record */
170
        return $this->query(
171
            $record->{static::SOURCE_ATTRIBUTE},
172
            $record->fieldId,
173
            $record->siteId
174
        );
175
    }
176
177
    /**
178
     * @inheritdoc
179
     * @param ObjectAssociationQuery $query
180
     */
181
    protected function existingAssociations(
182
        SortableAssociationQueryInterface $query
183
    ): array {
184
        $source = $this->resolveStringAttribute($query, 'element');
185
        $field = $this->resolveStringAttribute($query, 'field');
186
        $site = $this->resolveStringAttribute($query, 'siteId');
187
188
        if ($source === null || $field === null || $site === null) {
189
            return [];
190
        }
191
192
        return $this->associations($source, $field, $site);
193
    }
194
195
196
    /**
197
     * @param string $objectId
198
     * @return ElementInterface
199
     * @throws ElementNotFoundException
200
     */
201
    public function getElementByObjectId(string $objectId): ElementInterface
202
    {
203
        if (!$element = $this->findElementByObjectId($objectId)) {
204
            throw new ElementNotFoundException(sprintf(
205
                "Unable to get element from HubSpot Id: '%s'.",
206
                $objectId
207
            ));
208
        }
209
210
        return $element;
211
    }
212
213
    /**
214
     * @param string $objectId
215
     * @return ElementInterface|null
216
     */
217
    public function findElementByObjectId(string $objectId)
218
    {
219
        $record = $this->findByCondition([
220
            'objectId' => $objectId
221
        ]);
222
223
        if ($record === null) {
224
            return null;
225
        }
226
227
        return $record->getElement();
228
    }
229
230
    /**
231
     * Find the HubSpot Id by Element Id
232
     *
233
     * @param int $id
234
     * @return string|null
235
     */
236
    public function findObjectIdByElementId(int $id)
237
    {
238
        $objectId = $this->getQuery()
239
            ->select(['objectId'])
240
            ->element($id)
241
            ->scalar();
242
243
        if (!$objectId) {
244
            return null;
245
        }
246
247
        return $objectId;
248
    }
249
250
251
    /**
252
     * @param $source
253
     * @param int $fieldId
254
     * @param int $siteId
255
     * @return ObjectAssociationQuery
256
     */
257
    private function query(
258
        $source,
259
        int $fieldId,
260
        int $siteId
261
    ): ObjectAssociationQuery {
262
        return $this->getQuery()
263
            ->where([
264
                static::SOURCE_ATTRIBUTE => $source,
265
                'fieldId' => $fieldId,
266
                'siteId' => $siteId
267
            ])
268
            ->orderBy(['sortOrder' => SORT_ASC]);
269
    }
270
271
    /**
272
     * @param $source
273
     * @param int $fieldId
274
     * @param int $siteId
275
     * @return array
276
     */
277
    private function associations(
278
        $source,
279
        int $fieldId,
280
        int $siteId
281
    ): array {
282
        return $this->query($source, $fieldId, $siteId)
283
            ->indexBy(static::TARGET_ATTRIBUTE)
284
            ->all();
285
    }
286
287
    /**
288
     * @inheritdoc
289
     * @param bool $validate
290
     * @throws \Exception
291
     */
292
    public function save(
293
        SortableAssociationQueryInterface $query,
294
        bool $validate = true
295
    ): bool {
296
        if ($validate === true && null !== ($field = $this->resolveFieldFromQuery($query))) {
297
            $error = '';
298
            (new MinMaxValidator([
299
                'min' => $field->min ? (int)$field->min : null,
300
                'max' => $field->max ? (int)$field->max : null
301
            ]))->validate($query, $error);
302
303
            if (!empty($error)) {
304
                HubSpot::error(sprintf(
305
                    "Hubspot Resource failed to save due to the following validation errors: '%s'",
306
                    Json::encode($error)
307
                ));
308
                return false;
309
            }
310
        }
311
312
        return parent::save($query);
313
    }
314
315
    /**
316
     * @param SortableAssociationQueryInterface $query
317
     * @return Objects|null
318
     */
319
    protected function resolveFieldFromQuery(
320
        SortableAssociationQueryInterface $query
321
    ) {
322
        if (null === ($fieldId = $this->resolveStringAttribute($query, 'field'))) {
323
            return null;
324
        }
325
326
        return HubSpot::getInstance()->getObjectsField()->findById($fieldId);
327
    }
328
329
    /**
330
     * @inheritdoc
331
     */
332
    protected static function tableAlias(): string
333
    {
334
        return ObjectAssociation::tableAlias();
335
    }
336
337
    /**
338
     * @inheritdoc
339
     */
340
    public static function recordClass(): string
341
    {
342
        return ObjectAssociation::class;
343
    }
344
}
345