/**
  * 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;
 }