33
44use  ArrayObject ;
55use  Cake \Database \Expression \IdentifierExpression ;
6+ use  Cake \Datasource \EntityInterface ;
67use  Cake \Event \Event ;
78use  Cake \ORM \Behavior ;
89use  Cake \ORM \Entity ;
@@ -127,23 +128,9 @@ public function beforeSave(Event $event, Entity $entity, ArrayObject $options)
127128        $ config$ this config ();
128129
129130        $ newOrdernull ;
130-         $ newScope
131- 
132-         // If scope are specified and data for all scope fields is not 
133-         // provided we cannot calculate new order 
134-         if  ($ config'scope ' ]) {
135-             $ newScope$ entityextract ($ config'scope ' ]);
136-             if  (count ($ newScopecount ($ config'scope ' ])) {
137-                 return ;
138-             }
139- 
140-             // Modify where clauses when NULL values are used 
141-             foreach  ($ newScopeas  $ field$ value
142-                 if  (is_null ($ value
143-                     $ newScope$ field' IS ' ] = $ value
144-                     unset($ newScope$ field
145-                 }
146-             }
131+         $ newScope$ this _getScope ($ entity
132+         if  ($ newScopefalse ) {
133+             return ;
147134        }
148135
149136        $ orderField$ config'order ' ];
@@ -258,6 +245,97 @@ public function beforeDelete(Event $event, Entity $entity)
258245        );
259246    }
260247
248+     /** 
249+      * Decrease the position of the entity on the list 
250+      * 
251+      * If a "higher" entity exists, this will also swap positions with it 
252+      * 
253+      * @param \Cake\Datasource\EntityInterface $entity The entity that is going to be saved. 
254+      * @return bool 
255+      */ 
256+     public  function  moveUp (EntityInterface $ entity
257+     {
258+         return  $ this _movePosition ($ entity$ direction'- ' );
259+     }
260+ 
261+     /** 
262+      * Increase the position of the entity on the list 
263+      * 
264+      * If a "lower" entity exists, this will also swap positions with it 
265+      * 
266+      * @param \Cake\Datasource\EntityInterface $entity The entity that is going to be saved. 
267+      * @return bool 
268+      */ 
269+     public  function  moveDown (EntityInterface $ entity
270+     {
271+         return  $ this _movePosition ($ entity$ direction'+ ' );
272+     }
273+ 
274+     /** 
275+      * Change the position of the entity on the list by a single position 
276+      * 
277+      * If an entity that conflicts with the new position already exists, this 
278+      * will also swap positions with it 
279+      * 
280+      * @param \Cake\Datasource\EntityInterface $entity The entity that is going to be saved. 
281+      * @param string $direction Whether to increment or decrement the field. 
282+      * 
283+      * @return bool 
284+      */ 
285+     protected  function  _movePosition (EntityInterface $ entity$ direction'+ ' )
286+     {
287+         if  ($ entityisNew ()) {
288+             return  false ;
289+         }
290+ 
291+         $ scope$ this _getScope ($ entity
292+         if  ($ scopefalse ) {
293+             return  false ;
294+         }
295+ 
296+         $ config$ this config ();
297+         $ table$ this _table ;
298+ 
299+         $ tableremoveBehavior ('Sequence ' );
300+ 
301+         $ return$ tableconnection ()->transactional (
302+             function  ($ connectionuse  ($ table$ entity$ config$ scope$ direction
303+                 $ orderField$ config'order ' ];
304+                 // Nothing to do if trying to move up entity already at first position 
305+                 if  ($ direction'- '  && $ entityget ($ orderField$ config'start ' ]) {
306+                     return  true ;
307+                 }
308+ 
309+                 $ oldOrder$ entityget ($ orderField
310+                 $ newOrder$ entityget ($ orderField1 ;
311+                 if  ($ direction'+ ' ) {
312+                     $ newOrder$ entityget ($ orderField1 ;
313+                 }
314+ 
315+                 $ previousEntity$ tablefind ()
316+                                         ->where (array_merge ($ scope$ orderField$ newOrder
317+                                         ->first ();
318+                 if  (!empty ($ previousEntity
319+                     $ previousEntityset ($ orderField$ oldOrder
320+                     if  (!$ tablesave ($ previousEntity'atomic '  => false , 'checkRules '  => false ])) {
321+                         return  false ;
322+                     }
323+                 // Nothing to do if trying to move down entity already at last position 
324+                 } elseif  ($ direction'+ ' ) {
325+                     return  true ;
326+                 }
327+ 
328+                 $ entityset ($ orderField$ newOrder
329+ 
330+                 return  $ tablesave ($ entity'atomic '  => false , 'checkRules '  => false ]);
331+             }
332+         );
333+ 
334+         $ tableaddBehavior ('ADmad/Sequence.Sequence ' , $ config
335+ 
336+         return  (bool )$ return
337+     }
338+ 
261339    /** 
262340     * Set order for list of records provided. 
263341     * 
@@ -277,7 +355,7 @@ public function setOrder(array $records)
277355        $ tableremoveBehavior ('Sequence ' );
278356
279357        $ return$ tableconnection ()->transactional (
280-             function  ($ connectionuse  ($ table$ records,  $ config 
358+             function  ($ connectionuse  ($ table$ records
281359                $ order$ this _config ['start ' ];
282360                $ field$ this _config ['order ' ];
283361
@@ -352,6 +430,38 @@ protected function _getOldValues(Entity $entity)
352430        return  [$ order$ values
353431    }
354432
433+     /** 
434+      * Get scope values. 
435+      * 
436+      * @param \Cake\Datasource\EntityInterface $entity Entity. 
437+      * 
438+      * @return array|bool 
439+      */ 
440+     protected  function  _getScope (EntityInterface $ entity
441+     {
442+         $ scope
443+         $ config$ this config ();
444+ 
445+         // If scope are specified and data for all scope fields is not 
446+         // provided we cannot calculate new order 
447+         if  ($ config'scope ' ]) {
448+             $ scope$ entityextract ($ config'scope ' ]);
449+             if  (count ($ scopecount ($ config'scope ' ])) {
450+                 return  false ;
451+             }
452+ 
453+             // Modify where clauses when NULL values are used 
454+             foreach  ($ scopeas  $ field$ value
455+                 if  (is_null ($ value
456+                     $ scope$ field' IS ' ] = $ value
457+                     unset($ scope$ field
458+                 }
459+             }
460+         }
461+ 
462+         return  $ scope
463+     }
464+ 
355465    /** 
356466     * Returns the current highest order of all records in the set. When a new 
357467     * record is added to the set, it is added at the current highest order, plus 
0 commit comments