Completed
Push — develop ( 356f72...fcce06 )
by Nate
05:55
created

UserOrganizations::associations()   A

Complexity

Conditions 5
Paths 7

Size

Total Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 34
ccs 18
cts 18
cp 1
rs 9.0648
c 0
b 0
f 0
cc 5
nc 7
nop 3
crap 5
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\services;
10
11
use craft\elements\db\UserQuery;
12
use craft\elements\User as UserElement;
13
use craft\helpers\ArrayHelper;
14
use flipbox\organizations\db\OrganizationQuery;
15
use flipbox\organizations\elements\Organization as OrganizationElement;
16
use flipbox\organizations\Organizations as OrganizationPlugin;
17
use flipbox\organizations\records\UserAssociation;
18
use yii\base\Component;
19
20
/**
21
 * @author Flipbox Factory <[email protected]>
22
 * @since 1.0.0
23
 *
24
 * @method UserElement parentFind($identifier)
25
 * @method UserElement create($config = [])
26
 * @method UserElement get($identifier)
27
 * @method UserQuery getQuery($criteria = [])
28
 */
29
class UserOrganizations extends Component
30
{
31
    /**
32
     * @param UserElement $user
33
     * @param OrganizationQuery $query
34
     * @return bool
35
     * @throws \Exception
36
     */
37 6
    public function saveAssociations(
38
        UserElement $user,
39
        OrganizationQuery $query
40
    ): bool {
41
        /** @var UserElement[] $models */
42 6
        if (null === ($models = $query->getCachedResult())) {
43 3
            return true;
44
        }
45
46 3
        $associationService = OrganizationPlugin::getInstance()->getUserOrganizationAssociations();
47
48 3
        $query = $associationService->getQuery([
49 3
            $associationService::SOURCE_ATTRIBUTE => $user->getId() ?: false
50
        ]);
51
52 3
        $query->setCachedResult(
53 3
            $this->toAssociations($models, $user->getId())
54
        );
55
56 3
        return $associationService->save($query);
57
    }
58
59
    /**
60
     * @param UserElement $user
61
     * @param OrganizationQuery $query
62
     * @return bool
63
     * @throws \Exception
64
     */
65 3
    public function dissociate(
66
        UserElement $user,
67
        OrganizationQuery $query
68
    ): bool {
69 3
        return $this->associations(
70 3
            $user,
71 3
            $query,
72
            [
73 3
                OrganizationPlugin::getInstance()->getUserOrganizationAssociations(),
74 3
                'dissociate'
75
            ]
76
        );
77
    }
78
79
    /**
80
     * @param UserElement $user
81
     * @param OrganizationQuery $query
82
     * @return bool
83
     * @throws \Exception
84
     */
85 3
    public function associate(
86
        UserElement $user,
87
        OrganizationQuery $query
88
    ): bool {
89 3
        return $this->associations(
90 3
            $user,
91 3
            $query,
92
            [
93 3
                OrganizationPlugin::getInstance()->getUserOrganizationAssociations(),
94 3
                'associate'
95
            ]
96
        );
97
    }
98
99
    /**
100
     * @param UserElement $user
101
     * @param OrganizationQuery $query
102
     * @param callable $callable
103
     * @return bool
104
     */
105 9
    protected function associations(
106
        UserElement $user,
107
        OrganizationQuery $query,
108
        callable $callable
109
    ) {
110
        /** @var UserElement[] $models */
111 9
        if (null === ($models = $query->getCachedResult())) {
112 3
            return true;
113
        }
114
115 6
        $models = ArrayHelper::index($models, 'id');
116
117 6
        $success = true;
118 6
        $ids = [];
119 6
        $count = count($models);
120 6
        $i = 0;
121 6
        foreach ($this->toAssociations($models, $user->getId()) as $association) {
122 6
            if (true === call_user_func_array($callable, [$association, ++$i === $count])) {
123 3
                ArrayHelper::remove($models, $association->userId);
124 3
                $ids[] = $association->userId;
125 3
                continue;
126
            }
127
128 3
            $success = false;
129
        }
130
131 6
        $query->id($ids);
132
133 6
        if ($success === false) {
134 3
            $query->setCachedResult($models);
135
        }
136
137 6
        return $success;
138
    }
139
140
    /**
141
     * @param OrganizationElement[] $organizations
142
     * @param int $userId
143
     * @return UserAssociation[]
144
     */
145 3
    protected function toAssociations(
146
        array $organizations,
147
        int $userId
148
    ) {
149 3
        $associations = [];
150 3
        $sortOrder = 1;
151
152 3
        $associationService = OrganizationPlugin::getInstance()->getUserOrganizationAssociations();
153 3
        $sortOrderAttribute = $associationService::SORT_ORDER_ATTRIBUTE;
154
155 3
        $existingAssociations = $associationService->findAllByCriteria([
156
            'where' => [
157 3
                $associationService::SOURCE_ATTRIBUTE => ArrayHelper::getColumn($organizations, 'id'),
158 3
                $associationService::TARGET_ATTRIBUTE => $userId,
159
            ],
160 3
            'indexBy' => $associationService::SOURCE_ATTRIBUTE
161
        ]);
162
163 3
        foreach ($organizations as $organization) {
164 3
            if (null === ($association = ArrayHelper::remove($existingAssociations, $organization->getId()))) {
165 3
                $association = $associationService->create([
166 3
                    'userId' => (int)$userId,
167 3
                    'organizationId' => (int)$organization->getId()
168
                ]);
169
            }
170
171 3
            $association->{$sortOrderAttribute} = $sortOrder++;
172 3
            $associations[] = $association;
173
        }
174
175 3
        return $associations;
176
    }
177
}
178