Completed
Push — master ( f8c4bd...25c22e )
by Nate
09:23 queued 07:32
created

ObjectAssociations::save()   B

Complexity

Conditions 6
Paths 3

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

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