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 SessionInterface $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 (in_array($k, array_keys($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']);
} elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['unique']) {
$v = \Input::get('act') == 'copyAll' ? $v . '-' . substr(md5(uniqid(mt_rand(), true)), 0, 8) : \Widget::getEmptyValueByFieldType($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['sql']);
} 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 #2938)
if (isset($GLOBALS['TL_DCA'][$this->strTable]['fields']['headline'])) {
$headline = \StringUtil::deserialize($this->set['headline']);
if (!empty($headline) && is_array($headline) && $headline['value'] != '') {
$headline['value'] = sprintf($GLOBALS['TL_LANG']['MSC']['copyOf'], $headline['value']);
$this->set['headline'] = serialize($headline);
}
} elseif (isset($GLOBALS['TL_DCA'][$this->strTable]['fields']['name'])) {
if ($this->set['name'] != '') {
$this->set['name'] = sprintf($GLOBALS['TL_LANG']['MSC']['copyOf'], $this->set['name']);
}
} elseif (isset($GLOBALS['TL_DCA'][$this->strTable]['fields']['subject'])) {
if ($this->set['subject'] != '') {
$this->set['subject'] = sprintf($GLOBALS['TL_LANG']['MSC']['copyOf'], $this->set['subject']);
}
} elseif (isset($GLOBALS['TL_DCA'][$this->strTable]['fields']['title'])) {
if ($this->set['title'] != '') {
$this->set['title'] = sprintf($GLOBALS['TL_LANG']['MSC']['copyOf'], $this->set['title']);
}
}
// 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
if (!$blnDoNotRedirect) {
$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;
}