Completed
Push — master ( 6f2475...9a35ef )
by Nate
16:01
created

OrganizationsController   B

Complexity

Total Complexity 21

Size/Duplication

Total Lines 285
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 16

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 21
lcom 1
cbo 16
dl 0
loc 285
ccs 0
cts 161
cp 0
rs 8.4614
c 0
b 0
f 0

11 Methods

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