core-bundle/src/Resources/contao/drivers/DC_Table.php
protected function reviseTable()
	{
		$reload = false;
		$ptable = $GLOBALS['TL_DCA'][$this->strTable]['config']['ptable'];
		$ctable = $GLOBALS['TL_DCA'][$this->strTable]['config']['ctable'];

		/** @var AttributeBagInterface $objSessionBag */
		$objSessionBag = System::getContainer()->get('session')->getBag('contao_backend');

		$new_records = $objSessionBag->get('new_records');

		// HOOK: add custom logic
		if (isset($GLOBALS['TL_HOOKS']['reviseTable']) && \is_array($GLOBALS['TL_HOOKS']['reviseTable']))
		{
			foreach ($GLOBALS['TL_HOOKS']['reviseTable'] as $callback)
			{
				$status = null;

				if (\is_array($callback))
				{
					$this->import($callback[0]);
					$status = $this->{$callback[0]}->{$callback[1]}($this->strTable, $new_records[$this->strTable], $ptable, $ctable);
				}
				elseif (\is_callable($callback))
				{
					$status = $callback($this->strTable, $new_records[$this->strTable], $ptable, $ctable);
				}

				if ($status === true)
				{
					$reload = true;
				}
			}
		}

		// Delete all new but incomplete records (tstamp=0)
		if (!empty($new_records[$this->strTable]) && \is_array($new_records[$this->strTable]))
		{
			$intPreserved = null;

			// Unset the preserved record (see #1129)
			if ($this->intPreserveRecord && ($index = array_search($this->intPreserveRecord, $new_records[$this->strTable])) !== false)
			{
				$intPreserved = $new_records[$this->strTable][$index];
				unset($new_records[$this->strTable][$index]);
			}

			// Remove the entries from the database
			if (!empty($new_records[$this->strTable]))
			{
				$ids = array_map('\intval', $new_records[$this->strTable]);

				foreach ($ids as $id)
				{
					$dataContainer = static::class;
					$dc = new $dataContainer($this->strTable);
					$dc->id = $id;

					// Get the current record
					$objRow = $this->Database->prepare("SELECT * FROM " . $this->strTable . " WHERE id=?")
											 ->limit(1)
											 ->execute($id);

					$dc->activeRecord = $objRow;

					// Invalidate cache tags (no need to invalidate the parent)
					$this->invalidateCacheTags($dc);
				}

				$objStmt = $this->Database->execute("DELETE FROM " . $this->strTable . " WHERE id IN(" . implode(',', $ids) . ") AND tstamp=0");

				if ($objStmt->affectedRows > 0)
				{
					$reload = true;
				}
			}

			// Remove the entries from the session
			if ($intPreserved !== null)
			{
				$new_records[$this->strTable] = array($intPreserved);
			}
			else
			{
				unset($new_records[$this->strTable]);
			}

			$objSessionBag->set('new_records', $new_records);
		}

		// Delete all records of the current table that are not related to the parent table
		if ($ptable != '')
		{
			if ($GLOBALS['TL_DCA'][$this->strTable]['config']['dynamicPtable'])
			{
				$objStmt = $this->Database->execute("DELETE FROM " . $this->strTable . " WHERE ptable='" . $ptable . "' AND NOT EXISTS (SELECT * FROM " . $ptable . " WHERE " . $this->strTable . ".pid = " . $ptable . ".id)");
			}
			else
			{
				$objStmt = $this->Database->execute("DELETE FROM " . $this->strTable . " WHERE NOT EXISTS (SELECT * FROM " . $ptable . " WHERE " . $this->strTable . ".pid = " . $ptable . ".id)");
			}

			if ($objStmt->affectedRows > 0)
			{
				$reload = true;
			}
		}

		// Delete all records of the child table that are not related to the current table
		if (!empty($ctable) && \is_array($ctable))
		{
			foreach ($ctable as $v)
			{
				if ($v != '')
				{
					// Load the DCA configuration so we can check for "dynamicPtable"
					if (!isset($GLOBALS['loadDataContainer'][$v]))
					{
						$this->loadDataContainer($v);
					}

					if ($GLOBALS['TL_DCA'][$v]['config']['dynamicPtable'])
					{
						$objStmt = $this->Database->execute("DELETE FROM $v WHERE ptable='" . $this->strTable . "' AND NOT EXISTS (SELECT * FROM " . $this->strTable . " WHERE $v.pid = " . $this->strTable . ".id)");
					}
					else
					{
						$objStmt = $this->Database->execute("DELETE FROM $v WHERE NOT EXISTS (SELECT * FROM " . $this->strTable . " WHERE $v.pid = " . $this->strTable . ".id)");
					}

					if ($objStmt->affectedRows > 0)
					{
						$reload = true;
					}
				}
			}
		}

		// Reload the page
		if ($reload)
		{
			$this->reload();
		}
	}
