2018-07-14 03:23:37 +02:00
< ? php
namespace App ;
2018-11-12 14:35:06 +01:00
2018-07-14 03:23:37 +02:00
use Illuminate\Database\Eloquent\Model ;
class Thread extends Model
{
/**
2018-07-25 19:30:43 +02:00
* By whom action performed ( source_via ) .
2018-07-14 03:23:37 +02:00
*/
const PERSON_CUSTOMER = 1 ;
const PERSON_USER = 2 ;
2018-07-25 19:30:43 +02:00
public static $persons = [
2018-07-14 03:23:37 +02:00
self :: PERSON_CUSTOMER => 'customer' ,
2018-07-25 19:30:43 +02:00
self :: PERSON_USER => 'user' ,
];
2018-07-14 03:23:37 +02:00
/**
2018-07-25 19:30:43 +02:00
* Thread types .
2018-07-14 03:23:37 +02:00
*/
// Email from customer
const TYPE_CUSTOMER = 1 ;
// Thead created by user
const TYPE_MESSAGE = 2 ;
const TYPE_NOTE = 3 ;
// Thread status change
const TYPE_LINEITEM = 4 ;
2019-06-24 07:39:30 +02:00
//const TYPE_PHONE = 5;
// Forwarded threads - used in API only.
//const TYPE_FORWARDPARENT = 6;
//const TYPE_FORWARDCHILD = 7;
2018-07-14 03:23:37 +02:00
const TYPE_CHAT = 8 ;
public static $types = [
2018-07-20 08:19:25 +02:00
// Thread by customer
2018-07-25 19:30:43 +02:00
self :: TYPE_CUSTOMER => 'customer' ,
2018-07-20 08:19:25 +02:00
// Thread by user
2018-07-25 19:30:43 +02:00
self :: TYPE_MESSAGE => 'message' ,
self :: TYPE_NOTE => 'note' ,
2018-07-20 08:19:25 +02:00
// lineitem represents a change of state on the conversation. This could include, but not limited to, the conversation was assigned, the status changed, the conversation was moved from one mailbox to another, etc. A line item won’ t have a body, to/cc/bcc lists, or attachments.
2018-07-25 19:30:43 +02:00
self :: TYPE_LINEITEM => 'lineitem' ,
2019-06-24 07:39:30 +02:00
//self::TYPE_PHONE => 'phone',
2018-07-20 08:19:25 +02:00
// When a conversation is forwarded, a new conversation is created to represent the forwarded conversation.
// forwardparent is the type set on the thread of the original conversation that initiated the forward event.
2019-06-24 07:39:30 +02:00
//self::TYPE_FORWARDPARENT => 'forwardparent',
2018-07-20 08:19:25 +02:00
// forwardchild is the type set on the first thread of the new forwarded conversation.
2019-06-24 07:39:30 +02:00
//self::TYPE_FORWARDCHILD => 'forwardchild',
2018-07-25 19:30:43 +02:00
self :: TYPE_CHAT => 'chat' ,
2018-07-14 03:23:37 +02:00
];
2019-06-24 07:39:30 +02:00
/**
* Subtypes ( for notes mostly )
*/
const SUBTYPE_FORWARD = 1 ;
const SUBTYPE_PHONE = 2 ;
2018-07-14 03:23:37 +02:00
/**
2018-07-27 15:19:25 +02:00
* Statuses ( code must be equal to conversations statuses ) .
2018-07-14 03:23:37 +02:00
*/
const STATUS_ACTIVE = 1 ;
2018-07-27 15:19:25 +02:00
const STATUS_PENDING = 2 ;
const STATUS_CLOSED = 3 ;
const STATUS_SPAM = 4 ;
const STATUS_NOCHANGE = 6 ;
2018-07-14 03:23:37 +02:00
2018-07-25 19:30:43 +02:00
public static $statuses = [
self :: STATUS_ACTIVE => 'active' ,
self :: STATUS_CLOSED => 'closed' ,
self :: STATUS_NOCHANGE => 'nochange' ,
self :: STATUS_PENDING => 'pending' ,
self :: STATUS_SPAM => 'spam' ,
];
2018-07-14 03:23:37 +02:00
/**
2018-07-25 19:30:43 +02:00
* States .
2018-07-14 03:23:37 +02:00
*/
const STATE_DRAFT = 1 ;
const STATE_PUBLISHED = 2 ;
const STATE_HIDDEN = 3 ;
2018-08-02 18:17:13 +02:00
// A state of review means the thread has been stopped by Traffic Cop and is waiting
// to be confirmed (or discarded) by the person that created the thread.
2018-07-14 03:23:37 +02:00
const STATE_REVIEW = 4 ;
2018-07-25 19:30:43 +02:00
public static $states = [
self :: STATE_DRAFT => 'draft' ,
self :: STATE_PUBLISHED => 'published' ,
self :: STATE_HIDDEN => 'hidden' ,
self :: STATE_REVIEW => 'review' ,
];
2018-07-14 03:23:37 +02:00
/**
2018-07-25 19:30:43 +02:00
* Action associated with the line item .
2019-06-03 07:52:37 +02:00
* It is recommended to add custom action types between 100 and 1000
2018-07-14 03:23:37 +02:00
*/
2018-07-25 19:25:00 +02:00
// Conversation's status changed
const ACTION_TYPE_STATUS_CHANGED = 1 ;
// Conversation's assignee changed
const ACTION_TYPE_USER_CHANGED = 2 ;
2018-07-14 03:23:37 +02:00
// The conversation was moved from another mailbox
2018-07-25 19:25:00 +02:00
const ACTION_TYPE_MOVED_FROM_MAILBOX = 3 ;
2018-07-14 03:23:37 +02:00
// Another conversation was merged with this conversation
2018-07-25 19:25:00 +02:00
const ACTION_TYPE_MERGED = 4 ;
2018-07-14 03:23:37 +02:00
// The conversation was imported (no email notifications were sent)
2018-07-25 19:25:00 +02:00
const ACTION_TYPE_IMPORTED = 5 ;
2018-07-14 03:23:37 +02:00
// A workflow was run on this conversation (either automatic or manual)
2018-07-25 19:25:00 +02:00
const ACTION_TYPE_WORKFLOW_MANUAL = 6 ;
const ACTION_TYPE_WORKFLOW_AUTO = 7 ;
2018-07-14 03:23:37 +02:00
// The ticket was imported from an external Service
2018-07-25 19:25:00 +02:00
const ACTION_TYPE_IMPORTED_EXTERNAL = 8 ;
2018-08-29 08:45:15 +02:00
// Conversation customer changed
const ACTION_TYPE_CUSTOMER_CHANGED = 9 ;
2018-07-14 03:23:37 +02:00
// The ticket was deleted
2018-07-25 19:25:00 +02:00
const ACTION_TYPE_DELETED_TICKET = 10 ;
2018-07-14 03:23:37 +02:00
// The ticket was restored
2018-07-25 19:25:00 +02:00
const ACTION_TYPE_RESTORE_TICKET = 11 ;
2018-07-14 03:23:37 +02:00
// Describes an optional action associated with the line item
// todo: values need to be checked via HelpScout API
public static $action_types = [
2018-07-25 19:30:43 +02:00
self :: ACTION_TYPE_STATUS_CHANGED => 'changed-ticket-status' ,
self :: ACTION_TYPE_USER_CHANGED => 'changed-ticket-assignee' ,
self :: ACTION_TYPE_MOVED_FROM_MAILBOX => 'moved-from-mailbox' ,
self :: ACTION_TYPE_MERGED => 'merged' ,
self :: ACTION_TYPE_IMPORTED => 'imported' ,
self :: ACTION_TYPE_WORKFLOW_MANUAL => 'manual-workflow' ,
self :: ACTION_TYPE_WORKFLOW_AUTO => 'automatic-workflow' ,
self :: ACTION_TYPE_IMPORTED_EXTERNAL => 'imported-external' ,
2018-08-29 08:45:15 +02:00
self :: ACTION_TYPE_CUSTOMER_CHANGED => 'changed-ticket-customer' ,
2018-07-25 19:30:43 +02:00
self :: ACTION_TYPE_DELETED_TICKET => 'deleted-ticket' ,
self :: ACTION_TYPE_RESTORE_TICKET => 'restore-ticket' ,
2018-07-14 03:23:37 +02:00
];
2018-07-25 19:30:43 +02:00
/**
* Source types ( equal to thread source types ) .
2018-07-14 03:23:37 +02:00
*/
const SOURCE_TYPE_EMAIL = 1 ;
const SOURCE_TYPE_WEB = 2 ;
const SOURCE_TYPE_API = 3 ;
2018-07-25 19:30:43 +02:00
2018-07-14 03:23:37 +02:00
public static $source_types = [
2018-07-25 19:30:43 +02:00
self :: SOURCE_TYPE_EMAIL => 'email' ,
self :: SOURCE_TYPE_WEB => 'web' ,
self :: SOURCE_TYPE_API => 'api' ,
2018-07-14 03:23:37 +02:00
];
2018-11-09 15:09:42 +01:00
protected $dates = [
'opened_at' ,
'created_at' ,
'updated_at' ,
2018-11-12 14:35:06 +01:00
'deleted_at' ,
2019-06-20 12:37:43 +02:00
'edited_at' ,
2018-11-12 14:35:06 +01:00
];
2018-11-09 15:09:42 +01:00
2018-07-14 03:23:37 +02:00
/**
2018-07-25 19:30:43 +02:00
* The user assigned to this thread ( assignedTo ) .
2018-07-14 03:23:37 +02:00
*/
public function user ()
{
return $this -> belongsTo ( 'App\User' );
}
2018-09-05 10:05:00 +02:00
/**
2018-09-07 15:08:34 +02:00
* The user assigned to this thread ( cached ) .
2018-09-05 10:05:00 +02:00
*/
public function user_cached ()
{
return $this -> user () -> rememberForever ();
}
2018-07-14 03:23:37 +02:00
/**
2018-07-25 19:30:43 +02:00
* Get the thread customer .
2018-07-14 03:23:37 +02:00
*/
public function customer ()
{
return $this -> belongsTo ( 'App\Customer' );
}
2018-09-07 15:08:34 +02:00
/**
* Get the thread customer ( cached ) .
*/
public function customer_cached ()
{
return $this -> customer () -> rememberForever ();
}
2018-07-14 03:23:37 +02:00
/**
2018-07-25 19:30:43 +02:00
* Get conversation .
2018-07-14 03:23:37 +02:00
*/
public function conversation ()
{
return $this -> belongsTo ( 'App\Conversation' );
}
2018-07-20 08:19:25 +02:00
2018-08-04 12:50:55 +02:00
/**
* Get thread attachmets .
*/
public function attachments ()
{
2018-08-15 08:10:05 +02:00
return $this -> hasMany ( 'App\Attachment' ) -> where ( 'embedded' , false );
//return $this->hasMany('App\Attachment');
}
/**
* Get thread embedded attachments .
*/
public function embeds ()
{
return $this -> hasMany ( 'App\Attachment' ) -> where ( 'embedded' , true );
2018-08-04 12:50:55 +02:00
}
2018-09-14 10:24:04 +02:00
/**
* All kinds of attachments including embedded .
*/
public function all_attachments ()
{
return $this -> hasMany ( 'App\Attachment' );
}
2018-07-20 08:19:25 +02:00
/**
2018-07-25 19:25:00 +02:00
* Get user who created the thread .
*/
public function created_by_user ()
{
return $this -> belongsTo ( 'App\User' );
}
2018-09-05 10:05:00 +02:00
/**
2018-11-12 10:12:57 +01:00
* Get user who created the thread ( cached ) .
2018-09-05 10:05:00 +02:00
*/
public function created_by_user_cached ()
{
2018-09-07 15:08:34 +02:00
return $this -> created_by_user () -> rememberForever ();
2018-09-05 10:05:00 +02:00
}
2018-07-25 19:25:00 +02:00
/**
* Get customer who created the thread .
*/
public function created_by_customer ()
{
return $this -> belongsTo ( 'App\Customer' );
}
2018-09-14 10:24:04 +02:00
/**
2019-06-20 12:37:43 +02:00
* Get user who edited thread .
2018-09-14 10:24:04 +02:00
*/
public function edited_by_user ()
{
return $this -> belongsTo ( 'App\User' );
}
2019-06-20 12:37:43 +02:00
/**
* Get user who edited thread ( cached ) .
*/
public function edited_by_user_cached ()
{
return $this -> edited_by_user () -> rememberForever ();
}
2018-07-25 19:25:00 +02:00
/**
2018-07-25 19:30:43 +02:00
* Get sanitized body HTML .
*
2018-07-20 08:19:25 +02:00
* @ return string
*/
2019-06-20 12:37:43 +02:00
public function getCleanBody ( $body = '' )
2018-07-20 08:19:25 +02:00
{
2019-06-20 12:37:43 +02:00
if ( ! $body ) {
$body = $this -> body ;
}
$body = \Purifier :: clean ( $body );
2018-08-15 08:10:05 +02:00
// Remove all kinds of spaces after tags
// https://stackoverflow.com/questions/3230623/filter-all-types-of-whitespace-in-php
$body = preg_replace ( " /^(.*)>[ \r \n ]* \ s+/mu " , '$1>' , $body );
return $body ;
2018-07-20 08:19:25 +02:00
}
2019-06-20 12:37:43 +02:00
/**
* Get sanitized body HTML .
*
* @ return string
*/
public function getCleanBodyOriginal ()
{
return $this -> getCleanBody ( $this -> body_original );
}
2018-07-20 08:19:25 +02:00
/**
* Get thread recipients .
2018-07-25 19:30:43 +02:00
*
2018-07-20 08:19:25 +02:00
* @ return array
*/
2018-08-27 10:08:20 +02:00
public function getToArray ( $exclude_array = [])
2018-07-20 08:19:25 +02:00
{
2018-09-20 09:08:02 +02:00
return \App\Misc\Helper :: jsonToArray ( $this -> to , $exclude_array );
2018-07-20 08:19:25 +02:00
}
2018-09-14 10:24:04 +02:00
public function getToString ( $exclude_array = [])
{
return implode ( ', ' , $this -> getToArray ( $exclude_array ));
}
/**
* Get first address from the To list .
*/
public function getToFirst ()
2018-11-12 10:12:57 +01:00
{
2018-09-14 10:24:04 +02:00
$to = $this -> getToArray ();
2018-11-12 10:12:57 +01:00
2018-09-14 10:24:04 +02:00
return array_shift ( $to );
}
2018-11-12 10:12:57 +01:00
2018-08-18 14:21:14 +02:00
/**
* Get type name .
*/
public function getTypeName ()
{
return self :: $types [ $this -> type ];
}
2018-07-20 08:19:25 +02:00
/**
* Get thread CC recipients .
2018-07-25 19:30:43 +02:00
*
2018-07-20 08:19:25 +02:00
* @ return array
*/
2018-08-27 10:08:20 +02:00
public function getCcArray ( $exclude_array = [])
2018-07-20 08:19:25 +02:00
{
2018-09-20 09:08:02 +02:00
return \App\Misc\Helper :: jsonToArray ( $this -> cc , $exclude_array );
2018-07-20 08:19:25 +02:00
}
2018-09-14 10:24:04 +02:00
public function getCcString ( $exclude_array = [])
{
return implode ( ', ' , $this -> getCcArray ( $exclude_array ));
}
2018-07-20 08:19:25 +02:00
/**
* Get thread BCC recipients .
2018-07-25 19:30:43 +02:00
*
2018-07-20 08:19:25 +02:00
* @ return array
*/
2018-08-27 10:08:20 +02:00
public function getBccArray ( $exclude_array = [])
2018-07-20 08:19:25 +02:00
{
2018-09-20 09:08:02 +02:00
return \App\Misc\Helper :: jsonToArray ( $this -> bcc , $exclude_array );
2018-07-20 08:19:25 +02:00
}
2018-09-14 10:24:04 +02:00
public function getBccString ( $exclude_array = [])
{
return implode ( ', ' , $this -> getBccArray ( $exclude_array ));
}
2018-07-30 17:11:35 +02:00
/**
* Set to as JSON .
*/
public function setTo ( $emails )
{
$emails_array = Conversation :: sanitizeEmails ( $emails );
if ( $emails_array ) {
2018-08-04 17:33:45 +02:00
$emails_array = array_unique ( $emails_array );
2018-07-30 17:11:35 +02:00
$this -> to = json_encode ( $emails_array );
} else {
$this -> to = null ;
}
}
public function setCc ( $emails )
{
$emails_array = Conversation :: sanitizeEmails ( $emails );
if ( $emails_array ) {
2018-08-04 17:33:45 +02:00
$emails_array = array_unique ( $emails_array );
2018-07-30 17:11:35 +02:00
$this -> cc = json_encode ( $emails_array );
} else {
$this -> cc = null ;
}
}
public function setBcc ( $emails )
{
$emails_array = Conversation :: sanitizeEmails ( $emails );
if ( $emails_array ) {
2018-08-04 17:33:45 +02:00
$emails_array = array_unique ( $emails_array );
2018-07-30 17:11:35 +02:00
$this -> bcc = json_encode ( $emails_array );
} else {
$this -> bcc = null ;
}
}
2018-07-20 08:19:25 +02:00
/**
2018-07-25 19:25:00 +02:00
* Get thread ' s status name .
2018-07-25 19:30:43 +02:00
*
2018-07-24 08:34:28 +02:00
* @ return string
2018-07-20 08:19:25 +02:00
*/
2018-07-25 19:25:00 +02:00
public function getStatusName ()
{
return self :: statusCodeToName ( $this -> status );
}
/**
* Get status name . Made as a function to allow status names translation .
2018-07-25 19:30:43 +02:00
*
* @ param int $status
*
* @ return string
2018-07-25 19:25:00 +02:00
*/
public static function statusCodeToName ( $status )
2018-07-20 08:19:25 +02:00
{
switch ( $status ) {
case self :: STATUS_ACTIVE :
2018-07-25 19:30:43 +02:00
return __ ( 'Active' );
2018-07-20 08:19:25 +02:00
break ;
case self :: STATUS_PENDING :
2018-07-25 19:30:43 +02:00
return __ ( 'Pending' );
2018-07-20 08:19:25 +02:00
break ;
case self :: STATUS_CLOSED :
2018-07-25 19:30:43 +02:00
return __ ( 'Closed' );
2018-07-20 08:19:25 +02:00
break ;
case self :: STATUS_SPAM :
2018-07-25 19:30:43 +02:00
return __ ( 'Spam' );
2018-07-20 08:19:25 +02:00
break ;
case self :: STATUS_NOCHANGE :
2018-07-25 19:30:43 +02:00
return __ ( 'Not changed' );
2018-07-20 08:19:25 +02:00
break ;
default :
return '' ;
break ;
}
}
2018-07-27 08:01:34 +02:00
/**
2018-09-20 12:44:10 +02:00
* Get text for the assignee in line item .
2018-07-27 15:30:50 +02:00
*
2018-07-27 08:01:34 +02:00
* @ return string
*/
2018-09-20 12:44:10 +02:00
public function getAssigneeName ( $ucfirst = false , $by_user = null )
2018-07-27 08:01:34 +02:00
{
2018-09-20 12:44:10 +02:00
if ( ! $by_user ) {
$by_user = auth () -> user ();
}
2018-07-27 08:01:34 +02:00
if ( ! $this -> user_id ) {
2018-08-08 09:52:53 +02:00
if ( $ucfirst ) {
return __ ( 'Anyone' );
} else {
return __ ( 'anyone' );
}
2018-09-20 12:44:10 +02:00
} elseif ( $by_user && $this -> user_id == $by_user -> id ) {
if ( $this -> created_by_user_id && $this -> created_by_user_id == $this -> user_id ) {
$name = __ ( 'yourself' );
2018-08-08 09:52:53 +02:00
} else {
2018-09-20 12:44:10 +02:00
$name = __ ( 'you' );
}
if ( $ucfirst ) {
$name = ucfirst ( $name );
2018-08-08 09:52:53 +02:00
}
2018-11-12 10:12:57 +01:00
2018-09-10 17:24:20 +02:00
return $name ;
2018-07-27 08:01:34 +02:00
} else {
2018-09-19 10:00:59 +02:00
// User may be deleted
if ( $this -> user ) {
return $this -> user -> getFullName ();
} else {
return '' ;
}
2018-07-27 08:01:34 +02:00
}
}
2018-08-02 18:17:13 +02:00
/**
* Get user or customer who created the thead .
*/
public function getCreatedBy ()
{
if ( ! empty ( $this -> created_by_user_id )) {
2018-11-04 20:14:26 +01:00
// User can be deleted
if ( $this -> created_by_user ) {
return $this -> created_by_user ;
} else {
return \App\User :: getDeletedUser ();
}
2018-08-02 18:17:13 +02:00
} else {
return $this -> created_by_customer ;
}
}
2018-09-07 15:08:34 +02:00
/**
* Get creator of the thread .
*/
public function getPerson ( $cached = false )
{
2018-11-12 10:12:57 +01:00
if ( $this -> type == self :: TYPE_CUSTOMER ) {
2018-09-07 15:08:34 +02:00
if ( $cached ) {
return $this -> customer_cached ;
} else {
return $this -> customer ;
}
} else {
if ( $cached ) {
return $this -> created_by_user_cached ;
} else {
return $this -> created_by_user ;
}
}
}
/**
2019-06-03 07:52:37 +02:00
* Get action ' s person .
2018-09-07 15:08:34 +02:00
*/
2019-06-03 07:52:37 +02:00
public function getActionPerson ( $conversation_number = '' )
2018-09-07 15:08:34 +02:00
{
$person = '' ;
2018-11-12 10:12:57 +01:00
if ( $this -> type == self :: TYPE_CUSTOMER ) {
2018-09-20 16:34:34 +02:00
$person = $this -> customer_cached -> getFullName ( true );
2018-11-12 10:12:57 +01:00
} elseif ( $this -> state == self :: STATE_DRAFT && ! empty ( $this -> edited_by_user_id )) {
2018-09-14 10:24:04 +02:00
// Draft
if ( auth () -> user () && $this -> edited_by_user_id == auth () -> user () -> id ) {
2018-11-12 10:12:57 +01:00
$person = __ ( 'you' );
2018-09-14 10:24:04 +02:00
} else {
$person = $this -> edited_by_user -> getFullName ();
}
2018-11-02 07:35:47 +01:00
} elseif ( $this -> created_by_user_cached ) {
2018-09-10 11:50:53 +02:00
if ( $this -> created_by_user_id && auth () -> user () && $this -> created_by_user_cached -> id == auth () -> user () -> id ) {
2018-11-12 10:12:57 +01:00
$person = __ ( 'you' );
2018-09-07 15:08:34 +02:00
} else {
$person = $this -> created_by_user_cached -> getFullName ();
}
}
2019-06-03 07:52:37 +02:00
// https://github.com/tormjens/eventy/issues/19
$person = \Eventy :: filter ( 'thread.action_person' , $person , $this , $conversation_number );
return $person ;
}
/**
* Get action text .
*/
public function getActionText ( $conversation_number = '' , $escape = false , $strip_tags = false , $by_user = null )
{
$did_this = '' ;
2018-09-07 15:08:34 +02:00
// Did this
2018-11-12 10:12:57 +01:00
if ( $this -> type == self :: TYPE_LINEITEM ) {
2019-06-03 07:52:37 +02:00
2018-11-12 10:12:57 +01:00
if ( $this -> action_type == self :: ACTION_TYPE_STATUS_CHANGED ) {
2019-06-03 07:52:37 +02:00
if ( $conversation_number ) {
$did_this = __ ( 'marked as :status_name conversation #:conversation_number' , [ 'status_name' => $this -> getStatusName (), 'conversation_number' => $conversation_number ]);
} else {
$did_this = __ ( " marked as :status_name " , [ 'status_name' => $this -> getStatusName ()]);
}
2018-11-12 10:12:57 +01:00
} elseif ( $this -> action_type == self :: ACTION_TYPE_USER_CHANGED ) {
2019-06-03 07:52:37 +02:00
$assignee = $this -> getAssigneeName ( false , $by_user );
if ( $escape ) {
$assignee = htmlspecialchars ( $assignee );
}
if ( $conversation_number ) {
$did_this = __ ( 'assigned :assignee convsersation #:conversation_number' , [ 'assignee' => $assignee , 'conversation_number' => $conversation_number ]);
} else {
$did_this = __ ( " assigned to :assignee " , [ 'assignee' => $assignee ]);
}
2018-11-12 10:12:57 +01:00
} elseif ( $this -> action_type == self :: ACTION_TYPE_CUSTOMER_CHANGED ) {
2019-06-03 07:52:37 +02:00
if ( $conversation_number ) {
$did_this = __ ( 'changed the customer to :customer in conversation #:conversation_number' , [ 'customer' => $this -> customer -> getFullName ( true ), 'conversation_number' => $conversation_number ]);
} else {
$customer_name = $this -> customer -> getFullName ( true );
if ( $escape ) {
$customer_name = htmlspecialchars ( $customer_name );
}
$did_this = __ ( " changed the customer to :customer " , [ 'customer' => '<a href="' . $this -> customer -> url () . '" title="' . $this -> action_data . '" class="link-black">' . $customer_name . '</a>' ]);
}
} elseif ( $this -> action_type == self :: ACTION_TYPE_DELETED_TICKET ) {
$did_this = __ ( " deleted " );
} elseif ( $this -> action_type == self :: ACTION_TYPE_RESTORE_TICKET ) {
$did_this = __ ( " restored " );
2018-09-07 15:08:34 +02:00
}
2018-11-12 10:12:57 +01:00
} elseif ( $this -> state == self :: STATE_DRAFT ) {
2018-09-14 10:24:04 +02:00
if ( empty ( $this -> edited_by_user_id )) {
2018-11-12 10:12:57 +01:00
$did_this = __ ( 'created a draft' );
2018-09-14 10:24:04 +02:00
} else {
$did_this = __ ( " edited :creator's draft " , [ 'creator' => $this -> created_by_user_cached -> getFirstName ()]);
}
2018-11-12 10:12:57 +01:00
} else {
2018-09-07 15:08:34 +02:00
if ( $this -> first ) {
2018-11-12 10:12:57 +01:00
$did_this = __ ( 'started a new conversation #:conversation_number' , [ 'conversation_number' => $conversation_number ]);
} elseif ( $this -> type == self :: TYPE_NOTE ) {
$did_this = __ ( 'added a note to conversation #:conversation_number' , [ 'conversation_number' => $conversation_number ]);
2018-09-07 15:08:34 +02:00
} else {
2018-11-12 10:12:57 +01:00
$did_this = __ ( 'replied to conversation #:conversation_number' , [ 'conversation_number' => $conversation_number ]);
2018-09-07 15:08:34 +02:00
}
}
2019-06-03 07:52:37 +02:00
$did_this = \Eventy :: filter ( 'thread.action_text' , $did_this , $this , $conversation_number , $escape );
if ( $strip_tags ) {
$did_this = strip_tags ( $did_this );
}
return $did_this ;
}
/**
* Description of what happened .
*/
public function getActionDescription ( $conversation_number , $escape = true )
{
// Person
$person = $this -> getActionPerson ( $conversation_number );
$did_this = $this -> getActionText ( $conversation_number );
2018-09-07 15:08:34 +02:00
$description = ':person_tag_start:person:person_tag_end :did_this' ;
if ( $escape ) {
$description = htmlspecialchars ( $description );
}
return __ ( $description , [
2018-11-12 10:12:57 +01:00
'person' => $person ,
2018-09-07 15:08:34 +02:00
'person_tag_start' => '<strong>' ,
2018-11-12 10:12:57 +01:00
'person_tag_end' => '</strong>' ,
'did_this' => $did_this ,
2018-09-07 15:08:34 +02:00
]);
}
2018-09-14 10:24:04 +02:00
/**
* Get thread state name .
*/
public function getStateName ()
{
return self :: $states [ $this -> state ];
}
public function deleteThread ()
{
$this -> deteleAttachments ();
$this -> delete ();
}
/**
* Delete thread attachments .
*/
public function deteleAttachments ()
{
Attachment :: deleteByIds ( $this -> all_attachments () -> pluck ( 'id' ) -> toArray ());
}
2018-09-16 12:52:52 +02:00
public function isDraft ()
{
2018-11-12 10:12:57 +01:00
return $this -> state == self :: STATE_DRAFT ;
2018-09-16 12:52:52 +02:00
}
2018-09-26 19:35:11 +02:00
/**
* Get original body or body .
*/
public function getBodyOriginal ()
{
if ( ! empty ( $this -> body_original )) {
return $this -> body_original ;
} else {
return $this -> body ;
}
}
2018-10-24 12:50:05 +02:00
/**
* Get name for the reply to customer .
2018-11-12 10:12:57 +01:00
*
* @ param [ type ] $mailbox [ description ]
*
* @ return [ type ] [ description ]
2018-10-24 12:50:05 +02:00
*/
public function getFromName ( $mailbox = null )
{
2018-11-08 20:12:34 +01:00
// Created by customer
if ( $this -> source_via == self :: PERSON_CUSTOMER ) {
return $this -> getCreatedBy () -> getFirstName ( true );
}
// Created by user
2018-10-24 12:50:05 +02:00
if ( empty ( $mailbox )) {
$mailbox = $this -> conversation -> mailbox ;
}
2018-11-12 10:12:57 +01:00
// Mailbox name by default
2018-10-24 12:50:05 +02:00
$name = $mailbox -> name ;
if ( $mailbox -> from_name == Mailbox :: FROM_NAME_CUSTOM && $mailbox -> from_name_custom ) {
$name = $mailbox -> from_name_custom ;
} elseif ( $mailbox -> from_name == Mailbox :: FROM_NAME_USER && $this -> getCreatedBy ()) {
$name = $this -> getCreatedBy () -> getFirstName ( true );
}
2018-11-12 10:12:57 +01:00
2018-10-24 12:50:05 +02:00
return $name ;
}
2018-12-12 13:31:45 +01:00
/**
* Check if thread is a reply from customer or user .
2018-12-13 10:11:15 +01:00
*
* @ return bool [ description ]
2018-12-12 13:31:45 +01:00
*/
public function isReply ()
{
return in_array ( $this -> type , [ \App\Thread :: TYPE_MESSAGE , \App\Thread :: TYPE_CUSTOMER ]);
}
2018-12-14 07:41:30 +01:00
/**
* Is this thread created from auto responder email .
2018-12-21 10:10:07 +01:00
*
* @ return bool [ description ]
2018-12-14 07:41:30 +01:00
*/
public function isAutoResponder ()
{
return \MailHelper :: isAutoResponder ( $this -> headers );
}
2018-12-14 10:10:43 +01:00
/**
* Is thread created from incoming bounce email .
2018-12-21 10:10:07 +01:00
*
* @ return bool [ description ]
2018-12-14 10:10:43 +01:00
*/
public function isBounce ()
{
2018-12-15 10:15:30 +01:00
if ( ! empty ( $this -> getSendStatusData ()[ 'is_bounce' ])) {
2018-12-14 10:10:43 +01:00
return true ;
} else {
return false ;
}
}
2018-12-15 10:15:30 +01:00
/**
* Send status data mayb contain the following information :
* - bounce info ( status_code , action , diagnostic_code , is_bounce , bounce_for_thread , bounce_for_conversation , bounced_by_thread , bounced_by_conversation )
* - send error message
* - click date
* - unsubscribe date
2018-12-21 10:10:07 +01:00
* - complain date .
*
2018-12-15 10:15:30 +01:00
* @ return [ type ] [ description ]
*/
public function getSendStatusData ()
{
return \Helper :: jsonToArray ( $this -> send_status_data );
}
public function updateSendStatusData ( $new_data )
{
if ( $new_data ) {
$send_status_data = $this -> getSendStatusData ();
if ( $send_status_data ) {
$send_status_data = array_merge ( $send_status_data , $new_data );
} else {
$send_status_data = $new_data ;
}
$this -> send_status_data = json_encode ( $send_status_data );
} else {
$this -> send_status_data = null ;
}
}
public function isSendStatusError ()
{
return in_array ( $this -> send_status , \App\SendLog :: $status_errors );
}
2018-12-31 09:22:43 +01:00
/**
* Create thread .
*
* @ param [ type ] $conversation_id [ description ]
* @ param [ type ] $text [ description ]
* @ param array $data [ description ]
* @ return [ type ] [ description ]
*/
public static function create ( $conversation , $type , $body , $data = [], $save = true )
{
$thread = new Thread ();
$thread -> conversation_id = $conversation -> id ;
$thread -> type = $type ;
$thread -> body = $body ;
$thread -> status = $conversation -> status ;
$thread -> state = Thread :: STATE_PUBLISHED ;
// Assigned to.
if ( ! empty ( $data [ 'user_id' ])) {
$thread -> user_id = $data [ 'user_id' ];
}
if ( ! empty ( $data [ 'message_id' ])) {
$thread -> message_id = $data [ 'message_id' ];
}
if ( ! empty ( $data [ 'headers' ])) {
$thread -> headers = $data [ 'headers' ];
}
if ( ! empty ( $data [ 'from' ])) {
$thread -> from = $data [ 'from' ];
}
if ( ! empty ( $data [ 'to' ])) {
$thread -> setTo ( $data [ 'to' ]);
}
if ( ! empty ( $data [ 'cc' ])) {
$thread -> setCc ( $data [ 'cc' ]);
}
if ( ! empty ( $data [ 'bcc' ])) {
$thread -> setBcc ( $data [ 'bcc' ]);
}
if ( isset ( $data [ 'first' ])) {
$thread -> from = $data [ 'first' ];
}
if ( isset ( $data [ 'source_via' ])) {
$thread -> source_via = $data [ 'source_via' ];
}
if ( isset ( $data [ 'source_type' ])) {
$thread -> source_type = $data [ 'source_type' ];
}
if ( ! empty ( $data [ 'customer_id' ])) {
$thread -> customer_id = $data [ 'customer_id' ];
}
if ( ! empty ( $data [ 'created_by_customer_id' ])) {
$thread -> created_by_customer_id = $data [ 'created_by_customer_id' ];
}
if ( ! empty ( $data [ 'created_by_user_id' ])) {
$thread -> created_by_user_id = $data [ 'created_by_user_id' ];
}
2019-04-26 06:27:26 +02:00
if ( ! empty ( $data [ 'action_type' ])) {
$thread -> action_type = $data [ 'action_type' ];
}
2018-12-31 09:22:43 +01:00
if ( $save ) {
$thread -> save ();
}
return $thread ;
}
2019-06-20 12:37:43 +02:00
/**
* Get full name of the user who edited thread .
*/
public function getEditedByUserName ()
{
$name = '' ;
if ( ! $this -> edited_by_user_id ) {
return '' ;
}
if ( auth () -> user () && $this -> edited_by_user_id == auth () -> user () -> id ) {
$name = __ ( 'you' );
} else {
$name = $this -> edited_by_user_cached -> getFullName ();
}
return $name ;
}
2019-06-24 07:39:30 +02:00
/**
* Get thread meta data as array .
*/
public function getMetas ()
{
return \Helper :: jsonToArray ( $this -> meta );
}
/**
* Set thread meta value .
*/
public function setMetas ( $data )
{
$this -> meta = json_encode ( $data );
}
/**
* Get thread meta value .
*/
public function getMeta ( $key , $default = null )
{
$metas = $this -> getMetas ();
if ( isset ( $metas [ $key ])) {
return $metas [ $key ];
} else {
return $default ;
}
}
/**
* Set thread meta value .
*/
public function setMeta ( $key , $value )
{
$metas = $this -> getMetas ();
$metas [ $key ] = $value ;
$this -> setMetas ( $metas );
}
/**
* Get full name of the user who forwarded conversation .
*/
public function getForwardByFullName ( $by_user = null )
{
if ( ! $by_user ) {
$by_user = auth () -> user ();
}
if ( $by_user && $this -> created_by_user_id == $by_user -> id ) {
$name = __ ( 'you' );
} else {
$name = $this -> created_by_user -> getFullName ();
}
return $name ;
}
/**
* Is this a note informing that conversation has been forwarded .
*/
public function isForward ()
{
return ( $this -> subtype == \App\Thread :: SUBTYPE_FORWARD );
}
/**
* Is this a forwarded conversation .
*/
public function isForwarded ()
{
if ( $this -> getMeta ( 'forward_parent_conversation_id' )) {
return true ;
} else {
return false ;
}
}
/**
* Is this thread a note .
*/
public function isNote ()
{
return ( $this -> type == \App\Thread :: TYPE_NOTE );
}
/**
* Get forwarded conversation .
*/
public function getForwardParentConversation ()
{
return Conversation :: where ( 'id' , $this -> getMeta ( 'forward_parent_conversation_id' ))
-> rememberForever ()
-> first ();
}
2018-07-14 03:23:37 +02:00
}