Completed
Push — master ( a5dedb...d2c836 )
by Nate
07:01 queued 04:52
created

OrganizationsController::findActiveType()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 0
cts 11
cp 0
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 4
nop 1
crap 12
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\OrganizationType;
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 . '/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 . '/index';
49
50
    /**
51
     * The index view template path
52
     */
53
    const TEMPLATE_UPSERT = self::TEMPLATE_BASE . '/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 = $this->findActiveType($organization->getPrimaryType());
104
        if ($type !== null) {
105
            if (!$this->module->module->getSettings()->isSiteEnabled($site->id)) {
106
                throw new InvalidConfigException("Type is not enabled for site.");
107
            }
108
            $organization->setActiveType($type);
109
        }
110
111
        // Variables
112
        $variables = [];
113
        if (null === $organization->id) {
114
            $this->insertVariables($variables);
115
        } else {
116
            $this->updateVariables($variables, $organization);
117
        }
118
119
        $variables['enabledSiteIds'] = $this->getEnabledSiteIds($organization);
120
        $variables['siteIds'] = $this->getSiteIds();
121
        $variables['showSites'] = $this->hasMultipleSites();
122
        $variables['siteUrl'] = $this->getSiteUrl($organization);
123
124
        $variables['fullPageForm'] = true;
125
        $variables['organization'] = $organization;
126
        $variables['actions'] = $this->getActions($organization);
127
        $variables['tabs'] = $this->getTabs($organization);
128
129
        // Allow switching between types
130
        Craft::$app->getView()->registerAssetBundle(OrganizationAsset::class);
131
        Craft::$app->getView()->registerJs('new Craft.OrganizationTypeSwitcher();');
132
133
        // The user select input criteria
134
        $variables['elementType'] = UserElement::class;
135
        $variables['usersInputJsClass'] = 'Craft.NestedElementIndexSelectInput';
136
        $variables['usersInputJs'] = $this->getUserInputJs($organization);
137
        $variables['usersIndexJsClass'] = 'Craft.OrganizationUserIndex';
138
        $variables['usersIndexJs'] = $this->getUserIndexJs($organization);
139
140
        return $this->renderTemplate(
141
            static::TEMPLATE_UPSERT,
142
            $variables
143
        );
144
    }
145
146
    /**
147
     * @param OrganizationType|null $default
148
     * @return OrganizationType|mixed
149
     * @throws \flipbox\ember\exceptions\NotFoundException
150
     */
151
    private function findActiveType(OrganizationType $default = null)
152
    {
153
        $type = Craft::$app->getRequest()->getParam('type');
154
        if (!empty($type)) {
155
            $type = OrganizationPlugin::getInstance()->getOrganizationTypes()->get($type);
156
        }
157
158
        if ($type instanceof OrganizationType) {
159
            return $type;
160
        }
161
162
        return $default;
163
    }
164
165
    /**
166
     * @param OrganizationElement $organization
167
     * @return array
168
     */
169
    private function getActions(OrganizationElement $organization): array
170
    {
171
        $event = new RegisterOrganizationActionsEvent([
172
            'organization' => $organization,
173
            'destructiveActions' => [],
174
            'miscActions' => [],
175
        ]);
176
        $this->trigger(self::EVENT_REGISTER_ORGANIZATION_ACTIONS, $event);
177
178
        return array_filter([
179
            $event->miscActions,
180
            $event->destructiveActions,
181
        ]);
182
    }
183
184
    /*******************************************
185
     * JS CONFIGS
186
     *******************************************/
187
188
    /**
189
     * @param OrganizationElement $element
190
     * @return array
191
     */
192
    private function getUserIndexJs(OrganizationElement $element): array
193
    {
194
        return [
195
            'source' => 'nested',
196
            'context' => 'index',
197
            'showStatusMenu' => true,
198
            'showSiteMenu' => true,
199
            'hideSidebar' => false,
200
            'toolbarFixed' => false,
201
            'storageKey' => 'nested.index.organization.users',
202
            'updateElementsAction' => 'organizations/cp/user-indexes/get-elements',
203
            'submitActionsAction' => 'organizations/cp/user-indexes/perform-action',
204
            'criteria' => [
205
                'enabledForSite' => null,
206
                'siteId' => SiteHelper::ensureSiteId($element->siteId),
207
                'organization' => $element->getId()
208
            ],
209
            'viewParams' => [
210
                'organization' => $element->getId()
211
            ],
212
            'viewSettings' => [
213
                'loadMoreAction' => 'organizations/cp/user-indexes/get-more-elements'
214
            ]
215
        ];
216
    }
