core-bundle/src/Resources/contao/drivers/DC_Table.php
public function copy($blnDoNotRedirect=false)
	{
		if ($GLOBALS['TL_DCA'][$this->strTable]['config']['notCopyable'])
		{
			throw new InternalServerErrorException('Table "' . $this->strTable . '" is not copyable.');
		}

		if (!$this->intId)
		{
			$this->redirect($this->getReferer());
		}

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

		/** @var AttributeBagInterface $objSessionBag */
		$objSessionBag = $objSession->getBag('contao_backend');

		$objRow = $this->Database->prepare("SELECT * FROM " . $this->strTable . " WHERE id=?")
								 ->limit(1)
								 ->execute($this->intId);

		// Copy the values if the record contains data
		if ($objRow->numRows)
		{
			foreach ($objRow->row() as $k=>$v)
			{
				if (\array_key_exists($k, $GLOBALS['TL_DCA'][$this->strTable]['fields']))
				{
					// Never copy passwords
					if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['inputType'] == 'password')
					{
						$v = Widget::getEmptyValueByFieldType($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['sql']);
					}

					// Empty unique fields or add a unique identifier in copyAll mode
					elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['unique'])
					{
						$v = (Input::get('act') == 'copyAll' && !$GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['doNotCopy']) ? $v .'-'. substr(md5(uniqid(mt_rand(), true)), 0, 8) : Widget::getEmptyValueByFieldType($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['sql']);
					}

					// Reset doNotCopy and fallback fields to their default value
					elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['doNotCopy'] || $GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['fallback'])
					{
						$v = Widget::getEmptyValueByFieldType($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['sql']);

						// Use array_key_exists to allow NULL (see #5252)
						if (\array_key_exists('default', $GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]))
						{
							$v = \is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['default']) ? serialize($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['default']) : $GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['default'];
						}

						// Encrypt the default value (see #3740)
						if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['encrypt'])
						{
							$v = Encryption::encrypt($v);
						}
					}

					$this->set[$k] = $v;
				}
			}

			// HOOK: style sheet category
			if ($this->strTable == 'tl_style')
			{
				$filter = $objSessionBag->get('filter');
				$category = $filter['tl_style_' . CURRENT_ID]['category'];

				if ($category != '')
				{
					$this->set['category'] = $category;
				}
			}
		}

		// Get the new position
		$this->getNewPosition('copy', (\strlen(Input::get('pid')) ? Input::get('pid') : null), (Input::get('mode') == '2' ? true : false));

		// Dynamically set the parent table of tl_content
		if ($GLOBALS['TL_DCA'][$this->strTable]['config']['dynamicPtable'])
		{
			$this->set['ptable'] = $this->ptable;
		}

		// Empty clipboard
		$arrClipboard = $objSession->get('CLIPBOARD');
		$arrClipboard[$this->strTable] = array();
		$objSession->set('CLIPBOARD', $arrClipboard);

		// Insert the record if the table is not closed and switch to edit mode
		if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['closed'])
		{
			$this->set['tstamp'] = ($blnDoNotRedirect ? time() : 0);

			// Mark the new record with "copy of" (see #586)
			if (isset($GLOBALS['TL_DCA'][$this->strTable]['config']['markAsCopy']))
			{
				$strKey = $GLOBALS['TL_DCA'][$this->strTable]['config']['markAsCopy'];

				if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$strKey]['inputType'] == 'inputUnit')
				{
					$value = StringUtil::deserialize($this->set[$strKey]);

					if (!empty($value) && \is_array($value) && $value['value'] != '')
					{
						$value['value'] = sprintf($GLOBALS['TL_LANG']['MSC']['copyOf'], $value['value']);
						$this->set[$strKey] = serialize($value);
					}
				}
				elseif (!empty($this->set[$strKey]))
				{
					$this->set[$strKey] = sprintf($GLOBALS['TL_LANG']['MSC']['copyOf'], $this->set[$strKey]);
				}
			}

			// Remove the ID field from the data array
			unset($this->set['id']);

			$objInsertStmt = $this->Database->prepare("INSERT INTO " . $this->strTable . " %s")
											->set($this->set)
											->execute();

			if ($objInsertStmt->affectedRows)
			{
				$insertID = $objInsertStmt->insertId;

				// Save the new record in the session
				$new_records = $objSessionBag->get('new_records');
				$new_records[$this->strTable][] = $insertID;
				$objSessionBag->set('new_records', $new_records);

				// Duplicate the records of the child table
				$this->copyChilds($this->strTable, $insertID, $this->intId, $insertID);

				// Call the oncopy_callback after all new records have been created
				if (\is_array($GLOBALS['TL_DCA'][$this->strTable]['config']['oncopy_callback']))
				{
					foreach ($GLOBALS['TL_DCA'][$this->strTable]['config']['oncopy_callback'] as $callback)
					{
						if (\is_array($callback))
						{
							$this->import($callback[0]);
							$this->{$callback[0]}->{$callback[1]}($insertID, $this);
						}
						elseif (\is_callable($callback))
						{
							$callback($insertID, $this);
						}
					}
				}

				// Add a log entry
				$this->log('A new entry "'.$this->strTable.'.id='.$insertID.'" has been created by duplicating record "'.$this->strTable.'.id='.$this->intId.'"'.$this->getParentEntries($this->strTable, $insertID), __METHOD__, TL_GENERAL);

				// Switch to edit mode
				if (!$blnDoNotRedirect)
				{
					$this->redirect($this->switchToEdit($insertID));
				}

				return $insertID;
			}
		}

		if (!$blnDoNotRedirect)
		{
			$this->redirect($this->getReferer());
		}

		return false;
	}
