function export($path = null, $destination = null) { set_time_limit(0); if (!is_array($path) && !empty($path)) { $path = Site::splitPath($path); } if (empty($path)) { $files = DB::allRecords('SELECT MAX(`ID`) as `RID`' . ' FROM `_e_files`' . ' GROUP BY `Handle`,`CollectionID`'); foreach ($files as $file) { $SiteFile = SiteFile::getByID($file['RID'])->getData(); if (strpos($SiteFile['FullPath'], '_parent') !== 0 && $SiteFile['Status'] != 'Deleted') { $SiteFiles[$SiteFile['FullPath']] = Site::$rootPath . '/data/' . $SiteFile['ID']; } } } else { throw new Exception('Sub directories not yet supported.'); } if (count($SiteFiles)) { $zip = new ZipArchive(); $tmp = $destination ? $destination : tempnam("/tmp", "emr"); if ($zip->open($tmp) === TRUE) { foreach ($SiteFiles as $virtualPath => $realPath) { $zip->addFromString($virtualPath, file_get_contents($realPath)); } } $zip->close(); return $tmp; } else { throw new Exception('Nothing to compress found.'); } }
public static function getByHandle($collectionID, $handle) { if ($_SERVER['REQUEST_METHOD'] == 'GET' && !empty($_SERVER['HTTP_X_REVISION_ID'])) { return static::getByID($_SERVER['HTTP_X_REVISION_ID']); } else { return parent::getByHandle($collectionID, $handle); } }
public static function getSourceCode($minifier, $cacheHashOrSourceReport, $skipCache = false) { $cacheHash = is_string($cacheHashOrSourceReport) ? $cacheHashOrSourceReport : $cacheHashOrSourceReport['hash']; $cacheKey = "{$minifier}:{$cacheHash}"; if (!$skipCache && ($code = Cache::fetch($cacheKey))) { return $code; } if (is_array($cacheHashOrSourceReport) && is_array($cacheHashOrSourceReport['files'])) { $code = ''; foreach ($cacheHashOrSourceReport['files'] as $path => $fileData) { $code .= $minifier::minify(file_get_contents(SiteFile::getRealPathByID($fileData['ID']))); } Cache::store($cacheKey, $code); return $code; } return null; }
public function pushDiff($diff) { $results = array(); foreach ($diff as $d) { if (!$d['operation']) { $results[] = array('path' => $d['local']->FullPath, 'status' => 'skipped'); } elseif ($d['operation'] == 'create' || $d['operation'] == 'update') { //$this->put(); if (is_array($d['local'])) { $d['local'] = SiteFile::getByID($d['local']['ID']); } // PUT file $url = 'http://' . $this->_options['host'] . '/develop/' . $d['local']->FullPath; $results[] = array('path' => $d['local']->FullPath, 'status' => $d['operation'] . 'd', 'response' => $this->put($url, $d['local'])); } elseif ($d['operation'] == 'delete') { // DELETE file $url = 'http://' . $this->_options['host'] . '/develop/' . $d['remote']['FullPath']; $results[] = array('path' => $d['remote']['FullPath'], 'status' => 'deleted', 'response' => $this->delete($url)); } } return $results; }
public static function buildBacktraceLines() { $backtrace = debug_backtrace(); $lines = array(); // trim call to this method array_shift($backtrace); // build friendly output lines from backtrace frames while ($frame = array_shift($backtrace)) { if (!empty($frame['file']) && strpos($frame['file'], \Site::$rootPath . '/data/') === 0) { $fileNode = \SiteFile::getByID(basename($frame['file'])); if ($fileNode) { $frame['file'] = 'emergence:' . $fileNode->FullPath; } } // ignore log-routing frames if (!empty($frame['file']) && ($frame['file'] == 'emergence:_parent/php-classes/Psr/Log/AbstractLogger.php' || $frame['file'] == 'emergence:_parent/php-classes/Emergence/Logger.php') || empty($frame['file']) && $frame['class'] == 'Psr\\Log\\AbstractLogger' || !empty($frame['class']) && $frame['class'] == 'Emergence\\Logger' && $frame['function'] == '__callStatic') { continue; } $lines[] = (!empty($frame['class']) ? "{$frame['class']}{$frame['type']}" : '') . $frame['function'] . (!empty($frame['args']) ? '(' . implode(',', array_map(function ($arg) { return is_string($arg) || is_numeric($arg) ? var_export($arg, true) : gettype($arg); }, $frame['args'])) . ')' : '') . (!empty($frame['file']) ? " called at {$frame['file']}:{$frame['line']}" : ''); } return $lines; }
foreach ($repoCfg['trees'] as $srcPath => $treeOptions) { if (is_string($treeOptions)) { $treeOptions = array('path' => $treeOptions); } if (!is_string($srcPath)) { $srcPath = $treeOptions['path']; } elseif (!$treeOptions['path']) { $treeOptions['path'] = $srcPath; } $treeOptions['exclude'][] = '#(^|/)\\.git(/|$)#'; if (is_file($treeOptions['path'])) { $sha1 = sha1_file($treeOptions['path']); $existingNode = Site::resolvePath($srcPath); if (!$existingNode || $existingNode->SHA1 != $sha1) { $fileRecord = SiteFile::createFromPath($srcPath, null, $existingNode ? $existingNode->ID : null); SiteFile::saveRecordData($fileRecord, fopen($treeOptions['path'], 'r'), $sha1); Benchmark::mark("importing file {$srcPath} from {$treeOptions['path']}"); } else { Benchmark::mark("skipped unchanged file {$srcPath} from {$treeOptions['path']}"); } } else { $cachedFiles = Emergence_FS::cacheTree($srcPath); Benchmark::mark("precached {$srcPath}: " . $cachedFiles); $exportResult = Emergence_FS::importTree($treeOptions['path'], $srcPath, $treeOptions); Benchmark::mark("importing directory {$srcPath} from {$treeOptions['path']}: " . http_build_query($exportResult)); } } // commit changes #$repo->git('add --all'); # #$repo->git(sprintf(
public static function handleError($errno, $errstr, $errfile, $errline) { if (!(error_reporting() & $errno)) { return; } if (substr($errfile, 0, strlen(static::$rootPath)) == static::$rootPath) { $fileID = substr(strrchr($errfile, '/'), 1); $File = SiteFile::getByID($fileID); $errfile .= ' (' . $File->Handle . ')'; } $report = "<h1>Error</h1><p>{$errstr}</p><p><b>Source:</b> {$errfile}<br /><b>Line:</b> {$errline}</p>"; if (!empty($File)) { $report .= "<p><b>Author:</b> " . ($File->Author ? $File->Author->Username : '******') . "<br /><b>Timestamp:</b> " . date('Y-m-d h:i:s', $File->Timestamp) . "</p>"; } $report .= static::_getRequestReport(); $report .= sprintf("<h2>Backtrace</h2>\n<pre>%s</pre>\n", htmlspecialchars(print_r(debug_backtrace(), true))); if (!headers_sent()) { header('Status: 500 Internal Server Error'); } if (static::$debug) { die($report); } else { if (class_exists('Email')) { Email::send(static::$webmasterEmail, 'Scripting error on ' . static::$hostname, $report); } die('A problem has occurred and this request could not be handled, the webmaster has been sent a diagnostic report.'); } }
public static function findFiles($filename, $useRegexp = false, $scope = null, $localOnly = false) { $collections = array(); if ($scope) { if (!is_array($scope)) { $scope = array($scope); } foreach ($scope as $scopeItem) { if (is_string($scopeItem)) { foreach (static::getCollectionLayers($scopeItem, $localOnly) as $collection) { $collections[] = $collection; } } elseif (is_a($scopeItem, 'SiteCollection')) { $collections[] = $scopeItem; } } } DB::nonQuery('LOCK TABLES ' . SiteFile::$tableName . ' f1 READ, ' . SiteFile::$tableName . ' f2 READ, ' . SiteCollection::$tableName . ' collections READ'); $collectionsQuery = sprintf('SELECT collections.ID FROM `%s` collections WHERE Status != "Deleted"', SiteCollection::$tableName); if (count($collections)) { $collectionsQuery .= sprintf(' AND ((%s))', implode(') OR (', array_map(function ($collection) { $positions = DB::oneRecord('SELECT PosLeft, PosRight FROM `%s` collections WHERE ID = %u', array(SiteCollection::$tableName, $collection->ID)); return sprintf('PosLeft BETWEEN %u AND %u', $positions['PosLeft'], $positions['PosRight']); }, $collections))); } $fileResults = DB::query('SELECT f2.* FROM (SELECT MAX(f1.ID) AS ID FROM `%1$s` f1 WHERE CollectionID IN (%2$s) AND Status != "Phantom" GROUP BY f1.Handle) AS lastestFiles LEFT JOIN `%1$s` f2 ON (f2.ID = lastestFiles.ID) WHERE f2.Status != "Deleted" AND f2.Handle %3$s "%4$s"', array(SiteFile::$tableName, $collectionsQuery, $useRegexp ? 'REGEXP' : '=', DB::escape($filename))); DB::nonQuery('UNLOCK TABLES'); $results = array(); while ($record = $fileResults->fetch_assoc()) { $fileNode = new SiteFile($record['Handle'], $record); $results[join('/', $fileNode->getFullPath(null, false))] = $fileNode; } return $results; }
public static function handleRevisionsRequest() { $GLOBALS['Session']->requireAccountLevel('Developer'); $node = SiteFile::getByID($_REQUEST['ID']); if (!$node) { return static::throwNotFoundError(); } else { $data = array(); $Fields = array('ID', 'Class', 'Handle', 'Type', 'MIMEType', 'Size', 'SHA1', 'Status', 'Timestamp', 'AuthorID', 'AncestorID', 'CollectionID', 'FullPath'); foreach ($node->getRevisions() as $item) { $record = array(); foreach ($Fields as $Field) { $record[$Field] = $item->{$Field}; if ($Field == 'AuthorID') { $record['Author'] = Person::getByID($item->AuthorID); } } $data['revisions'][] = $record; } return static::respond('revisions', $data); } }
public function clearCacheTree($record) { $key = static::getCacheKey($record['Handle'], $record['ParentID'], $record['Site'] == 'Remote'); Cache::delete($key); // iterate child collections $childCollectionsKey = static::getCacheKey('.*', $record['ID'], $record['Site'] == 'Remote'); foreach (Cache::getIterator('|^' . $childCollectionsKey . '|') as $childCollection) { if ($childCollection['value']) { static::clearCacheTree($childCollection['value']); } } // iterate child files $childFilesKey = SiteFile::getCacheKey($record['ID'], '.*'); foreach (Cache::getIterator('|^' . $childFilesKey . '|') as $childFile) { if ($childFile['value']) { Cache::delete($childFile['key']); } } }
public static function handleError($errno, $errstr, $errfile, $errline) { if (!(error_reporting() & $errno)) { return; } if (substr($errfile, 0, strlen(static::$rootPath)) == static::$rootPath) { $fileID = substr(strrchr($errfile, '/'), 1); $File = SiteFile::getByID($fileID); $errfile .= ' (' . $File->Handle . ')'; } die("<h1>Error</h1><p>{$errstr}</p><p><b>Source:</b> {$errfile}<br /><b>Line:</b> {$errline}<br /><b>Author:</b> {$File->Author->Username}<br /><b>Timestamp:</b> " . date('Y-m-d h:i:s', $File->Timestamp) . "</p>"); }
public function delete() { // mark collection and all subcollections as deleted DB::nonQuery('UPDATE `%s` SET Status = "Deleted" WHERE PosLeft BETWEEN %u AND %u', array(static::$tableName, $this->PosLeft, $this->PosRight)); // TODO: mark files and all subfiles as deleted SiteFile::deleteTree($this); }
public static function handleImportRequest() { // get repo if (empty($_REQUEST['repo'])) { die('Parameter "repo" required'); } $repoName = $_REQUEST['repo']; if (!array_key_exists($repoName, Git::$repositories)) { die("Repo '{$repoName}' is not defined in Git::\$repositories"); } $repoCfg = Git::$repositories[$repoName]; // start the process set_time_limit(0); Benchmark::startLive(); Benchmark::mark("configured request: repoName={$repoName}"); // get paths $repoPath = "{$_SERVER['SITE_ROOT']}/site-data/git/{$repoName}"; // check if there is an existing repo if (!is_dir("{$repoPath}/.git")) { die("{$repoPath} does not contain .git"); } // get repo chdir($repoPath); // sync trees foreach ($repoCfg['trees'] as $srcPath => $treeOptions) { if (is_string($treeOptions)) { $treeOptions = array('path' => $treeOptions); } if (!is_string($srcPath)) { $srcPath = $treeOptions['path']; } elseif (!$treeOptions['path']) { $treeOptions['path'] = $srcPath; } if (is_string($treeOptions['exclude'])) { $treeOptions['exclude'] = array($treeOptions['exclude']); } $treeOptions['exclude'][] = '#(^|/)\\.git(/|$)#'; $treeOptions['dataPath'] = false; try { if (is_file($treeOptions['path'])) { $sha1 = sha1_file($treeOptions['path']); $existingNode = Site::resolvePath($srcPath); if (!$existingNode || $existingNode->SHA1 != $sha1) { $fileRecord = SiteFile::createFromPath($srcPath, null, $existingNode ? $existingNode->ID : null); SiteFile::saveRecordData($fileRecord, fopen($treeOptions['path'], 'r'), $sha1); Benchmark::mark("importing file {$srcPath} from {$treeOptions['path']}"); } else { Benchmark::mark("skipped unchanged file {$srcPath} from {$treeOptions['path']}"); } } else { $exportResult = Emergence_FS::importTree($treeOptions['path'], $srcPath, $treeOptions); Benchmark::mark("importing directory {$srcPath} from {$treeOptions['path']}: " . http_build_query($exportResult)); } } catch (Exception $e) { Benchmark::mark("failed to import directory {$srcPath} from {$treeOptions['path']}: " . $e->getMessage()); } } }
$patternPHP = '/(_|gettext)\\s*\\(\\s*(\'|")(.*?)\\2\\s*\\)/si'; $patternPHPValidators = '/(\'|")errorMessage\\1\\s*=>\\s*(\'|")(.*?)\\2/s'; // create a memory handle to write pot file to $pot = fopen('php://memory', 'w+'); $strings = array(); // extract strings from templates $files = Emergence_FS::getTreeFiles('html-templates', false, array('Type' => 'text/x-html-template')); foreach ($files as $path => $fileData) { $contents = file_get_contents(SiteFile::getByID($fileData['ID'])->RealPath); _extractStrings($patternTemplate, $contents, $path, $strings); _extractStrings($patternTemplateShort, $contents, $path, $strings); } // extract strings from PHP files $files = Emergence_FS::getTreeFiles(null, false, array('Type' => 'application/php')); foreach ($files as $path => $fileData) { $contents = file_get_contents(SiteFile::getByID($fileData['ID'])->RealPath); _extractStrings($patternPHP, $contents, $path, $strings); _extractStrings($patternPHPValidators, $contents, $path, $strings); } // write pot file foreach ($strings as $string => $sources) { fwrite($pot, '#: ' . implode(' ', $sources) . PHP_EOL); // switch output format if embedded newlines found (see https://www.gnu.org/software/gettext/manual/html_node/Normalizing.html) if (preg_match('/[^\\n]\\n+[^\\n]/', $string)) { // multiline output format fwrite($pot, 'msgid ""' . PHP_EOL); fwrite($pot, str_replace('\\n', '\\n"' . PHP_EOL . '"', _encodeString($string)) . PHP_EOL); } else { fwrite($pot, 'msgid ' . _encodeString($string) . PHP_EOL); } fwrite($pot, 'msgstr ""' . PHP_EOL . PHP_EOL);