/** * Compare the theme tables with the local database and check whether there are custom layout sections * * @param array $arrFiles * @param array $arrDbFields * * @return string */ protected function compareThemeFiles($arrFiles, $arrDbFields) { $return = ' <div id="tl_buttons"> <a href="' . ampersand(str_replace('&key=importTheme', '', \Environment::get('request'))) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> </div> ' . \Message::generate() . ' <form action="' . ampersand(\Environment::get('request'), true) . '" id="tl_theme_import" class="tl_form" method="post"> <div class="tl_formbody_edit"> <input type="hidden" name="FORM_SUBMIT" value="tl_theme_import"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"> <input type="hidden" name="confirm" value="1">'; $count = 0; // Check the theme data foreach ($arrFiles as $strFile) { $return .= ' <div class="tl_' . ($count++ < 1 ? 't' : '') . 'box theme_import"> <h3>' . basename($strFile) . '</h3> <h4>' . $GLOBALS['TL_LANG']['tl_theme']['tables_fields'] . '</h4>'; // Find the XML file $objArchive = new \ZipReader($strFile); // Continue if there is no XML file if ($objArchive->getFile('theme.xml') === false) { $return .= "\n " . '<p class="tl_red" style="margin:0">' . sprintf($GLOBALS['TL_LANG']['tl_theme']['missing_xml'], basename($strFile)) . "</p>\n</div>"; continue; } // Open the XML file $xml = new \DOMDocument(); $xml->preserveWhiteSpace = false; $xml->loadXML($objArchive->unzip()); $tables = $xml->getElementsByTagName('table'); $blnHasError = false; // Loop through the tables for ($i = 0; $i < $tables->length; $i++) { $rows = $tables->item($i)->childNodes; $table = $tables->item($i)->getAttribute('name'); // Skip invalid tables if ($table != 'tl_theme' && $table != 'tl_style_sheet' && $table != 'tl_style' && $table != 'tl_module' && $table != 'tl_layout' && $table != 'tl_image_size' && $table != 'tl_image_size_item') { continue; } $arrFieldNames = array(); // Loop through the rows for ($j = 0; $j < $rows->length; $j++) { $fields = $rows->item($j)->childNodes; // Loop through the fields for ($k = 0; $k < $fields->length; $k++) { $arrFieldNames[$fields->item($k)->getAttribute('name')] = true; } } $arrFieldNames = array_keys($arrFieldNames); // Loop through the fields foreach ($arrFieldNames as $name) { // Print a warning if a field is missing if (!in_array($name, $arrDbFields[$table])) { $blnHasError = true; $return .= "\n " . '<p class="tl_red" style="margin:0">' . sprintf($GLOBALS['TL_LANG']['tl_theme']['missing_field'], $table . '.' . $name) . '</p>'; } } } // Confirmation if (!$blnHasError) { $return .= "\n " . '<p class="tl_green" style="margin:0">' . $GLOBALS['TL_LANG']['tl_theme']['tables_ok'] . '</p>'; } // Check the custom templates $return .= ' <h4>' . $GLOBALS['TL_LANG']['tl_theme']['custom_templates'] . '</h4>'; $objArchive->reset(); $blnTplExists = false; // Loop through the archive while ($objArchive->next()) { if (strncmp($objArchive->file_name, 'templates/', 10) !== 0) { continue; } if (file_exists(TL_ROOT . '/' . $objArchive->file_name)) { $blnTplExists = true; $return .= "\n " . '<p class="tl_red" style="margin:0">' . sprintf($GLOBALS['TL_LANG']['tl_theme']['template_exists'], $objArchive->file_name) . '</p>'; } } // Confirmation if (!$blnTplExists) { $return .= "\n " . '<p class="tl_green" style="margin:0">' . $GLOBALS['TL_LANG']['tl_theme']['templates_ok'] . '</p>'; } // HOOK: add custom logic if (isset($GLOBALS['TL_HOOKS']['compareThemeFiles']) && is_array($GLOBALS['TL_HOOKS']['compareThemeFiles'])) { foreach ($GLOBALS['TL_HOOKS']['compareThemeFiles'] as $callback) { $return .= \System::importStatic($callback[0])->{$callback}[1]($xml, $objArchive); } } $return .= ' </div>'; } // Return the form return $return . ' </div> <div class="tl_formbody_submit"> <div class="tl_submit_container"> <input type="submit" name="save" id="save" class="tl_submit" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['MSC']['continue']) . '"> </div> </div> </form>'; }
/** * Compare the theme tables with the local database and check * whether there are custom layout sections * @param array * @param array */ protected function compareThemeFiles($arrFiles, $arrDbFields) { $return = ' <div id="tl_buttons"> <a href="'.ampersand(str_replace('&key=importTheme', '', $this->Environment->request)).'" class="header_back" title="'.specialchars($GLOBALS['TL_LANG']['MSC']['backBT']).'" accesskey="b">'.$GLOBALS['TL_LANG']['MSC']['backBT'].'</a> </div> <h2 class="sub_headline">'.$GLOBALS['TL_LANG']['tl_theme']['checking_theme'].'</h2> '.$this->getMessages().' <form action="'.ampersand($this->Environment->request, true).'" id="tl_theme_import" class="tl_form" method="post"> <div class="tl_formbody_edit"> <input type="hidden" name="FORM_SUBMIT" value="tl_theme_import"> <input type="hidden" name="REQUEST_TOKEN" value="'.REQUEST_TOKEN.'"> <input type="hidden" name="confirm" value="1">'; // Add the hidden fields foreach ($arrFiles as $strFile) { $return .= "\n" . '<input type="hidden" name="source[]" value="'.$strFile.'">'; } $count = 0; // Check the theme data foreach ($arrFiles as $strFile) { $return .= ' <div class="tl_'. (($count++ < 1) ? 't' : '') .'box"> <h3>'. basename($strFile) .'</h3> <h4>'.$GLOBALS['TL_LANG']['tl_theme']['tables_fields'].'</h4>'; // Find the XML file $objArchive = new ZipReader($strFile); // Continue if there is no XML file if ($objArchive->getFile('theme.xml') === false) { $blnHasError = true; $return .= "\n " . '<p style="margin:0;color:#c55">'. sprintf($GLOBALS['TL_LANG']['tl_theme']['missing_xml'], basename($strFile)) ."</p>\n</div>"; continue; } // Open the XML file $xml = new DOMDocument(); $xml->preserveWhiteSpace = false; $xml->loadXML($objArchive->unzip()); $tables = $xml->getElementsByTagName('table'); $tl_layout = null; $blnHasError = false; // Loop through the tables for ($i=0; $i<$tables->length; $i++) { $rows = $tables->item($i)->childNodes; $table = $tables->item($i)->getAttribute('name'); // Skip invalid tables if ($table != 'tl_theme' && $table != 'tl_style_sheet' && $table != 'tl_style' && $table != 'tl_module' && $table != 'tl_layout') { continue; } $fields = $rows->item(0)->childNodes; // Store the tl_layout element if ($table == 'tl_layout') { $tl_layout = $tables->item($i)->childNodes; } // Loop through the fields for ($j=0; $j<$fields->length; $j++) { $name = $fields->item($j)->getAttribute('name'); // Print a warning if a field is missing if (!in_array($name, $arrDbFields[$table])) { $blnHasError = true; $return .= "\n " . '<p style="margin:0; color:#c55">'. sprintf($GLOBALS['TL_LANG']['tl_theme']['missing_field'], $table .'.'. $name) .'</p>'; } } } // Confirmation if (!$blnHasError) { $return .= "\n " . '<p style="margin:0;color:#8ab858">'. $GLOBALS['TL_LANG']['tl_theme']['tables_ok'] .'</p>'; } $return .= ' <h4>'.$GLOBALS['TL_LANG']['tl_theme']['custom_sections'].'</h4>'; $blnHasLayout = false; $arrSections = trimsplit(',', $GLOBALS['TL_CONFIG']['customSections']); $arrProcessed = array(); // Loop through tl_layout for ($i=0; $i<$tl_layout->length; $i++) { $fields = $tl_layout->item($i)->childNodes; // Loop through the fields for ($j=0; $j<$fields->length; $j++) { if ($fields->item($j)->getAttribute('name') != 'modules') { continue; } $modules = deserialize($fields->item($j)->nodeValue); // Continue if there are no modules if (!is_array($modules) || empty($modules)) { continue; } // Check all columns foreach ($modules as $mod) { // Default columns if ($mod['col'] == 'header' || $mod['col'] == 'left' || $mod['col'] == 'main' || $mod['col'] == 'right' || $mod['col'] == 'footer') { continue; } // Do not show multiple warnings if (in_array($mod['col'], $arrProcessed) || in_array($mod['col'], $arrSections)) { continue; } $blnHasLayout = true; $arrProcessed[] = $mod['col']; $return .= "\n " . '<p style="margin:0;color:#c55">'. sprintf($GLOBALS['TL_LANG']['tl_theme']['missing_section'], $mod['col']) .'</p>'; } } } // Confirmation if (!$blnHasLayout) { $return .= "\n " . '<p style="margin:0;color:#8ab858">'. $GLOBALS['TL_LANG']['tl_theme']['sections_ok'] .'</p>'; } // Check the custom templates $return .= ' <h4>'.$GLOBALS['TL_LANG']['tl_theme']['custom_templates'].'</h4>'; $objArchive->reset(); $blnTplExists = false; // Loop through the archive while ($objArchive->next()) { if (strncmp($objArchive->file_name, 'templates/', 10) !== 0) { continue; } if (file_exists(TL_ROOT .'/'. $objArchive->file_name)) { $blnTplExists = true; $return .= "\n " . '<p style="margin:0;color:#c55">'. sprintf($GLOBALS['TL_LANG']['tl_theme']['template_exists'], $objArchive->file_name) .'</p>'; } } // Confirmation if (!$blnTplExists) { $return .= "\n " . '<p style="margin:0;color:#8ab858">'. $GLOBALS['TL_LANG']['tl_theme']['templates_ok'] .'</p>'; } $return .= ' </div>'; } // Return the form return $return . ' </div> <div class="tl_formbody_submit"> <div class="tl_submit_container"> <input type="submit" name="save" id="save" class="tl_submit" accesskey="s" value="'.specialchars($GLOBALS['TL_LANG']['MSC']['continue']).'"> </div> </div> </form>'; }
/** * Unzip the file by using the ZipReader class from contao * * @param sring $strZipPath Path to the zip * @return array A list with current path and taget path. * @throws Exception */ protected function unzipByContao($strZipPath) { $arrMoveList = array(); $objZipReader = new ZipReader($strZipPath); // Create tmp folder new Folder(self::TEMP_PATH . '/syncCtoAutoUpdate'); foreach ($objZipReader->getFileList() as $value) { // Check if the file part of the folder "FILES" if (!preg_match("/^" . self::ZIP_FILE_PATH . "\\//i", $value)) { continue; } $movePath = preg_replace("/^" . self::ZIP_FILE_PATH . "\\//i", "", $value); $targetPath = self::TEMP_PATH . 'syncCtoAutoUpdate/' . $movePath; $arrMoveList[$targetPath] = $movePath; // Write file $objZipReader->getFile($value); $objFile = new File($targetPath); $objFile->write($objZipReader->unzip()); $objFile->close(); unset($objFile); } return $arrMoveList; }
public function restoreBackup($restoreFile, $boolDB = false, $boolFiles = false) { $arrOutput = array(); if ($restoreFile) { $c2gFile = new File("backups/" . $restoreFile); if ($c2gFile->extension == 'c2g') { $c2gZipFile = new ZipReader("backups/" . $restoreFile); $descFile = $c2gZipFile->getFile("description.php"); if ($descFile) { unset($GLOBALS["package"]); eval($c2gZipFile->unzip()); $arrOutput[] = sprintf($GLOBALS['TL_LANG']['tl_content']['c2g_restorebackup'], $GLOBALS["package"]["Name"]); $dirName = TL_ROOT . '/' . $GLOBALS["package"]["RootDir"] . '/' . $GLOBALS["package"]["Name"]; if ($boolFiles) { $strRestoreFolder = new Folder($GLOBALS["package"]["RootDir"] . @'/' . $GLOBALS["package"]["Name"] . @'/'); if ($GLOBALS["package"]["RootDir"] != '.' && is_dir($dirName)) { $this->c2g_functions->rrmdir($dirName); $arrOutput[] = sprintf($GLOBALS['TL_LANG']['tl_content']['c2g_restorebackup_cleandir'], $GLOBALS["package"]["Name"]); } $directoryFile = $c2gZipFile->getFile("directories.dat"); if ($directoryFile) { $strDirectories = $c2gZipFile->unzip(); $arrDirectories = explode("\r\n", $strDirectories); if (is_array($arrDirectories)) { foreach ($arrDirectories as $dir) { $objDir = new Folder($dir); } } } $c2gZipFile->first(); $arrFileList = $c2gZipFile->getFileList(); foreach ($arrFileList as $file) { $c2gZipFile->getFile($file); $objFile = new File('vhosts/' . $file); $strData = $c2gZipFile->unzip(); if (basename($file) == 'localconfig.php') { $objFile->write($strData); $objFile->close(); $arrConfigReturn = @$this->c2g_functions->loadVHostConfig(TL_ROOT . '/vhosts/' . $GLOBALS["package"]["Name"], false); $objFile = new File('vhosts/' . $file); $strData = $this->c2g_functions->rewriteLocalconfig($strData, $GLOBALS['TL_CONFIG']['dbHost'], $GLOBALS['TL_CONFIG']['dbPort'], $arrConfigReturn['localconfig']['dbDatabase'], $GLOBALS['TL_CONFIG']['dbUser'], $GLOBALS['TL_CONFIG']['dbPass'], $arrConfigReturn['localconfig']['websitePath']); } $objFile->write($strData); $objFile->close(); // let the directorystructure create, but remove .empty file if (basename($file) == '.empty') { $objFile->delete(); } } $arrOutput[] = $GLOBALS['TL_LANG']['tl_content']['c2g_restorebackup_filesystemrestored']; } $arrConfigReturn = $this->c2g_functions->loadVHostConfig(TL_ROOT . '/vhosts/' . $GLOBALS["package"]["Name"]); if (IS_CONTAO3) { $objFile = new File('vhosts/' . $GLOBALS["package"]["Name"] . '/system/config/pathconfig.php', true); $objFile->write("<?php\n\n// Relative path to the installation\nreturn '/vhosts/" . $GLOBALS["package"]["Name"] . "';\n"); $objFile->close(); $arrOutput[] = $GLOBALS['TL_LANG']['tl_content']['c2g_createpathconfig']; } if ($boolDB) { $file = $c2gFile->filename . '.sql'; $c2gZipFile->getFile($file); $objFile = new File('vhosts/' . $file); $objFile->write($c2gZipFile->unzip()); $objFile->close(); $sqlDump = new File($GLOBALS["package"]["RootDir"] . '/' . $file); $this->c2g_functions->restoreDump($sqlDump->getContent()); $sqlDump->close(); $arrOutput[] = $GLOBALS['TL_LANG']['tl_content']['c2g_restorebackup_sqlrestored']; } $objDescFile = new File($GLOBALS["package"]["RootDir"] . '/description.php'); $objDescFile->delete(); $objDirFile = new File($GLOBALS["package"]["RootDir"] . '/directories.dat'); $objDirFile->delete(); $objSQLFile = new File($GLOBALS["package"]["RootDir"] . '/' . $c2gFile->filename . '.sql'); $objSQLFile->delete(); } } $arrOutput[] = sprintf('<a href="%s" title="%s">%s</a>', $this->pathMySelf, $GLOBALS['TL_LANG']['tl_content']['c2g_backupreturntooverview'], $GLOBALS['TL_LANG']['tl_content']['c2g_backupreturntooverview']); $pathBackups = $this->replaceInsertTags(sprintf('{{link_url::%s}}', $this->c2g_listvhosts)); $arrOutput[] = sprintf('<a href="%s" title="%s">%s</a>', $pathBackups, $GLOBALS['TL_LANG']['tl_content']['c2g_backupreturntovhosts'], $GLOBALS['TL_LANG']['tl_content']['c2g_backupreturntovhosts']); } return implode("<br />", $arrOutput); }
/** * Restore database-backup from zip * * @param string $strRestoreFile Path to file like system/backup/backup.zip * @param bool $booTruncate * @return type */ public function runRestore($strRestoreFile, $arrSuffixSQL = null) { try { // Set time out for database. Ticket #2653 if ($GLOBALS['TL_CONFIG']['syncCto_custom_settings'] == true && intval($GLOBALS['TL_CONFIG']['syncCto_wait_timeout']) > 0 && intval($GLOBALS['TL_CONFIG']['syncCto_interactive_timeout']) > 0) { $this->Database->query('SET SESSION wait_timeout = GREATEST(' . intval($GLOBALS['TL_CONFIG']['syncCto_wait_timeout']) . ', @@wait_timeout), SESSION interactive_timeout = GREATEST(' . intval($GLOBALS['TL_CONFIG']['syncCto_interactive_timeout']) . ', @@wait_timeout);'); } else { $this->Database->query('SET SESSION wait_timeout = GREATEST(28000, @@wait_timeout), SESSION interactive_timeout = GREATEST(28000, @@wait_timeout);'); } switch (pathinfo($strRestoreFile, PATHINFO_EXTENSION)) { case "zip": $objZipRead = new ZipReader($strRestoreFile); // Get structure if ($objZipRead->getFile($this->strFilenameSyncCto)) { $objGzFile = new File("system/tmp/{$this->strFilenameSyncCto}.gz"); $objGzFile->write($objZipRead->unzip()); $objGzFile->close(); $arrRestoreTables = $this->runRestoreFromXML("system/tmp/{$this->strFilenameSyncCto}.gz"); } else { $arrRestoreTables = $this->runRestoreFromSer($strRestoreFile); } break; case "synccto": $arrRestoreTables = $this->runRestoreFromXML($strRestoreFile); break; default: throw new Exception("Not supportet or Unknown file type."); break; } // After insert, call some SQL if (is_array($arrSuffixSQL)) { foreach ($arrSuffixSQL as $key => $value) { $this->Database->query($value['query']); } } // Rename temp tables foreach ($arrRestoreTables as $key => $value) { $this->Database->query("DROP TABLE IF EXISTS " . $value); $this->Database->query("RENAME TABLE " . "synccto_temp_" . $value . " TO " . $value); } } catch (Exception $exc) { // Drop synccto_temp tables foreach ($this->Database->listTables() as $key => $value) { if (preg_match("/synccto_temp_.*/", $value)) { $this->Database->query("DROP TABLE IF EXISTS {$value}"); } } throw $exc; } // Drop synccto_temp tables foreach ($this->Database->listTables() as $key => $value) { if (preg_match("/synccto_temp_.*/", $value)) { $this->Database->query("DROP TABLE IF EXISTS {$value}"); } } return $arrSuffixSQL; }
/** * Restore database-backup from zip. * * @param string $strRestoreFile Path to file like system/backup/backup.zip * * @param null $arrSuffixSQL * * @return type * * @throws Exception * * @internal param bool $booTruncate */ public function runRestore($strRestoreFile, $arrSuffixSQL = null) { // Load the path builder. $pathBuilder = new \SyncCto\Helper\PathBuilder(); try { // Set time out for database. Ticket #2653 $tmpResult = \Database::getInstance()->execute('SELECT @@SESSION.wait_timeout as wTimeout, @@SESSION.interactive_timeout as iTimeout'); $waitTimeOut = $tmpResult->wTimeout; $interactiveTimeout = $tmpResult->iTimeout; //overwrite the default values if higher ones are defined in the settings if ($GLOBALS['TL_CONFIG']['syncCto_custom_settings'] == true && intval($GLOBALS['TL_CONFIG']['syncCto_wait_timeout']) > 0 && intval($GLOBALS['TL_CONFIG']['syncCto_interactive_timeout']) > 0) { $waitTimeOut = max($waitTimeOut, intval($GLOBALS['TL_CONFIG']['syncCto_wait_timeout'])); $interactiveTimeout = max($interactiveTimeout, intval($GLOBALS['TL_CONFIG']['syncCto_interactive_timeout'])); } \Database::getInstance()->prepare('SET SESSION wait_timeout = ?,SESSION interactive_timeout = ?;')->execute(intval($waitTimeOut), intval($interactiveTimeout)); switch (pathinfo($strRestoreFile, PATHINFO_EXTENSION)) { case "zip": $objZipRead = new ZipReader($strRestoreFile); // Get structure if ($objZipRead->getFile($this->strFilenameSyncCto)) { $zipPath = $pathBuilder->addPath('system/tmp')->addUnknownPath(sprintf('%s.gz', $this->strFilenameSyncCto))->getPath(false); $objGzFile = new File($zipPath); $objGzFile->write($objZipRead->unzip()); $objGzFile->close(); $arrRestoreTables = $this->runRestoreFromXML("system/tmp/{$this->strFilenameSyncCto}.gz"); } else { $strRestoreFile = $pathBuilder->addUnknownPath($strRestoreFile)->getPath(false); $arrRestoreTables = $this->runRestoreFromSer($strRestoreFile); } break; case "synccto": $strRestoreFile = $pathBuilder->addUnknownPath($strRestoreFile)->getPath(false); $arrRestoreTables = $this->runRestoreFromXML($strRestoreFile); break; default: throw new Exception("Not supportet or Unknown file type."); break; } // After insert, call some SQL if (is_array($arrSuffixSQL)) { foreach ($arrSuffixSQL as $key => $value) { $this->Database->query($value['query']); } } // Rename temp tables foreach ($arrRestoreTables as $key => $value) { $this->Database->query("DROP TABLE IF EXISTS " . $value); $this->Database->query("RENAME TABLE " . "synccto_temp_" . $value . " TO " . $value); } } catch (Exception $exc) { // Drop synccto_temp tables foreach ($this->Database->listTables() as $key => $value) { if (preg_match("/synccto_temp_.*/", $value)) { $this->Database->query("DROP TABLE IF EXISTS {$value}"); } } throw $exc; } // Drop synccto_temp tables foreach ($this->Database->listTables() as $key => $value) { if (preg_match("/synccto_temp_.*/", $value)) { $this->Database->query("DROP TABLE IF EXISTS {$value}"); } } return $arrSuffixSQL; }