/** * Returns all available commands. * * @return array<\wcf\system\cli\command\ICLICommand> */ public static function getCommands() { if (empty(self::$commands)) { $directory = DirectoryUtil::getInstance(WCF_DIR . 'lib/system/cli/command/'); $commands = $directory->getFiles(SORT_ASC, new Regex('Command\\.class\\.php$')); foreach ($commands as $command) { $class = 'wcf\\system\\cli\\command\\' . basename($command, '.class.php'); if (!class_exists($class) && !interface_exists($class)) { Log::info('Invalid command file: ', $command); continue; } if (!class_exists($class)) { continue; } $object = new $class(); if (!$object instanceof ICLICommand) { Log::info('Invalid command file: ', $command); continue; } if (!$object->canAccess()) { continue; } self::$commands[strtolower(basename($command, 'CLICommand.class.php'))] = $object; } } return self::$commands; }
/** * Deletes the folders of this template group. */ public function deleteFolders() { // default template dir $folders = array(WCF_DIR . 'templates/' . $this->templateGroupFolderName); // get package dirs $sql = "SELECT\tpackageDir\n\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\tWHERE\tpackageDir <> ''"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(); while ($row = $statement->fetchArray()) { $packageDir = FileUtil::getRealPath(WCF_DIR . $row['packageDir']); DirectoryUtil::getInstance($packageDir . 'templates/' . $this->templateGroupFolderName)->deleteAll(); } }
/** * Deletes the folder of this template group. */ public function deleteFolder() { if (file_exists(WCF_DIR . 'templates/' . $this->templateGroupFolderName)) { DirectoryUtil::getInstance(WCF_DIR . 'templates/' . $this->templateGroupFolderName)->removeAll(); } // check template group folders in other applications $sql = "SELECT\tDISTINCT application\n\t\t\tFROM\twcf" . WCF_N . "_template\n\t\t\tWHERE\ttemplateGroupID = ?\n\t\t\t\tAND application <> ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($this->templateGroupID, 'wcf')); while ($row = $statement->fetchArray()) { $application = ApplicationHandler::getInstance()->getApplication($row['application']); $package = PackageCache::getInstance()->getPackage($application->packageID); if (file_exists(WCF_DIR . $package->packageDir . 'templates/' . $this->templateGroupFolderName)) { DirectoryUtil::getInstance(WCF_DIR . $package->packageDir . 'templates/' . $this->templateGroupFolderName)->removeAll(); } } }
/** * Deletes the compiled files of this template. */ public function deleteCompiledFiles() { DirectoryUtil::getInstance(WCF_DIR . 'templates/compiled/')->removePattern(new Regex(intval($this->packageID) . '_.*_' . preg_quote($this->templateName) . '.php$')); }
/** * Deletes relevant template compilations. */ public function deleteCompiledTemplates() { // templates DirectoryUtil::getInstance(WCF_DIR . 'templates/compiled/')->removePattern(new Regex('.*_' . $this->languageID . '_.*\\.php$')); // acp templates DirectoryUtil::getInstance(WCF_DIR . 'acp/templates/compiled/')->removePattern(new Regex('.*_' . $this->languageID . '_.*\\.php$')); }
/** * Returns an array with the list of all available workers. * * @return array */ public function generateList() { $directory = DirectoryUtil::getInstance(WCF_DIR . 'lib/system/worker/'); $workerList = $directory->getFiles(SORT_ASC, new Regex('Worker\\.class\\.php$')); $table = array(array('Class', 'Description')); foreach ($workerList as $worker) { $class = 'wcf\\system\\worker\\' . basename($worker, '.class.php'); if (!class_exists($class) && !interface_exists($class)) { Log::info('Invalid worker file: ', $worker); continue; } $reflection = new \ReflectionClass($class); if (!$reflection->isInstantiable()) { continue; } if (!ClassUtil::isInstanceOf($class, 'wcf\\system\\worker\\IWorker')) { Log::info('Invalid worker file: ', $worker); continue; } $docComment = explode("\n", StringUtil::unifyNewlines($reflection->getDocComment())); foreach ($docComment as $commentLine) { if (Regex::compile('[a-z]', Regex::CASE_INSENSITIVE)->match($commentLine)) { $comment = Regex::compile('^[^a-z]+', Regex::CASE_INSENSITIVE)->replace($commentLine, ''); break; } } $table[] = array(basename($worker, '.class.php'), $comment); } return $table; }
public function handleImport($filename) { //clean all foreach ($this->objects as $object) { if ($object == 'folder') { $actionName = '\\wcf\\data\\category\\CategoryAction'; } else { $actionName = '\\cms\\data\\' . $object . '\\' . ucfirst($object) . 'Action'; } $action = new $actionName($this->{$object . 's'}, 'delete'); $action->executeAction(); } if (file_exists(CMS_DIR . 'files/')) { DirectoryUtil::getInstance(CMS_DIR . 'files/')->removeAll(); } // get available languages $availableLanguages = LanguageFactory::getInstance()->getLanguages(); $this->openTar($filename); //import all foreach ($this->objects as $object) { // check if there is something to import if (isset($this->data[$object . 's'])) { // temp store parent ids $parentIDs = array(); $upperObjectIDs = array(); // go through every single object foreach ($this->data[$object . 's'] as $import) { $currentID = isset($import[$object . 'ID']) ? $import[$object . 'ID'] : ($object == 'folder' ? $import['categoryID'] : null); $langData = array(); // unset current id to be save if (isset($import[$object . 'ID'])) { unset($import[$object . 'ID']); } // check parent ids if ($object == 'page' || $object == 'content') { if (isset($import['parentID']) && $import['parentID'] != '') { if (isset($this->tmp[$object . 's'][$import['parentID']])) { // get new id for parent, if parent has been already processed $import['parentID'] = $this->tmp[$object . 's'][$import['parentID']]; } else { // set when everything is imported $parentIDs[$currentID] = $import['parentID']; unset($import['parentID']); } } } // obsolete columns for pages if ($object == 'page') { if (isset($import['robots'])) { unset($import['robots']); } if (isset($import['showSidebar'])) { unset($import['showSidebar']); } if (isset($import['styleID']) && $import['styleID'] == '') { $import['styleID'] = null; } if (isset($import['authorID'])) { $import['authorID'] = null; } if (isset($import['lastEditorID'])) { $import['lastEditorID'] = null; } // save stylesheets if (isset($import['stylesheets'])) { $tmpStylesheets = base64_decode($import['stylesheets']); if ($this->is_serialized($tmpStylesheets)) { $tmpStylesheets = unserialize($tmpStylesheets); if (!empty($tmpStylesheets)) { $upperObjectIDs[$currentID] = $tmpStylesheets; } } unset($import['stylesheets']); } // multilingual title $tmpTitle = base64_decode($import['title']); if ($this->is_serialized($tmpTitle)) { $tmpTitle = unserialize($tmpTitle); foreach ($availableLanguages as $lang) { if (isset($tmpTitle[$lang->countryCode])) { $langData['title'][$lang->languageID] = $tmpTitle[$lang->countryCode]; } else { $langData['title'][$lang->languageID] = ''; } } $import['title'] = ''; } else { $import['title'] = $tmpTitle; } // multilingual description $tmpDescription = base64_decode($import['description']); if ($this->is_serialized($tmpDescription)) { $tmpDescription = unserialize($tmpDescription); foreach ($availableLanguages as $lang) { if (isset($tmpDescription[$lang->countryCode])) { $langData['description'][$lang->languageID] = $tmpDescription[$lang->countryCode]; } else { $langData['description'][$lang->languageID] = ''; } } $import['description'] = ''; } else { $import['description'] = $tmpDescription; } // multilingual meta description $tmpMetaDescription = base64_decode($import['metaDescription']); if ($this->is_serialized($tmpMetaDescription)) { $tmpMetaDescription = unserialize($tmpMetaDescription); foreach ($availableLanguages as $lang) { if (isset($tmpMetaDescription[$lang->countryCode])) { $langData['metaDescription'][$lang->languageID] = $tmpMetaDescription[$lang->countryCode]; } else { $langData['metaDescription'][$lang->languageID] = ''; } } $import['metaDescription'] = ''; } else { $import['metaDescription'] = $tmpMetaDescription; } // multilingual description $tmpMetaKeywords = base64_decode($import['metaKeywords']); if ($this->is_serialized($tmpMetaKeywords)) { $tmpMetaKeywords = unserialize($tmpMetaKeywords); foreach ($availableLanguages as $lang) { if (isset($tmpMetaKeywords[$lang->countryCode])) { $langData['metaKeywords'][$lang->languageID] = $tmpMetaKeywords[$lang->countryCode]; } else { $langData['metaKeywords'][$lang->languageID] = ''; } } $import['metaKeywords'] = ''; } else { $import['metaKeywords'] = $tmpMetaKeywords; } } // obsolete columns for files if ($object == 'file') { if (isset($import['size'])) { $import['filesize'] = $import['size']; unset($import['size']); } if (isset($import['type'])) { $import['fileType'] = $import['type']; unset($import['type']); } // save folders -- compatibility mode if (isset($import['folderID'])) { $upperObjectIDs[$currentID] = array($import['folderID']); unset($import['folderID']); } if (isset($import['filename'])) { unset($import['filename']); } // save folders if (isset($import['categoryIDs'])) { $tmpCategoryIDs = base64_decode($import['categoryIDs']); if ($this->is_serialized($tmpCategoryIDs)) { $upperObjectIDs[$currentID] = unserialize($tmpCategoryIDs); } unset($import['categoryIDs']); } } // columns for folders if ($object == 'folder') { $import['objectTypeID'] = $this->categoryObjectType->objectTypeID; if (isset($import['folderName'])) { $import['title'] = $import['folderName']; unset($import['folderName']); } if (isset($import['folderPath'])) { unset($import['folderPath']); } if (!isset($import['description'])) { $import['description'] = ''; } // multilingual title $tmpTitle = base64_decode($import['title']); if ($this->is_serialized($tmpTitle)) { $tmpTitle = unserialize($tmpTitle); foreach ($availableLanguages as $lang) { if (isset($tmpTitle[$lang->countryCode])) { $langData['title'][$lang->languageID] = $tmpTitle[$lang->countryCode]; } else { $langData['title'][$lang->languageID] = ''; } } $import['title'] = ''; } else { $import['title'] = $tmpTitle; } // multilingual description $tmpDescription = base64_decode($import['description']); if ($this->is_serialized($tmpDescription)) { $tmpDescription = unserialize($tmpDescription); foreach ($availableLanguages as $lang) { if (isset($tmpDescription[$lang->countryCode])) { $langData['description'][$lang->languageID] = $tmpDescription[$lang->countryCode]; } else { $langData['description'][$lang->languageID] = ''; } } $import['description'] = ''; } else { $import['description'] = $tmpDescription; } } // columns for contents if ($object == 'content') { $import['pageID'] = $this->tmp['pages'][$import['pageID']]; $import['contentData'] = base64_decode($import['contentData']); // multilingual title $tmpTitle = base64_decode($import['title']); if ($this->is_serialized($tmpTitle)) { $tmpTitle = unserialize($tmpTitle); foreach ($availableLanguages as $lang) { if (isset($tmpTitle[$lang->countryCode])) { $langData['title'][$lang->languageID] = $tmpTitle[$lang->countryCode]; } else { $langData['title'][$lang->languageID] = ''; } } $import['title'] = ''; } else { $import['title'] = $tmpTitle; } // multilingual text? if ($this->is_serialized($import['contentData'])) { $tmpData = unserialize($import['contentData']); // text || php if (isset($tmpData['text'])) { $tmpText = $tmpData['text']; if ($this->is_serialized($tmpText)) { $tmpText = unserialize($tmpText); foreach ($availableLanguages as $lang) { if (isset($tmpText[$lang->countryCode])) { // replace bbcode and urls $tmpText[$lang->countryCode] = $this->replaceOldFileIDs($tmpText[$lang->countryCode]); $langData['text'][$lang->languageID] = $tmpText[$lang->countryCode]; } else { $langData['text'][$lang->languageID] = ''; } } $tmpData['text'] = ''; } else { $tmpData['text'] = $this->replaceOldFileIDs($tmpData['text']); } } // headline with link if (isset($tmpData['link'])) { $tmpData['link'] = $this->replaceOldFileIDs($tmpData['link']); } // gallery if (isset($tmpData['imageIDs'])) { $imageIDs = array(); if (is_array($tmpData['imageIDs'])) { foreach ($tmpData['imageIDs'] as $fileID) { if (isset($this->tmp['files'][$fileID])) { $imageIDs[] = $this->tmp['files'][$fileID]; } } } else { $oldIDs = explode(',', $tmpData['imageIDs']); if (is_array($oldIDs) && !empty($oldIDs)) { foreach ($oldIDs as $fileID) { if (isset($this->tmp['files'][$fileID])) { $imageIDs[] = $this->tmp['files'][$fileID]; } } } } $tmpData['imageIDs'] = $imageIDs; } // image if (isset($tmpData['imageID'])) { if (isset($this->tmp['files'][$tmpData['imageID']])) { $tmpData['imageID'] = $this->tmp['files'][$tmpData['imageID']]; } else { $tmpData['imageID'] = null; } } // file if (isset($tmpData['fileID'])) { if (isset($this->tmp['files'][$tmpData['fileID']])) { $tmpData['fileID'] = $this->tmp['files'][$tmpData['fileID']]; } else { $tmpData['fileID'] = null; } } // template if (isset($tmpData['template'])) { $tmpData['template'] = $this->replaceOldFileIDs($tmpData['template']); } // get everything back serialized $import['contentData'] = serialize($tmpData); } } // get action class name if ($object == 'folder') { $actionName = '\\wcf\\data\\category\\CategoryAction'; } else { $actionName = '\\cms\\data\\' . $object . '\\' . ucfirst($object) . 'Action'; } $action = new $actionName(array(), 'create', array('data' => $import)); $new = $action->executeAction(); $new = $new['returnValues']; // save temp if ($object == 'folder') { $this->tmp[$object . 's'][$currentID] = $new->categoryID; } else { $this->tmp[$object . 's'][$currentID] = $new->{$object . 'ID'}; } // save lang items if (!empty($langData)) { foreach ($langData as $column => $values) { I18nHandler::getInstance()->setValues($column, $values); $this->saveI18nValue($new, $object, $column); } } } // set new parents if needed if ($object == 'page' || $object == 'content') { foreach ($parentIDs as $child => $parent) { $editorName = '\\cms\\data\\' . $object . '\\' . ucfirst($object) . 'Editor'; $className = '\\cms\\data\\' . $object . '\\' . ucfirst($object); $element = new $className($this->tmp[$object . 's'][$child]); if ($element !== null) { $editor = new $editorName($element); $update['parentID'] = $this->tmp[$object . 's'][$parent]; $editor->update($update); } } } // link stylesheets and pages if ($object == 'page') { foreach ($upperObjectIDs as $pageID => $stylesheetIDs) { $editorName = '\\cms\\data\\' . $object . '\\' . ucfirst($object) . 'Editor'; $className = '\\cms\\data\\' . $object . '\\' . ucfirst($object); $newStylesheetIDs = array(); foreach ($stylesheetIDs as $stylesheet) { if (isset($this->tmp['stylesheets'][$stylesheet])) { $newStylesheetIDs[] = $this->tmp['stylesheets'][$stylesheet]; } } $page = new $className($this->tmp[$object . 's'][$pageID]); if ($page !== null && !empty($newStylesheetIDs)) { $editor = new $editorName($page); $editor->updateStylesheetIDs($newStylesheetIDs); } } } // link files and folders if ($object == 'file') { foreach ($upperObjectIDs as $file => $folders) { $editorName = '\\cms\\data\\' . $object . '\\' . ucfirst($object) . 'Editor'; $className = '\\cms\\data\\' . $object . '\\' . ucfirst($object); $element = new $className($this->tmp[$object . 's'][$file]); $newFolders = array(); foreach ($folders as $folder) { if (isset($this->tmp['folders'][$folder])) { $newFolders[] = $this->tmp['folders'][$folder]; } } if ($element !== null) { $editor = new $editorName($element); $editor->updateCategoryIDs($newFolders); } } $this->importFiles($filename); } } } }
/** * Deletes all compiled templates. * * @param string $compileDir */ public static function deleteCompiledTemplates($compileDir = '') { if (empty($compileDir)) { $compileDir = WCF_DIR . 'templates/compiled/'; } // delete compiled templates DirectoryUtil::getInstance($compileDir)->removePattern(new Regex('.*_.*_.*\\.php$')); }
/** * Deletes the compiled files of this template. */ public function deleteCompiledFiles() { DirectoryUtil::getInstance(WCF_DIR . 'templates/compiled/')->removePattern(new Regex($this->templateGroupID . '_' . $this->application . '_.*_' . preg_quote($this->templateName) . '.php$')); }
/** * Removes files matching given pattern. * * @param string $pattern */ protected function removeFiles($pattern) { $directory = FileUtil::unifyDirSeperator(WCF_DIR.'cache/'); $pattern = str_replace('*', '.*', str_replace('.', '\.', $pattern)); DirectoryUtil::getInstance($directory)->executeCallback(new Callback(function ($filename) { if (!@touch($filename, 1)) { @unlink($filename); } }), new Regex('^'.$directory.$pattern.'$', Regex::CASE_INSENSITIVE)); }
/** * Registers with wcf setup delivered packages in the package installation queue. */ protected function installPackages() { // init database connection $this->initDB(); // get admin account $admin = new User(1); // get delivered packages $wcfPackageFile = ''; $otherPackages = array(); $tar = new Tar(SETUP_FILE); foreach ($tar->getContentList() as $file) { if ($file['type'] != 'folder' && mb_strpos($file['filename'], 'install/packages/') === 0) { $packageFile = basename($file['filename']); // ignore any files which aren't an archive if (preg_match('~\\.(tar\\.gz|tgz|tar)$~', $packageFile)) { $packageName = preg_replace('!\\.(tar\\.gz|tgz|tar)$!', '', $packageFile); if ($packageName == 'com.woltlab.wcf') { $wcfPackageFile = $packageFile; } else { $isStrato = !empty($_SERVER['DOCUMENT_ROOT']) && strpos($_SERVER['DOCUMENT_ROOT'], 'strato') !== false; if (!$isStrato && preg_match('!\\.(tar\\.gz|tgz)$!', $packageFile)) { // try to unzip zipped package files if (FileUtil::uncompressFile(TMP_DIR . 'install/packages/' . $packageFile, TMP_DIR . 'install/packages/' . $packageName . '.tar')) { @unlink(TMP_DIR . 'install/packages/' . $packageFile); $packageFile = $packageName . '.tar'; } } $otherPackages[$packageName] = $packageFile; } } } } $tar->close(); // register packages in queue // get new process id $sql = "SELECT\tMAX(processNo) AS processNo\n\t\t\tFROM\twcf" . WCF_N . "_package_installation_queue"; $statement = self::getDB()->prepareStatement($sql); $statement->execute(); $result = $statement->fetchArray(); $processNo = intval($result['processNo']) + 1; // search existing wcf package $sql = "SELECT\tCOUNT(*) AS count\n\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\tWHERE\tpackage = 'com.woltlab.wcf'"; $statement = self::getDB()->prepareStatement($sql); $statement->execute(); $row = $statement->fetchArray(); if (!$row['count']) { if (empty($wcfPackageFile)) { throw new SystemException('the essential package com.woltlab.wcf is missing.'); } // register essential wcf package $queue = PackageInstallationQueueEditor::create(array('processNo' => $processNo, 'userID' => $admin->userID, 'package' => 'com.woltlab.wcf', 'packageName' => 'WoltLab Community Framework', 'archive' => TMP_DIR . 'install/packages/' . $wcfPackageFile, 'isApplication' => 1)); } // register all other delivered packages asort($otherPackages); foreach ($otherPackages as $packageName => $packageFile) { // extract packageName from archive's package.xml $archive = new PackageArchive(TMP_DIR . 'install/packages/' . $packageFile); try { $archive->openArchive(); } catch (\Exception $e) { // we've encountered a broken archive, revert everything and then fail $sql = "SELECT\tqueueID, parentQueueID\n\t\t\t\t\tFROM\twcf" . WCF_N . "_package_installation_queue"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(); $queues = array(); while ($row = $statement->fetchArray()) { $queues[$row['queueID']] = $row['parentQueueID']; } $queueIDs = array(); $queueID = $queue->queueID; while ($queueID) { $queueIDs[] = $queueID; $queueID = isset($queues[$queueID]) ? $queues[$queueID] : 0; } // remove previously created queues if (!empty($queueIDs)) { $sql = "DELETE FROM\twcf" . WCF_N . "_package_installation_queue\n\t\t\t\t\t\tWHERE\t\tqueueID = ?"; $statement = WCF::getDB()->prepareStatement($sql); WCF::getDB()->beginTransaction(); foreach ($queueIDs as $queueID) { $statement->execute(array($queueID)); } WCF::getDB()->commitTransaction(); } // remove package files @unlink(TMP_DIR . 'install/packages/' . $wcfPackageFile); foreach ($otherPackages as $packageFile) { @unlink(TMP_DIR . 'install/packages/' . $packageFile); } // throw exception again throw new SystemException('', 0, '', $e); } $queue = PackageInstallationQueueEditor::create(array('parentQueueID' => $queue->queueID, 'processNo' => $processNo, 'userID' => $admin->userID, 'package' => $packageName, 'packageName' => $archive->getLocalizedPackageInfo('packageName'), 'archive' => TMP_DIR . 'install/packages/' . $packageFile, 'isApplication' => 1)); } // login as admin $factory = new ACPSessionFactory(); $factory->load(); SessionHandler::getInstance()->changeUser($admin); SessionHandler::getInstance()->register('masterPassword', 1); SessionHandler::getInstance()->register('__wcfSetup_developerMode', self::$developerMode); SessionHandler::getInstance()->update(); $installPhpDeleted = @unlink('./install.php'); @unlink('./test.php'); $wcfSetupTarDeleted = @unlink('./WCFSetup.tar.gz'); // print page WCF::getTPL()->assign(array('installPhpDeleted' => $installPhpDeleted, 'wcfSetupTarDeleted' => $wcfSetupTarDeleted)); WCF::getTPL()->display('stepInstallPackages'); // delete tmp files $directory = TMP_DIR . '/'; DirectoryUtil::getInstance($directory)->removePattern(new Regex('\\.tar(\\.gz)?$'), true); }
/** * Reads the information of cached files * * @param string $cacheType * @param strign $cacheDir * @param wcf\system\Regex $ignore */ protected function readCacheFiles($cacheType, $cacheDir, Regex $ignore = null, $extension = 'php') { if (!isset($this->cacheData[$cacheType])) { $this->cacheData[$cacheType] = array(); } // get files in cache directory try { $directoryUtil = DirectoryUtil::getInstance($cacheDir); } catch (SystemException $e) { return; } $files = $directoryUtil->getFileObjects(SORT_ASC, new Regex('\.'.$extension.'$')); // get additional file information $data = array(); if (is_array($files)) { foreach ($files as $file) { if ($ignore !== null && $ignore->match($file)) { continue; } $data[] = array( 'filename' => $file->getBasename(), 'filesize' => $file->getSize(), 'mtime' => $file->getMtime(), 'perm' => substr(sprintf('%o', $file->getPerms()), -3), 'writable' => $file->isWritable() ); $this->cacheData['files']++; $this->cacheData['size'] += $file->getSize(); } } $this->caches[$cacheType][$cacheDir] = $data; }
/** * @see \wcf\page\IPage::readData() */ public function readData() { AbstractPage::readData(); $fileNameRegex = new Regex('(?:^|/)\\d{4}-\\d{2}-\\d{2}\\.txt$'); $this->logFiles = DirectoryUtil::getInstance(WCF_DIR . 'log/')->getFiles(SORT_DESC, $fileNameRegex); if ($this->exceptionID) { // search the appropriate file foreach ($this->logFiles as $logFile) { $contents = file_get_contents($logFile); if (mb_strpos($contents, '<<<<<<<<' . $this->exceptionID . '<<<<') !== false) { $fileNameRegex->match($logFile); $matches = $fileNameRegex->getMatches(); $this->logFile = $matches[0]; break; } unset($contents); } if (!isset($contents)) { $this->logFile = ''; return; } } else { if ($this->logFile) { if (!$fileNameRegex->match(basename($this->logFile))) { throw new IllegalLinkException(); } if (!file_exists(WCF_DIR . 'log/' . $this->logFile)) { throw new IllegalLinkException(); } $contents = file_get_contents(WCF_DIR . 'log/' . $this->logFile); } else { return; } } // unify newlines $contents = StringUtil::unifyNewlines($contents); // split contents $split = new Regex('(?:^|\\n<<<<\\n\\n)(?:<<<<<<<<([a-f0-9]{40})<<<<\\n|$)'); $contents = $split->split($contents, Regex::SPLIT_NON_EMPTY_ONLY | Regex::CAPTURE_SPLIT_DELIMITER); // even items become keys, odd items become values try { $this->exceptions = call_user_func_array('array_merge', array_map(function ($v) { return array($v[0] => $v[1]); }, array_chunk($contents, 2))); } catch (\Exception $e) { // logfile contents are pretty malformed, abort return; } if ($this->exceptionID) { $this->searchPage($this->exceptionID); } $this->calculateNumberOfPages(); $i = 0; $exceptionRegex = new Regex('(?P<date>[MTWFS][a-z]{2}, \\d{1,2} [JFMASOND][a-z]{2} \\d{4} \\d{2}:\\d{2}:\\d{2} [+-]\\d{4}) Message: (?P<message>.*?) File: (?P<file>.*?) \\((?P<line>\\d+)\\) PHP version: (?P<phpVersion>.*?) WCF version: (?P<wcfVersion>.*?) Request URI: (?P<requestURI>.*?) Referrer: (?P<referrer>.*?) User-Agent: (?P<userAgent>.*?) Information: (?P<information>.*?) Stacktrace: (?P<stacktrace>.*)', Regex::DOT_ALL); $stackTraceFormatter = new Regex('^\\s+(#\\d+)', Regex::MULTILINE); foreach ($this->exceptions as $key => $val) { $i++; if ($i < $this->startIndex || $i > $this->endIndex) { unset($this->exceptions[$key]); continue; } if (!$exceptionRegex->match($val)) { unset($this->exceptions[$key]); continue; } $this->exceptions[$key] = $exceptionRegex->getMatches(); $this->exceptions[$key]['stacktrace'] = explode("\n", $stackTraceFormatter->replace(StringUtil::encodeHTML($this->exceptions[$key]['stacktrace']), '<strong>\\1</strong>')); $this->exceptions[$key]['information'] = JSON::decode($this->exceptions[$key]['information']); } }
/** * @see \wcf\system\cronjob\ICronjob::execute() */ public function execute(Cronjob $cronjob) { parent::execute($cronjob); // clean up search keywords $sql = "SELECT\tAVG(searches) AS searches\n\t\t\tFROM\twcf" . WCF_N . "_search_keyword"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(); if (($row = $statement->fetchArray()) !== false) { $sql = "DELETE FROM\twcf" . WCF_N . "_search_keyword\n\t\t\t\tWHERE\t\tsearches <= ?\n\t\t\t\t\t\tAND lastSearchTime < ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(floor($row['searches'] / 4), TIME_NOW - 86400 * 30)); } // clean up notifications $sql = "DELETE FROM\twcf" . WCF_N . "_user_notification\n\t\t\tWHERE\t\ttime < ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(TIME_NOW - 86400 * USER_CLEANUP_NOTIFICATION_LIFETIME)); // clean up user activity events $sql = "DELETE FROM\twcf" . WCF_N . "_user_activity_event\n\t\t\tWHERE\t\ttime < ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(TIME_NOW - 86400 * USER_CLEANUP_ACTIVITY_EVENT_LIFETIME)); // clean up profile visitors $sql = "DELETE FROM\twcf" . WCF_N . "_user_profile_visitor\n\t\t\tWHERE\t\ttime < ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(TIME_NOW - 86400 * USER_CLEANUP_PROFILE_VISITOR_LIFETIME)); // tracked visits $sql = "DELETE FROM\twcf" . WCF_N . "_tracked_visit\n\t\t\tWHERE\t\tobjectTypeID = ?\n\t\t\t\t\tAND visitTime < ?"; $statement1 = WCF::getDB()->prepareStatement($sql); $sql = "DELETE FROM\twcf" . WCF_N . "_tracked_visit_type\n\t\t\tWHERE\t\tobjectTypeID = ?\n\t\t\t\t\tAND visitTime < ?"; $statement2 = WCF::getDB()->prepareStatement($sql); WCF::getDB()->beginTransaction(); foreach (ObjectTypeCache::getInstance()->getObjectTypes('com.woltlab.wcf.visitTracker.objectType') as $objectType) { // get lifetime $lifetime = $objectType->lifetime ?: VisitTracker::DEFAULT_LIFETIME; // delete data $statement1->execute(array($objectType->objectTypeID, $lifetime)); $statement2->execute(array($objectType->objectTypeID, $lifetime)); } WCF::getDB()->commitTransaction(); // clean up cronjob log $sql = "DELETE FROM\twcf" . WCF_N . "_cronjob_log\n\t\t\tWHERE\t\texecTime < ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(TIME_NOW - 86400 * 7)); // clean up session access log $sql = "DELETE FROM\twcf" . WCF_N . "_acp_session_access_log\n\t\t\tWHERE\t\tsessionLogID IN (\n\t\t\t\t\t\tSELECT\tsessionLogID\n\t\t\t\t\t\tFROM\twcf" . WCF_N . "_acp_session_log\n\t\t\t\t\t\tWHERE\tlastActivityTime < ?\n\t\t\t\t\t)"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(TIME_NOW - 86400 * 30)); // clean up session log $sql = "DELETE FROM\twcf" . WCF_N . "_acp_session_log\n\t\t\tWHERE\t\tlastActivityTime < ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(TIME_NOW - 86400 * 30)); // clean up search data $sql = "DELETE FROM\twcf" . WCF_N . "_search\n\t\t\tWHERE\t\tsearchTime < ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(TIME_NOW - 86400)); // clean up expired edit history entries if (MODULE_EDIT_HISTORY) { if (EDIT_HISTORY_EXPIRATION) { $sql = "DELETE FROM\twcf" . WCF_N . "_edit_history_entry\n\t\t\t\t\tWHERE\t\tobsoletedAt < ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(TIME_NOW - 86400 * EDIT_HISTORY_EXPIRATION)); } } else { // edit history is disabled, prune old versions $sql = "DELETE FROM\twcf" . WCF_N . "_edit_history_entry"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(); } // clean up user authentication failure log if (ENABLE_USER_AUTHENTICATION_FAILURE) { $sql = "DELETE FROM\twcf" . WCF_N . "_user_authentication_failure\n\t\t\t\tWHERE\t\ttime < ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(TIME_NOW - 86400 * USER_AUTHENTICATION_FAILURE_EXPIRATION)); } // clean up error logs $files = @glob(WCF_DIR . 'log/*.txt'); if (is_array($files)) { foreach ($files as $filename) { if (filectime($filename) < TIME_NOW - 86400 * 14) { @unlink($filename); } } } // clean up temporary folder $tempFolder = FileUtil::getTempFolder(); DirectoryUtil::getInstance($tempFolder)->executeCallback(new Callback(function ($filename, $object) use($tempFolder) { if ($filename === $tempFolder) { return; } if ($filename === $tempFolder . '.htaccess') { return; } if ($object->getMTime() < TIME_NOW - 86400) { if ($object->isDir()) { @rmdir($filename); } else { if ($object->isFile()) { @unlink($filename); } } } })); }
/** * @see wcf\page\IPage::readData() */ public function readData() { parent::readData(); // init cache data $this->cacheData = array('source' => get_class(CacheHandler::getInstance()->getCacheSource()), 'version' => '', 'size' => 0, 'files' => 0); $_this = $this; $readFileCache = function ($cacheDir, Regex $ignore = null) use($_this) { $_this->caches[$cacheDir] = array(); // get files in cache directory try { $directoryUtil = DirectoryUtil::getInstance($cacheDir); } catch (SystemException $e) { return; } $files = $directoryUtil->getFileObjects(SORT_ASC, new Regex('\\.php$')); // get additional file information if (is_array($files)) { foreach ($files as $file) { if ($ignore !== null) { if ($ignore->match($file)) { continue; } } $_this->caches[$cacheDir][] = array('filename' => $file->getBasename(), 'filesize' => $file->getSize(), 'mtime' => $file->getMtime(), 'perm' => substr(sprintf('%o', $file->getPerms()), -3), 'writable' => $file->isWritable()); $_this->cacheData['files']++; $_this->cacheData['size'] += $file->getSize(); } } }; // filesystem cache if ($this->cacheData['source'] == 'wcf\\system\\cache\\source\\DiskCacheSource') { // set version $this->cacheData['version'] = WCF_VERSION; $conditions = new PreparedStatementConditionBuilder(); $conditions->add("packageID IN (?)", array(PackageDependencyHandler::getInstance()->getDependencies())); $conditions->add("isApplication = ?", array(1)); // get package dirs $sql = "SELECT\tpackageDir\n\t\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\t\t" . $conditions; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute($conditions->getParameters()); while ($row = $statement->fetchArray()) { $packageDir = FileUtil::getRealPath(WCF_DIR . $row['packageDir']); $readFileCache($packageDir . 'cache'); } } else { if ($this->cacheData['source'] == 'wcf\\system\\cache\\source\\MemcacheCacheSource') { // get version $this->cacheData['version'] = MemcacheAdapter::getInstance()->getMemcache()->getVersion(); // get stats $stats = MemcacheAdapter::getInstance()->getMemcache()->getStats(); $this->cacheData['files'] = $stats['curr_items']; $this->cacheData['size'] = $stats['bytes']; } else { if ($this->cacheData['source'] == 'wcf\\system\\cache\\source\\ApcCacheSource') { // set version $this->cacheData['version'] = phpversion('apc'); $conditions = new PreparedStatementConditionBuilder(); $conditions->add("packageID IN (?)", array(PackageDependencyHandler::getInstance()->getDependencies())); $conditions->add("isApplication = ?", array(1)); // get package dirs $sql = "SELECT\tpackageDir, packageName, instanceNo\n\t\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\t\t" . $conditions; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute($conditions->getParameters()); $packageNames = array(); while ($row = $statement->fetchArray()) { $packagePath = FileUtil::getRealPath(WCF_DIR . $row['packageDir']) . 'cache/'; $packageNames[$packagePath] = $row['packageName'] . ' #' . $row['instanceNo']; } $apcinfo = apc_cache_info('user'); $cacheList = $apcinfo['cache_list']; foreach ($cacheList as $cache) { $cachePath = FileUtil::addTrailingSlash(FileUtil::unifyDirSeperator(dirname($cache['info']))); if (isset($packageNames[$cachePath])) { // Use the packageName + the instance number, because pathes could confuse the administrator. // He could think this is a file cache. If instanceName would be unique, we could use it instead. $packageName = $packageNames[$cachePath]; if (!isset($this->caches[$packageName])) { $this->caches[$packageName] = array(); } // get additional cache information $this->caches[$packageName][] = array('filename' => basename($cache['info'], '.php'), 'filesize' => $cache['mem_size'], 'mtime' => $cache['mtime']); $this->cacheData['files']++; $this->cacheData['size'] += $cache['mem_size']; } } } else { if ($this->cacheData['source'] == 'wcf\\system\\cache\\source\\NoCacheSource') { $this->cacheData['version'] = WCF_VERSION; $this->cacheData['files'] = $this->cacheData['size'] = 0; } } } } $readFileCache(WCF_DIR . 'language'); $readFileCache(WCF_DIR . 'templates/compiled', new Regex('\\.meta\\.php$')); $readFileCache(WCF_DIR . 'acp/templates/compiled', new Regex('\\.meta\\.php$')); }
/** * @see wcf\system\cache\source\ICacheSource::flush() */ public function flush() { $sql = "SELECT\t\tpackage.packageDir\n\t\t\tFROM\t\twcf" . WCF_N . "_package_dependency package_dependency\n\t\t\tLEFT JOIN\twcf" . WCF_N . "_package package\n\t\t\tON\t\t(package.packageID = package_dependency.dependency)\n\t\t\tWHERE\t\tpackage_dependency.packageID = ?\n\t\t\t\t\tAND isApplication = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(PACKAGE_ID, 1)); while ($row = $statement->fetchArray()) { $packageDir = FileUtil::getRealPath(WCF_DIR . $row['packageDir']); $cacheDir = $packageDir . 'cache'; DirectoryUtil::getInstance($cacheDir)->removePattern(new Regex('.*\\.php$')); } }