217
218
    /**
219
     * @param OrganizationElement $element
220
     * @return array
221
     */
222
    private function getUserInputJs(OrganizationElement $element): array
223
    {
224
        return [
225
            'elementType' => UserElement::class,
226
            'sources' => '*',
227
            'criteria' => [
228
                'enabledForSite' => null,
229
                'siteId' => SiteHelper::ensureSiteId($element->siteId)
230
            ],
231
            'sourceElementId' => $element->getId() ?: null,
232
            'viewMode' => 'list',
233
            'limit' => null,
234
            'selectionLabel' => Craft::t('organizations', "Add a user"),
235
            'storageKey' => 'nested.index.input.organization.users',
236
            'elements' => OrganizationPlugin::getInstance()->getUsers()->getQuery([
237
                'organization' => $element->getId(),
238
                'status' => null
239
            ])->ids(),
240
            'addAction' => 'organizations/cp/users/associate',
241
            'selectTargetAttribute' => 'user',
242
            'selectParams' => [
243
                'organization' => $element->getId() ?: null
244
            ]
245
        ];
246
    }
247
248
    /*******************************************
249
     * RESOLVE TYPE
250
     *******************************************/
251
252
    /**
253
     * @return Site
254
     * @throws Exception
255
     */
256
    private function activeSiteFromRequest(): Site
257
    {
258
        $siteSettings = $this->module->module->getSettings()->getSiteSettings();
259
260
        if (true === $this->hasMultipleSites()) {
261
            $siteSetting = reset($siteSettings);
262
            return $siteSetting->getSite();
263
        }
264
265
        $site = $this->resolveSiteFromRequest();
266
267
        if (array_key_exists($site->id, $siteSettings)) {
268
            return $site;
269
        }
270
271
        throw new Exception("Site is not enabled");
272
    }
273
274
275
276
    /*******************************************
277
     * BASE PATHS
278
     *******************************************/
279
280
    /**
281
     * @return string
282
     */
283
    protected function getBaseCpPath(): string
284
    {
285
        return OrganizationPlugin::getInstance()->getUniqueId();
286
    }
287
288
    /**
289
     * @return string
290
     */
291
    protected function getBaseActionPath(): string
292
    {
293
        return parent::getBaseActionPath() . '/organizations';
294
    }
295
296
    /*******************************************
297
     * UPDATE VARIABLES
298
     *******************************************/
299
300
    /**
301
     * @param array $variables
302
     * @param OrganizationElement $organization
303
     */
304
    protected function updateVariables(array &$variables, OrganizationElement $organization)
305
    {
306
        $this->baseVariables($variables);
307
        $variables['title'] .= ' - ' . Craft::t('organizations', 'Edit') . ' ' . $organization->title;
308
        $variables['continueEditingUrl'] = $this->getBaseContinueEditingUrl('/' . $organization->getId());
309
        $variables['crumbs'][] = [
310
            'label' => $organization->title,
311
            'url' => UrlHelper::url($variables['continueEditingUrl'])
312
        ];
313
    }
314
315
316
    /**
317
     * Set base variables used to generate template views
318
     *
319
     * @param array $variables
320
     */
321
    protected function baseVariables(array &$variables = [])
322
    {
323
        parent::baseVariables($variables);
324
325
        // Types
326
        $variables['types'] = OrganizationPlugin::getInstance()->getOrganizationTypes()->findAll();
327
        $variables['typeOptions'] = [];
328
        /** @var OrganizationType $type */
329
        foreach ($variables['types'] as $type) {
330
            $variables['typeOptions'][] = [
331
                'label' => Craft::t('site', $type->name),
332
                'value' => $type->id
333
            ];
334
        }
335
    }
336
}
337