protected function reviseTable()
	{
		$reload = false;
		$ptable = $GLOBALS['TL_DCA'][$this->strTable]['config']['ptable'];
		$ctable = $GLOBALS['TL_DCA'][$this->strTable]['config']['ctable'];

		/** @var AttributeBagInterface $objSessionBag */
		$objSessionBag = System::getContainer()->get('session')->getBag('contao_backend');

		$new_records = $objSessionBag->get('new_records');

		// HOOK: add custom logic
		if (isset($GLOBALS['TL_HOOKS']['reviseTable']) && \is_array($GLOBALS['TL_HOOKS']['reviseTable']))
		{
			foreach ($GLOBALS['TL_HOOKS']['reviseTable'] as $callback)
			{
				$status = null;

				if (\is_array($callback))
				{
					$this->import($callback[0]);
					$status = $this->{$callback[0]}->{$callback[1]}($this->strTable, $new_records[$this->strTable], $ptable, $ctable);
				}
				elseif (\is_callable($callback))
				{
					$status = $callback($this->strTable, $new_records[$this->strTable], $ptable, $ctable);
				}

				if ($status === true)
				{
					$reload = true;
				}
			}
		}

		// Delete all new but incomplete records (tstamp=0)
		if (!empty($new_records[$this->strTable]) && \is_array($new_records[$this->strTable]))
		{
			$intPreserved = null;

			// Unset the preserved record (see #1129)
			if ($this->intPreserveRecord && ($index = array_search($this->intPreserveRecord, $new_records[$this->strTable])) !== false)
			{
				$intPreserved = $new_records[$this->strTable][$index];
				unset($new_records[$this->strTable][$index]);
			}

			// Remove the entries from the database
			if (!empty($new_records[$this->strTable]))
			{
				$ids = array_map('\intval', $new_records[$this->strTable]);

				foreach ($ids as $id)
				{
					$dataContainer = static::class;
					$dc = new $dataContainer($this->strTable);
					$dc->id = $id;

					// Get the current record
					$objRow = $this->Database->prepare("SELECT * FROM " . $this->strTable . " WHERE id=?")
											 ->limit(1)
											 ->execute($id);

					$dc->activeRecord = $objRow;

					// Invalidate cache tags (no need to invalidate the parent)
					$this->invalidateCacheTags($dc);
				}

				$objStmt = $this->Database->execute("DELETE FROM " . $this->strTable . " WHERE id IN(" . implode(',', $ids) . ") AND tstamp=0");

				if ($objStmt->affectedRows > 0)
				{
					$reload = true;
				}
			}

			// Remove the entries from the session
			if ($intPreserved !== null)
			{
				$new_records[$this->strTable] = array($intPreserved);
			}
			else
			{
				unset($new_records[$this->strTable]);
			}

			$objSessionBag->set('new_records', $new_records);
		}

		// Delete all records of the current table that are not related to the parent table
		if ($ptable != '')
		{
			if ($GLOBALS['TL_DCA'][$this->strTable]['config']['dynamicPtable'])
			{
				$objStmt = $this->Database->execute("DELETE FROM " . $this->strTable . " WHERE ptable='" . $ptable . "' AND NOT EXISTS (SELECT * FROM " . $ptable . " WHERE " . $this->strTable . ".pid = " . $ptable . ".id)");
			}
			else
			{
				$objStmt = $this->Database->execute("DELETE FROM " . $this->strTable . " WHERE NOT EXISTS (SELECT * FROM " . $ptable . " WHERE " . $this->strTable . ".pid = " . $ptable . ".id)");
			}

			if ($objStmt->affectedRows > 0)
			{
				$reload = true;
			}
		}

		// Delete all records of the child table that are not related to the current table
		if (!empty($ctable) && \is_array($ctable))
		{
			foreach ($ctable as $v)
			{
				if ($v != '')
				{
					// Load the DCA configuration so we can check for "dynamicPtable"
					if (!isset($GLOBALS['loadDataContainer'][$v]))
					{
						$this->loadDataContainer($v);
					}

					if ($GLOBALS['TL_DCA'][$v]['config']['dynamicPtable'])
					{
						$objStmt = $this->Database->execute("DELETE FROM $v WHERE ptable='" . $this->strTable . "' AND NOT EXISTS (SELECT * FROM " . $this->strTable . " WHERE $v.pid = " . $this->strTable . ".id)");
					}
					else
					{
						$objStmt = $this->Database->execute("DELETE FROM $v WHERE NOT EXISTS (SELECT * FROM " . $this->strTable . " WHERE $v.pid = " . $this->strTable . ".id)");
					}

					if ($objStmt->affectedRows > 0)
					{
						$reload = true;
					}
				}
			}
		}

		// Reload the page
		if ($reload)
		{
			$this->reload();
		}
	}
Delete all incomplete and unrelated records