From ee77d2f02d4ac1d71f9bea4de3f6e058f2c68b2b Mon Sep 17 00:00:00 2001 From: Antoine Le Gonidec Date: Wed, 10 Jul 2024 18:26:08 +0200 Subject: [PATCH] Rely on hooks to filter the customers search --- Http/Controllers/ConversationsController.php | 172 ------------------ Http/Controllers/CustomersController.php | 2 +- .../MMFRestrictedCustomersServiceProvider.php | 19 +- README.md | 41 +---- 4 files changed, 27 insertions(+), 207 deletions(-) delete mode 100644 Http/Controllers/ConversationsController.php diff --git a/Http/Controllers/ConversationsController.php b/Http/Controllers/ConversationsController.php deleted file mode 100644 index a089c65..0000000 --- a/Http/Controllers/ConversationsController.php +++ /dev/null @@ -1,172 +0,0 @@ - - */ - -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); - } -} diff --git a/Http/Controllers/CustomersController.php b/Http/Controllers/CustomersController.php index 7d8d051..b02bee7 100644 --- a/Http/Controllers/CustomersController.php +++ b/Http/Controllers/CustomersController.php @@ -382,7 +382,7 @@ class CustomersController extends BaseCustomersController { // Conversations navigation 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'; diff --git a/Providers/MMFRestrictedCustomersServiceProvider.php b/Providers/MMFRestrictedCustomersServiceProvider.php index b247376..510c518 100644 --- a/Providers/MMFRestrictedCustomersServiceProvider.php +++ b/Providers/MMFRestrictedCustomersServiceProvider.php @@ -4,6 +4,8 @@ namespace Modules\MMFRestrictedCustomers\Providers; use Illuminate\Support\ServiceProvider; use Illuminate\Database\Eloquent\Factory; +use Eventy; +use App\User; use Modules\MMFRestrictedCustomers\Console\Commands\FetchEmails; class MMFRestrictedCustomersServiceProvider extends ServiceProvider { @@ -34,7 +36,18 @@ class MMFRestrictedCustomersServiceProvider extends ServiceProvider { * Module 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'; $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'); $this->loadViewsFrom(array_merge(array_map(function ($path) { diff --git a/README.md b/README.md index 442910a..0383405 100644 --- a/README.md +++ b/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'); ``` -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 The following list of routes: @@ -160,3 +128,12 @@ should be replaced with: ``` 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 +```