Test Failed
Pull Request — master (#80)
by Maximo
06:05
created

library/Models/Users.php (2 issues)

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

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
432
433
            if (!$this->update()) {
434
                throw new ServerErrorHttpException((string) current($this->getMessages()));
435
            }
436
437
            $this->stripe_id = $company->getPaymentGatewayCustomerId();
438
            $this->default_company_branch = $this->defaultCompany->branch->getId();
439
            $this->update();
440
441
        //update default subscription free trial
442
            //$company->app->subscriptions_id = $this->startFreeTrial()->getId();
443
            //$company->update();
444
        } else {
445
            //we have the company id
446
            if (empty($this->default_company_branch)) {
447
                $this->default_company_branch = $this->defaultCompany->branch->getId();
448
            }
449
        }
450
451
        //Create new company associated company
452
        $this->defaultCompany->associate($this, $this->defaultCompany);
453
454
        //Insert record into user_roles
455
        $userRole = new UserRoles();
456
        $userRole->users_id = $this->id;
457
        $userRole->roles_id = $this->roles_id;
458
        $userRole->apps_id = $this->di->getApp()->getId();
459
        $userRole->companies_id = $this->default_company;
460
461
        if (!$userRole->save()) {
462
            throw new ServerErrorHttpException((string)current($userRole->getMessages()));
463
        }
464
465
        //update user activity when its not a empty user
466
        if (!$isFirstSignup) {
467
            $this->updateAppActivityLimit();
468
        }
469
    }
470
}
471