core-bundle/src/Resources/contao/drivers/DC_Table.php
protected function getNewPosition($mode, $pid=null, $insertInto=false)
	{
		// If there is pid and sorting
		if ($this->Database->fieldExists('pid', $this->strTable) && $this->Database->fieldExists('sorting', $this->strTable))
		{
			// PID is not set - only valid for duplicated records, as they get the same parent ID as the original record!
			if ($pid === null && $this->intId && $mode == 'copy')
			{
				$pid = $this->intId;
			}

			// PID is set (insert after or into the parent record)
			if (is_numeric($pid))
			{
				$newPID = null;
				$newSorting = null;
				$filter = ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 4) ? $this->strTable.'_'.CURRENT_ID : $this->strTable;

				/** @var Session $objSession */
				$objSession = System::getContainer()->get('session');
				$session = $objSession->all();

				// Consider the pagination menu when inserting at the top (see #7895)
				if ($insertInto && isset($session['filter'][$filter]['limit']))
				{
					$limit = substr($session['filter'][$filter]['limit'], 0, strpos($session['filter'][$filter]['limit'], ','));

					if ($limit > 0)
					{
						$objInsertAfter = $this->Database->prepare("SELECT id FROM " . $this->strTable . " WHERE pid=? ORDER BY sorting")
														 ->limit(1, $limit - 1)
														 ->execute($pid);

						if ($objInsertAfter->numRows)
						{
							$insertInto = false;
							$pid = $objInsertAfter->id;
						}
					}
				}

				// Insert the current record at the beginning when inserting into the parent record
				if ($insertInto)
				{
					$newPID = $pid;

					$objSorting = $this->Database->prepare("SELECT MIN(sorting) AS sorting FROM " . $this->strTable . " WHERE pid=?")
												 ->execute($pid);

					// Select sorting value of the first record
					if ($objSorting->numRows)
					{
						$curSorting = $objSorting->sorting;

						// Resort if the new sorting value is not an integer or smaller than 1
						if (($curSorting % 2) != 0 || $curSorting < 1)
						{
							$objNewSorting = $this->Database->prepare("SELECT id FROM " . $this->strTable . " WHERE pid=? ORDER BY sorting")
															->execute($pid);

							$count = 2;
							$newSorting = 128;

							while ($objNewSorting->next())
							{
								$this->Database->prepare("UPDATE " . $this->strTable . " SET sorting=? WHERE id=?")
											   ->limit(1)
											   ->execute(($count++ * 128), $objNewSorting->id);
							}
						}

						// Else new sorting = (current sorting / 2)
						else $newSorting = ($curSorting / 2);
					}

					// Else new sorting = 128
					else $newSorting = 128;
				}

				// Else insert the current record after the parent record
				elseif ($pid > 0)
				{
					$objSorting = $this->Database->prepare("SELECT pid, sorting FROM " . $this->strTable . " WHERE id=?")
												 ->limit(1)
												 ->execute($pid);

					// Set parent ID of the current record as new parent ID
					if ($objSorting->numRows)
					{
						$newPID = $objSorting->pid;
						$curSorting = $objSorting->sorting;

						// Do not proceed without a parent ID
						if (is_numeric($newPID))
						{
							$objNextSorting = $this->Database->prepare("SELECT MIN(sorting) AS sorting FROM " . $this->strTable . " WHERE pid=? AND sorting>?")
															 ->execute($newPID, $curSorting);

							// Select sorting value of the next record
							if ($objNextSorting->sorting !== null)
							{
								$nxtSorting = $objNextSorting->sorting;

								// Resort if the new sorting value is no integer or bigger than a MySQL integer
								if ((($curSorting + $nxtSorting) % 2) != 0 || $nxtSorting >= 4294967295)
								{
									$count = 1;

									$objNewSorting = $this->Database->prepare("SELECT id, sorting FROM " . $this->strTable . " WHERE pid=? ORDER BY sorting")
																	->execute($newPID);

									while ($objNewSorting->next())
									{
										$this->Database->prepare("UPDATE " . $this->strTable . " SET sorting=? WHERE id=?")
													   ->execute(($count++ * 128), $objNewSorting->id);

										if ($objNewSorting->sorting == $curSorting)
										{
											$newSorting = ($count++ * 128);
										}
									}
								}

								// Else new sorting = (current sorting + next sorting) / 2
								else $newSorting = (($curSorting + $nxtSorting) / 2);
							}

							// Else new sorting = (current sorting + 128)
							else $newSorting = ($curSorting + 128);
						}
					}

					// Use the given parent ID as parent ID
					else
					{
						$newPID = $pid;
						$newSorting = 128;
					}
				}

				// Set new sorting and new parent ID
				$this->set['pid'] = (int) $newPID;
				$this->set['sorting'] = (int) $newSorting;
			}
		}

		// If there is only pid
		elseif ($this->Database->fieldExists('pid', $this->strTable))
		{
			// PID is not set - only valid for duplicated records, as they get the same parent ID as the original record!
			if ($pid === null && $this->intId && $mode == 'copy')
			{
				$pid = $this->intId;
			}

			// PID is set (insert after or into the parent record)
			if (is_numeric($pid))
			{
				// Insert the current record into the parent record
				if ($insertInto)
				{
					$this->set['pid'] = $pid;
				}

				// Else insert the current record after the parent record
				elseif ($pid > 0)
				{
					$objParentRecord = $this->Database->prepare("SELECT pid FROM " . $this->strTable . " WHERE id=?")
													  ->limit(1)
													  ->execute($pid);

					if ($objParentRecord->numRows)
					{
						$this->set['pid'] = $objParentRecord->pid;
					}
				}
			}
		}

		// If there is only sorting
		elseif ($this->Database->fieldExists('sorting', $this->strTable))
		{
			// ID is set (insert after the current record)
			if ($this->intId)
			{
				$objCurrentRecord = $this->Database->prepare("SELECT * FROM " . $this->strTable . " WHERE id=?")
												   ->limit(1)
												   ->execute($this->intId);

				// Select current record
				if ($objCurrentRecord->numRows)
				{
					$newSorting = null;
					$curSorting = $objCurrentRecord->sorting;

					$objNextSorting = $this->Database->prepare("SELECT MIN(sorting) AS sorting FROM " . $this->strTable . " WHERE sorting>?")
													 ->execute($curSorting);

					// Select sorting value of the next record
					if ($objNextSorting->numRows)
					{
						$nxtSorting = $objNextSorting->sorting;

						// Resort if the new sorting value is no integer or bigger than a MySQL integer field
						if ((($curSorting + $nxtSorting) % 2) != 0 || $nxtSorting >= 4294967295)
						{
							$count = 1;

							$objNewSorting = $this->Database->execute("SELECT id, sorting FROM " . $this->strTable . " ORDER BY sorting");

							while ($objNewSorting->next())
							{
								$this->Database->prepare("UPDATE " . $this->strTable . " SET sorting=? WHERE id=?")
											   ->execute(($count++ * 128), $objNewSorting->id);

								if ($objNewSorting->sorting == $curSorting)
								{
									$newSorting = ($count++ * 128);
								}
							}
						}

						// Else new sorting = (current sorting + next sorting) / 2
						else $newSorting = (($curSorting + $nxtSorting) / 2);
					}

					// Else new sorting = (current sorting + 128)
					else $newSorting = ($curSorting + 128);

					// Set new sorting
					$this->set['sorting'] = (int) $newSorting;

					return;
				}
			}

			// ID is not set or not found (insert at the end)
			$objNextSorting = $this->Database->execute("SELECT MAX(sorting) AS sorting FROM " . $this->strTable);
			$this->set['sorting'] = ((int) $objNextSorting->sorting + 128);
		}
	}
