Beispiel #1
0
 /**
  * Answer the Id objects of the owners of this slot.
  * This method has been over-ridden to allow lazy loading of slot owners from
  * a course object rather than forcing that to be done at instance creation time.
  * 
  * @return array
  * @access public
  * @since 7/30/07
  */
 public function getOwners()
 {
     if (!$this->mergedWithExternal) {
         $this->mergeWithExternal();
         $this->mergedWithExternal = true;
     }
     // Lazily load the slot owners.
     if (!$this->ownersPopulated && isset($this->course)) {
         foreach ($this->course->getInstructors() as $instructor) {
             $this->populateOwnerId($instructor);
         }
         $this->ownersPopulated = true;
     }
     return parent::getOwners();
 }
Beispiel #2
0
 /**
  * Print out a slot
  * 
  * @param object $slot
  * @return object Component
  * @access public
  * @since 12/4/07
  */
 public function getSlotComponent(Slot $slot)
 {
     $harmoni = Harmoni::instance();
     ob_start();
     print "\n\t<tr>";
     print "\n\t\t<td>";
     if ($slot->siteExists()) {
         print "\n\t\t\t<a href='";
         print $harmoni->request->quickURL('ui1', 'view', array('site' => $slot->getShortname()));
         print "' target='_blank'>" . $slot->getShortname() . "</a>";
     } else {
         print $slot->getShortname();
     }
     print "</td>";
     print "\n\t\t<td>" . $slot->getType() . "</td>";
     print "\n\t\t<td>" . $slot->getLocationCategory() . "</td>";
     // Media Quota
     print "\n\t\t<td>";
     if ($slot->usesDefaultMediaQuota()) {
         $quota = SlotAbstract::getDefaultMediaQuota()->asString();
         print "<a href='#' title='{$quota}' onclick='alert(\"{$quota}\"); return false;'>";
         print _("Default");
         print "</a>";
     } else {
         print $slot->getMediaQuota()->asString();
     }
     print "</td>";
     print "\n\t\t<td style='text-align: center'>" . ($slot->siteExists() ? "yes" : '') . "</td>";
     print "\n\t\t<td>";
     $owners = $slot->getOwners();
     $ownerStrings = array();
     $agentMgr = Services::getService('Agent');
     foreach ($owners as $ownerId) {
         $ownerStrings[] = $agentMgr->getAgent($ownerId)->getDisplayName();
     }
     print implode("; ", $ownerStrings);
     print "</td>";
     $harmoni->request->passthrough('starting_number');
     $harmoni->request->startNamespace("slots");
     print "\n\t\t<td style='white-space: nowrap;'>";
     print "\n\t\t\t<a href='";
     print $harmoni->request->quickURL('slots', 'edit', array('name' => $slot->getShortname()));
     print "'>" . _("edit") . "</a>";
     if (!$slot->siteExists()) {
         $harmoni->request->startNamespace(null);
         print "\n\t\t\t| <a href='";
         print $harmoni->request->quickURL('dataport', 'import', array('site' => $slot->getShortname()));
         print "'>" . _("import") . "</a>";
         $harmoni->request->endNamespace();
         print "\n\t\t\t| <a href='";
         print $harmoni->request->quickURL('slots', 'delete', array('name' => $slot->getShortname()));
         print "' onclick=\"";
         print "return confirm('" . _('Are you sure you want to delete this placeholder?') . "');";
         print "\">" . _("delete") . "</a>";
     } else {
         $harmoni->request->startNamespace(null);
         print "\n\t\t\t| <a href='";
         print $harmoni->request->quickURL('dataport', 'export', array('node' => $slot->getSiteId()->getIdString()));
         print "'>" . _("export") . "</a>";
         $harmoni->request->endNamespace();
     }
     print "\n\t\t</td>";
     $harmoni->request->endNamespace();
     $harmoni->request->forget('starting_number');
     print "\n\t</tr>";
     return ob_get_clean();
 }
 /**
  * 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()));
 }
Beispiel #4
0
 /**
  * Set the default media quota
  * 
  * @param object Integer $quota
  * @return void
  * @access public
  * @since 3/20/08
  * @static
  */
 public static function setDefaultMediaQuota(Integer $quota)
 {
     self::$defaultMediaQuota = $quota->value();
 }
 /**
  * Get the base-url (MYURL equivalent) to use for a particular location-category.
  * 
  * @param string $locationCategory
  * @return void
  * @access public
  * @since 8/7/08
  * @static
  */
 public static function getBaseUrlForLocationCategory($locationCategory)
 {
     if (!in_array($locationCategory, SlotAbstract::getLocationCategories())) {
         throw new Exception("Invalid category, '{$locationCategory}'.");
     }
     if (!isset(self::$locationCategoryUrls[$locationCategory])) {
         return MYURL;
     }
     return self::$locationCategoryUrls[$locationCategory];
 }
 /**
  * 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, '', '&amp;');
                 $content->_setValue(str_replace($m[0], '"' . '[[localurl:' . $url . ']]' . '"', $content->value()));
             }
         }
     }
 }
 /**
  * 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;
 }
Beispiel #8
0
 /**
  * Create the wizard
  * 
  * @return Wizard
  * @access public
  * @since 12/7/07
  */
 public function createWizard()
 {
     $wizard = SingleStepWizard::withDefaultLayout();
     $step = $wizard->addStep("slot", new WizardStep());
     $harmoni = Harmoni::instance();
     $harmoni->request->startNamespace("slots");
     $name = strtolower(RequestContext::value("name"));
     $harmoni->request->endNamespace();
     $slotMgr = SlotManager::instance();
     $slot = $slotMgr->getSlotByShortname($name);
     $wizard->slot = $slot;
     $property = $step->addComponent('type', new WSelectList());
     $property->setValue($slot->getType());
     foreach (array(Slot::custom, Slot::course, Slot::personal) as $type) {
         $property->addOption($type, ucfirst($type));
     }
     $property = $step->addComponent('name', new WTextField());
     $property->setValue($slot->getShortname());
     $property->setEnabled(false, true);
     $property = $step->addComponent('category', new WSelectList());
     $property->setValue($slot->getLocationCategory());
     foreach (SlotAbstract::getLocationCategories() as $category) {
         $property->addOption($category, ucfirst($category));
     }
     $property = $step->addComponent('quota', new WTextField());
     $property->setSize(10);
     if (!$slot->usesDefaultMediaQuota()) {
         $property->setValue($slot->getMediaQuota()->asString());
     }
     $property = $step->addComponent('owners', new WSearchList());
     $property->setSearchSource(new AgentSearchSource());
     $agentMgr = Services::getService("Agent");
     foreach ($slot->getOwners() as $ownerId) {
         $property->addValue(new AgentSearchResult($agentMgr->getAgentOrGroup($ownerId)));
     }
     ob_start();
     print "\n<h4>" . _("Edit Placeholder") . "</h4>";
     print "\n<p><strong>" . _("Owner Definition Type") . ":</strong> [[type]]</p>";
     print "<div style='margin-left: 10px;'>";
     print _("The 'Owner Definition Type' indicates to the system where to search for placeholder owners. 'Course' will force a lookup in the course information system. 'Personal' will match against a user's email address. 'Custom' will not do an external lookup. <br/><br/>Note: If there is a name collision between a 'Custom' placeholder and a 'Course' placeholder. Valid 'Course' owners will still have access to the placeholder.");
     print "</div>";
     print "\n<p><strong>" . _("Placeholder Name") . ":</strong> [[name]]</p>";
     print "<div style='margin-left: 10px;'>";
     print _("The placeholder name will be an identifier for the site. It must be globally unique. Choose wisely to avoid collisions between system-generated personal names and course names.");
     print "</div>";
     print "\n<p><strong>" . _("Location Category") . ":</strong> [[category]]</p>";
     print "<div style='margin-left: 10px;'>";
     print _("The 'Location Category' is the Segue location in which this site will be made available. In the default installation this is disregarded, however some installations will be divided into 'main' and 'community', or other combinations. This flag is what is used in that determination.");
     print "</div>";
     print "\n<p><strong>" . _("Media Library Quota") . ":</strong> [[quota]]</p>";
     print "<div style='margin-left: 10px;'>";
     print _("The 'Media Library Quota' is a limit on the size of media that can be uploaded to a Segue site. Quotas greater or smaller than the default can be set, leave blank for the default. Quotas can be specified in B, kB, MB, GB (e.g. 25MB).");
     print "</div>";
     print "\n<p><strong>" . _("Owners") . ":</strong> </p>";
     print "<div style='margin-left: 10px;'>";
     print _("Placeholder owners are people who can create a site for the placeholder and/or will be given full access to the site at the time of its creation. After the site has been created, changes to placeholder ownership will not change any roles or privileges.");
     print "</div>";
     print "[[owners]]";
     $step->setContent(ob_get_clean());
     return $wizard;
 }