OrganizationsController   A
last analyzed

Complexity

Total Complexity 25

Size/Duplication

Total Lines 318
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 16

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 25
lcom 1
cbo 16
dl 0
loc 318
ccs 0
cts 184
cp 0
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A actionIndex() 0 13 1
B actionUpsert() 0 62 7
A findActiveType() 0 13 3
A getActions() 0 14 1
A getUserIndexJs() 0 27 1
A getUserInputJs() 0 28 3
A activeSiteFromRequest() 0 19 3
A getBaseCpPath() 0 4 1
A getBaseActionPath() 0 4 1
A updateVariables() 0 11 1
A baseVariables() 0 15 2
A resolveSiteFromRequest() 0 4 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\cp\controllers\view;
10
11
use Craft;
12
use craft\elements\db\UserQuery;
13
use craft\elements\User;
14
use craft\elements\User as UserElement;
15
use craft\helpers\UrlHelper;
16
use craft\models\Site;
17
use flipbox\craft\ember\helpers\SiteHelper;
18
use flipbox\organizations\cp\controllers\OrganizationTabsTrait;
19
use flipbox\organizations\cp\controllers\OrganizationSitesTrait;
20
use flipbox\organizations\elements\Organization;
21
use flipbox\organizations\elements\Organization as OrganizationElement;
22
use flipbox\organizations\events\RegisterOrganizationActionsEvent;
23
use flipbox\organizations\Organizations as OrganizationPlugin;
24
use flipbox\organizations\records\OrganizationType;
25
use flipbox\organizations\web\assets\organization\Organization as OrganizationAsset;
26
use yii\base\Exception;
27
use yii\base\InvalidConfigException;
28
use yii\web\Response;
29
30
/**
31
 * @author Flipbox Factory <[email protected]>
32
 * @since 1.0.0
33
 */
