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