Failed Conditions
Push — master ( 55bfad...b74acd )
by Maximo
02:48
created

Users::hasRole()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 1
nc 2
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 2
rs 10
c 0
b 0
f 0
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;
1 ignored issue
show
introduced by
The trait Phalcon\Cashier\Billable requires some properties which are not provided by Gewaer\Models\Users: $stripe, $data, $brand, $last4, $paid, $customer, $secretKey, $card, $sources, $subscriptions
Loading history...
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 44
    public function initialize()
54
    {
55 44
        $this->setSource('users');
56
57
        //overwrite parent relationships
58 44
        $this->hasOne('id', 'Baka\Auth\Models\Sessions', 'users_id', ['alias' => 'session']);
59 44
        $this->hasMany('id', 'Baka\Auth\Models\Sessions', 'users_id', ['alias' => 'sessions']);
60 44
        $this->hasMany('id', 'Baka\Auth\Models\SessionKeys', 'users_id', ['alias' => 'sessionKeys']);
61 44
        $this->hasMany('id', 'Baka\Auth\Models\Banlist', 'users_id', ['alias' => 'bans']);
62 44
        $this->hasMany('id', 'Baka\Auth\Models\Sessions', 'users_id', ['alias' => 'sessions']);
63 44
        $this->hasMany('id', 'Gewaer\Models\UserConfig', 'users_id', ['alias' => 'config']);
64 44
        $this->hasMany('id', 'Gewaer\Models\UserLinkedSources', 'users_id', ['alias' => 'sources']);
65 44
        $this->hasMany('id', 'Baka\Auth\Models\UsersAssociatedCompany', 'users_id', ['alias' => 'companies']);
66 44
        $this->hasOne('default_company', 'Gewaer\Models\Companies', 'id', ['alias' => 'defaultCompany']);
67
68 44
        $this->hasOne(
69 44
            'id',
70 44
            'Gewaer\Models\UserRoles',
71 44
            'users_id',
72 44
            ['alias' => 'permission']
73
        );
74
75 44
        $this->hasMany(
76 44
            'id',
77 44
            'Gewaer\Models\UserRoles',
78 44
            'users_id',
79 44
            ['alias' => 'permissions']
80
        );
81
82 44
        $this->hasManyToMany(
83 44
            'id',
84 44
            'Gewaer\Models\UserRoles',
85 44
            'users_id',
86 44
            'roles_id',
87 44
            'Gewaer\Models\Roles',
88 44
            'id',
89
            [
90 44
                'alias' => 'roles',
91
                'params' => [
92 44
                    'limit' => 1,
93 44
                    'conditions' => 'Gewaer\Models\UserRoles.apps_id = ' . $this->di->getConfig()->app->id,
94
                ]
95
            ]
96
        );
97
98 44
        $this->hasMany(
99 44
            'id',
100 44
            'Gewaer\Models\Subscription',
101 44
            'user_id',
102
            [
103 44
                'alias' => 'allSubscriptions',
104
                'params' => [
105 44
                    'conditions' => 'apps_id = ?0',
106 44
                    'bind' => [$this->di->getApp()->getId()],
107 44
                    'order' => 'id DESC'
108
                ]
109
            ]
110
        );
111 44
    }
112
113
    /**
114
     * Validations and business logic
115
     */
116 3
    public function validation()
117
    {
118 3
        $validator = new Validation();
119 3
        $validator->add(
120 3
            'email',
121 3
            new Email([
122 3
                'field' => 'email',
123
                'required' => true,
124
            ])
125
        );
126
127 3
        $validator->add(
128 3
            'displayname',
129 3
            new PresenceOf([
130 3
                'field' => 'displayname',
131
                'required' => true,
132
            ])
133
        );
134
135 3
        $validator->add(
136 3
            'displayname',
137 3
            new Regex([
138 3
                'field' => 'displayname',
139 3
                'message' => _('Please use alphanumerics only.'),
140 3
                'pattern' => '/^[A-Za-z0-9_-]{1,32}$/',
141
            ])
142
        );
143
144
        // Unique values
145 3
        $validator->add(
146 3
            'email',
147 3
            new Uniqueness([
148 3
                'field' => 'email',
149 3
                'message' => _('This email already has an account.'),
150
            ])
151
        );
152
153 3
        return $this->validate($validator);
154
    }
155
156
    /**
157
     * Returns table name mapped in the model.
158
     *
159
     * @return string
160
     */
161 35
    public function getSource() : string
162
    {
163 35
        return 'users';
164
    }
165
166
    /**
167
     * Get the User key for redis
168
     *
169
     * @return string
170
     */
171
    public function getKey() : string
172
    {
173
        return $this->id;
174
    }
175
176
    /**
177
     * A company owner is the first person that register this company
178
     * This only ocurres when signing up the first time, after that all users invites
179
     * come with a default_company id attached
180
     *
181
     * @return boolean
182
     */
183 3
    public function isFirstSignup(): bool
184
    {
185 3
        return empty($this->default_company) ? true : false;
186
    }
187
188
    /**
189
     * Does the user have a role assign to him?
190
     *
191
     * @return boolean
192
     */
193 7
    public function hasRole(): bool
194
    {
195 7
        return !empty($this->roles_id) ? true : false;
196
    }
