Completed
Push — develop ( 0f5a88...a06987 )
by Nate
04:58
created

OrganizationRelationship::associationDelta()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 32
ccs 0
cts 25
cp 0
rs 9.408
c 0
b 0
f 0
cc 4
nc 4
nop 0
crap 20
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://flipboxfactory.com/software/organization/license
6
 * @link       https://www.flipboxfactory.com/software/organization/
7
 */
8
9
namespace flipbox\organizations\relationships;
10
11
use craft\elements\User;
12
use craft\helpers\ArrayHelper;
13
use craft\helpers\Json;
14
use flipbox\craft\ember\helpers\QueryHelper;
15
use flipbox\organizations\elements\Organization;
16
use flipbox\organizations\Organizations;
17
use flipbox\organizations\queries\UserAssociationQuery;
18
use flipbox\organizations\records\UserAssociation;
19
use Tightenco\Collect\Support\Collection;
20
21
/**
22
 * Manages Organizations associated to Users
23
 *
24
 * @author Flipbox Factory <[email protected]>
25
 * @since 2.0.0
26
 * *
27
 * @method UserAssociation findOrCreate($object)
28
 * @method UserAssociation findOne($object = null)
29
 * @method UserAssociation findOrFail($object)
30
 */
31
class OrganizationRelationship implements RelationshipInterface
32
{
33
    use RelationshipTrait;
34
35
    /**
36
     * @var User
37
     */
38
    private $user;
39
40
    /**
41
     * @param User $user
42
     */
43
    public function __construct(User $user)
44
    {
45
        $this->user = $user;
46
    }
47
48
49
    /************************************************************
50
     * COLLECTION
51
     ************************************************************/
52
53
    /**
54
     * @inheritDoc
55
     * @return Organization[]|Collection
56
     */
57
    public function getCollection(): Collection
58
    {
59
        return $this->getRelationships()
60
            ->sortBy('organizationOrder')
61
            ->pluck('organization');
62
    }
63
64
    /**
65
     * @inheritDoc
66
     * @return Collection
67
     */
68
    protected function existingRelationships(): Collection
69
    {
70
        $relationships = $this->query()
71
            ->with('types')
72
            ->all();
73
74
        // 'eager' load where we'll pre-populate all of the associations
75
        $elements = Organization::find()
76
            ->id(array_keys($relationships))
77
            ->anyStatus()
78
            ->limit(null)
79
            ->indexBy('id')
80
            ->all();
81
82
        return (new Collection($relationships))
83
            ->transform(function (UserAssociation $association, $key) use ($elements) {
84
                if (isset($elements[$key])) {
85
                    $association->setOrganization($elements[$key]);
86
                    $association->setUser($this->user);
87
                }
88
                return $association;
89
            });
90
    }
91
92
    /************************************************************
93
     * QUERY
94
     ************************************************************/
95
96
    /**
97
     * @return UserAssociationQuery
98
     */
99
    protected function query(): UserAssociationQuery
100
    {
101
        /** @noinspection PhpUndefinedMethodInspection */
102
        return UserAssociation::find()
103
            ->setUserId($this->user->getId() ?: false)
0 ignored issues
show
Security Bug introduced by
It seems like $this->user->getId() ?: false can also be of type false; however, flipbox\craft\ember\quer...ibuteTrait::setUserId() does only seem to accept string|array<integer,str...ft\elements\User>>|null, did you maybe forget to handle an error condition?
Loading history...
104
            ->orderBy([
105
                'organizationOrder' => SORT_ASC
106
            ])
107
            ->limit(null)
108
            ->indexBy('organizationId');
109
    }
110
111
112
    /************************************************************
113
     * QUERY
114
     ************************************************************/
115
116
    /**
117
     * @param $object
118
     * @return UserAssociation
119
     */
120
    protected function create($object): UserAssociation
121
    {
122
        return (new UserAssociation())
123
            ->setOrganization($this->resolve($object))
124
            ->setUser($this->user);
125
    }
126
127
128
    /*******************************************
129
     * DELTA
130
     *******************************************/
131
132
    /**
133
     * @inheritDoc
134
     */
135
    protected function delta(): array
136
    {
137
        $existingAssociations = $this->query()->all();
138
139
        $associations = [];
140
        $order = 1;
141
142
        /** @var UserAssociation $newAssociation */
143
        foreach ($this->getRelationships()->sortBy('organizationOrder') as $newAssociation) {
144
            if (null === ($association = ArrayHelper::remove(
145
                    $existingAssociations,
146
                    $newAssociation->getOrganizationId()
147
                ))) {
148
                $association = $newAssociation;
149
            } elseif ($newAssociation->getTypes()->isMutated()) {
150
                /** @var UserAssociation $association */
151
                $association->getTypes()->clear()->add(
152
                    $newAssociation->getTypes()->getCollection()
153
                );
154
            }
155
156
            $association->userOrder = $newAssociation->userOrder;
157
            $association->organizationOrder = $order++;
158
            $association->state = $newAssociation->state;
159
160
            $associations[] = $association;
161
        }
162
163
        return [$associations, $existingAssociations];
164
    }
165
166
167
    /*******************************************
168
     * UTILS
169
     *******************************************/
170
171
    /**
172
     * @param UserAssociation|Organization|int|array|null $object
173
     * @return int|null
174
     */
175
    protected function findKey($object = null)
176
    {
177
        if (null === ($element = $this->resolve($object))) {
178
            Organizations::info(sprintf(
179
                "Unable to resolve organization: %s",
180
                (string)Json::encode($object)
181
            ));
182
            return null;
183
        }
184
185
        /** @var UserAssociation $association */
186
        foreach ($this->getRelationships()->all() as $key => $association) {
187
            if ($association->getOrganizationId() == $element->getId()) {
188
                return $key;
189
            }
190
        }
191
192
        return null;
193
    }
194
195
    /**
196
     * @param UserAssociation|Organization|int|array $organization
197
     * @return Organization|null
198
     */
199
    protected function resolveObject($organization)
200
    {
201
        if ($organization instanceof UserAssociation) {
202
            return $organization->getOrganization();
203
        }
204
205
        if ($organization instanceof Organization) {
206
            return $organization;
207
        }
208
209
        return Organization::findOne($organization);
210
    }
211
}
212