protected function getNewPosition($mode, $pid=null, $insertInto=false)
	{
		// If there is pid and sorting
		if ($this->Database->fieldExists('pid', $this->strTable) && $this->Database->fieldExists('sorting', $this->strTable))
		{
			// PID is not set - only valid for duplicated records, as they get the same parent ID as the original record!
			if ($pid === null && $this->intId && $mode == 'copy')
			{
				$pid = $this->intId;
			}

			// PID is set (insert after or into the parent record)
			if (is_numeric($pid))
			{
				$newPID = null;
				$newSorting = null;
				$filter = ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 4) ? $this->strTable.'_'.CURRENT_ID : $this->strTable;

				/** @var Session $objSession */
				$objSession = System::getContainer()->get('session');
				$session = $objSession->all();

				// Consider the pagination menu when inserting at the top (see #7895)
				if ($insertInto && isset($session['filter'][$filter]['limit']))
				{
					$limit = substr($session['filter'][$filter]['limit'], 0, strpos($session['filter'][$filter]['limit'], ','));

					if ($limit > 0)
					{
						$objInsertAfter = $this->Database->prepare("SELECT id FROM " . $this->strTable . " WHERE pid=? ORDER BY sorting")
														 ->limit(1, $limit - 1)
														 ->execute($pid);

						if ($objInsertAfter->numRows)
						{
							$insertInto = false;
							$pid = $objInsertAfter->id;
						}
					}
				}

				// Insert the current record at the beginning when inserting into the parent record
				if ($insertInto)
				{
					$newPID = $pid;

					$objSorting = $this->Database->prepare("SELECT MIN(sorting) AS sorting FROM " . $this->strTable . " WHERE pid=?")
												 ->execute($pid);

					// Select sorting value of the first record
					if ($objSorting->numRows)
					{
						$curSorting = $objSorting->sorting;

						// Resort if the new sorting value is not an integer or smaller than 1
						if (($curSorting % 2) != 0 || $curSorting < 1)
						{
							$objNewSorting = $this->Database->prepare("SELECT id FROM " . $this->strTable . " WHERE pid=? ORDER BY sorting")
															->execute($pid);

							$count = 2;
							$newSorting = 128;

							while ($objNewSorting->next())
							{
								$this->Database->prepare("UPDATE " . $this->strTable . " SET sorting=? WHERE id=?")
											   ->limit(1)
											   ->execute(($count++ * 128), $objNewSorting->id);
							}
						}

						// Else new sorting = (current sorting / 2)
						else $newSorting = ($curSorting / 2);
					}

					// Else new sorting = 128
					else $newSorting = 128;
				}

				// Else insert the current record after the parent record
				elseif ($pid > 0)
				{
					$objSorting = $this->Database->prepare("SELECT pid, sorting FROM " . $this->strTable . " WHERE id=?")
												 ->limit(1)
												 ->execute($pid);

					// Set parent ID of the current record as new parent ID
					if ($objSorting->numRows)
					{
						$newPID = $objSorting->pid;
						$curSorting = $objSorting->sorting;

						// Do not proceed without a parent ID
						if (is_numeric($newPID))
						{
							$objNextSorting = $this->Database->prepare("SELECT MIN(sorting) AS sorting FROM " . $this->strTable . " WHERE pid=? AND sorting>?")
															 ->execute($newPID, $curSorting);

							// Select sorting value of the next record
							if ($objNextSorting->sorting !== null)
							{
								$nxtSorting = $objNextSorting->sorting;

								// Resort if the new sorting value is no integer or bigger than a MySQL integer
								if ((($curSorting + $nxtSorting) % 2) != 0 || $nxtSorting >= 4294967295)
								{
									$count = 1;

									$objNewSorting = $this->Database->prepare("SELECT id, sorting FROM " . $this->strTable . " WHERE pid=? ORDER BY sorting")
																	->execute($newPID);

									while ($objNewSorting->next())
									{
										$this->Database->prepare("UPDATE " . $this->strTable . " SET sorting=? WHERE id=?")
													   ->execute(($count++ * 128), $objNewSorting->id);

										if ($objNewSorting->sorting == $curSorting)
										{
											$newSorting = ($count++ * 128);
										}
									}
								}

								// Else new sorting = (current sorting + next sorting) / 2
								else $newSorting = (($curSorting + $nxtSorting) / 2);
							}

							// Else new sorting = (current sorting + 128)
							else $newSorting = ($curSorting + 128);
						}
					}

					// Use the given parent ID as parent ID
					else
					{
						$newPID = $pid;
						$newSorting = 128;
					}
				}

				// Set new sorting and new parent ID
				$this->set['pid'] = (int) $newPID;
				$this->set['sorting'] = (int) $newSorting;
			}
		}

		// If there is only pid
		elseif ($this->Database->fieldExists('pid', $this->strTable))
		{
			// PID is not set - only valid for duplicated records, as they get the same parent ID as the original record!
			if ($pid === null && $this->intId && $mode == 'copy')
			{
				$pid = $this->intId;
			}

			// PID is set (insert after or into the parent record)
			if (is_numeric($pid))
			{
				// Insert the current record into the parent record
				if ($insertInto)
				{
					$this->set['pid'] = $pid;
				}

				// Else insert the current record after the parent record
				elseif ($pid > 0)
				{
					$objParentRecord = $this->Database->prepare("SELECT pid FROM " . $this->strTable . " WHERE id=?")
													  ->limit(1)
													  ->execute($pid);

					if ($objParentRecord->numRows)
					{
						$this->set['pid'] = $objParentRecord->pid;
					}
				}
			}
		}

		// If there is only sorting
		elseif ($this->Database->fieldExists('sorting', $this->strTable))
		{
			// ID is set (insert after the current record)
			if ($this->intId)
			{
				$objCurrentRecord = $this->Database->prepare("SELECT * FROM " . $this->strTable . " WHERE id=?")
												   ->limit(1)
												   ->execute($this->intId);

				// Select current record
				if ($objCurrentRecord->numRows)
				{
					$newSorting = null;
					$curSorting = $objCurrentRecord->sorting;

					$objNextSorting = $this->Database->prepare("SELECT MIN(sorting) AS sorting FROM " . $this->strTable . " WHERE sorting>?")
													 ->execute($curSorting);

					// Select sorting value of the next record
					if ($objNextSorting->numRows)
					{
						$nxtSorting = $objNextSorting->sorting;

						// Resort if the new sorting value is no integer or bigger than a MySQL integer field
						if ((($curSorting + $nxtSorting) % 2) != 0 || $nxtSorting >= 4294967295)
						{
							$count = 1;

							$objNewSorting = $this->Database->execute("SELECT id, sorting FROM " . $this->strTable . " ORDER BY sorting");

							while ($objNewSorting->next())
							{
								$this->Database->prepare("UPDATE " . $this->strTable . " SET sorting=? WHERE id=?")
											   ->execute(($count++ * 128), $objNewSorting->id);

								if ($objNewSorting->sorting == $curSorting)
								{
									$newSorting = ($count++ * 128);
								}
							}
						}

						// Else new sorting = (current sorting + next sorting) / 2
						else $newSorting = (($curSorting + $nxtSorting) / 2);
					}

					// Else new sorting = (current sorting + 128)
					else $newSorting = ($curSorting + 128);

					// Set new sorting
					$this->set['sorting'] = (int) $newSorting;

					return;
				}
			}

			// ID is not set or not found (insert at the end)
			$objNextSorting = $this->Database->execute("SELECT MAX(sorting) AS sorting FROM " . $this->strTable);
			$this->set['sorting'] = ((int) $objNextSorting->sorting + 128);
		}
	}
