Completed
Push — develop ( fcce06...87d9a9 )
by Nate
02:07
created

cp/controllers/view/OrganizationsController.php (7 issues)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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::findOne([
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);
0 ignored issues
show
$organization is of type object<craft\base\Elemen...ct<craft\base\Element>>, but the function expects a object<flipbox\organizat...\elements\Organization>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
119
        }
120
121
        $variables['enabledSiteIds'] = $this->getEnabledSiteIds($organization);
0 ignored issues
show
$organization is of type object<craft\base\Elemen...ct<craft\base\Element>>, but the function expects a object<flipbox\organizat...\elements\Organization>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
122
        $variables['siteIds'] = $this->getSiteIds();
123
        $variables['showSites'] = $this->showSites();
124
        $variables['siteUrl'] = $this->getSiteUrl($organization);
0 ignored issues
show
$organization is of type object<craft\base\Elemen...ct<craft\base\Element>>, but the function expects a object<flipbox\organizat...\elements\Organization>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
125
126
        $variables['fullPageForm'] = true;
127
        $variables['organization'] = $organization;
128
        $variables['actions'] = $this->getActions($organization);
0 ignored issues
show
$organization is of type object<craft\base\Elemen...ct<craft\base\Element>>, but the function expects a object<flipbox\organizat...\elements\Organization>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
129
        $variables['tabs'] = $this->getTabs($organization);
0 ignored issues
show
$organization is of type object<craft\base\Elemen...ct<craft\base\Element>>, but the function expects a object<flipbox\organizat...\elements\Organization>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
130
131
        // Allow switching between types
132
        Craft::$app->getView()->registerAssetBundle(OrganizationAsset::class);
133
        Craft::$app->getView()->registerJs('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);
0 ignored issues
show
$organization is of type object<craft\base\Elemen...ct<craft\base\Element>>, but the function expects a object<flipbox\organizat...\elements\Organization>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
139
        $variables['usersIndexJsClass'] = 'Craft.OrganizationUserIndex';
140
        $variables['usersIndexJs'] = $this->getUserIndexJs($organization);
0 ignored issues
show
$organization is of type object<craft\base\Elemen...ct<craft\base\Element>>, but the function expects a object<flipbox\organizat...\elements\Organization>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
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' => 'index',
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
                'loadMoreAction' => 'organizations/cp/user-indexes/get-more-elements'
216
            ]
217
        ];
218
    }
219
220
    /**
221
     * @param OrganizationElement $element
222
     * @return array
223
     */
224
    private function getUserInputJs(OrganizationElement $element): array
225
    {
226
        /** @noinspection PhpUndefinedMethodInspection */
227
        /** @var UserQuery $query */
228
        $query = User::find()
229
            ->organization($element->getId())
230
            ->status(null);
231
232
        return [
233
            'elementType' => UserElement::class,
234
            'sources' => '*',
235
            'criteria' => [
236
                'enabledForSite' => null,
237
                'siteId' => SiteHelper::ensureSiteId($element->siteId)
238
            ],
239
            'sourceElementId' => $element->getId() ?: null,
240
            'viewMode' => 'list',
241
            'limit' => null,
242
            'selectionLabel' => Craft::t('organizations', "Add a user"),
243
            'storageKey' => 'nested.index.input.organization.users',
244
            'elements' => $query->ids(),
245
            'addAction' => 'organizations/cp/users/associate',
246
            'selectTargetAttribute' => 'user',
247
            'selectParams' => [
248
                'organization' => $element->getId() ?: null
249
            ]
250
        ];
251
    }
252
253
    /*******************************************
254
     * RESOLVE TYPE
255
     *******************************************/
256
257
    /**
258
     * @return Site
259
     * @throws Exception
260
     */
261
    private function activeSiteFromRequest(): Site
262
    {
263
        $siteSettings = $this->module->module->getSettings()->getSiteSettings();
264
265
        $site = Craft::$app->getRequest()->getParam('site');
266
267
        if (true === Craft::$app->getIsMultiSite()) {
268
            $siteSetting = $siteSettings[$site] ?? reset($siteSettings);
269
            return $siteSetting->getSite();
270
        }
271
272
        $site = Craft::$app->getSites()->currentSite;
273
274
        if (array_key_exists($site->id, $siteSettings)) {
275
            return $site;
276
        }
277
278
        return reset($siteSettings);
279
    }
280
281
282
283
    /*******************************************
284
     * BASE PATHS
285
     *******************************************/
286
287
    /**
288
     * @return string
289
     */
290
    protected function getBaseCpPath(): string
291
    {
292
        return OrganizationPlugin::getInstance()->getUniqueId();
293
    }
294
295
    /**
296
     * @return string
297
     */
298
    protected function getBaseActionPath(): string
299
    {
300
        return parent::getBaseActionPath() . '/organizations';
301
    }
302
303
    /*******************************************
304
     * UPDATE VARIABLES
305
     *******************************************/
306
307
    /**
308
     * @param array $variables
309
     * @param OrganizationElement $organization
310
     */
311
    protected function updateVariables(array &$variables, OrganizationElement $organization)
312
    {
313
        $this->baseVariables($variables);
314
        $variables['title'] .= ' - ' . Craft::t('organizations', 'Edit') . ' ' . $organization->title;
315
        $variables['continueEditingUrl'] = $this->getBaseContinueEditingUrl('/' . $organization->getId());
316
        $variables['saveShortcutRedirect'] = $variables['continueEditingUrl'];
317
        $variables['crumbs'][] = [
318
            'label' => $organization->title,
319
            'url' => UrlHelper::url($variables['continueEditingUrl'])
320
        ];
321
    }
322
323
324
    /**
325
     * Set base variables used to generate template views
326
     *
327
     * @param array $variables
328
     */
329
    protected function baseVariables(array &$variables = [])
330
    {
331
        parent::baseVariables($variables);
332
333
        // Types
334
        $variables['types'] = OrganizationType::findAll([]);
335
        $variables['typeOptions'] = [];
336
        /** @var OrganizationType $type */
337
        foreach ($variables['types'] as $type) {
338
            $variables['typeOptions'][] = [
339
                'label' => Craft::t('site', $type->name),
340
                'value' => $type->id
341
            ];
342
        }
343
    }
344
345
    protected function resolveSiteFromRequest()
346
    {
347
        return Craft::$app->getSites()->currentSite;
348
    }
349
}
350