public function copy($blnDoNotRedirect=false)
	{
		if ($GLOBALS['TL_DCA'][$this->strTable]['config']['notCopyable'])
		{
			throw new InternalServerErrorException('Table "' . $this->strTable . '" is not copyable.');
		}

		if (!$this->intId)
		{
			$this->redirect($this->getReferer());
		}

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

		/** @var AttributeBagInterface $objSessionBag */
		$objSessionBag = $objSession->getBag('contao_backend');

		$objRow = $this->Database->prepare("SELECT * FROM " . $this->strTable . " WHERE id=?")
								 ->limit(1)
								 ->execute($this->intId);

		// Copy the values if the record contains data
		if ($objRow->numRows)
		{
			foreach ($objRow->row() as $k=>$v)
			{
				if (\array_key_exists($k, $GLOBALS['TL_DCA'][$this->strTable]['fields']))
				{
					// Never copy passwords
					if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['inputType'] == 'password')
					{
						$v = Widget::getEmptyValueByFieldType($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['sql']);
					}

					// Empty unique fields or add a unique identifier in copyAll mode
					elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['unique'])
					{
						$v = (Input::get('act') == 'copyAll' && !$GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['doNotCopy']) ? $v .'-'. substr(md5(uniqid(mt_rand(), true)), 0, 8) : Widget::getEmptyValueByFieldType($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['sql']);
					}

					// Reset doNotCopy and fallback fields to their default value
					elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['doNotCopy'] || $GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['fallback'])
					{
						$v = Widget::getEmptyValueByFieldType($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['sql']);

						// Use array_key_exists to allow NULL (see #5252)
						if (\array_key_exists('default', $GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]))
						{
							$v = \is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['default']) ? serialize($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['default']) : $GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['default'];
						}

						// Encrypt the default value (see #3740)
						if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['encrypt'])
						{
							$v = Encryption::encrypt($v);
						}
					}

					$this->set[$k] = $v;
				}
			}

			// HOOK: style sheet category
			if ($this->strTable == 'tl_style')
			{
				$filter = $objSessionBag->get('filter');
				$category = $filter['tl_style_' . CURRENT_ID]['category'];

				if ($category != '')
				{
					$this->set['category'] = $category;
				}
			}
		}

		// Get the new position
		$this->getNewPosition('copy', (\strlen(Input::get('pid')) ? Input::get('pid') : null), (Input::get('mode') == '2' ? true : false));

		// Dynamically set the parent table of tl_content
		if ($GLOBALS['TL_DCA'][$this->strTable]['config']['dynamicPtable'])
		{
			$this->set['ptable'] = $this->ptable;
		}

		// Empty clipboard
		$arrClipboard = $objSession->get('CLIPBOARD');
		$arrClipboard[$this->strTable] = array();
		$objSession->set('CLIPBOARD', $arrClipboard);

		// Insert the record if the table is not closed and switch to edit mode
		if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['closed'])
		{
			$this->set['tstamp'] = ($blnDoNotRedirect ? time() : 0);

			// Mark the new record with "copy of" (see #586)
			if (isset($GLOBALS['TL_DCA'][$this->strTable]['config']['markAsCopy']))
			{
				$strKey = $GLOBALS['TL_DCA'][$this->strTable]['config']['markAsCopy'];

				if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$strKey]['inputType'] == 'inputUnit')
				{
					$value = StringUtil::deserialize($this->set[$strKey]);

					if (!empty($value) && \is_array($value) && $value['value'] != '')
					{
						$value['value'] = sprintf($GLOBALS['TL_LANG']['MSC']['copyOf'], $value['value']);
						$this->set[$strKey] = serialize($value);
					}
				}
				elseif (!empty($this->set[$strKey]))
				{
					$this->set[$strKey] = sprintf($GLOBALS['TL_LANG']['MSC']['copyOf'], $this->set[$strKey]);
				}
			}

			// Remove the ID field from the data array
			unset($this->set['id']);

			$objInsertStmt = $this->Database->prepare("INSERT INTO " . $this->strTable . " %s")
											->set($this->set)
											->execute();

			if ($objInsertStmt->affectedRows)
			{
				$insertID = $objInsertStmt->insertId;

				// Save the new record in the session
				$new_records = $objSessionBag->get('new_records');
				$new_records[$this->strTable][] = $insertID;
				$objSessionBag->set('new_records', $new_records);

				// Duplicate the records of the child table
				$this->copyChilds($this->strTable, $insertID, $this->intId, $insertID);

				// Call the oncopy_callback after all new records have been created
				if (\is_array($GLOBALS['TL_DCA'][$this->strTable]['config']['oncopy_callback']))
				{
					foreach ($GLOBALS['TL_DCA'][$this->strTable]['config']['oncopy_callback'] as $callback)
					{
						if (\is_array($callback))
						{
							$this->import($callback[0]);
							$this->{$callback[0]}->{$callback[1]}($insertID, $this);
						}
						elseif (\is_callable($callback))
						{
							$callback($insertID, $this);
						}
					}
				}

				// Add a log entry
				$this->log('A new entry "'.$this->strTable.'.id='.$insertID.'" has been created by duplicating record "'.$this->strTable.'.id='.$this->intId.'"'.$this->getParentEntries($this->strTable, $insertID), __METHOD__, TL_GENERAL);

				// Switch to edit mode
				if (!$blnDoNotRedirect)
				{
					$this->redirect($this->switchToEdit($insertID));
				}

				return $insertID;
			}
		}

		if (!$blnDoNotRedirect)
		{
			$this->redirect($this->getReferer());
		}

		return false;
	}