protected function getNewPosition ( $ mode , $ pid = null , $ insertInto = false ) { // If there is pid and sorting if ( $ this -> Database -> fieldExists ( 'pid' , $ this -> strTable ) && $ this -> Database -> fieldExists ( 'sorting' , $ this -> strTable ) ) { // PID is not set - only valid for duplicated records, as they get the same parent ID as the original record! if ( $ pid === null && $ this -> intId && $ mode == 'copy' ) { $ pid = $ this -> intId ; } // PID is set (insert after or into the parent record) if ( is_numeric ( $ pid ) ) { $ newPID = null ; $ newSorting = null ; $ filter = ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'list' ] [ 'sorting' ] [ 'mode' ] == 4 ) ? $ this -> strTable . '_' . CURRENT_ID : $ this -> strTable ; /** @var Session $objSession */ $ objSession = System :: getContainer ( ) -> get ( 'session' ) ; $ session = $ objSession -> all ( ) ; // Consider the pagination menu when inserting at the top (see #7895) if ( $ insertInto && isset ( $ session [ 'filter' ] [ $ filter ] [ 'limit' ] ) ) { $ limit = substr ( $ session [ 'filter' ] [ $ filter ] [ 'limit' ] , 0 , strpos ( $ session [ 'filter' ] [ $ filter ] [ 'limit' ] , ',' ) ) ; if ( $ limit > 0 ) { $ objInsertAfter = $ this -> Database -> prepare ( "SELECT id FROM " . $ this -> strTable . " WHERE pid=? ORDER BY sorting" ) -> limit ( 1 , $ limit - 1 ) -> execute ( $ pid ) ; if ( $ objInsertAfter -> numRows ) { $ insertInto = false ; $ pid = $ objInsertAfter -> id ; } } } // Insert the current record at the beginning when inserting into the parent record if ( $ insertInto ) { $ newPID = $ pid ; $ objSorting = $ this -> Database -> prepare ( "SELECT MIN(sorting) AS sorting FROM " . $ this -> strTable . " WHERE pid=?" ) -> execute ( $ pid ) ; // Select sorting value of the first record if ( $ objSorting -> numRows ) { $ curSorting = $ objSorting -> sorting ; // Resort if the new sorting value is not an integer or smaller than 1 if ( ( $ curSorting % 2 ) != 0 || $ curSorting < 1 ) { $ objNewSorting = $ this -> Database -> prepare ( "SELECT id FROM " . $ this -> strTable . " WHERE pid=? ORDER BY sorting" ) -> execute ( $ pid ) ; $ count = 2 ; $ newSorting = 128 ; while ( $ objNewSorting -> next ( ) ) { $ this -> Database -> prepare ( "UPDATE " . $ this -> strTable . " SET sorting=? WHERE id=?" ) -> limit ( 1 ) -> execute ( ( $ count ++ * 128 ) , $ objNewSorting -> id ) ; } } // Else new sorting = (current sorting / 2) else $ newSorting = ( $ curSorting / 2 ) ; } // Else new sorting = 128 else $ newSorting = 128 ; } // Else insert the current record after the parent record elseif ( $ pid > 0 ) { $ objSorting = $ this -> Database -> prepare ( "SELECT pid, sorting FROM " . $ this -> strTable . " WHERE id=?" ) -> limit ( 1 ) -> execute ( $ pid ) ; // Set parent ID of the current record as new parent ID if ( $ objSorting -> numRows ) { $ newPID = $ objSorting -> pid ; $ curSorting = $ objSorting -> sorting ; // Do not proceed without a parent ID if ( is_numeric ( $ newPID ) ) { $ objNextSorting = $ this -> Database -> prepare ( "SELECT MIN(sorting) AS sorting FROM " . $ this -> strTable . " WHERE pid=? AND sorting>?" ) -> execute ( $ newPID , $ curSorting ) ; // Select sorting value of the next record if ( $ objNextSorting -> sorting !== null ) { $ nxtSorting = $ objNextSorting -> sorting ; // Resort if the new sorting value is no integer or bigger than a MySQL integer if ( ( ( $ curSorting + $ nxtSorting ) % 2 ) != 0 || $ nxtSorting >= 4294967295 ) { $ count = 1 ; $ objNewSorting = $ this -> Database -> prepare ( "SELECT id, sorting FROM " . $ this -> strTable . " WHERE pid=? ORDER BY sorting" ) -> execute ( $ newPID ) ; while ( $ objNewSorting -> next ( ) ) { $ this -> Database -> prepare ( "UPDATE " . $ this -> strTable . " SET sorting=? WHERE id=?" ) -> execute ( ( $ count ++ * 128 ) , $ objNewSorting -> id ) ; if ( $ objNewSorting -> sorting == $ curSorting ) { $ newSorting = ( $ count ++ * 128 ) ; } } } // Else new sorting = (current sorting + next sorting) / 2 else $ newSorting = ( ( $ curSorting + $ nxtSorting ) / 2 ) ; } // Else new sorting = (current sorting + 128) else $ newSorting = ( $ curSorting + 128 ) ; } } // Use the given parent ID as parent ID else { $ newPID = $ pid ; $ newSorting = 128 ; } } // Set new sorting and new parent ID $ this -> set [ 'pid' ] = ( int ) $ newPID ; $ this -> set [ 'sorting' ] = ( int ) $ newSorting ; } } // If there is only pid elseif ( $ this -> Database -> fieldExists ( 'pid' , $ this -> strTable ) ) { // PID is not set - only valid for duplicated records, as they get the same parent ID as the original record! if ( $ pid === null && $ this -> intId && $ mode == 'copy' ) { $ pid = $ this -> intId ; } // PID is set (insert after or into the parent record) if ( is_numeric ( $ pid ) ) { // Insert the current record into the parent record if ( $ insertInto ) { $ this -> set [ 'pid' ] = $ pid ; } // Else insert the current record after the parent record elseif ( $ pid > 0 ) { $ objParentRecord = $ this -> Database -> prepare ( "SELECT pid FROM " . $ this -> strTable . " WHERE id=?" ) -> limit ( 1 ) -> execute ( $ pid ) ; if ( $ objParentRecord -> numRows ) { $ this -> set [ 'pid' ] = $ objParentRecord -> pid ; } } } } // If there is only sorting elseif ( $ this -> Database -> fieldExists ( 'sorting' , $ this -> strTable ) ) { // ID is set (insert after the current record) if ( $ this -> intId ) { $ objCurrentRecord = $ this -> Database -> prepare ( "SELECT * FROM " . $ this -> strTable . " WHERE id=?" ) -> limit ( 1 ) -> execute ( $ this -> intId ) ; // Select current record if ( $ objCurrentRecord -> numRows ) { $ newSorting = null ; $ curSorting = $ objCurrentRecord -> sorting ; $ objNextSorting = $ this -> Database -> prepare ( "SELECT MIN(sorting) AS sorting FROM " . $ this -> strTable . " WHERE sorting>?" ) -> execute ( $ curSorting ) ; // Select sorting value of the next record if ( $ objNextSorting -> numRows ) { $ nxtSorting = $ objNextSorting -> sorting ; // Resort if the new sorting value is no integer or bigger than a MySQL integer field if ( ( ( $ curSorting + $ nxtSorting ) % 2 ) != 0 || $ nxtSorting >= 4294967295 ) { $ count = 1 ; $ objNewSorting = $ this -> Database -> execute ( "SELECT id, sorting FROM " . $ this -> strTable . " ORDER BY sorting" ) ; while ( $ objNewSorting -> next ( ) ) { $ this -> Database -> prepare ( "UPDATE " . $ this -> strTable . " SET sorting=? WHERE id=?" ) -> execute ( ( $ count ++ * 128 ) , $ objNewSorting -> id ) ; if ( $ objNewSorting -> sorting == $ curSorting ) { $ newSorting = ( $ count ++ * 128 ) ; } } } // Else new sorting = (current sorting + next sorting) / 2 else $ newSorting = ( ( $ curSorting + $ nxtSorting ) / 2 ) ; } // Else new sorting = (current sorting + 128) else $ newSorting = ( $ curSorting + 128 ) ; // Set new sorting $ this -> set [ 'sorting' ] = ( int ) $ newSorting ; return ; } } // ID is not set or not found (insert at the end) $ objNextSorting = $ this -> Database -> execute ( "SELECT MAX(sorting) AS sorting FROM " . $ this -> strTable ) ; $ this -> set [ 'sorting' ] = ( ( int ) $ objNextSorting -> sorting + 128 ) ; } }
Calculate the new position of a moved or inserted record

@param string  $mode
@param integer $pid
@param boolean $insertInto
Calculate the new position of a moved or inserted record