197
198
    /**
199
     * Get all of the subscriptions for the user.
200
     */
201 3
    public function subscriptions()
202
    {
203 3
        $this->hasMany(
204 3
            'id',
205 3
            'Gewaer\Models\Subscription',
206 3
            'user_id',
207
            [
208 3
                'alias' => 'subscriptions',
209
                'params' => [
210 3
                    'conditions' => 'apps_id = ?0 and companies_id = ?1',
211 3
                    'bind' => [$this->di->getApp()->getId(), $this->default_company],
212 3
                    'order' => 'id DESC'
213
                ]
214
            ]
215
        );
216
217 3
        return $this->getRelated('subscriptions');
218
    }
219
220
    /**
221
     * Strat a free trial
222
     *
223
     * @param Users $user
224
     * @return Subscription
225
     */
226 1
    public function startFreeTrial() : Subscription
227
    {
228 1
        $defaultPlan = AppsPlans::getDefaultPlan();
229
230 1
        $subscription = new Subscription();
231 1
        $subscription->user_id = $this->getId();
232 1
        $subscription->companies_id = $this->default_company;
233 1
        $subscription->apps_id = $this->di->getApp()->getId();
234 1
        $subscription->apps_plans_id = $this->di->getApp()->default_apps_plan_id;
235 1
        $subscription->name = $defaultPlan->name;
236 1
        $subscription->stripe_id = $defaultPlan->stripe_id;
237 1
        $subscription->stripe_plan = $defaultPlan->stripe_plan;
238 1
        $subscription->quantity = 1;
239 1
        $subscription->trial_ends_at = Carbon::now()->addDays($this->di->getApp()->plan->free_trial_dates)->toDateTimeString();
240
241 1
        if (!$subscription->save()) {
242
            throw new ServerErrorHttpException((string)current($this->getMessages()));
243
        }
244
245 1
        $this->trial_ends_at = $subscription->trial_ends_at;
246 1
        $this->update();
247
248 1
        return $subscription;
249
    }
250
251
    /**
252
     * Before create
253
     *
254
     * @return void
255
     */
256 3
    public function beforeCreate()
257
    {
258 3
        parent::beforeCreate();
259
260
        //this is only empty when creating a new user
261 3
        if (!$this->isFirstSignup()) {
262
            //confirm if the app reach its limit
263 2
            $this->isAtLimit();
264
        }
265
266
        //Assign admin role to the system if we dont get a specify role
267 3
        if (!$this->hasRole()) {
268 1
            $role = Roles::findFirstByName('Admins');
269 1
            $this->roles_id = $role->getId();
270
        }
271 3
    }
272
273
    /**
274
     * What to do after the creation of a new users
275
     *  - Assign default role
276
     *
277
     * @return void
278
     */
279 3
    public function afterCreate()
280
    {
281
        //need to run it here, since we overwirte the default_company id and null this function objective
282 3
        $isFirstSignup = $this->isFirstSignup();
283
284
        /**
285
         * User signing up for a new app / plan
286
         * How do we know? well he doesnt have a default_company
287
         */
288 3
        if ($isFirstSignup) {
289 1
            $company = new Companies();
290 1
            $company->name = $this->defaultCompanyName;
291 1
            $company->users_id = $this->getId();
292
293 1
            if (!$company->save()) {
294
                throw new Exception(current($company->getMessages()));
295
            }
296
297 1
            $this->default_company = $company->getId();
298
299 1
            if (!$this->update()) {
300
                throw new ServerErrorHttpException((string) current($this->getMessages()));
301
            }
302
303 1
            $this->default_company_branch = $this->defaultCompany->branch->getId();
304 1
            $this->update();
305
306
            //update default subscription free trial
307 1
            $company->app->subscriptions_id = $this->startFreeTrial()->getId();
308 1
            $company->update();
309
        } else {
310
            //we have the company id
311 2
            if (empty($this->default_company_branch)) {
312
                $this->default_company_branch = $this->defaultCompany->branch->getId();
313
            }
314
        }
315
316
        //Create new company associated company
317 3
        $newUserAssocCompany = new UsersAssociatedCompany();
318 3
        $newUserAssocCompany->users_id = $this->id;
319 3
        $newUserAssocCompany->companies_id = $this->default_company;
320 3
        $newUserAssocCompany->identify_id = 1;
321 3
        $newUserAssocCompany->user_active = 1;
322 3
        $newUserAssocCompany->user_role = $this->roles_id == 1 ? 'admins' : 'users';
323
324 3
        if (!$newUserAssocCompany->save()) {
325
            throw new ServerErrorHttpException((string)current($newUserAssocCompany->getMessages()));
326
        }
327
328
        //Insert record into user_roles
329 3
        $userRole = new UserRoles();
330 3
        $userRole->users_id = $this->id;
331 3
        $userRole->roles_id = $this->roles_id;
332 3
        $userRole->apps_id = $this->di->getApp()->getId();
333 3
        $userRole->companies_id = $this->default_company;
334
335 3
        if (!$userRole->save()) {
336
            throw new ServerErrorHttpException((string)current($userRole->getMessages()));
337
        }
338
339
        //update user activity when its not a empty user
340 3
        if (!$isFirstSignup) {
341 2
            $this->updateAppActivityLimit();
342
        }
343 3
    }
344
}
345