Rely on hooks to filter the customers search
This commit is contained in:
parent
128301db41
commit
ee77d2f02d
4 changed files with 27 additions and 207 deletions
|
@ -1,172 +0,0 @@
|
||||||
<?php
|
|
||||||
/*
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
SPDX-FileCopyrightText: © 2024 Millions Missing FRANCE <info@millionsmissing.fr>
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Modules\MMFRestrictedCustomers\Http\Controllers;
|
|
||||||
|
|
||||||
use App\Conversation;
|
|
||||||
use App\User;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use App\Http\Controllers\ConversationsController as BaseConversationsController;
|
|
||||||
use Modules\MMFRestrictedCustomers\Entities\Customer;
|
|
||||||
|
|
||||||
class ConversationsController extends BaseConversationsController {
|
|
||||||
/**
|
|
||||||
* Search.
|
|
||||||
*/
|
|
||||||
public function search(Request $request) {
|
|
||||||
$user = auth()->user();
|
|
||||||
$conversations = [];
|
|
||||||
$customers = [];
|
|
||||||
|
|
||||||
$mode = $this->getSearchMode($request);
|
|
||||||
|
|
||||||
// Search query
|
|
||||||
$q = $this->getSearchQuery($request);
|
|
||||||
|
|
||||||
// Filters.
|
|
||||||
$filters = $this->getSearchFilters($request);
|
|
||||||
$filters_data = [];
|
|
||||||
// Modify filters is needed.
|
|
||||||
if (!empty($filters['customer'])) {
|
|
||||||
// Get customer name.
|
|
||||||
$filters_data['customer'] = Customer::find($filters['customer']);
|
|
||||||
}
|
|
||||||
//$filters = \Eventy::filter('search.filters', $filters, $filters_data, $mode, $q);
|
|
||||||
|
|
||||||
// Remember recent query.
|
|
||||||
$recent_search_queries = session('recent_search_queries') ?? [];
|
|
||||||
if ($q && !in_array($q, $recent_search_queries)) {
|
|
||||||
array_unshift($recent_search_queries, $q);
|
|
||||||
$recent_search_queries = array_slice($recent_search_queries, 0, 4);
|
|
||||||
session()->put('recent_search_queries', $recent_search_queries);
|
|
||||||
}
|
|
||||||
|
|
||||||
$conversations = [];
|
|
||||||
if (\Eventy::filter('search.is_needed', true, 'conversations')) {
|
|
||||||
$conversations = $this->searchQuery($user, $q, $filters);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Jump to the conversation if searching by conversation number.
|
|
||||||
if (count($conversations) == 1
|
|
||||||
&& $conversations[0]->number == $q
|
|
||||||
&& empty($filters)
|
|
||||||
&& !$request->x_embed
|
|
||||||
) {
|
|
||||||
return redirect()->away($conversations[0]->url($conversations[0]->folder_id));
|
|
||||||
}
|
|
||||||
|
|
||||||
$customers = $this->searchCustomers($request, $user);
|
|
||||||
|
|
||||||
// Dummy folder
|
|
||||||
$folder = $this->getSearchFolder($conversations);
|
|
||||||
|
|
||||||
// List of available filters.
|
|
||||||
if ($mode == Conversation::SEARCH_MODE_CONV) {
|
|
||||||
$filters_list = \Eventy::filter('search.filters_list', Conversation::$search_filters, $mode, $filters, $q);
|
|
||||||
} else {
|
|
||||||
$filters_list = \Eventy::filter('search.filters_list_customers', Customer::$search_filters, $mode, $filters, $q);
|
|
||||||
}
|
|
||||||
|
|
||||||
$mailboxes = \Cache::remember('search_filter_mailboxes_'.$user->id, 5, function () use ($user) {
|
|
||||||
return $user->mailboxesCanView();
|
|
||||||
});
|
|
||||||
$users = \Cache::remember('search_filter_users_'.$user->id, 5, function () use ($user, $mailboxes) {
|
|
||||||
return \Eventy::filter('search.assignees', $user->whichUsersCanView($mailboxes), $user, $mailboxes);
|
|
||||||
});
|
|
||||||
$search_mailbox = null;
|
|
||||||
if (isset($filters['mailbox'])) {
|
|
||||||
$mailbox_id = (int)$filters['mailbox'];
|
|
||||||
if ($mailbox_id && in_array($mailbox_id, $mailboxes->pluck('id')->toArray())) {
|
|
||||||
foreach ($mailboxes as $mailbox_item) {
|
|
||||||
if ($mailbox_item->id == $mailbox_id) {
|
|
||||||
$search_mailbox = $mailbox_item;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} elseif (count($mailboxes) == 1) {
|
|
||||||
$search_mailbox = $mailboxes[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return view('mmfrestrictedcustomers::conversations/search', [
|
|
||||||
'folder' => $folder,
|
|
||||||
'q' => $request->q,
|
|
||||||
'filters' => $filters,
|
|
||||||
'filters_list' => $filters_list,
|
|
||||||
'filters_data' => $filters_data,
|
|
||||||
//'filters_list_all' => $filters_list_all,
|
|
||||||
'mode' => $mode,
|
|
||||||
'conversations' => $conversations,
|
|
||||||
'customers' => $customers,
|
|
||||||
'recent' => session('recent_search_queries'),
|
|
||||||
'users' => $users,
|
|
||||||
'mailboxes' => $mailboxes,
|
|
||||||
'search_mailbox' => $search_mailbox,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Search conversations.
|
|
||||||
*/
|
|
||||||
public function searchCustomers($request, $user) {
|
|
||||||
// Get IDs of mailboxes to which user has access
|
|
||||||
$mailbox_ids = $user->mailboxesIdsCanView();
|
|
||||||
|
|
||||||
// Filters
|
|
||||||
$filters = $this->getSearchFilters($request);;
|
|
||||||
|
|
||||||
// Search query
|
|
||||||
$q = $this->getSearchQuery($request);
|
|
||||||
|
|
||||||
// Like is case insensitive.
|
|
||||||
$like = '%'.mb_strtolower($q).'%';
|
|
||||||
|
|
||||||
// We need to use aggregate function for email to avoid "Grouping error" error in PostgreSQL.
|
|
||||||
$query_customers = Customer::select(['customers.*', \DB::raw('MAX(emails.email)')])
|
|
||||||
->groupby('customers.id')
|
|
||||||
->leftJoin('emails', function ($join) {
|
|
||||||
$join->on('customers.id', '=', 'emails.customer_id');
|
|
||||||
})
|
|
||||||
->where(function ($query) use ($like, $q) {
|
|
||||||
$like_op = 'like';
|
|
||||||
if (\Helper::isPgSql()) {
|
|
||||||
$like_op = 'ilike';
|
|
||||||
}
|
|
||||||
|
|
||||||
$query
|
|
||||||
->where('customers.first_name', $like_op, $like)
|
|
||||||
->orwhere('customers.last_name', $like_op, $like)
|
|
||||||
->orwhere('customers.company', $like_op, $like)
|
|
||||||
->orwhere('customers.job_title', $like_op, $like)
|
|
||||||
->orwhere('customers.websites', $like_op, $like)
|
|
||||||
->orwhere('customers.social_profiles', $like_op, $like)
|
|
||||||
->orwhere('customers.address', $like_op, $like)
|
|
||||||
->orwhere('customers.city', $like_op, $like)
|
|
||||||
->orwhere('customers.state', $like_op, $like)
|
|
||||||
->orwhere('customers.zip', $like_op, $like)
|
|
||||||
->orwhere('emails.email', $like_op, $like);
|
|
||||||
|
|
||||||
$phone_numeric = \Helper::phoneToNumeric($q);
|
|
||||||
|
|
||||||
if ($phone_numeric) {
|
|
||||||
$query->orWhere('customers.phones', $like_op, '%"'.$phone_numeric.'"%');
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
// Restrict the query to the Customers the current User is allowed to access.
|
|
||||||
if ( $user->role != User::ROLE_ADMIN ) {
|
|
||||||
$query_customers->whereIn('customers.mailbox_id', $mailbox_ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($filters['mailbox']) && in_array($filters['mailbox'], $mailbox_ids)) {
|
|
||||||
$query_customers->where('customers.mailbox_id', '=', $filters['mailbox']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$query_customers = \Eventy::filter('search.customers.apply_filters', $query_customers, $filters, $q);
|
|
||||||
|
|
||||||
return $query_customers->paginate(50);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -382,7 +382,7 @@ class CustomersController extends BaseCustomersController {
|
||||||
// Conversations navigation
|
// Conversations navigation
|
||||||
case 'customers_pagination':
|
case 'customers_pagination':
|
||||||
|
|
||||||
$customers = app('Modules\MMFRestrictedCustomers\Http\Controllers\ConversationsController')->searchCustomers($request, $user);
|
$customers = app('App\Http\Controllers\ConversationsController')->searchCustomers($request, $user);
|
||||||
|
|
||||||
$response['status'] = 'success';
|
$response['status'] = 'success';
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@ namespace Modules\MMFRestrictedCustomers\Providers;
|
||||||
|
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
use Illuminate\Database\Eloquent\Factory;
|
use Illuminate\Database\Eloquent\Factory;
|
||||||
|
use Eventy;
|
||||||
|
use App\User;
|
||||||
use Modules\MMFRestrictedCustomers\Console\Commands\FetchEmails;
|
use Modules\MMFRestrictedCustomers\Console\Commands\FetchEmails;
|
||||||
|
|
||||||
class MMFRestrictedCustomersServiceProvider extends ServiceProvider {
|
class MMFRestrictedCustomersServiceProvider extends ServiceProvider {
|
||||||
|
@ -34,7 +36,18 @@ class MMFRestrictedCustomersServiceProvider extends ServiceProvider {
|
||||||
* Module hooks.
|
* Module hooks.
|
||||||
*/
|
*/
|
||||||
public function hooks() {
|
public function hooks() {
|
||||||
//
|
// When searching for customer, restrict the list to the ones the current user is allowed to see.
|
||||||
|
Eventy::addFilter('search.customers.apply_filters', function($query_customers) {
|
||||||
|
$user = auth()->user();
|
||||||
|
// Do not restrict the query if the current user is an admin.
|
||||||
|
if ( $user->role != User::ROLE_ADMIN ) {
|
||||||
|
// Get IDs of mailboxes the current user is allowed to access.
|
||||||
|
$mailboxes = $user->mailboxesIdsCanView();
|
||||||
|
// Restrict the query to the Customers the current user is allowed to access.
|
||||||
|
$query_customers->whereIn('customers.mailbox_id', $mailbox_ids);
|
||||||
|
}
|
||||||
|
return $query_customers;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -71,7 +84,9 @@ class MMFRestrictedCustomersServiceProvider extends ServiceProvider {
|
||||||
$sourcePath = __DIR__.'/../Resources/views';
|
$sourcePath = __DIR__.'/../Resources/views';
|
||||||
|
|
||||||
$this->publishes([
|
$this->publishes([
|
||||||
$sourcePath => $viewPath
|
$sourcePath => $viewPath,
|
||||||
|
// Override the application view for the Conversations search results.
|
||||||
|
$sourcePath . '/conversations/search.blade.php' => resource_path('views') . '/conversations/search.blade.php',
|
||||||
],'views');
|
],'views');
|
||||||
|
|
||||||
$this->loadViewsFrom(array_merge(array_map(function ($path) {
|
$this->loadViewsFrom(array_merge(array_map(function ($path) {
|
||||||
|
|
41
README.md
41
README.md
|
@ -51,38 +51,6 @@ Route::get('/customers/ajax-search', ['uses' => '\Modules\MMFRestrictedCustomers
|
||||||
Route::post('/customers/ajax', ['uses' => '\Modules\MMFRestrictedCustomers\Http\Controllers\CustomersController@ajax', 'laroute' => true])->name('customers.ajax');
|
Route::post('/customers/ajax', ['uses' => '\Modules\MMFRestrictedCustomers\Http\Controllers\CustomersController@ajax', 'laroute' => true])->name('customers.ajax');
|
||||||
```
|
```
|
||||||
|
|
||||||
This other section should be edited too:
|
|
||||||
|
|
||||||
```php
|
|
||||||
// Conversations
|
|
||||||
Route::get('/conversation/{id}', ['uses' => 'ConversationsController@view', 'laroute' => true])->name('conversations.view');
|
|
||||||
Route::post('/conversation/ajax', ['uses' => 'ConversationsController@ajax', 'laroute' => true])->name('conversations.ajax');
|
|
||||||
Route::post('/conversation/upload', ['uses' => 'ConversationsController@upload', 'laroute' => true])->name('conversations.upload');
|
|
||||||
Route::get('/mailbox/{mailbox_id}/new-ticket', 'ConversationsController@create')->name('conversations.create');
|
|
||||||
Route::get('/mailbox/{mailbox_id}/clone-ticket/{from_thread_id}', 'ConversationsController@cloneConversation')->name('conversations.clone_conversation');
|
|
||||||
//Route::get('/conversation/draft/{id}', 'ConversationsController@draft')->name('conversations.draft');
|
|
||||||
Route::get('/conversation/ajax-html/{action}', ['uses' => 'ConversationsController@ajaxHtml', 'laroute' => true])->name('conversations.ajax_html');
|
|
||||||
Route::get('/search', 'ConversationsController@search')->name('conversations.search');
|
|
||||||
Route::get('/conversation/undo-reply/{thread_id}', 'ConversationsController@undoReply')->name('conversations.undo');
|
|
||||||
Route::get('/mailbox/{mailbox_id}/chats', 'ConversationsController@chats')->name('conversations.chats');
|
|
||||||
```
|
|
||||||
|
|
||||||
and replaced with:
|
|
||||||
|
|
||||||
```php
|
|
||||||
// Conversations
|
|
||||||
Route::get('/conversation/{id}', ['uses' => 'ConversationsController@view', 'laroute' => true])->name('conversations.view');
|
|
||||||
Route::post('/conversation/ajax', ['uses' => 'ConversationsController@ajax', 'laroute' => true])->name('conversations.ajax');
|
|
||||||
Route::post('/conversation/upload', ['uses' => 'ConversationsController@upload', 'laroute' => true])->name('conversations.upload');
|
|
||||||
Route::get('/mailbox/{mailbox_id}/new-ticket', 'ConversationsController@create')->name('conversations.create');
|
|
||||||
Route::get('/mailbox/{mailbox_id}/clone-ticket/{from_thread_id}', 'ConversationsController@cloneConversation')->name('conversations.clone_conversation');
|
|
||||||
//Route::get('/conversation/draft/{id}', 'ConversationsController@draft')->name('conversations.draft');
|
|
||||||
Route::get('/conversation/ajax-html/{action}', ['uses' => 'ConversationsController@ajaxHtml', 'laroute' => true])->name('conversations.ajax_html');
|
|
||||||
Route::get('/search', '\Modules\MMFRestrictedCustomers\Http\Controllers\ConversationsController@search')->name('conversations.search');
|
|
||||||
Route::get('/conversation/undo-reply/{thread_id}', 'ConversationsController@undoReply')->name('conversations.undo');
|
|
||||||
Route::get('/mailbox/{mailbox_id}/chats', 'ConversationsController@chats')->name('conversations.chats');
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Modules/Crm/Http/routes.php
|
#### Modules/Crm/Http/routes.php
|
||||||
|
|
||||||
The following list of routes:
|
The following list of routes:
|
||||||
|
@ -160,3 +128,12 @@ should be replaced with:
|
||||||
```
|
```
|
||||||
php artisan migrate
|
php artisan migrate
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Use the updated views
|
||||||
|
|
||||||
|
Beware that this will overwrite any customization you might have done to the following templates:
|
||||||
|
- `resources/views/conversations/search.blade.php`
|
||||||
|
|
||||||
|
```
|
||||||
|
php artisan vendor:publish --provider='Modules\MMFRestrictedCustomers\Providers\MMFRestrictedCustomersServiceProvider' --tag='views' --force
|
||||||
|
```
|
||||||
|
|
Loading…
Reference in a new issue