/** * Execute the action. */ public function execute() { // get parameters $this->currentTheme = $this->getParameter('theme', 'string'); // does the item exist if ($this->currentTheme !== null && BackendExtensionsModel::existsTheme($this->currentTheme)) { // call parent, this will probably add some general CSS/JS or other required files parent::execute(); // make sure this theme can be installed $this->validateInstall(); try { // do the actual install BackendExtensionsModel::installTheme($this->currentTheme); // redirect to index with a success message $this->redirect(BackendModel::createURLForAction('Themes') . '&report=theme-installed&var=' . $this->currentTheme); } catch (Exception $e) { // redirect to index with a success message $this->redirect(BackendModel::createURLForAction('Themes') . '&report=information-file-is-empty&var=' . $this->currentTheme); } } else { // no item found, redirect to index, because somebody is f*****g with our url $this->redirect(BackendModel::createURLForAction('Themes') . '&error=non-existing'); } }
/** * Validate a submitted form and process it. */ private function validateForm() { // The form is submitted if (!$this->frm->isSubmitted()) { return; } /** @var $fileFile \SpoonFormFile */ $fileFile = $this->frm->getField('file'); $zip = null; $zipFiles = null; // Validate the file. Check if the file field is filled and if it's a zip. if ($fileFile->isFilled(BL::err('FieldIsRequired')) && $fileFile->isAllowedExtension(array('zip'), sprintf(BL::getError('ExtensionNotAllowed'), 'zip'))) { // Create ziparchive instance $zip = new ZipArchive(); // Try and open it if ($zip->open($fileFile->getTempFileName()) === true) { // zip file needs to contain some files if ($zip->numFiles > 0) { $infoXml = $this->findInfoFileInZip($zip); // Throw error if info.xml is not found if ($infoXml === null) { return $fileFile->addError(sprintf(BL::getError('NoInformationFile'), $fileFile->getFileName())); } // Parse xml try { // Load info.xml $infoXml = @new \SimpleXMLElement($infoXml, LIBXML_NOCDATA, false); // Convert xml to useful array $this->info = BackendExtensionsModel::processThemeXml($infoXml); // Empty data (nothing useful) if (empty($this->info)) { return $fileFile->addError(BL::getMessage('InformationFileIsEmpty')); } // Define the theme name, based on the info.xml file. $this->themeName = $this->info['name']; } catch (Exception $e) { // Warning that the information file is corrupt return $fileFile->addError(BL::getMessage('InformationFileCouldNotBeLoaded')); } // Wow wow, you are trying to upload an already existing theme if (BackendExtensionsModel::existsTheme($this->themeName)) { return $fileFile->addError(sprintf(BL::getError('ThemeAlreadyExists'), $this->themeName)); } $zipFiles = $this->getValidatedFilesList($zip); } else { // Empty zip file $fileFile->addError(BL::getError('FileIsEmpty')); } } else { // Something went very wrong, probably corrupted return $fileFile->addError(BL::getError('CorruptedFile')); } } // Passed all validation if ($this->frm->isCorrect() && $zip !== null) { // Unpack the zip. If the files were not found inside a parent directory, we create the theme directory. $themePath = FRONTEND_PATH . '/Themes'; if ($this->parentFolderName === null) { $themePath .= "/{$this->themeName}"; } $zip->extractTo($themePath, $zipFiles); // Rename the original name of the parent folder from the zip to the correct theme foldername. $fs = new Filesystem(); $parentZipFolderPath = $themePath . '/' . $this->parentFolderName; if ($this->parentFolderName !== $this->themeName && $this->parentFolderName !== null && $fs->exists($parentZipFolderPath)) { $fs->rename($parentZipFolderPath, "{$themePath}/{$this->themeName}"); } // Run installer BackendExtensionsModel::installTheme($this->themeName); // Redirect with fireworks $this->redirect(BackendModel::createURLForAction('Themes') . '&report=theme-installed&var=' . $this->themeName); } }
/** * Validate a submitted form and process it. */ private function validateForm() { // the form is submitted if ($this->frm->isSubmitted()) { // shorten field variables /** @var $fileFile \SpoonFormFile */ $fileFile = $this->frm->getField('file'); // validate the file if ($fileFile->isFilled(BL::err('FieldIsRequired'))) { // only zip files allowed if ($fileFile->isAllowedExtension(array('zip'), sprintf(BL::getError('ExtensionNotAllowed'), 'zip'))) { // create ziparchive instance $zip = new \ZipArchive(); // try and open it if ($zip->open($fileFile->getTempFileName()) === true) { // zip file needs to contain some files if ($zip->numFiles > 0) { // get first entry (= the theme folder) $file = $zip->statIndex(0); // name of the module we are trying to upload $themeName = trim($file['name'], '/'); // find info.xml $infoXml = $zip->getFromName($themeName . '/info.xml'); // add error if info.xml is not found if ($infoXml === false) { $fileFile->addError(sprintf(BL::getError('NoInformationFile'), $themeName)); } else { // parse xml try { // load info.xml $infoXml = @new \SimpleXMLElement($infoXml, LIBXML_NOCDATA, false); // convert xml to useful array $this->information = BackendExtensionsModel::processThemeXml($infoXml); // empty data (nothing useful) if (empty($this->information)) { $fileFile->addError(BL::getMessage('InformationFileIsEmpty')); } // check if theme name in info.xml matches folder name if ($this->information['name'] != $themeName) { $fileFile->addError(BL::err('ThemeNameDoesntMatch')); } } catch (\Exception $e) { // warning that the information file is corrupt $fileFile->addError(BL::getMessage('InformationFileCouldNotBeLoaded')); } } // wow wow, you are trying to upload an already existing theme if (BackendExtensionsModel::existsTheme($themeName)) { $fileFile->addError(sprintf(BL::getError('ThemeAlreadyExists'), $themeName)); } // list of validated files (these files will actually be unpacked) $files = array(); // check every file in the zip for ($i = 0; $i < $zip->numFiles; $i++) { // get the file name $file = $zip->statIndex($i); $fileName = $file['name']; // yay, in a valid directory if (stripos($fileName, $themeName . '/') === 0) { // valid file, add to extraction-list $files[] = $fileName; } } } else { // empty zip file $fileFile->addError(BL::getError('FileIsEmpty')); } } else { // something went very wrong, probably corrupted $fileFile->addError(BL::getError('CorruptedFile')); } } } // passed all validation if ($this->frm->isCorrect()) { // unpack module files $zip->extractTo(FRONTEND_PATH . '/Themes', $files); // run installer BackendExtensionsModel::installTheme($themeName); // redirect with fireworks $this->redirect(BackendModel::createURLForAction('Themes') . '&report=theme-installed&var=' . $themeName); } } }