public function copy ( $ blnDoNotRedirect = false ) { if ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'config' ] [ 'notCopyable' ] ) { throw new InternalServerErrorException ( 'Table "' . $ this -> strTable . '" is not copyable.' ) ; } if ( ! $ this -> intId ) { $ this -> redirect ( $ this -> getReferer ( ) ) ; } /** @var Session $objSession */ $ objSession = System :: getContainer ( ) -> get ( 'session' ) ; /** @var AttributeBagInterface $objSessionBag */ $ objSessionBag = $ objSession -> getBag ( 'contao_backend' ) ; $ objRow = $ this -> Database -> prepare ( "SELECT * FROM " . $ this -> strTable . " WHERE id=?" ) -> limit ( 1 ) -> execute ( $ this -> intId ) ; // Copy the values if the record contains data if ( $ objRow -> numRows ) { foreach ( $ objRow -> row ( ) as $ k => $ v ) { if ( \ array_key_exists ( $ k , $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] ) ) { // Never copy passwords if ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ k ] [ 'inputType' ] == 'password' ) { $ v = Widget :: getEmptyValueByFieldType ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ k ] [ 'sql' ] ) ; } // Empty unique fields or add a unique identifier in copyAll mode elseif ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ k ] [ 'eval' ] [ 'unique' ] ) { $ v = ( Input :: get ( 'act' ) == 'copyAll' && ! $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ k ] [ 'eval' ] [ 'doNotCopy' ] ) ? $ v . '-' . substr ( md5 ( uniqid ( mt_rand ( ) , true ) ) , 0 , 8 ) : Widget :: getEmptyValueByFieldType ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ k ] [ 'sql' ] ) ; } // Reset doNotCopy and fallback fields to their default value elseif ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ k ] [ 'eval' ] [ 'doNotCopy' ] || $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ k ] [ 'eval' ] [ 'fallback' ] ) { $ v = Widget :: getEmptyValueByFieldType ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ k ] [ 'sql' ] ) ; // Use array_key_exists to allow NULL (see #5252) if ( \ array_key_exists ( 'default' , $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ k ] ) ) { $ v = \ is_array ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ k ] [ 'default' ] ) ? serialize ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ k ] [ 'default' ] ) : $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ k ] [ 'default' ] ; } // Encrypt the default value (see #3740) if ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ k ] [ 'eval' ] [ 'encrypt' ] ) { $ v = Encryption :: encrypt ( $ v ) ; } } $ this -> set [ $ k ] = $ v ; } } // HOOK: style sheet category if ( $ this -> strTable == 'tl_style' ) { $ filter = $ objSessionBag -> get ( 'filter' ) ; $ category = $ filter [ 'tl_style_' . CURRENT_ID ] [ 'category' ] ; if ( $ category != '' ) { $ this -> set [ 'category' ] = $ category ; } } } // Get the new position $ this -> getNewPosition ( 'copy' , ( \ strlen ( Input :: get ( 'pid' ) ) ? Input :: get ( 'pid' ) : null ) , ( Input :: get ( 'mode' ) == '2' ? true : false ) ) ; // Dynamically set the parent table of tl_content if ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'config' ] [ 'dynamicPtable' ] ) { $ this -> set [ 'ptable' ] = $ this -> ptable ; } // Empty clipboard $ arrClipboard = $ objSession -> get ( 'CLIPBOARD' ) ; $ arrClipboard [ $ this -> strTable ] = array ( ) ; $ objSession -> set ( 'CLIPBOARD' , $ arrClipboard ) ; // Insert the record if the table is not closed and switch to edit mode if ( ! $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'config' ] [ 'closed' ] ) { $ this -> set [ 'tstamp' ] = ( $ blnDoNotRedirect ? time ( ) : 0 ) ; // Mark the new record with "copy of" (see #586) if ( isset ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'config' ] [ 'markAsCopy' ] ) ) { $ strKey = $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'config' ] [ 'markAsCopy' ] ; if ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'fields' ] [ $ strKey ] [ 'inputType' ] == 'inputUnit' ) { $ value = StringUtil :: deserialize ( $ this -> set [ $ strKey ] ) ; if ( ! empty ( $ value ) && \ is_array ( $ value ) && $ value [ 'value' ] != '' ) { $ value [ 'value' ] = sprintf ( $ GLOBALS [ 'TL_LANG' ] [ 'MSC' ] [ 'copyOf' ] , $ value [ 'value' ] ) ; $ this -> set [ $ strKey ] = serialize ( $ value ) ; } } elseif ( ! empty ( $ this -> set [ $ strKey ] ) ) { $ this -> set [ $ strKey ] = sprintf ( $ GLOBALS [ 'TL_LANG' ] [ 'MSC' ] [ 'copyOf' ] , $ this -> set [ $ strKey ] ) ; } } // Remove the ID field from the data array unset ( $ this -> set [ 'id' ] ) ; $ objInsertStmt = $ this -> Database -> prepare ( "INSERT INTO " . $ this -> strTable . " %s" ) -> set ( $ this -> set ) -> execute ( ) ; if ( $ objInsertStmt -> affectedRows ) { $ insertID = $ objInsertStmt -> insertId ; // Save the new record in the session $ new_records = $ objSessionBag -> get ( 'new_records' ) ; $ new_records [ $ this -> strTable ] [ ] = $ insertID ; $ objSessionBag -> set ( 'new_records' , $ new_records ) ; // Duplicate the records of the child table $ this -> copyChilds ( $ this -> strTable , $ insertID , $ this -> intId , $ insertID ) ; // Call the oncopy_callback after all new records have been created if ( \ is_array ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'config' ] [ 'oncopy_callback' ] ) ) { foreach ( $ GLOBALS [ 'TL_DCA' ] [ $ this -> strTable ] [ 'config' ] [ 'oncopy_callback' ] as $ callback ) { if ( \ is_array ( $ callback ) ) { $ this -> import ( $ callback [ 0 ] ) ; $ this -> { $ callback [ 0 ] } -> { $ callback [ 1 ] } ( $ insertID , $ this ) ; } elseif ( \ is_callable ( $ callback ) ) { $ callback ( $ insertID , $ this ) ; } } } // Add a log entry $ this -> log ( 'A new entry "' . $ this -> strTable . '.id=' . $ insertID . '" has been created by duplicating record "' . $ this -> strTable . '.id=' . $ this -> intId . '"' . $ this -> getParentEntries ( $ this -> strTable , $ insertID ) , __METHOD__ , TL_GENERAL ) ; // Switch to edit mode if ( ! $ blnDoNotRedirect ) { $ this -> redirect ( $ this -> switchToEdit ( $ insertID ) ) ; } return $ insertID ; } } if ( ! $ blnDoNotRedirect ) { $ this -> redirect ( $ this -> getReferer ( ) ) ; } return false ; }
Duplicate a particular record of the current table

@param boolean $blnDoNotRedirect

@return integer|boolean

@throws InternalServerErrorException
Duplicate a particular record of the current table