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

OrganizationUsers::associate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

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