@@ -139,17 +139,22 @@ abstract class Model
139139
140140 /**
141141 * Cle primaire.
142- *
143- * @var string
144142 */
145- protected $ primaryKey = 'id ' ;
143+ protected string $ primaryKey = 'id ' ;
146144
147145 /**
148146 * Le format dans lequel les résultats doivent être renvoyés.
149147 * Ce format sera surchargé si les méthodes as* sont utilisées.
150148 */
151149 protected string $ returnType = 'array ' ;
152150
151+ /**
152+ * Utilié pour fournir une surchage temporaire pour le format de retour des resultats.
153+ *
154+ * @var string
155+ */
156+ protected $ tempReturnType ;
157+
153158 /**
154159 * Primary Key value when inserting and useAutoIncrement is false.
155160 *
@@ -166,19 +171,60 @@ abstract class Model
166171
167172 /**
168173 * Doit-on utiliser l'auto increment.
169- *
170- * @var bool
171174 */
172- protected $ useAutoIncrement = true ;
175+ protected bool $ useAutoIncrement = true ;
173176
174177 /**
175178 * Le type de colonne que created_at et updated_at sont censés avoir.
176179 *
177180 * Autorisé: 'datetime', 'date', 'int'
181+ */
182+ protected string $ dateFormat = 'datetime ' ;
183+
184+ /**
185+ * Si ce modèle doit utiliser "softDeletes" et définir simplement une date à laquelle les lignes sont supprimées,
186+ * ou effectuer des suppressions réelles.
187+ */
188+ protected bool $ useSoftDeletes = false ;
189+
190+ /**
191+ * Un tableau de noms de champs qui peuvent être définis par l'utilisateur dans les insertions/mises à jour.
178192 *
179- * @var string
193+ * @var string[]
194+ */
195+ protected array $ allowedFields = [];
196+
197+ /**
198+ * Si c'est vrai, définira les valeurs Created_at et Updated_at pendant les routines d'insertion et de mise à jour.
180199 */
181- protected $ dateFormat = 'datetime ' ;
200+ protected bool $ useTimestamps = false ;
201+
202+ /**
203+ * La colonne utilisée pour insérer les horodatages
204+ */
205+ protected string $ createdField = 'created_at ' ;
206+
207+ /**
208+ * La colonne utilisée pour modifier les horodatages
209+ */
210+ protected string $ updatedField = 'updated_at ' ;
211+
212+ /**
213+ * Utilisé par withDeleted pour remplacer le paramètre softDelete du modèle.
214+ *
215+ * @var bool
216+ */
217+ protected $ tempUseSoftDeletes ;
218+
219+ /**
220+ * La colonne utilisée pour enregistrer l'état de suppression réversible.
221+ */
222+ protected string $ deletedField = 'deleted_at ' ;
223+
224+ /**
225+ * Le nombre de données à renvoyer pour la pagination.
226+ */
227+ protected int $ perPage = 15 ;
182228
183229 /**
184230 * Connexion à la base de données
@@ -219,11 +265,122 @@ abstract class Model
219265 'getCompiledUpdate ' ,
220266 ];
221267
268+ /**
269+ * Callbacks.
270+ *
271+ * Chaque tableau doit contenir les noms de méthodes (au sein du modèle) qui doivent
272+ * être appelées lorsque ces événements sont déclenchés.
273+ *
274+ * Les méthodes « Update » et « Delete » reçoivent les mêmes éléments que ceux attribués
275+ * à leur méthode respective.
276+ *
277+ * Les méthodes "Find" reçoivent l'ID recherché (s'il est présent),
278+ * et "afterFind" reçoit en outre les résultats trouvés.
279+ */
280+
281+ /**
282+ * S'il faut déclencher les callbacks définis
283+ */
284+ protected bool $ allowCallbacks = true ;
285+
286+ /**
287+ * Utilisé par AllowCallbacks() pour remplacer le paramètre allowCallbacks du modèle.
288+ *
289+ * @var bool
290+ */
291+ protected $ tempAllowCallbacks ;
292+
293+ /**
294+ * Callbacks pour beforeInsert
295+ *
296+ * @var string[]
297+ */
298+ protected array $ beforeInsert = [];
299+
300+ /**
301+ * Callbacks pour afterInsert
302+ *
303+ * @var string[]
304+ */
305+ protected array $ afterInsert = [];
306+
307+ /**
308+ * Callbacks pour beforeUpdate
309+ *
310+ * @var string[]
311+ */
312+ protected array $ beforeUpdate = [];
313+
314+ /**
315+ * Callbacks pour afterUpdate
316+ *
317+ * @var string[]
318+ */
319+ protected array $ afterUpdate = [];
320+
321+ /**
322+ * Callbacks pour beforeInsertBatch
323+ *
324+ * @var string[]
325+ */
326+ protected array $ beforeInsertBatch = [];
327+
328+ /**
329+ * Callbacks pour afterInsertBatch
330+ *
331+ * @var string[]
332+ */
333+ protected array $ afterInsertBatch = [];
334+
335+ /**
336+ * Callbacks pour beforeUpdateBatch
337+ *
338+ * @var string[]
339+ */
340+ protected array $ beforeUpdateBatch = [];
341+
342+ /**
343+ * Callbacks pour afterUpdateBatch
344+ *
345+ * @var string[]
346+ */
347+ protected array $ afterUpdateBatch = [];
348+
349+ /**
350+ * Callbacks pour beforeFind
351+ *
352+ * @var string[]
353+ */
354+ protected array $ beforeFind = [];
355+
356+ /**
357+ * Callbacks pour afterFind
358+ *
359+ * @var string[]
360+ */
361+ protected array $ afterFind = [];
362+
363+ /**
364+ * Callbacks pour beforeDelete
365+ *
366+ * @var string[]
367+ */
368+ protected array $ beforeDelete = [];
369+
370+ /**
371+ * Callbacks pour afterDelete
372+ *
373+ * @var string[]
374+ */
375+ protected array $ afterDelete = [];
376+
222377 public function __construct (protected ConnectionResolverInterface $ resolver , ?ConnectionInterface $ db = null )
223378 {
224- $ db ??= $ this ->resolver ->connection ($ this ->group );
379+ $ this -> db = $ db ?: $ this ->resolver ->connection ($ this ->group );
225380
226- $ this ->db = $ db ;
381+ $ this ->tempReturnType = $ this ->returnType ;
382+ $ this ->tempUseSoftDeletes = $ this ->useSoftDeletes ;
383+ $ this ->tempAllowCallbacks = $ this ->allowCallbacks ;
227384 }
228385
229386 /**
@@ -372,7 +529,7 @@ public function save(array|object $data): bool
372529 */
373530 public function chunk (int $ size , Closure $ userFunc )
374531 {
375- $ total = ( clone $ this ->builder ())-> count ();
532+ $ total = $ this ->builder ()-> countAllResults ();
376533 $ offset = 0 ;
377534
378535 while ($ offset <= $ total ) {
@@ -397,6 +554,74 @@ public function chunk(int $size, Closure $userFunc)
397554 }
398555 }
399556
557+ /**
558+ * Remplacez countAllResults pour tenir compte des lignes supprimés de manière logique (softdeletes).
559+ *
560+ * @return int|string
561+ */
562+ public function countAllResults (bool $ reset = true , bool $ test = false )
563+ {
564+ if ($ this ->tempUseSoftDeletes ) {
565+ $ this ->builder ()->whereNull ($ this ->table . '. ' . $ this ->deletedField );
566+ }
567+
568+ // Lorsque $reset === false, $tempUseSoftDeletes dépendra de la valeur $useSoftDeletes
569+ // car nous ne voulons pas ajouter la même condition "where" pour la deuxième fois.
570+ $ this ->tempUseSoftDeletes = $ reset
571+ ? $ this ->useSoftDeletes
572+ : ($ this ->useSoftDeletes ? false : $ this ->useSoftDeletes );
573+
574+ return $ this ->builder ()->testMode ($ test )->countAllResults ($ reset );
575+ }
576+
577+ public function paginate (?int $ limit = null , ?int $ page = null , ?int $ total = null ): array
578+ {
579+ $ page = max ((int ) $ page , 1 );
580+ $ total = $ total ?: $ this ->countAllResults (false );
581+ $ limit = $ limit ?: $ this ->perPage ;
582+ $ offset = ($ page - 1 ) * $ limit ;
583+
584+ return $ this ->findAll ($ limit , $ offset );
585+ }
586+
587+ /**
588+ * Récupère tous les résultats, tout en les limitant éventuellement.
589+ */
590+ public function findAll (int $ limit = 0 , int $ offset = 0 ): array
591+ {
592+ if ($ this ->tempAllowCallbacks ) {
593+ // Call the before event and check for a return
594+ $ eventData = $ this ->trigger ('beforeFind ' , [
595+ 'method ' => 'findAll ' ,
596+ 'limit ' => $ limit ,
597+ 'offset ' => $ offset ,
598+ 'singleton ' => false ,
599+ ]);
600+
601+ if (isset ($ eventData ['returnData ' ]) && $ eventData ['returnData ' ] === true ) {
602+ return $ eventData ['data ' ];
603+ }
604+ }
605+
606+ $ eventData = [
607+ 'data ' => $ this ->builder ()->findAll ('* ' , compact ('limit ' , 'offset ' ), $ this ->returnType ),
608+ 'limit ' => $ limit ,
609+ 'offset ' => $ offset ,
610+ 'method ' => 'findAll ' ,
611+ 'singleton ' => false ,
612+ ];
613+
614+ if ($ this ->tempAllowCallbacks ) {
615+ $ eventData = $ this ->trigger ('afterFind ' , $ eventData );
616+ }
617+
618+ $ this ->tempReturnType = $ this ->returnType ;
619+ $ this ->tempUseSoftDeletes = $ this ->useSoftDeletes ;
620+ $ this ->tempAllowCallbacks = $ this ->allowCallbacks ;
621+
622+ return $ eventData ['data ' ];
623+ }
624+
400625 /**
401626 * Fournit/instancie la connexion builder/db et les noms de table/clé primaire du modèle et le type de retour.
402627 *
@@ -615,6 +840,47 @@ protected function transformDataToArray(null|array|object $data, string $type):
615840 return $ data ;
616841 }
617842
843+ /**
844+ * Définit la valeur $tempAllowCallbacks afin que nous puissions temporairement remplacer le paramètre.
845+ * Se réinitialise après la prochaine méthode utilisant des déclencheurs.
846+ */
847+ public function allowCallbacks (bool $ val = true ): self
848+ {
849+ $ this ->tempAllowCallbacks = $ val ;
850+
851+ return $ this ;
852+ }
853+
854+ /**
855+ * Un simple déclencheur d'événement pour les événements de modèle qui permet une manipulation supplémentaire des données au sein du modèle.
856+ * Spécifiquement destiné à être utilisé par les modèles enfants, il peut être utilisé pour formater des données, enregistrer/charger des classes associées, etc.
857+ *
858+ * Il est de la responsabilité des méthodes de rappel de renvoyer les données elles-mêmes.
859+ *
860+ * Chaque tableau $eventData DOIT avoir une clé 'data' avec les données pertinentes pour les méthodes de rappel (comme un tableau de paires clé/valeur à insérer ou à mettre à jour, un tableau de résultats, etc.)
861+ *
862+ * Si les rappels ne sont pas autorisés, renvoie immédiatement $eventData.
863+ *
864+ * @throws DataException
865+ */
866+ protected function trigger (string $ event , array $ eventData ): array
867+ {
868+ // S'assurer que c'est un evenement valide
869+ if (! isset ($ this ->{$ event }) || $ this ->{$ event } === []) {
870+ return $ eventData ;
871+ }
872+
873+ foreach ($ this ->{$ event } as $ callback ) {
874+ if (! method_exists ($ this , $ callback )) {
875+ throw DataException::invalidMethodTriggered ($ callback );
876+ }
877+
878+ $ eventData = $ this ->{$ callback }($ eventData );
879+ }
880+
881+ return $ eventData ;
882+ }
883+
618884 /**
619885 * Verifie si la methode du builder peut etre utilisee dans le modele.
620886 */
0 commit comments