262 lines
6.4 KiB
PHP
262 lines
6.4 KiB
PHP
<?php
|
|
/*
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
SPDX-FileCopyrightText: © 2024 Millions Missing FRANCE <info@millionsmissing.fr>
|
|
*/
|
|
|
|
namespace Modules\MMFRestrictedCustomers;
|
|
|
|
use App\CustomerChannel;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Watson\Rememberable\Rememberable;
|
|
use Modules\MMFRestrictedCustomers\Mailbox;
|
|
use App\Customer as BaseCustomer;
|
|
|
|
class Customer extends BaseCustomer {
|
|
/**
|
|
* Attributes fillable using fill() method.
|
|
*
|
|
* @var [type]
|
|
*/
|
|
protected $fillable = [
|
|
// Default list, imported from BaseCustomer.
|
|
'first_name',
|
|
'last_name',
|
|
'company',
|
|
'job_title',
|
|
'address',
|
|
'city',
|
|
'state',
|
|
'zip',
|
|
'country',
|
|
'photo_url',
|
|
'age',
|
|
'gender',
|
|
'notes',
|
|
'channel',
|
|
'channel_id',
|
|
'social_profiles',
|
|
// Addition specific to this package.
|
|
'mailbox_id',
|
|
];
|
|
|
|
/**
|
|
* Get the Mailbox that is allowed to access this Customer information.
|
|
*/
|
|
public function mailbox() {
|
|
return $this->belongsTo(Mailbox::class);
|
|
}
|
|
|
|
/**
|
|
* Create customer or get existing and fill empty fields.
|
|
*
|
|
* @param string $email
|
|
* @param array $data [description]
|
|
*
|
|
* @return [type] [description]
|
|
*/
|
|
public static function create($email, $data = []) {
|
|
$new = false;
|
|
|
|
$email = Email::sanitizeEmail($email);
|
|
if (!$email) {
|
|
return null;
|
|
}
|
|
$email_obj = Email::where('email', $email)->first();
|
|
if ($email_obj) {
|
|
$customer = $email_obj->customer;
|
|
|
|
// In case somehow the email has no customer.
|
|
if (!$customer) {
|
|
// Customer will be saved and connected to the email later.
|
|
$customer = new self();
|
|
}
|
|
|
|
// Update name if empty.
|
|
/*if (empty($customer->first_name) && !empty($data['first_name'])) {
|
|
$customer->first_name = $data['first_name'];
|
|
if (empty($customer->last_name) && !empty($data['last_name'])) {
|
|
$customer->last_name = $data['last_name'];
|
|
}
|
|
$customer->save();
|
|
}*/
|
|
} else {
|
|
$customer = new self();
|
|
$email_obj = new Email();
|
|
$email_obj->email = $email;
|
|
|
|
$new = true;
|
|
}
|
|
// Ensure that the Mailbox relationship is set, if provided.
|
|
if ( in_array('mailbox_id', $data) )
|
|
$customer->mailbox_id = $data['mailbox_id'];
|
|
|
|
// Set empty fields
|
|
if ($customer->setData($data, false) || !$customer->id) {
|
|
$customer->save();
|
|
}
|
|
|
|
if (empty($email_obj->id) || !$email_obj->customer_id || $email_obj->customer_id != $customer->id) {
|
|
// Email may have been set in setData().
|
|
$save_email = true;
|
|
if (!empty($data['emails']) && is_array($data['emails'])) {
|
|
foreach ($data['emails'] as $data_email) {
|
|
if (is_string($data_email) && $data_email == $email) {
|
|
$save_email = false;
|
|
break;
|
|
}
|
|
if (is_array($data_email) && !empty($data_email['value']) && $data_email['value'] == $email) {
|
|
$save_email = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if ($save_email) {
|
|
$email_obj->customer()->associate($customer);
|
|
$email_obj->save();
|
|
}
|
|
}
|
|
|
|
// Todo: check phone uniqueness.
|
|
|
|
if ($new) {
|
|
\Eventy::action('customer.created', $customer);
|
|
}
|
|
|
|
return $customer;
|
|
}
|
|
|
|
/**
|
|
* Set empty fields.
|
|
*/
|
|
public function setData($data, $replace_data = true, $save = false) {
|
|
// Set the Mailbox this Customer should be linked to.
|
|
// TODO: Throw an error if the Mailbox is not set.
|
|
if ( isset($data['mailbox']) ) {
|
|
// TODO: Check that the current user is allowed to access this Mailbox.
|
|
$data['mailbox_id'] = $data['mailbox'];
|
|
unset($data['mailbox']);
|
|
}
|
|
|
|
return parent::setData($data, $replace_data, $save);
|
|
}
|
|
|
|
/**
|
|
* Only return a Customer instance if it is available to the current User.
|
|
*
|
|
* @param int $id
|
|
* @param array $columns
|
|
* @return mixed|static
|
|
*/
|
|
public static function find($id, $columns = ['*']) {
|
|
// Get the list of Mailboxes the current User has access to.
|
|
$user = auth()->user();
|
|
$mailboxes = $user->mailboxesIdsCanView();
|
|
|
|
$customer = self
|
|
::where('id', '=', $id)
|
|
->whereIn('mailbox_id', $mailboxes)
|
|
->first($columns);
|
|
}
|
|
|
|
/**
|
|
* Get the Mailboxes this Customer is linked to through Conversations.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function mailboxesThroughConversations() {
|
|
return $this
|
|
->conversations
|
|
->pluck('mailbox')
|
|
->unique();
|
|
}
|
|
|
|
/**
|
|
* If this Customer is linked to a single Mailbox through Conversations, link it to it.
|
|
*/
|
|
public function linkToMailboxThroughConversations() {
|
|
$mailboxes = $this->mailboxesThroughConversations();
|
|
if ( $mailboxes->count() == 1 ) {
|
|
$this->mailbox_id = $mailboxes->first()->id;
|
|
$this->save();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set customer emails.
|
|
*
|
|
* @param array $emails
|
|
*/
|
|
public function syncEmails($emails) {
|
|
if (is_array($emails)) {
|
|
$deleted_emails = [];
|
|
foreach ($this->emails as $email) {
|
|
foreach ($emails as $email_address) {
|
|
if (Email::sanitizeEmail($email->email) == Email::sanitizeEmail($email_address)) {
|
|
continue 2;
|
|
}
|
|
}
|
|
$deleted_emails[] = $email;
|
|
}
|
|
$mailbox = $this->mailbox;
|
|
foreach ($emails as $email_address) {
|
|
$email_address = Email::sanitizeEmail($email_address);
|
|
if (!$email_address) {
|
|
continue;
|
|
}
|
|
$email = Email
|
|
::whereInMailbox($mailbox)
|
|
->where('email', $email_address)
|
|
->first();
|
|
$new_emails = [];
|
|
if ($email) {
|
|
// Assign email to current customer
|
|
if ($email->customer_id != $this->id) {
|
|
$email->customer()->associate($this);
|
|
$email->save();
|
|
}
|
|
} else {
|
|
$new_emails[] = new Email(['email' => $email_address]);
|
|
}
|
|
if ($new_emails) {
|
|
$this->emails()->saveMany($new_emails);
|
|
}
|
|
}
|
|
|
|
foreach ($deleted_emails as $email) {
|
|
if (Conversation::where('customer_email', $email->email)->exists()) {
|
|
// Create customers for deleted emails
|
|
// if there is a conversation with 'customer_email'.
|
|
$customer = new self();
|
|
$customer->save();
|
|
$email->customer()->associate($customer);
|
|
$email->save();
|
|
} else {
|
|
// Simply delete an email.
|
|
$email->delete();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add new email to customer.
|
|
*/
|
|
public function addEmail($email_address, $check_if_exists = false) {
|
|
// Check if email already exists and belongs to another customer.
|
|
if ($check_if_exists) {
|
|
$mailbox = $this->mailbox;
|
|
$email = Email
|
|
::whereInMailbox($mailbox)
|
|
->where('email', $email_address)
|
|
->first();
|
|
if ($email && !empty($email->customer_id)) {
|
|
return false;
|
|
}
|
|
}
|
|
$new_email = new Email(['email' => $email_address]);
|
|
$this->emails()->save($new_email);
|
|
}
|
|
}
|