Passed
Pull Request — master (#42)
by Rafael
05:35
created

Users::initialize()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 89
Code Lines 61

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 60
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 61
nc 1
nop 0
dl 0
loc 89
ccs 60
cts 60
cp 1
crap 1
rs 8.8509
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
declare(strict_types=1);
3
4
namespace Gewaer\Models;
5
6
use Gewaer\Traits\PermissionsTrait;
7
use Gewaer\Traits\SubscriptionPlanLimitTrait;
8
use Phalcon\Cashier\Billable;
9
use Gewaer\Exception\ServerErrorHttpException;
10
use Exception;
11
use Carbon\Carbon;
12
use Phalcon\Validation;
13
use Phalcon\Validation\Validator\Email;
14
use Phalcon\Validation\Validator\PresenceOf;
15
use Phalcon\Validation\Validator\Regex;
16
use Phalcon\Validation\Validator\Uniqueness;
17
18
/**
19
 * Class Users
20
 *
21
 * @package Gewaer\Models
22
 *
23
 * @property Users $user
24
 * @property Config $config
25
 * @property Apps $app
26
 * @property Companies $defaultCompany
27
 * @property \Phalcon\Di $di
28
 */
29
class Users extends \Baka\Auth\Models\Users
30
{
31
    use PermissionsTrait;
32
    use Billable;
33
    use SubscriptionPlanLimitTrait;
34
35
    public $default_company_branch;
36
    public $roles_id;
37
    public $stripe_id;
38
    public $card_last_four;
39
    public $card_brand;
40
    public $trial_ends_at;
41
42
    /**
43
     * Provide the app plan id
44
     * if the user is signing up a new company
45
     *
46
     * @var integer
47
     */
48
    public $appPlanId = null;
49
50
    /**
51
     * Initialize method for model.
52
     */
53 59
    public function initialize()
54
    {
55 59
        $this->setSource('users');
56
57
        //overwrite parent relationships
58 59
        $this->hasOne('id', 'Baka\Auth\Models\Sessions', 'users_id', ['alias' => 'session']);
59 59
        $this->hasMany('id', 'Baka\Auth\Models\Sessions', 'users_id', ['alias' => 'sessions']);
60 59
        $this->hasMany('id', 'Baka\Auth\Models\SessionKeys', 'users_id', ['alias' => 'sessionKeys']);
61 59
        $this->hasMany('id', 'Baka\Auth\Models\Banlist', 'users_id', ['alias' => 'bans']);
62 59
        $this->hasMany('id', 'Baka\Auth\Models\Sessions', 'users_id', ['alias' => 'sessions']);
63 59
        $this->hasMany('id', 'Gewaer\Models\UserConfig', 'users_id', ['alias' => 'config']);
64 59
        $this->hasMany('id', 'Gewaer\Models\UserLinkedSources', 'users_id', ['alias' => 'sources']);
65 59
        $this->hasMany('id', 'Baka\Auth\Models\UsersAssociatedCompany', 'users_id', ['alias' => 'companies']);
66 59
        $this->hasOne('default_company', 'Gewaer\Models\Companies', 'id', ['alias' => 'defaultCompany']);
67 59
        $this->hasOne('default_company', 'Gewaer\Models\Companies', 'id', ['alias' => 'currentCompany']);
68
69 59
        $this->hasOne(
70 59
            'id',
71 59
            'Gewaer\Models\UserRoles',
72 59
            'users_id',
73 59
            ['alias' => 'permission']
74
        );
75
76 59
        $this->hasMany(
77 59
            'id',
78 59
            'Gewaer\Models\UserRoles',
79 59
            'users_id',
80 59
            ['alias' => 'permissions']
81
        );
82
83 59
        $this->hasManyToMany(
84 59
            'id',
85 59
            'Gewaer\Models\UserRoles',
86 59
            'users_id',
87 59
            'roles_id',
88 59
            'Gewaer\Models\Roles',
89 59
            'id',
90
            [
91 59
                'alias' => 'roles',
92
                'params' => [
93 59
                    'limit' => 1,
94 59
                    'conditions' => 'Gewaer\Models\UserRoles.apps_id = ' . $this->di->getConfig()->app->id,
95
                ]
96
            ]
97
        );
98
99 59
        $this->hasMany(
100 59
            'id',
101 59
            'Gewaer\Models\Subscription',
102 59
            'user_id',
103
            [
104 59
                'alias' => 'allSubscriptions',
105
                'params' => [
106 59
                    'conditions' => 'apps_id = ?0',
107 59
                    'bind' => [$this->di->getApp()->getId()],
108 59
                    'order' => 'id DESC'
109
                ]
110
            ]
111
        );
112
113 59
        $this->hasMany(
114 59
            'id',
115 59
            'Gewaer\Models\UsersAssociatedCompany',
116 59
            'users_id',
117
            [
118 59
                'alias' => 'companies',
119
            ]
120
        );
121
122 59
        $this->hasMany(
123 59
            'id',
124 59
            'Gewaer\Models\UserWebhooks',
125 59
            'users_id',
126 59
            ['alias' => 'userWebhook']
127
        );
128
129 59
        $systemModule = SystemModules::findFirst([
130 59
            'conditions' => 'model_name = ?0 and apps_id = ?1',
131 59
            'bind' => [self::class, $this->di->getApp()->getId()]
132
        ]);
133
134 59
        $this->hasMany(
135 59
            'id',
136 59
            'Gewaer\Models\FileSystem',
137 59
            'entity_id',
138
            [
139 59
                'alias' => 'filesystem',
140 59
                'conditions' => 'system_modules_id = ?0',
141 59
                'bind' => [$systemModule->getId()]
142
            ]
143
        );
144 59
    }
145
146
    /**
147
     * Validations and business logic
148
     */
149 3
    public function validation()
150
    {
151 3
        $validator = new Validation();
152 3
        $validator->add(
153 3
            'email',
154 3
            new Email([
155 3
                'field' => 'email',
156
                'required' => true,
157
            ])
158
        );
159
160 3
        $validator->add(
161 3
            'displayname',
162 3
            new PresenceOf([
163 3
                'field' => 'displayname',
164
                'required' => true,
165
            ])
166
        );
167
168 3
        $validator->add(
169 3
            'displayname',
170 3
            new Regex([
171 3
                'field' => 'displayname',
172 3
                'message' => _('Please use alphanumerics only.'),
173 3
                'pattern' => '/^[A-Za-z0-9_-]{1,32}$/',
174
            ])
175
        );
176
177
        // Unique values
178 3
        $validator->add(
179 3
            'email',
180 3
            new Uniqueness([
181 3
                'field' => 'email',
182 3
                'message' => _('This email already has an account.'),
183
            ])
184
        );
185
186 3
        return $this->validate($validator);
187
    }
188
189
    /**
190
     * Returns table name mapped in the model.
191
     *
192
     * @return string
193
     */
194 45
    public function getSource() : string
195
    {
196 45
        return 'users';
197
    }
198
199
    /**
200
     * Get the User key for redis
201
     *
202
     * @return string
203
     */
204
    public function getKey() : string
205
    {
206
        return $this->id;
207
    }
208
209
    /**
210
     * A company owner is the first person that register this company
211
     * This only ocurres when signing up the first time, after that all users invites
212
     * come with a default_company id attached
213
     *
214
     * @return boolean
215
     */
216 3
    public function isFirstSignup(): bool
217
    {
218 3
        return empty($this->default_company) ? true : false;
219
    }
220
221
    /**
222
     * Does the user have a role assign to him?
223
     *
224
     * @return boolean
225
     */
226 7
    public function hasRole(): bool
227
    {
228 7
        return !empty($this->roles_id) ? true : false;
229
    }
230
231
    /**
232
     * Get all of the subscriptions for the user.
233
     */
234 3
    public function subscriptions()
235
    {
236 3
        $this->hasMany(
237 3
            'id',
238 3
            'Gewaer\Models\Subscription',
239 3
            'user_id',
240
            [
241 3
                'alias' => 'subscriptions',
242
                'params' => [
243 3
                    'conditions' => 'apps_id = ?0 and companies_id = ?1',
244 3
                    'bind' => [$this->di->getApp()->getId(), $this->default_company],
245 3
                    'order' => 'id DESC'
246
                ]
247
            ]
248
        );
249
250 3
        return $this->getRelated('subscriptions');
251
    }
252
253
    /**
254
     * Strat a free trial
255
     *
256
     * @param Users $user
257
     * @return Subscription
258
     */
259 1
    public function startFreeTrial() : Subscription
260
    {
261 1
        $defaultPlan = AppsPlans::getDefaultPlan();
262
263 1
        $subscription = new Subscription();
264 1
        $subscription->user_id = $this->getId();
265 1
        $subscription->companies_id = $this->default_company;
266 1
        $subscription->apps_id = $this->di->getApp()->getId();
267 1
        $subscription->apps_plans_id = $this->di->getApp()->default_apps_plan_id;
268 1
        $subscription->name = $defaultPlan->name;
269 1
        $subscription->stripe_id = $defaultPlan->stripe_id;
270 1
        $subscription->stripe_plan = $defaultPlan->stripe_plan;
271 1
        $subscription->quantity = 1;
272 1
        $subscription->trial_ends_at = Carbon::now()->addDays($this->di->getApp()->plan->free_trial_dates)->toDateTimeString();
273
274 1
        if (!$subscription->save()) {
275
            throw new ServerErrorHttpException((string)current($this->getMessages()));
276
        }
277
278 1
        $this->trial_ends_at = $subscription->trial_ends_at;
279 1
        $this->update();
280
281 1
        return $subscription;
282
    }
283
284
    /**
285
     * Before create
286
     *
287
     * @return void
288
     */
289 3
    public function beforeCreate()
290
    {
291 3
        parent::beforeCreate();
292
293
        //this is only empty when creating a new user
294 3
        if (!$this->isFirstSignup()) {
295
            //confirm if the app reach its limit
296 2
            $this->isAtLimit();
297
        }
298
299
        //Assign admin role to the system if we dont get a specify role
300 3
        if (!$this->hasRole()) {
301 1
            $role = Roles::findFirstByName('Admins');
302 1
            $this->roles_id = $role->getId();
303
        }
304 3
    }
305
306
    /**
307
     * Get an array of the associates companies Ids
308
     *
309
     * @return array
310
     */
311 6
    public function getAssociatedCompanies(): array
312
    {
313
        return array_map(function ($company) {
314 6
            return $company['companies_id'];
315 6
        }, $this->getCompanies(['columns' => 'companies_id'])->toArray());
316
    }
317
318
    /**
319
     * What the current company the users is logged in with
320
     * in this current session?
321
     *
322
     * @return integer
323
     */
324 33
    public function currentCompanyId(): int
325
    {
326 33
        return (int) $this->default_company;
327
    }
328
329
    /**
330
     * What the current company brach the users is logged in with
331
     * in this current session?
332
     *
333
     * @return integer
334
     */
335 1
    public function currentCompanyBranchId(): int
336
    {
337 1
        return (int) $this->default_company_branch;
338
    }
339
340
    /**
341
     * What to do after the creation of a new users
342
     *  - Assign default role
343
     *
344
     * @return void
345
     */
346 3
    public function afterCreate()
347
    {
348
        //need to run it here, since we overwirte the default_company id and null this function objective
349 3
        $isFirstSignup = $this->isFirstSignup();
350
351
        /**
352
         * User signing up for a new app / plan
353
         * How do we know? well he doesnt have a default_company
354
         */
355 3
        if ($isFirstSignup) {
356 1
            $company = new Companies();
357 1
            $company->name = $this->defaultCompanyName;
358 1
            $company->users_id = $this->getId();
359
360 1
            if (!$company->save()) {
361
                throw new Exception(current($company->getMessages()));
362
            }
363
364 1
            $this->default_company = $company->getId();
365
366 1
            if (!$this->update()) {
367
                throw new ServerErrorHttpException((string) current($this->getMessages()));
368
            }
369
370 1
            $this->default_company_branch = $this->defaultCompany->branch->getId();
371 1
            $this->update();
372
373
            //update default subscription free trial
374 1
            $company->app->subscriptions_id = $this->startFreeTrial()->getId();
375 1
            $company->update();
376
        } else {
377
            //we have the company id
378 2
            if (empty($this->default_company_branch)) {
379
                $this->default_company_branch = $this->defaultCompany->branch->getId();
380
            }
381
        }
382
383
        //Create new company associated company
384 3
        $newUserAssocCompany = new UsersAssociatedCompany();
385 3
        $newUserAssocCompany->users_id = $this->id;
386 3
        $newUserAssocCompany->companies_id = $this->default_company;
387 3
        $newUserAssocCompany->identify_id = 1;
388 3
        $newUserAssocCompany->user_active = 1;
389 3
        $newUserAssocCompany->user_role = $this->roles_id == 1 ? 'admins' : 'users';
390
391 3
        if (!$newUserAssocCompany->save()) {
392
            throw new ServerErrorHttpException((string)current($newUserAssocCompany->getMessages()));
393
        }
394
395
        //Insert record into user_roles
396 3
        $userRole = new UserRoles();
397 3
        $userRole->users_id = $this->id;
398 3
        $userRole->roles_id = $this->roles_id;
399 3
        $userRole->apps_id = $this->di->getApp()->getId();
400 3
        $userRole->companies_id = $this->default_company;
401
402 3
        if (!$userRole->save()) {
403
            throw new ServerErrorHttpException((string)current($userRole->getMessages()));
404
        }
405
406
        //update user activity when its not a empty user
407 3
        if (!$isFirstSignup) {
408 2
            $this->updateAppActivityLimit();
409
        }
410 3
    }
411
}
412