public function prepare() { $routeParts = Route::getInstance()->match(); // There are 2 types of results to display // 1 - Display an already evaluated file which results were stored on the server. Just need the id. e.g : results?id=162804c3c358267d3a16855686ab1887 // 2 - Unknown file. Need $_FILES and $_POST["filetype"] if (isset($routeParts["ut"])) { $path_item = TC_ROOTDIR . '/include/unittests/'; $filename = urldecode($routeParts["ut"]); if (!(substr($filename, -4) == ".zip" && file_exists($path_item . $filename))) { echo $path_item . $filename . ' does not exist. Cannot continue'; die; } $themeInfo = FileValidator::prepareThemeInfo($path_item . $filename, $filename, 'application/zip', false); $this->fileValidator = new FileValidator($themeInfo); $this->fileValidator->validate(); $this->validationResults = $this->fileValidator->getValidationResults(I18N::getCurLang()); } else { if (isset($routeParts["hash"])) { $hash = $routeParts["hash"]; $this->fileValidator = FileValidator::unserialize($hash); $themeInfo = $this->fileValidator->themeInfo; $checkfiles = scandir(TC_INCDIR . '/Checks'); $youngestCheckTimestamp = 0; foreach ($checkfiles as $f) { if ($f == '.' || $f == '..') { continue; } $m = filemtime(TC_INCDIR . '/Checks/' . $f); if ($youngestCheckTimestamp < $m) { $youngestCheckTimestamp = $m; } } if ($this->fileValidator->themeInfo->validationDate < $youngestCheckTimestamp) { $this->fileValidator->validate(); if (UserMessage::getCount(ERRORLEVEL_FATAL) == 0) { // serialize only if no fatal errors $this->fileValidator->serialize(true); } } $this->validationResults = $this->fileValidator->getValidationResults(I18N::getCurLang()); } else { if (count($_FILES) > 0 && isset($_FILES["file"]) && !empty($_FILES["file"]["name"])) { if (TC_ENVIRONMENT == "dev" || isset($_SESSION['token_' . $_POST['token']])) { unset($_SESSION['token_' . $_POST['token']]); $themeInfo = FileValidator::upload(); if ($themeInfo) { $this->fileValidator = new FileValidator($themeInfo); $this->fileValidator->validate(); if (isset($_POST["donotstore"]) || UserMessage::getCount(ERRORLEVEL_FATAL) > 0) { $this->fileValidator->clean(); } else { $this->fileValidator->serialize(true); } $this->validationResults = $this->fileValidator->getValidationResults(I18N::getCurLang()); if (isset($_POST["donotstore"])) { $this->inlinescripts[] = "ga('send', 'event', 'theme', 'submit', 'not stored');"; } else { $this->inlinescripts[] = "ga('send', 'event', 'theme', 'submit', 'stored');"; } } } else { UserMessage::enqueue(__("Unvalid form"), ERRORLEVEL_FATAL); } } else { UserMessage::enqueue(__("No file uploaded."), ERRORLEVEL_FATAL); $this->meta["title"] = __("No file uploaded"); $this->meta["description"] = __("No file uploaded"); return; } } } if (!empty($themeInfo)) { if ($themeInfo->themetype == TT_JOOMLA) { $this->meta["title"] = sprintf(__("%s%% : Joomla template %s"), htmlspecialchars($themeInfo->score), htmlspecialchars($themeInfo->name)); $this->meta["description"] = sprintf(__("Security and code quality score of Joomla template %s."), htmlspecialchars($themeInfo->name)); } else { $this->meta["title"] = sprintf(__("%s%% : Wordpress theme %s"), htmlspecialchars($themeInfo->score), htmlspecialchars($themeInfo->name)); $this->meta["description"] = sprintf(__("Security and code quality score of Wordpress theme %s."), htmlspecialchars($themeInfo->name)); } if ($themeInfo->score < 100.0) { if ($themeInfo->score > 95) { $this->meta["favicon"] = "favicon100"; } else { if ($themeInfo->score > 80) { $this->meta["favicon"] = "favicon95"; } else { $this->meta["favicon"] = "favicon80"; } } } } else { $this->meta["title"] = __("Check results"); $this->meta["description"] = __("Security and code quality score"); } global $ExistingLangs; foreach ($ExistingLangs as $l) { if ($this->fileValidator) { $themeInfo = $this->fileValidator->themeInfo; if (!empty($themeInfo) && $themeInfo->serializable && USE_DB) { $this->samepage_i18n[$l] = TC_HTTPDOMAIN . '/' . Route::getInstance()->assemble(array("lang" => $l, "phpfile" => "results", "hash" => $themeInfo->hash)); } else { $this->samepage_i18n[$l] = null; } } else { $this->samepage_i18n[$l] = TC_HTTPDOMAIN . '/' . Route::getInstance()->assemble(array("lang" => $l, "phpfile" => "results")); } } }
/** * Generate a hash, move or copy the archive and return a ThemeInfo object **/ public static function prepareThemeInfo($src_path, $src_name, $src_type, $isUpload = false) { $src_size = filesize($src_path); if (!($src_size > 100 || strpos($src_path, '/unittests/') !== false)) { $userMessage = UserMessage::getInstance(); $userMessage->enqueueMessage(__('Files under 100 bytes are not accepted. Operation canceled.'), ERRORLEVEL_CRITICAL); return null; } $hash_md5 = md5_file($src_path); $sha1_file = sha1_file($src_path); $hash_alpha = base_convert($hash_md5, 16, 36); // shorten hash to shorten urls (better looking, less bandwidth) while (strlen($hash_alpha) < 25) { $hash_alpha = '0' . $hash_alpha; } $zipfilepath = self::hashToPathUpload($hash_alpha); if ($isUpload) { move_uploaded_file($src_path, $zipfilepath); } else { copy($src_path, $zipfilepath); } // copy the file (overwrites if already existing) try { $zip = new \ZipArchive(); $path = TC_ROOTDIR . '/../themecheck_vault/unzip'; if (!file_exists($path)) { trigger_error('Directory TC_ROOTDIR/../themecheck_vault/unzip does not exist', E_USER_ERROR); } $unzippath = $path . '/' . $hash_alpha . "/"; $res = $zip->open($zipfilepath); if ($res === TRUE) { if (file_exists($unzippath)) { ListDirectoryFiles::recursiveRemoveDir($unzippath); } // needed to avoid keeping old files that don't exist anymore in the new archive $zip->extractTo($unzippath); $zip->close(); } else { UserMessage::enqueue(__("File could not be unzipped."), ERRORLEVEL_FATAL); } } catch (Exception $e) { UserMessage::enqueue(__("Archive extraction failed. The following exception occured : ") . $e->getMessage(), ERRORLEVEL_FATAL); } // create a theme info $themeInfo = new ThemeInfo($hash_alpha); $themeInfo->hash_md5 = $hash_md5; $themeInfo->hash_sha1 = $sha1_file; $r = $themeInfo->initFromUnzippedArchive($unzippath, $src_name, $src_type, $src_size); if (!empty($themeInfo->parentName)) { $history = new History(); $fewInfo = $history->getFewInfoFromName($themeInfo->parentName); if (!empty($fewInfo["id"])) { $themeInfo->parentId = intval($fewInfo["id"]); } $themeInfo->parentNameSanitized = $fewInfo["namesanitized"]; $themeInfo->parentThemeType = $fewInfo["themetype"]; } if (!$r) { return null; } return $themeInfo; }
/** * Auto detect theme type **/ public static function detectThemetype($unzippath) { $files = listdir($unzippath); $score_wordpress = 0; $score_joomla = 0; $hasparenttemplate = false; $stylecss = false; $indexphp = false; $templateDetails = false; if ($files) { foreach ($files as $key => $filename) { $path_parts = pathinfo($filename); $basename = $path_parts['basename']; if ($basename == 'style.css') { $file_content = file_get_contents($filename); if (preg_match('/[ \\t\\/*#]*Theme Name:/i', $file_content) | preg_match('/[ \\t\\/*#]*Description:/i', $file_content) | preg_match('/[ \\t\\/*#]*Author:/i', $file_content)) { $score_wordpress++; } if (preg_match('/[ \\t\\/*#]*Template/i', $file_content)) { $hasparenttemplate = true; } $stylecss = true; } if ($basename == 'screenshot.png') { $score_wordpress++; } if ($basename == 'screenshot.jpg') { $score_wordpress++; } if ($basename == 'templateDetails.xml') { $score_joomla++; $templateDetails = true; } if ($basename == 'templatedetails.xml') { UserMessage::enqueue(__("Invalid joomla template. templatedetails.xml found. Please rename it templateDetails.xml (capital D)"), ERRORLEVEL_FATAL); } if ($basename == 'template_thumbnail.png') { $score_joomla++; } if ($basename == 'template_preview.png') { $score_joomla++; } if ($basename == 'index.php') { $file_content = file_get_contents($filename); if (preg_match('/get_header\\s?\\(\\s?\\)/', $file_content) && preg_match('/get_footer\\s?\\(\\s?\\)/', $file_content)) { $score_wordpress++; } if (strpos($file_content, "'_JEXEC'") !== false) { $score_joomla++; } $indexphp = true; } } } if ($score_joomla > $score_wordpress && $templateDetails) { return TT_JOOMLA; } if ($score_joomla < $score_wordpress && $stylecss) { if (!$indexphp && $hasparenttemplate) { return TT_WORDPRESS_CHILD; } return TT_WORDPRESS; } return TT_UNDEFINED; }