Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 121
0.00% covered (danger)
0.00%
0 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
SenderController
0.00% covered (danger)
0.00%
0 / 121
0.00% covered (danger)
0.00%
0 / 11
1482
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 index
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 create
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 store
0.00% covered (danger)
0.00%
0 / 29
0.00% covered (danger)
0.00%
0 / 1
56
 edit
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
12
 update
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 1
72
 delete
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 getProvidersByChannel
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 byChannel
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
56
 buildActiveChannels
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 getCountry
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace App\Modules\ContactModule\Controllers;
4
5use App\Controllers\BaseController;
6use App\Modules\ContactModule\Models\SenderModel;
7use App\Modules\ContactModule\Services\SenderResolverService;
8use App\Modules\ChannelModule\Models\ChannelProviderModel;
9use App\Modules\ChannelModule\Models\ChannelSettingModel;
10use CodeIgniter\HTTP\ResponseInterface;
11
12class SenderController extends BaseController
13{
14    protected SenderModel           $senderModel;
15    protected SenderResolverService $resolverService;
16
17    public function __construct()
18    {
19        $this->senderModel     = model(SenderModel::class);
20        $this->resolverService = new SenderResolverService(
21            model(ChannelProviderModel::class),
22            model(ChannelSettingModel::class),
23            $this->senderModel
24        );
25    }
26
27    // ====================== LISTE ======================
28    public function index()
29    {
30        $senders = $this->senderModel->getAllWithProvider();
31
32        return view('App\Modules\ContactModule\Views\senders\index', [
33            'senders' => $senders,
34        ]);
35    }
36
37    // ====================== CREATE ======================
38    public function create()
39    {
40        $country  = $this->getCountry();
41        $flags    = $this->resolverService->getChannelFlags();
42        $channels = $this->buildActiveChannels($flags);
43
44        return view('App\Modules\ContactModule\Views\senders\create', [
45            'channels' => $channels,
46            'country'  => $country,
47            'baseUrl'  => base_url('dashboard/expediteurs'),
48        ]);
49    }
50
51    // ====================== STORE ======================
52    public function store()
53    {
54        $rules = [
55            'name'        => 'required|min_length[2]|max_length[100]',
56            'channel'     => 'required',
57            'provider_id' => 'required|numeric',
58            'value'       => 'required|max_length[150]',
59            'is_default'  => 'in_list[0,1]',
60            'status'      => 'in_list[0,1]',
61        ];
62
63        if (!$this->validate($rules)) {
64            return redirect()->back()->withInput()->with('error', 'Données invalides');
65        }
66
67        $data    = $this->request->getPost();
68        $channel = trim($data['channel']);
69        $country = $this->getCountry();
70
71        if (!$this->resolverService->isValidChannel($channel)) {
72            return redirect()->back()->withInput()->with('error', 'Canal invalide ou désactivé.');
73        }
74
75        $providers   = $this->resolverService->getProviders($channel, $country);
76        $providerIds = array_map(fn($p) => (int)(is_object($p) ? $p->id : $p['id']), $providers);
77
78        if (!in_array((int) $data['provider_id'], $providerIds, true)) {
79            return redirect()->back()->withInput()
80                ->with('error', 'Le provider sélectionné ne correspond pas au canal choisi.');
81        }
82
83        $data['channel']      = $channel;
84        $data['country_code'] = $country;
85        $data['is_default']   = (int) ($data['is_default'] ?? 0);
86        $data['status']       = (int) ($data['status'] ?? 1);
87
88        if ($data['is_default'] === 1) {
89            $this->senderModel->unsetDefault($channel, (int) $data['provider_id']);
90        }
91
92        if ($this->senderModel->insert($data)) {
93            return redirect()->to('/dashboard/expediteurs')->with('success', 'Expéditeur créé avec succès');
94        }
95
96        return redirect()->back()->withInput()->with('error', 'Erreur lors de l\'enregistrement');
97    }
98
99    // ====================== EDIT ======================
100    public function edit($id = null)
101    {
102        if (!is_numeric($id)) {
103            return redirect()->to('/dashboard/expediteurs')->with('error', 'ID invalide');
104        }
105
106       // $sender = $this->senderModel->select('sender.*')->find($id);
107        $sender = $this->senderModel->getSenderById($id);
108  
109        if (!$sender) {
110            return redirect()->to('/dashboard/expediteurs')->with('error', 'Expéditeur introuvable');
111        }
112
113        $flags    = $this->resolverService->getChannelFlags();
114        $channels = $this->buildActiveChannels($flags);
115
116        return view('App\Modules\ContactModule\Views\senders\edit', [
117            'sender'   => $sender,
118            'baseUrl'  => base_url('dashboard/expediteurs'),
119            'channels' => $channels,
120            'country'  => $this->getCountry(),
121        ]);
122    }
123
124    // ====================== UPDATE ======================
125    public function update($id = null)
126    {
127        if (!is_numeric($id)) {
128            return redirect()->to('/dashboard/expediteurs')->with('error', 'ID invalide');
129        }
130
131        $rules = [
132            'name'        => 'required|min_length[2]|max_length[100]',
133            'channel'     => 'required',
134            'provider_id' => 'required|numeric',
135            'value'       => 'required|max_length[150]',
136            'is_default'  => 'in_list[0,1]',
137            'status'      => 'in_list[0,1]',
138        ];
139
140        if (!$this->validate($rules)) {
141            return redirect()->back()->withInput()->with('error', 'Données invalides');
142        }
143
144        $data    = $this->request->getPost();
145        $channel = trim($data['channel']);
146        $country = $this->getCountry();
147
148        if (!$this->resolverService->isValidChannel($channel)) {
149            return redirect()->back()->withInput()->with('error', 'Canal invalide ou désactivé.');
150        }
151
152        $providers   = $this->resolverService->getProviders($channel, $country);
153        $providerIds = array_map(fn($p) => (int)(is_object($p) ? $p->id : $p['id']), $providers);
154
155        if (!in_array((int) $data['provider_id'], $providerIds, true)) {
156            return redirect()->back()->withInput()
157                ->with('error', 'Le provider sélectionné ne correspond pas au canal choisi.');
158        }
159
160        $data['channel']      = $channel;
161        $data['country_code'] = $country;
162        $data['is_default']   = (int) ($data['is_default'] ?? 0);
163        $data['status']       = (int) ($data['status'] ?? 1);
164
165        if ($data['is_default'] === 1) {
166            $this->senderModel->unsetDefault($channel, (int) $data['provider_id']);
167        }
168
169        if ($this->senderModel->update($id, $data)) {
170            return redirect()->to('/dashboard/expediteurs')->with('success', 'Expéditeur mis à jour');
171        }
172
173        return redirect()->back()->withInput()->with('error', 'Erreur lors de la mise à jour');
174    }
175
176    // ====================== DELETE ======================
177    public function delete($id = null)
178    {
179        if (!is_numeric($id)) {
180            return redirect()->back()->with('error', 'ID invalide');
181        }
182
183        if ($this->senderModel->delete($id)) {
184            return redirect()->to('/dashboard/expediteurs')->with('success', 'Expéditeur supprimé');
185        }
186
187        return redirect()->back()->with('error', 'Erreur lors de la suppression');
188    }
189
190    // ====================== AJAX — PROVIDERS PAR CANAL (formulaire create/edit) ======================
191    public function getProvidersByChannel($channel): ResponseInterface
192    {
193        if (empty($channel) || !$this->resolverService->isValidChannel($channel)) {
194            return $this->response->setJSON([]);
195        }
196
197        $providers = $this->resolverService->getProviders($channel, $this->getCountry());
198
199        return $this->response->setJSON($providers);
200    }
201
202    // ====================== AJAX — EXPÉDITEURS PAR CANAL (envoi unique) ======================
203    /**
204     * Retourne les expéditeurs actifs pour un canal.
205     * Consommé par la vue sender_single/index.php via :
206     *   fetch(`/dashboard/expediteurs/channel/${channel}`)
207     * Route : GET dashboard/expediteurs/channel/(:segment) → SenderController::byChannel/$1
208     */
209    public function byChannel($channel): ResponseInterface
210    {
211        if (empty($channel) || !$this->resolverService->isValidChannel($channel)) {
212            return $this->response->setJSON([]);
213        }
214
215        $senders = $this->senderModel
216            ->where('channel', $channel)
217            ->where('status', 1)
218            ->orderBy('is_default', 'DESC')
219            ->orderBy('name', 'ASC')
220            ->findAll();
221
222        $result = array_map(fn($s) => [
223            'id'         => is_object($s) ? $s->id         : $s['id'],
224            'name'       => is_object($s) ? $s->name       : $s['name'],
225            'value'      => is_object($s) ? $s->value      : $s['value'],
226            'is_default' => is_object($s) ? (int) $s->is_default : (int) $s['is_default'],
227        ], $senders);
228
229        return $this->response->setJSON($result);
230    }
231
232    // ====================== HELPERS ======================
233    private function buildActiveChannels(array $flags): array
234    {
235        $channels = [];
236        foreach ($flags as $channel => $enabled) {
237            if ($enabled) {
238                $channels[] = (object) ['channel' => $channel];
239            }
240        }
241        return $channels;
242    }
243
244    private function getCountry(): string
245    {
246        return session()->get('country_code') ?? 'CI';
247    }
248}