/** * Rewrite file urls that weren't properly localized. * * @param object BlockSiteComponent $siteComponent * @return void */ protected function rewriteNonlocalFileUrls(BlockSiteComponent $siteComponent) { static $baseUrls; if (empty($baseUrls)) { $baseUrls = array('http://segue.middlebury.edu', 'https://segue.middlebury.edu', 'http://seguecommunity.middlebury.edu', 'https://seguecommunity.middlebury.edu'); foreach (SlotAbstract::getLocationCategories() as $locationCategory) { $baseUrls[] = rtrim(SiteDispatcher::getBaseUrlForLocationCategory($locationCategory), '/'); } $baseUrls = array_unique($baseUrls); } $content = $siteComponent->getAsset()->getContent(); foreach ($baseUrls as $baseUrl) { if (preg_match_all('#[\'"]' . $baseUrl . '/repository/(viewfile|viewfile_flash|viewthumbnail|viewthumbnail_flash)/polyphony-repository___repository_id/edu.middlebury.segue.sites_repository/polyphony-repository___asset_id/([0-9]+)/polyphony-repository___record_id/([0-9]+)(?:polyphony-repository___file_name/(.+))?[\'"]#', $content->asString(), $matches, PREG_SET_ORDER)) { foreach ($matches as $m) { $urlParts = array('module' => 'repository', 'action' => $m[1], 'polyphony-repository___repository_id' => 'edu.middlebury.segue.sites_repository', 'polyphony-repository___asset_id' => $m[2], 'polyphony-repository___record_id' => $m[3]); if (!empty($m[4])) { $urlParts['polyphony-repository___file_name'] = $m[4]; } else { if ($m[1] == 'viewfile') { try { $file = MediaFile::withIdStrings('edu.middlebury.segue.sites_repository', $m[2], $m[3]); $urlParts['polyphony-repository___file_name'] = $file->getFilename(); } catch (UnknownIdException $e) { } } } $url = http_build_query($urlParts, '', '&'); $content->_setValue(str_replace($m[0], '"' . '[[localurl:' . $url . ']]' . '"', $content->value())); } } } }
/** * Answer the url the JS functions should use to get the feed. * Due to browser restrictions on the location of documents loaded via the * XMLHTTPRequest, this may be different from the url returned by _getFeedUrl(); * * @return string * @access protected * @since 6/17/08 */ protected function _getFeedAccessUrl() { // For local-server urls, return the feed url if ($this->isLocal($this->_getFeedUrl()) && $this->isContentTrusted($this->_getFeedUrl())) { return $this->_getFeedUrl(); } // URLs to other location categories in the same segue instance. // These can be rebuilt to go through our local host. $pattern = '#(('; $pattern .= '(' . str_replace('.', '\\.', MYURL) . ')'; foreach (SlotAbstract::getLocationCategories() as $category) { $pattern .= '|(' . str_replace('.', '\\.', SiteDispatcher::getBaseUrlForLocationCategory($category)) . ')'; } $pattern .= ')[^\'"\\s\\]<>}]*)#i'; if (preg_match($pattern, $this->_getFeedUrl(), $matches)) { $harmoni = Harmoni::instance(); // Create a local-server version of the URL. $harmoni->request->startNamespace(null); $url = $harmoni->request->quickURL($harmoni->request->getModuleFromUrlWithBase($matches[2], $matches[0]), $harmoni->request->getActionFromUrlWithBase($matches[2], $matches[0]), $harmoni->request->getParameterArrayFromUrlWithBase($matches[2], $matches[0])); $harmoni->request->endNamespace(); if ($this->isContentTrusted($url)) { return $url; } } // For remote urls, pass through a local data-fetching gateway. return $this->getPluginActionUrl('remote_feed', array('url' => $this->_getFeedUrl())); }
/** * Execute * * @return void * @access public * @since 3/26/08 */ public function execute() { if (!$this->isAuthorizedToExecute()) { throw new PermissionDeniedException('This command can only be run by admins or from the command-line.'); } header("Content-Type: text/plain"); if (RequestContext::value('help') || RequestContext::value('h') || RequestContext::value('?')) { throw new HelpRequestedException($this->usage); } $outDir = RequestContext::value('d'); if (empty($outDir)) { throw new InvalidArgumentException("An output directory must be specified.\n\n" . $this->usage); } if (!is_dir($outDir) || !is_writable($outDir)) { throw new InvalidArgumentException("The output directory doesn't exist or is not writeable.\n\n" . $this->usage); } foreach (SlotAbstract::getLocationCategories() as $category) { $baseUrl = SiteDispatcher::getBaseUrlForLocationCategory($category); if (!preg_match('/^https?:\\/\\/.+/', $baseUrl)) { throw new ConfigurationErrorException('Please set a base URL for the \'' . $category . '\' category with SiteDispatcher::setBaseUrlForLocationCategory($category, $url); in config/slots.conf.php'); } } while (ob_get_level()) { ob_end_flush(); } flush(); /********************************************************* * Check for a running export *********************************************************/ $dbc = Services::getService('DatabaseManager'); $query = new SelectQuery(); $query->addColumn('slot'); $query->addColumn('pid'); $query->addTable('site_export_queue'); $query->addWhereNotEqual('pid', 0); $result = $dbc->query($query); // If we are exporting, check the status of the export process if ($result->hasMoreRows()) { // Don't start a new export if one is running. if ($this->isRunning($result->field('pid'))) { print "An export is already running\n"; exit; } else { $query = new UpdateQuery(); $query->setTable('site_export_queue'); $query->addValue('status', 'DIED'); $query->addRawValue('pid', 'NULL'); $query->addValue('info', 'Process ' . $result->field('pid') . ' has died.'); $query->addWhereEqual('slot', $result->field('slot')); $query->addWhereEqual('pid', $result->field('pid')); $dbc->query($query); } } /********************************************************* * If there aren't any other exports happening, run our export *********************************************************/ // Find the next slot to update $query = new SelectQuery(); $query->addColumn('slot'); $query->addTable('site_export_queue', NO_JOIN, '', 'q'); $query->addTable('segue_slot', INNER_JOIN, 'q.slot = s.shortname', 's'); $query->addWhereNull('pid'); $query->addWhereNull('status'); $query->addWhereNull('alias_target'); $query->addWhereNotEqual('site_id', ''); $query->addOrderBy('priority', DESCENDING); $query->addOrderBy('slot', ASCENDING); $result = $dbc->query($query); // Exit if there is nothing to do. if (!$result->hasMoreRows()) { print "The queue is empty\n"; exit; } $slot = $result->field('slot'); $slotMgr = SlotManager::instance(); $slotObj = $slotMgr->getSlotByShortname($slot); $baseUrl = SiteDispatcher::getBaseUrlForLocationCategory($slotObj->getLocationCategory()); // Mark that we are running $query = new UpdateQuery(); $query->setTable('site_export_queue'); $query->addValue('pid', strval(getmypid())); $query->addWhereEqual('slot', $slot); $dbc->query($query); // Run the export $start = microtime(true); try { $exportDirname = $slot . "-html"; $exportDir = $outDir . "/" . $exportDirname; $archivePath = $outDir . '/' . $exportDirname . ".zip"; if (file_exists($exportDir)) { $this->deleteRecursive($exportDir); } mkdir($exportDir); if (file_exists($archivePath)) { unlink($archivePath); } // Set the user to be an admin. $idMgr = Services::getService("Id"); $authType = new Type("Authentication", "edu.middlebury.harmoni", "Harmoni DB"); $_SESSION['__AuthenticatedAgents']['Authentication::edu.middlebury.harmoni::Harmoni DB'] = $idMgr->getId('17008'); $authZ = Services::getService("AuthZ"); $isAuthorizedCache = $authZ->getIsAuthorizedCache(); $isAuthorizedCache->dirtyUser(); // Close the session. If we don't, a lock on the session file will // cause the request initiated via wget to hang. session_write_close(); // Do the export $urlParts = parse_url($baseUrl); $urlPrefix = rtrim($urlParts['path'], '/'); $include = array($urlPrefix . '/gui2', $urlPrefix . '/images', $urlPrefix . '/javascript', $urlPrefix . '/polyphony', $urlPrefix . '/repository', $urlPrefix . '/plugin_manager', $urlPrefix . '/rss', $urlPrefix . '/dataport/html/site/' . $slot); if (defined('WGET_PATH')) { $wget = WGET_PATH; } else { $wget = 'wget'; } if (defined('WGET_OPTIONS')) { $wgetOptions = WGET_OPTIONS; } else { $wgetOptions = ''; } $command = $wget . " " . $wgetOptions . " -r --page-requisites --html-extension --convert-links --no-directories -e robots=off " . "--directory-prefix=" . escapeshellarg($exportDir . '/content') . " " . "--include=" . escapeshellarg(implode(',', $include)) . " " . "--header=" . escapeshellarg("Cookie: " . session_name() . "=" . session_id()) . " " . escapeshellarg($baseUrl . '/dataport/html/site/' . $slot); print "Cookie: " . session_name() . "=" . session_id() . "\n"; // throw new Exception($command); exec($command, $output, $exitCode); if ($exitCode) { throw new Exception('Wget Failed. ' . implode("\n", $output)); } // Copy the main HTML file to index.html copy($exportDir . '/content/' . $slot . '.html', $exportDir . '/content/index.html'); // Copy the index.html file up a level to make it easy to find file_put_contents($exportDir . '/index.html', preg_replace('/(src|href)=([\'"])([^\'"\\/]+)([\'"])/', '$1=$2content/$3$4', file_get_contents($exportDir . '/content/index.html'))); // Zip up the result $archive = new ZipArchive(); if ($archive->open($archivePath, ZIPARCHIVE::CREATE) !== TRUE) { throw new Exception("Could not create zip archive."); } $this->addDirectoryToZip($archive, $exportDir, $exportDirname); $archive->close(); // Remove the directory $this->deleteRecursive($exportDir); // Mark our success $query = new UpdateQuery(); $query->setTable('site_export_queue'); $query->addRawValue('pid', 'NULL'); $query->addValue('status', 'SUCCESS'); $query->addValue('running_time', strval(round(microtime(true) - $start, 2))); $query->addWhereEqual('slot', $slot); $dbc->query($query); } catch (Exception $e) { $this->deleteRecursive($exportDir); if (file_exists($archivePath)) { unlink($archivePath); } // Mark our failure $query = new UpdateQuery(); $query->setTable('site_export_queue'); $query->addRawValue('pid', 'NULL'); $query->addValue('status', 'EXCEPTION'); $query->addValue('info', $e->getMessage()); $query->addValue('running_time', strval(round(microtime(true) - $start, 2))); $query->addWhereEqual('slot', $slot); $dbc->query($query); throw $e; } exit; }