2018-06-22 19:44:21 +02:00
|
|
|
<?php
|
2018-07-15 12:30:49 +02:00
|
|
|
/**
|
|
|
|
* User model class.
|
|
|
|
* Class also responsible for dates conversion and representation.
|
|
|
|
*/
|
2018-07-25 19:30:43 +02:00
|
|
|
|
2018-06-22 19:44:21 +02:00
|
|
|
namespace App;
|
|
|
|
|
2018-08-31 18:17:38 +02:00
|
|
|
use App\Mail\UserInvite;
|
2018-07-25 19:30:43 +02:00
|
|
|
use Carbon\Carbon;
|
2018-07-25 19:25:00 +02:00
|
|
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
2018-07-25 19:30:43 +02:00
|
|
|
use Illuminate\Notifications\Notifiable;
|
2018-07-07 08:42:21 +02:00
|
|
|
use Illuminate\Support\Facades\Hash;
|
2018-08-31 18:17:38 +02:00
|
|
|
use Illuminate\Support\Str;
|
2018-06-22 19:44:21 +02:00
|
|
|
|
|
|
|
class User extends Authenticatable
|
|
|
|
{
|
|
|
|
use Notifiable;
|
|
|
|
|
|
|
|
/**
|
2018-07-25 19:30:43 +02:00
|
|
|
* Roles.
|
2018-06-22 19:44:21 +02:00
|
|
|
*/
|
2018-07-14 03:23:37 +02:00
|
|
|
const ROLE_USER = 1;
|
|
|
|
const ROLE_ADMIN = 2;
|
|
|
|
|
2018-07-25 19:30:43 +02:00
|
|
|
public static $roles = [
|
2018-07-14 03:23:37 +02:00
|
|
|
self::ROLE_ADMIN => 'admin',
|
2018-07-25 19:30:43 +02:00
|
|
|
self::ROLE_USER => 'user',
|
|
|
|
];
|
2018-06-22 19:44:21 +02:00
|
|
|
|
2018-07-10 12:15:58 +02:00
|
|
|
/**
|
2018-07-25 19:30:43 +02:00
|
|
|
* Types.
|
2018-07-10 12:15:58 +02:00
|
|
|
*/
|
2018-07-14 03:23:37 +02:00
|
|
|
const TYPE_USER = 1;
|
|
|
|
const TYPE_TEAM = 2;
|
2018-07-25 19:30:43 +02:00
|
|
|
|
2018-06-22 19:44:21 +02:00
|
|
|
/**
|
2018-07-25 19:30:43 +02:00
|
|
|
* Invite states.
|
2018-06-22 19:44:21 +02:00
|
|
|
*/
|
2018-08-31 18:17:38 +02:00
|
|
|
const INVITE_STATE_ACTIVATED = 1;
|
2018-06-22 19:44:21 +02:00
|
|
|
const INVITE_STATE_SENT = 2;
|
2018-08-31 18:17:38 +02:00
|
|
|
const INVITE_STATE_NOT_INVITED = 3;
|
2018-06-22 19:44:21 +02:00
|
|
|
|
|
|
|
/**
|
2018-07-25 19:30:43 +02:00
|
|
|
* Time formats.
|
2018-06-22 19:44:21 +02:00
|
|
|
*/
|
|
|
|
const TIME_FORMAT_12 = 1;
|
|
|
|
const TIME_FORMAT_24 = 2;
|
2018-07-25 19:30:43 +02:00
|
|
|
|
2018-08-29 16:20:25 +02:00
|
|
|
/**
|
|
|
|
* Global user permissions.
|
|
|
|
*/
|
|
|
|
const USER_PERM_DELETE_CONVERSATIONS = 1;
|
|
|
|
const USER_PERM_EDIT_CONVERSATIONS = 2;
|
|
|
|
const USER_PERM_EDIT_SAVED_REPLIES = 3;
|
|
|
|
const USER_PERM_EDIT_TAGS = 4;
|
|
|
|
|
|
|
|
public static $user_permissions = [
|
|
|
|
self::USER_PERM_DELETE_CONVERSATIONS,
|
|
|
|
self::USER_PERM_EDIT_CONVERSATIONS,
|
|
|
|
self::USER_PERM_EDIT_SAVED_REPLIES,
|
|
|
|
self::USER_PERM_EDIT_TAGS,
|
|
|
|
];
|
|
|
|
|
2018-06-22 19:44:21 +02:00
|
|
|
/**
|
2018-06-26 11:43:11 +02:00
|
|
|
* The attributes that are not mass assignable.
|
2018-06-22 19:44:21 +02:00
|
|
|
*
|
|
|
|
* @var array
|
|
|
|
*/
|
2018-07-25 19:30:43 +02:00
|
|
|
protected $guarded = ['role'];
|
2018-06-22 19:44:21 +02:00
|
|
|
|
|
|
|
/**
|
2018-06-26 11:43:11 +02:00
|
|
|
* The attributes that should be hidden for arrays, excluded from the model's JSON form.
|
2018-06-22 19:44:21 +02:00
|
|
|
*
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
protected $hidden = [
|
|
|
|
'password', 'remember_token',
|
|
|
|
];
|
|
|
|
|
2018-06-24 11:01:26 +02:00
|
|
|
/**
|
2018-07-25 19:30:43 +02:00
|
|
|
* Attributes fillable using fill() method.
|
|
|
|
*
|
2018-06-24 11:01:26 +02:00
|
|
|
* @var [type]
|
|
|
|
*/
|
2018-07-25 19:30:43 +02:00
|
|
|
protected $fillable = ['role', 'first_name', 'last_name', 'email', 'password', 'role', 'timezone', 'photo_url', 'type', 'emails', 'job_title', 'phone', 'time_format', 'enable_kb_shortcuts'];
|
2018-06-22 19:44:21 +02:00
|
|
|
|
2018-08-08 09:52:53 +02:00
|
|
|
/**
|
2018-08-08 09:56:03 +02:00
|
|
|
* For array_unique function.
|
|
|
|
*
|
2018-08-08 09:52:53 +02:00
|
|
|
* @return string
|
|
|
|
*/
|
2018-08-08 09:56:03 +02:00
|
|
|
public function __toString()
|
|
|
|
{
|
2018-08-08 09:52:53 +02:00
|
|
|
return $this->id.'';
|
|
|
|
}
|
|
|
|
|
2018-06-29 07:07:00 +02:00
|
|
|
/**
|
2018-07-25 19:30:43 +02:00
|
|
|
* Get mailboxes to which usre has access.
|
2018-06-29 07:07:00 +02:00
|
|
|
*/
|
|
|
|
public function mailboxes()
|
|
|
|
{
|
2018-08-10 16:28:35 +02:00
|
|
|
return $this->belongsToMany('App\Mailbox')->as('settings')->withPivot('after_send');
|
2018-06-29 07:07:00 +02:00
|
|
|
}
|
|
|
|
|
2018-07-14 03:23:37 +02:00
|
|
|
/**
|
2018-07-25 19:30:43 +02:00
|
|
|
* Get conversations assigned to user.
|
2018-07-14 03:23:37 +02:00
|
|
|
*/
|
|
|
|
public function conversations()
|
|
|
|
{
|
|
|
|
return $this->hasMany('App\Conversation');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-07-25 19:30:43 +02:00
|
|
|
* User's folders.
|
2018-07-14 03:23:37 +02:00
|
|
|
*/
|
|
|
|
public function folders()
|
|
|
|
{
|
|
|
|
return $this->hasMany('App\Folder');
|
|
|
|
}
|
|
|
|
|
2018-08-08 09:52:53 +02:00
|
|
|
/**
|
|
|
|
* User's subscriptions.
|
|
|
|
*/
|
|
|
|
public function subscriptions()
|
|
|
|
{
|
|
|
|
return $this->hasMany('App\Subscription');
|
|
|
|
}
|
|
|
|
|
2018-06-22 19:44:21 +02:00
|
|
|
/**
|
2018-07-25 19:30:43 +02:00
|
|
|
* Get user role.
|
|
|
|
*
|
2018-06-22 19:44:21 +02:00
|
|
|
* @return string
|
|
|
|
*/
|
2018-07-14 03:23:37 +02:00
|
|
|
public function getRoleName($ucfirst = false)
|
2018-06-22 19:44:21 +02:00
|
|
|
{
|
2018-07-14 03:23:37 +02:00
|
|
|
$role_name = self::$roles[$this->role];
|
|
|
|
if ($ucfirst) {
|
|
|
|
$role_name = ucfirst($role_name);
|
|
|
|
}
|
2018-07-25 19:30:43 +02:00
|
|
|
|
2018-07-14 03:23:37 +02:00
|
|
|
return $role_name;
|
2018-06-22 19:44:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-07-25 19:30:43 +02:00
|
|
|
* Check if user is admin.
|
|
|
|
*
|
|
|
|
* @return bool
|
2018-06-22 19:44:21 +02:00
|
|
|
*/
|
|
|
|
public function isAdmin()
|
|
|
|
{
|
2018-07-25 19:30:43 +02:00
|
|
|
return $this->role == self::ROLE_ADMIN;
|
2018-06-22 19:44:21 +02:00
|
|
|
}
|
2018-06-24 11:01:26 +02:00
|
|
|
|
|
|
|
/**
|
2018-07-25 19:30:43 +02:00
|
|
|
* Get user full name.
|
|
|
|
*
|
2018-06-24 11:01:26 +02:00
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getFullName()
|
|
|
|
{
|
2018-07-25 19:30:43 +02:00
|
|
|
return $this->first_name.' '.$this->last_name;
|
2018-06-24 11:01:26 +02:00
|
|
|
}
|
2018-07-06 05:19:49 +02:00
|
|
|
|
2018-08-04 17:33:45 +02:00
|
|
|
/**
|
|
|
|
* Get user first name.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getFirstName()
|
|
|
|
{
|
|
|
|
return $this->first_name;
|
|
|
|
}
|
|
|
|
|
2018-07-06 05:19:49 +02:00
|
|
|
/**
|
2018-07-25 19:30:43 +02:00
|
|
|
* Get mailboxes to which user has access.
|
2018-07-06 05:19:49 +02:00
|
|
|
*/
|
2018-07-14 03:23:37 +02:00
|
|
|
public function mailboxesCanView()
|
2018-07-06 05:19:49 +02:00
|
|
|
{
|
|
|
|
if ($this->isAdmin()) {
|
|
|
|
return Mailbox::all();
|
|
|
|
} else {
|
2018-08-10 16:28:35 +02:00
|
|
|
return $this->mailboxes;
|
2018-07-06 05:19:49 +02:00
|
|
|
}
|
|
|
|
}
|
2018-07-07 08:42:21 +02:00
|
|
|
|
2018-08-23 10:46:08 +02:00
|
|
|
/**
|
|
|
|
* Get IDs of mailboxes to which user has access.
|
|
|
|
*/
|
|
|
|
public function mailboxesIdsCanView()
|
|
|
|
{
|
|
|
|
if ($this->isAdmin()) {
|
|
|
|
return Mailbox::pluck('id')->toArray();
|
|
|
|
} else {
|
2018-08-23 11:00:43 +02:00
|
|
|
return $this->mailboxes()->pluck('mailboxes.id')->toArray();
|
2018-08-23 10:46:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-07 08:42:21 +02:00
|
|
|
/**
|
2018-07-25 19:30:43 +02:00
|
|
|
* Generate random password for the user.
|
|
|
|
*
|
|
|
|
* @param int $length
|
|
|
|
*
|
2018-07-07 08:42:21 +02:00
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function generatePassword($length = 8)
|
|
|
|
{
|
|
|
|
$this->password = Hash::make(str_random($length));
|
2018-07-25 19:30:43 +02:00
|
|
|
|
2018-07-07 08:42:21 +02:00
|
|
|
return $this->password;
|
|
|
|
}
|
2018-07-08 09:39:12 +02:00
|
|
|
|
|
|
|
/**
|
2018-07-25 19:30:43 +02:00
|
|
|
* Get URL for editing user.
|
|
|
|
*
|
2018-07-08 09:39:12 +02:00
|
|
|
* @return string
|
|
|
|
*/
|
2018-08-02 18:17:13 +02:00
|
|
|
public function url()
|
2018-07-08 09:39:12 +02:00
|
|
|
{
|
|
|
|
return route('users.profile', ['id'=>$this->id]);
|
|
|
|
}
|
2018-07-14 03:23:37 +02:00
|
|
|
|
2018-08-31 18:17:38 +02:00
|
|
|
/**
|
|
|
|
* Get URL for settings up an account from invitation.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function urlSetup()
|
|
|
|
{
|
|
|
|
return route('user_setup', ['hash' => $this->invite_hash]);
|
|
|
|
}
|
|
|
|
|
2018-07-14 03:23:37 +02:00
|
|
|
/**
|
|
|
|
* Create personal folders for user mailboxes.
|
2018-07-25 19:30:43 +02:00
|
|
|
*
|
|
|
|
* @param int $mailbox_id
|
|
|
|
* @param mixed $users
|
2018-07-14 03:23:37 +02:00
|
|
|
*/
|
|
|
|
public function syncPersonalFolders($mailboxes)
|
|
|
|
{
|
2018-08-10 16:28:35 +02:00
|
|
|
if ($this->isAdmin()) {
|
|
|
|
// For admin we get all mailboxes
|
|
|
|
$mailbox_ids = Mailbox::pluck('mailboxes.id');
|
2018-07-14 03:23:37 +02:00
|
|
|
} else {
|
2018-08-10 16:28:35 +02:00
|
|
|
if (is_array($mailboxes)) {
|
|
|
|
$mailbox_ids = $mailboxes;
|
|
|
|
} else {
|
|
|
|
$mailbox_ids = $this->mailboxes()->pluck('mailboxes.id');
|
|
|
|
}
|
2018-07-14 03:23:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$cur_mailboxes = Folder::select('mailbox_id')
|
|
|
|
->where('user_id', $this->id)
|
|
|
|
->whereIn('mailbox_id', $mailbox_ids)
|
|
|
|
->groupBy('mailbox_id')
|
|
|
|
->pluck('mailbox_id')
|
|
|
|
->toArray();
|
|
|
|
|
|
|
|
foreach ($mailbox_ids as $mailbox_id) {
|
|
|
|
if (in_array($mailbox_id, $cur_mailboxes)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
foreach (Folder::$personal_types as $type) {
|
2018-07-25 19:30:43 +02:00
|
|
|
$folder = new Folder();
|
2018-07-14 03:23:37 +02:00
|
|
|
$folder->mailbox_id = $mailbox_id;
|
|
|
|
$folder->user_id = $this->id;
|
|
|
|
$folder->type = $type;
|
|
|
|
$folder->save();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-07-15 12:30:49 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Format date according to user's timezone and time format.
|
2018-07-25 19:30:43 +02:00
|
|
|
*
|
|
|
|
* @param Carbon $date
|
|
|
|
* @param string $format
|
|
|
|
*
|
|
|
|
* @return string
|
2018-07-15 12:30:49 +02:00
|
|
|
*/
|
2018-08-08 09:52:53 +02:00
|
|
|
public static function dateFormat($date, $format = 'M j, Y H:i', $user = null)
|
2018-07-15 12:30:49 +02:00
|
|
|
{
|
2018-08-08 09:52:53 +02:00
|
|
|
if (!$user) {
|
|
|
|
$user = auth()->user();
|
|
|
|
}
|
2018-07-15 12:30:49 +02:00
|
|
|
if ($user) {
|
|
|
|
if ($user->time_format == self::TIME_FORMAT_12) {
|
|
|
|
$format = strtr($format, [
|
2018-07-25 19:30:43 +02:00
|
|
|
'H' => 'h',
|
|
|
|
'G' => 'g',
|
|
|
|
':i' => ':ia',
|
2018-07-15 12:30:49 +02:00
|
|
|
':ia:s' => ':i:sa',
|
|
|
|
]);
|
|
|
|
} else {
|
|
|
|
$format = strtr($format, [
|
2018-07-25 19:30:43 +02:00
|
|
|
'h' => 'H',
|
|
|
|
'g' => 'G',
|
|
|
|
':ia' => ':i',
|
2018-07-15 12:30:49 +02:00
|
|
|
':i:sa' => ':i:s',
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
// todo: formatLocalized has to be used here and below,
|
|
|
|
// but it returns $format value instead of formatted date
|
|
|
|
return $date->setTimezone($user->timezone)->format($format);
|
|
|
|
} else {
|
|
|
|
return $date->format($format);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert date into human readable format.
|
2018-07-25 19:30:43 +02:00
|
|
|
*
|
|
|
|
* @param Carbon $date
|
|
|
|
*
|
2018-07-15 12:30:49 +02:00
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public static function dateDiffForHumans($date)
|
|
|
|
{
|
2018-07-25 19:25:00 +02:00
|
|
|
if (!$date) {
|
|
|
|
return '';
|
|
|
|
}
|
2018-07-25 19:30:43 +02:00
|
|
|
|
2018-07-15 12:30:49 +02:00
|
|
|
$user = auth()->user();
|
|
|
|
if ($user) {
|
|
|
|
$date->setTimezone($user->timezone);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($date->diffInSeconds(Carbon::now()) <= 60) {
|
2018-07-25 19:30:43 +02:00
|
|
|
return __('Just now');
|
2018-07-15 12:30:49 +02:00
|
|
|
} elseif ($date->diffInDays(Carbon::now()) > 7) {
|
|
|
|
// Exact date
|
|
|
|
if (Carbon::now()->year == $date->year) {
|
2018-07-25 19:30:43 +02:00
|
|
|
return self::dateFormat($date, 'M j');
|
2018-07-15 12:30:49 +02:00
|
|
|
} else {
|
2018-07-25 19:30:43 +02:00
|
|
|
return self::dateFormat($date, 'M j, Y');
|
2018-07-15 12:30:49 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$diff_text = $date->diffForHumans();
|
2018-07-25 19:30:43 +02:00
|
|
|
$diff_text = preg_replace('/minutes?/', 'min', $diff_text);
|
|
|
|
|
2018-07-15 12:30:49 +02:00
|
|
|
return $diff_text;
|
|
|
|
}
|
|
|
|
}
|
2018-08-29 16:20:25 +02:00
|
|
|
|
|
|
|
public static function getUserPermissionName($user_permission)
|
|
|
|
{
|
|
|
|
$user_permission_names = [
|
|
|
|
self::USER_PERM_DELETE_CONVERSATIONS => __('Users are allowed to delete notes/conversations'),
|
|
|
|
self::USER_PERM_EDIT_CONVERSATIONS => __('Users are allowed to edit notes/threads'),
|
|
|
|
self::USER_PERM_EDIT_SAVED_REPLIES => __('Users are allowed to edit/delete saved replies'),
|
|
|
|
self::USER_PERM_EDIT_TAGS => __('Users are allowed to manage tags'),
|
|
|
|
];
|
|
|
|
|
|
|
|
if (!empty($user_permission_names[$user_permission])) {
|
|
|
|
return $user_permission_names[$user_permission];
|
|
|
|
} else {
|
|
|
|
return \Event::fire('filter.user_permission_name', [$user_permission]);
|
|
|
|
}
|
|
|
|
}
|
2018-08-31 18:17:38 +02:00
|
|
|
|
|
|
|
public function getInviteStateName()
|
|
|
|
{
|
|
|
|
$names = [
|
|
|
|
self::INVITE_STATE_ACTIVATED => __('Active'),
|
|
|
|
self::INVITE_STATE_SENT => __('Invited'),
|
|
|
|
self::INVITE_STATE_NOT_INVITED => __('Not Invited'),
|
|
|
|
];
|
|
|
|
if (!isset($names[$this->invite_state])) {
|
|
|
|
return $names[self::INVITE_STATE_ACTIVATED];
|
|
|
|
} else {
|
|
|
|
return $names[$this->invite_state];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Send invitation to this user.
|
|
|
|
*/
|
2018-09-02 08:45:13 +02:00
|
|
|
public function sendInvite($throw_exceptions = false)
|
2018-08-31 18:17:38 +02:00
|
|
|
{
|
2018-09-02 08:45:13 +02:00
|
|
|
if ($this->invite_state == self::INVITE_STATE_ACTIVATED) {
|
|
|
|
return false;
|
|
|
|
}
|
2018-08-31 18:17:38 +02:00
|
|
|
// We are using remember_token as a hash for invite
|
|
|
|
if (!$this->invite_hash) {
|
|
|
|
$this->invite_hash = Str::random(60);
|
|
|
|
$this->save();
|
|
|
|
}
|
|
|
|
|
2018-09-02 08:45:13 +02:00
|
|
|
try {
|
|
|
|
\App\Mail\Mail::setSystemMailDriver();
|
|
|
|
|
|
|
|
\Mail::to([['name' => $this->getFullName(), 'email' => $this->email]])
|
|
|
|
->send(new UserInvite($this));
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
// We come here in case SMTP server unavailable for example
|
|
|
|
// activity()
|
|
|
|
// ->causedBy($this->customer)
|
|
|
|
// ->withProperties([
|
|
|
|
// 'error' => $e->getMessage().'; File: '.$e->getFile().' ('.$e->getLine().')',
|
|
|
|
// ])
|
|
|
|
// ->useLog(\App\ActivityLog::NAME_EMAILS_SENDING)
|
|
|
|
// ->log(\App\ActivityLog::DESCRIPTION_EMAILS_SENDING_ERROR_TO_CUSTOMER);
|
|
|
|
|
|
|
|
if ($throw_exceptions) {
|
|
|
|
throw $e;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2018-08-31 18:17:38 +02:00
|
|
|
|
|
|
|
if (\Mail::failures()) {
|
2018-09-02 08:45:13 +02:00
|
|
|
if ($throw_exceptions) {
|
|
|
|
throw new Exception(__("Error occured sending email to :email. Please check logs for more details.", ['email' => $this->email]), 1);
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($this->invite_state != User::INVITE_STATE_SENT) {
|
|
|
|
$this->invite_state = User::INVITE_STATE_SENT;
|
|
|
|
$this->save();
|
2018-08-31 18:17:38 +02:00
|
|
|
}
|
2018-09-02 08:45:13 +02:00
|
|
|
return true;
|
2018-08-31 18:17:38 +02:00
|
|
|
}
|
2018-06-22 19:44:21 +02:00
|
|
|
}
|