Completed
Push — master ( 065a6e...42280b )
by Nate
11:59 queued 10:16
created

OrganizationsController::getUserIndexJs()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 25
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 25
ccs 0
cts 25
cp 0
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 19
nc 1
nop 1
crap 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
            'viewSettings' => [
195
                'loadMoreAction' => 'organizations/cp/user-indexes/get-more-elements'
196
            ]
197
        ];
198
    }
199
200
    /**
201
     * @param OrganizationElement $element
202
     * @return array
203
     */
204
    private function getUserInputJs(OrganizationElement $element): array
205
    {
206
        return [
207
            'elementType' => UserElement::class,
208
            'sources' => '*',
209
            'criteria' => [
210
                'enabledForSite' => null,
211
                'siteId' => SiteHelper::ensureSiteId($element->siteId)
212
            ],
213
            'sourceElementId' => $element->getId() ?: null,
214
            'viewMode' => 'list',
215
            'limit' => null,
216
            'selectionLabel' => Craft::t('organizations', "Add a user"),
217
            'storageKey' => 'nested.index.input.organization.users',
218
            'elements' => OrganizationPlugin::getInstance()->getUsers()->getQuery([
219
                'organization' => $element->getId(),
220
                'status' => null
221
            ])->ids(),
222
            'addAction' => 'organizations/cp/users/associate',
223
            'selectTargetAttribute' => 'user',
224
            'selectParams' => [
225
                'organization' => $element->getId() ?: null
226
            ]
227
        ];
228
    }
229
230
    /*******************************************
231
     * RESOLVE TYPE
232
     *******************************************/
233
234
    /**
235
     * @return Site
236
     * @throws Exception
237
     */
238
    private function activeSiteFromRequest(): Site
239
    {
240
        $siteSettings = $this->module->module->getSettings()->getSiteSettings();
241
242
        if (true === $this->hasMultipleSites()) {
243
            $siteSetting = reset($siteSettings);
244
            return $siteSetting->getSite();
245
        }
246
247
        $site = $this->resolveSiteFromRequest();
248
249
        if (array_key_exists($site->id, $siteSettings)) {
250
            return $site;
251
        }
252
253
        throw new Exception("Site is not enabled");
254
    }
255
256
257
258
    /*******************************************
259
     * BASE PATHS
260
     *******************************************/
261
262
    /**
263
     * @return string
264
     */
265
    protected function getBaseCpPath(): string
266
    {
267
        return OrganizationPlugin::getInstance()->getUniqueId();
268
    }
269
270
    /**
271
     * @return string
272
     */
273
    protected function getBaseActionPath(): string
274
    {
275
        return parent::getBaseActionPath() . '/organizations';
276
    }
277
278
    /*******************************************
279
     * UPDATE VARIABLES
280
     *******************************************/
281
282
    /**
283
     * @param array $variables
284
     * @param OrganizationElement $organization
285
     */
286
    protected function updateVariables(array &$variables, OrganizationElement $organization)
287
    {
288
        $this->baseVariables($variables);
289
        $variables['title'] .= ' - ' . Craft::t('organizations', 'Edit') . ' ' . $organization->title;
290
        $variables['continueEditingUrl'] = $this->getBaseContinueEditingUrl('/' . $organization->getId());
291
        $variables['crumbs'][] = [
292
            'label' => $organization->title,
293
            'url' => UrlHelper::url($variables['continueEditingUrl'])
294
        ];
295
    }
296
297
298
    /**
299
     * Set base variables used to generate template views
300
     *
301
     * @param array $variables
302
     */
303
    protected function baseVariables(array &$variables = [])
304
    {
305
        parent::baseVariables($variables);
306
307
        // Types
308
        $variables['types'] = OrganizationPlugin::getInstance()->getTypes()->findAll();
309
        $variables['typeOptions'] = [];
310
        /** @var Type $type */
311
        foreach ($variables['types'] as $type) {
312
            $variables['typeOptions'][] = [
313
                'label' => Craft::t('site', $type->name),
314
                'value' => $type->id
315
            ];
316
        }
317
    }
318
}
319