34
class OrganizationsController extends AbstractController
35
{
36
    use OrganizationSitesTrait,
37
        OrganizationTabsTrait;
38
39
    /**
40
     * The template base path
41
     */
42
    const TEMPLATE_BASE = parent::TEMPLATE_BASE . '/organization';
43
44
    /**
45
     * @event RegisterOrganizationActionsEvent
46
     */
47
    const EVENT_REGISTER_ORGANIZATION_ACTIONS = 'registerOrganizationActions';
48
49
    /**
50
     * The index view template path
51
     */
52
    const TEMPLATE_INDEX = self::TEMPLATE_BASE . '/index';
53
54
    /**
55
     * The index view template path
56
     */
57
    const TEMPLATE_UPSERT = self::TEMPLATE_BASE . '/upsert';
58
59
    /**
60
     * @return Response
61
     * @throws \craft\errors\SiteNotFoundException
62
     */
63
    public function actionIndex()
64
    {
65
        $variables = [];
66
        $this->baseVariables($variables);
67
68
        $variables['elementType'] = OrganizationElement::class;
69
        $variables['siteIds'] = $this->getSiteIds();
70
71
        return $this->renderTemplate(
72
            static::TEMPLATE_INDEX,
73
            $variables
74
        );
75
    }
76
77
    /**
78
     * @param null $identifier
79
     * @param OrganizationElement|null $organization
80
     * @return Response
81
     * @throws Exception
82
     * @throws InvalidConfigException
83
     * @throws \craft\errors\SiteNotFoundException
84
     */
85
    public function actionUpsert($identifier = null, OrganizationElement $organization = null)
86
    {
87
        // Site
88
        $site = $this->activeSiteFromRequest();
89
90
        // Organization
91
        if (null === $organization) {
92
            if (null === $identifier) {
93
                $organization = new Organization([
94
                    'siteId' => $site->id
95
                ]);
96
            } else {
97
                $organization = Organization::getOne([
98
                    is_numeric($identifier) ? 'id' : 'slug' => $identifier,
99
                    'siteId' => $site->id,
100
                    'status' => null
101
                ]);
102
            }
103
        }
104
105
        $type = $this->findActiveType($organization->getPrimaryType());
106
        if ($type !== null) {
107
            if (!$this->module->module->getSettings()->isSiteEnabled($site->id)) {
108
                throw new InvalidConfigException("Type is not enabled for site.");
109
            }
110
            $organization->setActiveType($type);
111
        }
112
113
        // Variables
114
        $variables = [];
115
        if (null === $organization->id) {
116
            $this->insertVariables($variables);
117
        } else {
118
            $this->updateVariables($variables, $organization);
119
        }
120
121
        $variables['enabledSiteIds'] = $this->getEnabledSiteIds($organization);
122
        $variables['siteIds'] = $this->getSiteIds();
123
        $variables['showSites'] = $this->showSites();
124
        $variables['siteUrl'] = $this->getSiteUrl($organization);
125
126
        $variables['fullPageForm'] = true;
127
        $variables['organization'] = $organization;
128
        $variables['actions'] = $this->getActions($organization);
129
        $variables['tabs'] = $this->getTabs($organization);
130
131
        // Allow switching between types
132
        Craft::$app->getView()->registerAssetBundle(OrganizationAsset::class);
133
        Craft::$app->getView()->registerJs('window.OrganizationTypeSwitcher = new Craft.OrganizationTypeSwitcher();');
134
135
        // The user select input criteria
136
        $variables['elementType'] = UserElement::class;
137
        $variables['usersInputJsClass'] = 'Craft.NestedElementIndexSelectInput';
138
        $variables['usersInputJs'] = $this->getUserInputJs($organization);
139
        $variables['usersIndexJsClass'] = 'Craft.NestedElementIndex';
140
        $variables['usersIndexJs'] = $this->getUserIndexJs($organization);
141
142
        return $this->renderTemplate(
143
            static::TEMPLATE_UPSERT,
144
            $variables
145
        );
146
    }
147
148
    /**
149
     * @param OrganizationType|null $default
150
     * @return OrganizationType|mixed|null
151
     * @throws \flipbox\craft\ember\exceptions\RecordNotFoundException
152
     */
153
    private function findActiveType(OrganizationType $default = null)
154
    {
155
        $type = Craft::$app->getRequest()->getParam('type');
156
        if (!empty($type)) {
157
            $type = OrganizationType::getOne($type);
158
        }
159
160
        if ($type instanceof OrganizationType) {
161
            return $type;
162
        }
163
164
        return $default;
165
    }
166
167
    /**
168
     * @param OrganizationElement $organization
169
     * @return array
170
     */
171
    private function getActions(OrganizationElement $organization): array
172
    {
173
        $event = new RegisterOrganizationActionsEvent([
174
            'organization' => $organization,
175
            'destructiveActions' => [],
176
            'miscActions' => [],
177
        ]);
178
        $this->trigger(self::EVENT_REGISTER_ORGANIZATION_ACTIONS, $event);
179
180
        return array_filter([
181
            $event->miscActions,
182
            $event->destructiveActions,
183
        ]);
184
    }
185
186
    /*******************************************
187
     * JS CONFIGS
188
     *******************************************/
189
190
    /**
191
     * @param OrganizationElement $element
192
     * @return array
193
     */
194
    private function getUserIndexJs(OrganizationElement $element): array
195
    {
196
        return [
197
            'source' => 'nested',
198
            'context' => 'organizations',
199
            'showStatusMenu' => true,
200
            'showSiteMenu' => true,
201
            'hideSidebar' => false,
202
            'toolbarFixed' => false,
203
            'storageKey' => 'nested.index.organization.users',
204
            'updateElementsAction' => 'organizations/cp/user-indexes/get-elements',
205
            'submitActionsAction' => 'organizations/cp/user-indexes/perform-action',
206
            'criteria' => [
207
                'enabledForSite' => null,
208
                'siteId' => SiteHelper::ensureSiteId($element->siteId),
209
                'organization' => $element->getId()
210
            ],
211
            'viewParams' => [
212
                'organization' => $element->getId(),
213
            ],
214
            'viewSettings' => [
215
                'loadMoreElementsAction' => 'organizations/cp/user-indexes/get-more-elements',
216
                'context' => 'index',
217
                'batchSize' => null
218
            ]
219
        ];
220
    }
221
222
    /**
223
     * @param OrganizationElement $element
224
     * @return array
225
     */
226
    private function getUserInputJs(OrganizationElement $element): array
227
    {
228
        /** @noinspection PhpUndefinedMethodInspection */
229
        /** @var UserQuery $query */
230
        $query = User::find()
231
            ->organization($element->getId())
232
            ->status(null);
233
234
        return [
235
            'elementType' => UserElement::class,
236
            'sources' => '*',
237
            'criteria' => [
238
                'enabledForSite' => null,
239
                'siteId' => SiteHelper::ensureSiteId($element->siteId)
240
            ],
241
            'sourceElementId' => $element->getId() ?: null,
242
            'viewMode' => 'list',
243
            'limit' => null,
244
            'selectionLabel' => Craft::t('organizations', "Add a user"),
245
            'storageKey' => 'nested.index.input.organization.users',
246
            'elements' => $query->ids(),
247
            'addAction' => 'organizations/cp/users/associate',
248
            'selectTargetAttribute' => 'user',
249
            'selectParams' => [
250
                'organization' => $element->getId() ?: null
251
            ]
252
        ];
253
    }
254
255
    /*******************************************
256
     * RESOLVE TYPE
257
     *******************************************/
258
259
    /**
260
     * @return Site
261
     * @throws Exception
262
     */
263
    private function activeSiteFromRequest(): Site
264
    {
265
        $siteSettings = $this->module->module->getSettings()->getSiteSettings();
266
267
        $site = Craft::$app->getRequest()->getParam('site');
268
269
        if (true === Craft::$app->getIsMultiSite()) {
270
            $siteSetting = $siteSettings[$site] ?? reset($siteSettings);
271
            return $siteSetting->getSite();
272
        }
273
274
        $site = Craft::$app->getSites()->currentSite;
275
276
        if (array_key_exists($site->id, $siteSettings)) {
277
            return $site;
278
        }
279
280
        return reset($siteSettings);
281
    }
282
283
284
285
    /*******************************************
286
     * BASE PATHS
287
     *******************************************/
288
289
    /**
290
     * @return string
291
     */
292
    protected function getBaseCpPath(): string
293
    {
294
        return OrganizationPlugin::getInstance()->getUniqueId();
295
    }
296
297
    /**
298
     * @return string
299
     */
300
    protected function getBaseActionPath(): string
301
    {
302
        return parent::getBaseActionPath() . '/organizations';
303
    }
304
305
    /*******************************************
306
     * UPDATE VARIABLES
307
     *******************************************/
308
309
    /**
310
     * @param array $variables
311
     * @param OrganizationElement $organization
312
     */
313
    protected function updateVariables(array &$variables, OrganizationElement $organization)
314
    {
315
        $this->baseVariables($variables);
316
        $variables['title'] .= ' - ' . Craft::t('organizations', 'Edit') . ' ' . $organization->title;
317
        $variables['continueEditingUrl'] = $this->getBaseContinueEditingUrl('/' . $organization->getId());
318
        $variables['saveShortcutRedirect'] = $variables['continueEditingUrl'];
319
        $variables['crumbs'][] = [
320
            'label' => $organization->title,
321
            'url' => UrlHelper::url($variables['continueEditingUrl'])
322
        ];
323
    }
324
325
326
    /**
327
     * Set base variables used to generate template views
328
     *
329
     * @param array $variables
330
     */
331
    protected function baseVariables(array &$variables = [])
332
    {
333
        parent::baseVariables($variables);
334
335
        // Types
336
        $variables['types'] = OrganizationType::findAll([]);
337
        $variables['typeOptions'] = [];
338
        /** @var OrganizationType $type */
339
        foreach ($variables['types'] as $type) {
340
            $variables['typeOptions'][] = [
341
                'label' => Craft::t('site', $type->name),
342
                'value' => $type->id
343
            ];
344
        }
345
    }
346
347
    protected function resolveSiteFromRequest()
348
    {
349
        return Craft::$app->getSites()->currentSite;
350
    }
351
}
352