/**
  * Answer an array of search result objects after searching for the term passed
  * 
  * @param string $searchTerm
  * @return array of WSearchResult objects
  * @access public
  * @since 11/27/07
  */
 public function getResults($searchTerm)
 {
     $results = array();
     $orderKeys = array();
     // Return an empty array if there is no search term.
     if (!strlen($searchTerm)) {
         return $results;
     }
     $agentManager = Services::getService("Agent");
     $searchType = new HarmoniType("Agent & Group Search", "edu.middlebury.harmoni", "TokenSearch");
     $string = "*" . $searchTerm . "*";
     $agents = new MultiIteratorIterator();
     $agents->addIterator($agentManager->getAgentsBySearch($string, $searchType));
     $agents->addIterator($agentManager->getGroupsBySearch($string, $searchType));
     while ($agents->hasNext()) {
         $result = new AgentSearchResult($agents->next());
         $results[] = $result;
         $orderKeys[] = strtolower($result->getName());
     }
     array_multisort($orderKeys, SORT_ASC, SORT_STRING, $results);
     return $results;
 }
    /**
     * Build the content for this action
     * 
     * @return void
     * @access public
     * @since 4/26/05
     */
    function buildContent()
    {
        $defaultTextDomain = textdomain("polyphony");
        $actionRows = $this->getActionRows();
        $pageRows = new Container(new YLayout(), OTHER, 1);
        $harmoni = Harmoni::instance();
        // start our namespace
        $harmoni->history->markReturnURL("polyphony/authorization/edit_authorizations");
        $harmoni->request->startNamespace("polyphony-authorizations");
        $harmoni->request->passthrough();
        $agentManager = Services::getService("Agent");
        $idManager = Services::getService("Id");
        $everyoneId = $idManager->getId("edu.middlebury.agents.everyone");
        $usersId = $idManager->getId("edu.middlebury.agents.users");
        /*********************************************************
         * Buttons
         *********************************************************/
        ob_start();
        print "<table width='100%'><tr><td align='left'>";
        print "<a href='" . $harmoni->request->quickURL("admin", "main") . "'><button>" . _("Return to the Admin Tools") . "</button></a>";
        print "</td><td align='right'>";
        print "<input type='button'";
        print " onclick='Javascript:submitAgentChoice()'";
        print " value='" . _("Edit Authorizations for the selected User/Group") . " --&gt;' />";
        print "</td></tr></table>";
        $submit = new Block(ob_get_contents(), STANDARD_BLOCK);
        $actionRows->add($submit, "100%", null, LEFT, CENTER);
        ob_end_clean();
        // Users header
        $actionRows->add(new Heading("Users", 2), "100%", null, LEFT, CENTER);
        /*********************************************************
         * the agent search form
         *********************************************************/
        ob_start();
        $self = $harmoni->request->quickURL();
        $lastCriteria = $harmoni->request->get('search_criteria');
        $search_criteria_name = RequestContext::name('search_criteria');
        $search_type_name = RequestContext::name('search_type');
        print _("Search For Users") . ": ";
        print <<<END
\t\t<form action='{$self}' method='post'>
\t\t\t<div>
\t\t\t<input type='text' name='{$search_criteria_name}' value='{$lastCriteria}' />
\t\t\t<br /><select name='{$search_type_name}'>
END;
        $searchTypes = $agentManager->getAgentSearchTypes();
        while ($searchTypes->hasNext()) {
            $type = $searchTypes->next();
            $typeString = $type->getDomain() . "::" . $type->getAuthority() . "::" . $type->getKeyword();
            print "\n\t\t<option value='" . htmlspecialchars($typeString, ENT_QUOTES) . "'";
            if ($harmoni->request->get("search_type") == $typeString) {
                print " selected='selected'";
            }
            print ">" . htmlspecialchars($typeString) . "</option>";
        }
        print "\n\t</select>";
        print "\n\t<br /><input type='submit' value='" . _("Search") . "' />";
        print "\n\t<a href='" . $harmoni->request->quickURL() . "'>";
        print "\n\t\t<input type='button' value='" . _("Clear") . "' />\n\t</a>";
        print "\n</div>\n</form>";
        $actionRows->add(new Block(ob_get_contents(), STANDARD_BLOCK));
        ob_end_clean();
        /*********************************************************
         * Form and Javascript
         *********************************************************/
        // In order to preserve proper nesting on the HTML output put the form
        // around the row layout
        ob_start();
        $errorString = _("You must select a User or Group.");
        $agentFieldName = RequestContext::name("agentId");
        print <<<END
\t\t
\t\t<script type='text/javascript'>
\t\t//<![CDATA[ 
\t\t
\t\t\t// Make sure a selection has been made and submit if it has.
\t\t\tfunction submitAgentChoice() {
\t\t\t\tvar f;\t\t
\t\t\t\tfor (i = 0; i < document.forms.length; i++) {
\t\t\t\t\tf = document.forms[i];\t\t\t
\t\t\t\t\tif (f.id == 'chooseform') {
\t\t\t\t\t\tvar form = f;
\t\t\t\t\t\tbreak;
\t\t\t\t\t}
\t\t\t\t}
\t\t\t\t
\t\t\t\tvar radioArray = form.agentId;
\t\t\t\tvar isChecked = false;
\t\t\t\t
\t\t\t\tfor (i=0; i<radioArray.length; i++) {
\t\t\t\t\tif (radioArray[i].checked) {
\t\t\t\t\t\tisChecked = true;
\t\t\t\t\t}
\t\t\t\t}
\t\t\t\t
\t\t\t\tif (isChecked) {
\t\t\t\t\tform.submit();
\t\t\t\t} else {
\t\t\t\t\talert("{$errorString}");
\t\t\t\t}
\t\t\t}
\t\t\t
\t\t//]]> 
\t\t</script>
\t\t
END;
        print "<form id='chooseform' method='post' action='" . $harmoni->request->quickURL("authorization", "edit_authorizations") . "'>\n";
        $pageRows->setPreHTML(ob_get_contents());
        ob_end_clean();
        $pageRows->setPostHTML("</form>");
        /*********************************************************
         * the agent search results
         *********************************************************/
        $search_criteria = $harmoni->request->get("search_criteria");
        $search_type = $harmoni->request->get("search_type");
        if ($search_criteria && $search_type) {
            $typeParts = explode("::", $search_type);
            $searchType = new HarmoniType($typeParts[0], $typeParts[1], $typeParts[2]);
            $agents = new MultiIteratorIterator();
            $agents->addIterator($agentManager->getGroupsBySearch($search_criteria, $searchType));
            $agents->addIterator($agentManager->getAgentsBySearch($search_criteria, $searchType));
            print <<<END
\t\t
\t\t
\t\t<table>
\t\t\t<tr>
\t\t\t\t<td valign='top'>
\t\t\t\t\t<div style='
\t\t\t\t\t\tborder: 1px solid #000; 
\t\t\t\t\t\twidth: 15px; 
\t\t\t\t\t\theight: 15px;
\t\t\t\t\t\ttext-align: center;
\t\t\t\t\t\ttext-decoration: none;
\t\t\t\t\t\tfont-weight: bold;
\t\t\t\t\t'>
\t\t\t\t\t\t-
\t\t\t\t\t</div>
\t\t\t\t</td>
\t\t\t\t<td>
END;
            print "\n\t\t\t" . _("Search Results");
            print <<<END
\t\t\t\t</td>
\t\t\t</tr>
\t\t</table>
\t\t<div style='
\t\t\tmargin-left: 13px; 
\t\t\tmargin-right: 0px; 
\t\t\tmargin-top:0px; 
\t\t\tpadding-left: 10px;
\t\t\tborder-left: 1px solid #000;
\t\t'>
END;
            while ($agents->hasNext()) {
                $agent = $agents->next();
                if ($agent->isGroup()) {
                    $this->printGroup($agent);
                } else {
                    $this->printMember($agent);
                }
                print "<br />";
            }
            print "\n</div>";
            $pageRows->add(new Block(ob_get_contents(), STANDARD_BLOCK), "100%", null, LEFT, CENTER);
            ob_end_clean();
        }
        /*********************************************************
         * Groups
         *********************************************************/
        // Users header
        $pageRows->add(new Heading(_("Groups"), 2), "100%", null, LEFT, CENTER);
        // Loop through all of the Groups
        $childGroupIds = array();
        $groups = $agentManager->getGroupsBySearch($null = null, new Type("Agent & Group Search", "edu.middlebury.harmoni", "RootGroups"));
        while ($groups->hasNext()) {
            $group = $groups->next();
            $groupId = $group->getId();
            // Create a layout for this group using the GroupPrinter
            ob_start();
            GroupPrinter::printGroup($group, $harmoni, 2, array($this, "printGroup"), array($this, "printMember"));
            $groupLayout = new Block(ob_get_contents(), STANDARD_BLOCK);
            ob_end_clean();
            $pageRows->add($groupLayout, "100%", null, LEFT, CENTER);
        }
        $pageRows->add($submit, "100%", null, LEFT, CENTER);
        $actionRows->add($pageRows);
        $harmoni->request->endNamespace();
        textdomain($defaultTextDomain);
    }
    /**
     * Build the content for this action
     * 
     * @return void
     * @access public
     * @since 4/26/05
     */
    function buildContent()
    {
        $defaultTextDomain = textdomain("polyphony");
        $actionRows = $this->getActionRows();
        $pageRows = new Container(new YLayout(), OTHER, 1);
        $harmoni = Harmoni::instance();
        $harmoni->request->startNamespace("polyphony-agents");
        $harmoni->request->passthrough();
        // register this action as the return-point for the following operations:
        $harmoni->history->markReturnURL("polyphony/agents/add_to_group");
        $harmoni->history->markReturnURL("polyphony/agents/remove_from_group");
        $agentManager = Services::getService("Agent");
        $idManager = Services::getService("Id");
        $everyoneId = $idManager->getId("edu.middlebury.agents.everyone");
        $usersId = $idManager->getId("edu.middlebury.agents.users");
        $allGroupsId = $idManager->getId("edu.middlebury.agents.all_groups");
        /*********************************************************
         * the agent search form
         *********************************************************/
        // Users header
        $actionRows->add(new Heading(_("Users"), 2), "100%", null, LEFT, CENTER);
        ob_start();
        $self = $harmoni->request->quickURL();
        $lastCriteria = $harmoni->request->get("search_criteria");
        $search_criteria_name = RequestContext::name("search_criteria");
        $search_type_name = RequestContext::name("search_type");
        print _("Search For Users") . ": ";
        print <<<END
\t\t<form action='{$self}' method='post'>
\t\t\t<div>
\t\t\t<input type='text' name='{$search_criteria_name}' value='{$lastCriteria}' />
\t\t\t<br /><select name='{$search_type_name}'>
END;
        $searchTypes = $agentManager->getAgentSearchTypes();
        while ($searchTypes->hasNext()) {
            $type = $searchTypes->next();
            $typeString = htmlspecialchars($type->getDomain() . "::" . $type->getAuthority() . "::" . $type->getKeyword());
            print "\n\t\t<option value='{$typeString}'";
            if ($harmoni->request->get("search_type") == $typeString) {
                print " selected='selected'";
            }
            print ">{$typeString}</option>";
        }
        print "\n\t</select>";
        print "\n\t<br /><input type='submit' value='" . _("Search") . "' />";
        print "\n\t<a href='" . $harmoni->request->quickURL() . "'>";
        print "<input type='button' value='" . _("Clear") . "' /></a>";
        print "\n</div>\n</form>";
        $actionRows->add(new Block(ob_get_contents(), STANDARD_BLOCK), "100%", null, LEFT, CENTER);
        ob_end_clean();
        /*********************************************************
         * the agent search results
         *********************************************************/
        ob_start();
        if (($search_criteria = $harmoni->request->get('search_criteria')) && ($search_type = $harmoni->request->get('search_type'))) {
            $typeParts = explode("::", @html_entity_decode($search_type, ENT_COMPAT, 'UTF-8'));
            $searchType = new HarmoniType($typeParts[0], $typeParts[1], $typeParts[2]);
            $agents = new MultiIteratorIterator();
            $agents->addIterator($agentManager->getAgentsBySearch($search_criteria, $searchType));
            $agents->addIterator($agentManager->getGroupsBySearch($search_criteria, $searchType));
            print "search: " . $search_criteria;
            print <<<END
\t\t
\t\t
\t\t<table>
\t\t\t<tr>
\t\t\t\t<td valign='top'>
\t\t\t\t\t<div style='
\t\t\t\t\t\tborder: 1px solid #000; 
\t\t\t\t\t\twidth: 15px; 
\t\t\t\t\t\theight: 15px;
\t\t\t\t\t\ttext-align: center;
\t\t\t\t\t\ttext-decoration: none;
\t\t\t\t\t\tfont-weight: bold;
\t\t\t\t\t'>
\t\t\t\t\t\t-
\t\t\t\t\t</div>
\t\t\t\t</td>
\t\t\t\t<td>
END;
            print "\n\t\t\t" . _("Search Results");
            print <<<END
\t\t\t\t</td>
\t\t\t</tr>
\t\t</table>
\t\t<div style='
\t\t\tmargin-left: 13px; 
\t\t\tmargin-right: 0px; 
\t\t\tmargin-top:0px; 
\t\t\tpadding-left: 10px;
\t\t\tborder-left: 1px solid #000;
\t\t'>
END;
            while ($agents->hasNext()) {
                $agent = $agents->next();
                group_membershipAction::printMember($agent);
                print "<br />";
            }
            print "\n</div>";
            $pageRows->add(new Block(ob_get_contents(), STANDARD_BLOCK), "100%", null, LEFT, CENTER);
            ob_end_clean();
        }
        /*********************************************************
         * Groups
         *********************************************************/
        $pageRows->add(new Heading(_("Groups"), 2), "100%", null, LEFT, CENTER);
        // Define some global variables to store javascript array definitions
        // for validating adding/removing inputs.
        $GLOBALS['decendent_groups_string'] = "";
        $GLOBALS['child_groups_string'] = "";
        $GLOBALS['child_agents_string'] = "";
        // Loop through all of the Root Groups
        $groups = $agentManager->getGroupsBySearch($null = null, new Type("Agent & Group Search", "edu.middlebury.harmoni", "RootGroups"));
        while ($groups->hasNext()) {
            $group = $groups->next();
            $groupId = $group->getId();
            // Create a layout for this group using the GroupPrinter
            ob_start();
            GroupPrinter::printGroup($group, $harmoni, 2, array($this, "printGroup"), array($this, "printMember"));
            $groupLayout = new Block(ob_get_contents(), STANDARD_BLOCK);
            ob_end_clean();
            $pageRows->add($groupLayout, "100%", null, LEFT, CENTER);
        }
        /*********************************************************
         * Javascript for validating checkboxes,
         * Form Definition.
         *********************************************************/
        ob_start();
        // Create translated errorstrings
        $cannotAddGroup = _("Cannot add group");
        $toItsself = _("to itself");
        $deselecting = _("Deselecting");
        $toOwnDesc = _("to its own descendent");
        $groupString = _("Group");
        $isAlreadyInGroup = _("is alread in this group");
        $agentString = _("Agent");
        $fromItsself = _("from itself");
        $cannotRemoveGroup = _("Cannot remove group");
        $notInGroup = _("is not in this group");
        $confirmAdd = _("Are you sure that you wish to add the selected Groups and Agents to Group");
        $confirmRemove = _("Are you sure that you wish to remove the selected Groups and Agents from Group");
        $destinationgroup_name = RequestContext::name("destinationgroup");
        $operation_name = RequestContext::name("operation");
        $actionURL = $harmoni->request->quickURL("agents", "add_to_group");
        // Print out a Javascript function for submitting our groups choices
        $decendentGroups = $GLOBALS['decendent_groups_string'];
        $childGroups = $GLOBALS['child_groups_string'];
        $childAgents = $GLOBALS['child_agents_string'];
        print <<<END
\t\t
\t\t<script type='text/javascript'>
\t\t//<![CDATA[ 
\t\t
\t\t\t// Validate ancestory and submit to add checked to the group
\t\t\tfunction submitCheckedToGroup ( destGroupId ) {
\t\t\t\tvar f;
\t\t\t\tvar form;
\t\t\t\tfor (i = 0; i < document.forms.length; i++) {
\t\t\t\t\tf = document.forms[i];\t\t\t
\t\t\t\t\tif (f.id == 'memberform') {
\t\t\t\t\t\tform = f;
\t\t\t\t\t\tbreak;
\t\t\t\t\t}
\t\t\t\t}
\t\t\t\t
\t\t\t\tvar elements = form.elements;
\t\t\t\tvar i;
\t\t\t\tvar numToAdd = 0;
\t\t\t\t\t\t
\t\t\t\tfor (i = 0; i < elements.length; i++) {
\t\t\t\t\tvar element = elements[i];
\t\t\t\t\t
\t\t\t\t\tif (element.type == 'checkbox' && element.checked == true) {
\t\t\t\t\t\t
\t\t\t\t\t\tif (element.className == 'group') {
\t\t\t\t\t\t\t// Check that the destination is not the new member
\t\t\t\t\t\t\tif ( element.id == destGroupId ) {
\t\t\t\t\t\t\t\talert ("{$cannotAddGroup} " + element.id + " {$toItsself}. {$deselecting}...");
\t\t\t\t\t\t\t\telement.checked = false;
\t\t\t\t\t\t\t\tcontinue;
\t\t\t\t\t\t\t}
\t\t\t\t\t\t\t
\t\t\t\t\t\t\t// Check that the destination is not a decendent of the new member
\t\t\t\t\t\t\tif ( in_array(destGroupId, decendentGroups[element.id]) ) {
\t\t\t\t\t\t\t\talert ("{$cannotAddGroup} " + element.id + " {$toOwnDesc}.  {$deselecting}...");
\t\t\t\t\t\t\t\telement.checked = false;
\t\t\t\t\t\t\t\tcontinue;
\t\t\t\t\t\t\t}
\t\t\t\t\t\t\t
\t\t\t\t\t\t\t// Check that the new member is not already a child of the destination
\t\t\t\t\t\t\tif ( in_array(element.id, childGroups[destGroupId]) ) {
\t\t\t\t\t\t\t\talert ("{$groupString} " + element.id + " {$isAlreadyInGroup}.  {$deselecting}...");
\t\t\t\t\t\t\t\telement.checked = false;
\t\t\t\t\t\t\t\tcontinue;
\t\t\t\t\t\t\t}
\t\t\t\t\t\t} else {
\t\t\t\t\t\t\t// Check that the new member is not already a child of the destination
\t\t\t\t\t\t\tif ( in_array(element.id, childAgents[destGroupId]) ) {
\t\t\t\t\t\t\t\talert ("{$agentString} " + element.id + " {$isAlreadyInGroup}.  {$deselecting}...");
\t\t\t\t\t\t\t\telement.checked = false;
\t\t\t\t\t\t\t\tcontinue;
\t\t\t\t\t\t\t}
\t\t\t\t\t\t}
\t\t\t\t\t\t
\t\t\t\t\t\t// If we haven't skipped back to the top of the loop yet, increment our ticker.
\t\t\t\t\t\tnumToAdd++;
\t\t\t\t\t}
\t\t\t\t}
\t\t\t\t
\t\t\t\t
\t\t\t\tif (numToAdd && confirm("{$confirmAdd} " + destGroupId + "?")) {
\t\t\t\t\tform.destinationgroup.value = destGroupId;
\t\t\t\t\tform.submit();
\t\t\t\t}
\t\t\t}
\t\t\t
\t\t\t// Validate that the check are children and submit to remove them from the group
\t\t\tfunction submitCheckedFromGroup ( destGroupId ) {
\t\t\t\tvar f;
\t\t\t\tvar form;
\t\t\t\tfor (i = 0; i < document.forms.length; i++) {
\t\t\t\t\tf = document.forms[i];\t\t\t
\t\t\t\t\tif (f.id == 'memberform') {
\t\t\t\t\t\tform = f;
\t\t\t\t\t\tbreak;
\t\t\t\t\t}
\t\t\t\t}\t\t
\t\t\t\t
\t\t\t\tvar elements = form.elements;
\t\t\t\tvar i;
\t\t\t\tvar numToAdd = 0;
\t\t\t\t\t\t\t\t
\t\t\t\tfor (i = 0; i < elements.length; i++) {
\t\t\t\t\tvar element = elements[i];
\t\t\t\t\t
\t\t\t\t\tif (element.type == 'checkbox' && element.checked == true) {
\t\t\t\t\t\t// Check that the destination is not the new member
\t\t\t\t\t\tif ( element.id == destGroupId ) {
\t\t\t\t\t\t\talert ("{$cannotRemoveGroup} " + element.id + " {$fromItsself}. {$deselecting}...");
\t\t\t\t\t\t\telement.checked = false;
\t\t\t\t\t\t\tcontinue;
\t\t\t\t\t\t}
\t\t\t\t\t\t
\t\t\t\t\t\tif (element.className == 'group') {\t\t\t\t\t
\t\t\t\t\t\t\t// Check that the new member is not already a child of the destination
\t\t\t\t\t\t\tif ( !in_array(element.id, childGroups[destGroupId]) ) {
\t\t\t\t\t\t\t\talert ("{$groupString} " + element.id + " {$notInGroup}.  {$deselecting}...");
\t\t\t\t\t\t\t\telement.checked = false;
\t\t\t\t\t\t\t\tcontinue;
\t\t\t\t\t\t\t}
\t\t\t\t\t\t} else {
\t\t\t\t\t\t\t// Check that the new member is not already a child of the destination
\t\t\t\t\t\t\tif ( !in_array(element.id, childAgents[destGroupId]) ) {
\t\t\t\t\t\t\t\talert ("{$agentString} " + element.id + " {$notInGroup}.  {$deselecting}...");
\t\t\t\t\t\t\t\telement.checked = false;
\t\t\t\t\t\t\t\tcontinue;
\t\t\t\t\t\t\t}
\t\t\t\t\t\t}
\t\t\t\t\t\t
\t\t\t\t\t\t// If we haven't skipped back to the top of the loop yet, increment our ticker.
\t\t\t\t\t\tnumToAdd++;
\t\t\t\t\t}
\t\t\t\t}
\t\t\t\t
\t\t\t\tif (numToAdd && confirm("{$confirmRemove} " + destGroupId + "?")) {
\t\t\t\t\tform.destinationgroup.value = destGroupId;
\t\t\t\t\tform.action = form.action.replace('add_to_group','remove_from_group');
\t\t\t\t\tform.submit();
\t\t\t\t}
\t\t\t}
\t\t\t
\t\t\tfunction in_array( aValue, anArray) {
\t\t\t\tfor (i = 0; i < anArray.length; i++) {
\t\t\t\t\tif (anArray[i] == aValue)
\t\t\t\t\t\treturn true;
\t\t\t\t}
\t\t\t\t
\t\t\t\treturn false;
\t\t\t}
\t\t\t
\t\t\t// Decendent Groups
\t\t\tvar decendentGroups = new Array ();
{$decendentGroups}
\t\t
\t\t\t// Child Groups
\t\t\tvar childGroups = new Array ();
{$childGroups}
\t\t\t
\t\t\t// Child Agents
\t\t\tvar childAgents = new Array ();
{$childAgents}
\t\t\t
\t\t//]]> 
\t\t</script>
\t\t
\t\t<form id='memberform' method='post' action='{$actionURL}'>
\t\t<input type='hidden' id='destinationgroup' name='{$destinationgroup_name}' value=''/>
\t\t
END;
        $pageRows->setPreHTML(ob_get_contents());
        ob_end_clean();
        $pageRows->setPostHTML("</form>");
        // In order to preserve proper nesting on the HTML output, the checkboxes
        // are all in the pagerows layout instead of actionrows.
        $actionRows->add($pageRows, null, null, CENTER, CENTER);
        textdomain($defaultTextDomain);
    }
 /**
  * Print out a slide XML element
  * 
  * @param object Asset $slideAsset
  * @return void
  * @access public
  * @since 9/28/05
  */
 function printSlide($slideAsset)
 {
     $idManager = Services::getService("Id");
     $repositoryManager = Services::getService("Repository");
     $authZ = Services::getService("AuthZ");
     // Get our record and its data
     $slideRecords = $slideAsset->getRecordsByRecordStructure($idManager->getId("Repository::edu.middlebury.concerto.exhibition_repository::edu.middlebury.concerto.slide_record_structure"));
     if ($slideRecords->hasNext()) {
         $slideRecord = $slideRecords->next();
         // Text-Position
         $textPosition = $this->getFirstPartValueFromRecord("Repository::edu.middlebury.concerto.exhibition_repository::edu.middlebury.concerto.slide_record_structure.edu.middlebury.concerto.slide_record_structure.text_position", $slideRecord);
         // Display Metadata
         $displayMetadata = $this->getFirstPartValueFromRecord("Repository::edu.middlebury.concerto.exhibition_repository::edu.middlebury.concerto.slide_record_structure.edu.middlebury.concerto.slide_record_structure.display_metadata", $slideRecord);
         // Media
         $mediaIdStringObj = $this->getFirstPartValueFromRecord("Repository::edu.middlebury.concerto.exhibition_repository::edu.middlebury.concerto.slide_record_structure.edu.middlebury.concerto.slide_record_structure.target_id", $slideRecord);
         if (strlen($mediaIdStringObj->asString())) {
             $mediaId = $idManager->getId($mediaIdStringObj->asString());
         } else {
             $mediaId = null;
         }
     }
     // ------------------------------------------
     print "<slide>\n";
     // Title
     print "\t\t<title><![CDATA[";
     print htmlspecialchars($slideAsset->getDisplayName(), ENT_COMPAT, 'UTF-8');
     print "]]></title>\n";
     // Caption
     print "\t\t<caption><![CDATA[";
     print $slideAsset->getDescription();
     if (isset($displayMetadata) && $displayMetadata->isTrue() && isset($mediaId) && $authZ->isUserAuthorized($idManager->getId("edu.middlebury.authorization.view"), $mediaId)) {
         print "\t\t\t<hr/>\n";
         $mediaAsset = $repositoryManager->getAsset($mediaId);
         $this->printAsset($mediaAsset);
     }
     // Unauthorized to view Media Message
     if (isset($mediaId) && !$authZ->isUserAuthorized($idManager->getId("edu.middlebury.authorization.view"), $mediaId)) {
         print "\t\t\t<div style='font-size: large; font-weight: bold; border: 2px dotted; padding: 5px;'>";
         $harmoni = Harmoni::instance();
         print "\n\t\t\t\t<p>";
         print _("You are not authorized to view the media for this slide.");
         print "</p>\n\t\t\t\t<p>";
         print _("If you have not done so, please go to ");
         print "<a href='" . $harmoni->request->quickURL("home", "welcome");
         print "'>Concerto</a>";
         print _(" and log in.");
         print "\t\t\t\t</p>\n\t\t\t</div>\n";
     }
     print "]]></caption>\n";
     // Text-Position
     print "\t\t<text-position>";
     if (isset($textPosition)) {
         print $textPosition->asString();
     } else {
         if (!isset($mediaId)) {
             print "center";
         }
     }
     print "</text-position>\n";
     /*********************************************************
      * Media
      *********************************************************/
     if (isset($mediaId) && $authZ->isUserAuthorized($idManager->getId("edu.middlebury.authorization.view"), $mediaId)) {
         $mediaAsset = $repositoryManager->getAsset($mediaId);
         $mediaAssetRepository = $mediaAsset->getRepository();
         $mediaAssetRepositoryId = $mediaAssetRepository->getId();
         $fileRecords = new MultiIteratorIterator();
         $fileRecords->addIterator($mediaAsset->getRecordsByRecordStructure($idManager->getId("FILE")));
         $fileRecords->addIterator($mediaAsset->getRecordsByRecordStructure($idManager->getId("REMOTE_FILE")));
         while ($fileRecords->hasNext()) {
             $this->printFileRecord($fileRecords->next(), $mediaAssetRepositoryId, $mediaId);
         }
     }
     print "\t</slide>\n";
 }
 /**
  * Answer the first image Record of the Asset, if none is availible, answer
  * the first file of any time. If none are availible, answer FALSE.
  * 
  * @param object Id $assetId
  * @return mixed
  * @access public
  * @since 8/19/05
  * @static
  */
 static function getFirstImageOrFileRecordForAsset($assetOrId)
 {
     ArgumentValidator::validate($assetOrId, OrValidatorRule::getRule(ExtendsValidatorRule::getRule("Id"), ExtendsValidatorRule::getRule("Asset")));
     $rule = ExtendsValidatorRule::getRule("Id");
     if ($rule->check($assetOrId)) {
         $repositoryManager = Services::getService("RepositoryManager");
         $asset = $repositoryManager->getAsset($assetOrId);
     } else {
         $asset = $assetOrId;
     }
     $idManager = Services::getService("IdManager");
     $assetId = $asset->getId();
     // Check the cache
     if (!isset($GLOBALS['__RepositoryThumbRecordCache'])) {
         $GLOBALS['__RepositoryThumbRecordCache'] = array();
     }
     if (!isset($GLOBALS['__RepositoryThumbRecordCache'][$assetId->getIdString()])) {
         $imageProcessor = Services::getService("ImageProcessor");
         $fileRecords = new MultiIteratorIterator();
         try {
             $fileRecords->addIterator($asset->getRecordsByRecordStructure($idManager->getId("FILE")));
         } catch (UnknownIdException $e) {
         }
         try {
             $fileRecords->addIterator($asset->getRecordsByRecordStructure($idManager->getId("REMOTE_FILE")));
         } catch (UnknownIdException $e) {
         }
         while ($fileRecords->hasNext()) {
             $record = $fileRecords->next();
             if (!isset($fileRecord)) {
                 $fileRecord = $record;
             }
             $mimeTypeParts = $record->getPartsByPartStructure($idManager->getId("MIME_TYPE"));
             $mimeTypePart = $mimeTypeParts->next();
             $mimeType = $mimeTypePart->getValue();
             // If this record is supported by the image processor, then use it
             // to generate a thumbnail instead of the default icons.
             if ($imageProcessor->isFormatSupported($mimeType)) {
                 $fileRecord = $record;
                 break;
             }
         }
         if (!isset($fileRecord)) {
             $GLOBALS['__RepositoryThumbRecordCache'][$assetId->getIdString()] = FALSE;
         } else {
             $GLOBALS['__RepositoryThumbRecordCache'][$assetId->getIdString()] = $fileRecord;
         }
     }
     return $GLOBALS['__RepositoryThumbRecordCache'][$assetId->getIdString()];
 }
 /**
  * Answer all of the MediaFiles for this asset
  * 
  * @return object Iterator
  * @access public
  * @since 4/27/07
  */
 function getFiles()
 {
     $idManager = Services::getService('Id');
     $records = new MultiIteratorIterator();
     $records->addIterator($this->_asset->getRecordsByRecordStructure($idManager->getId('FILE')));
     $records->addIterator($this->_asset->getRecordsByRecordStructure($idManager->getId('REMOTE_FILE')));
     $files = array();
     while ($records->hasNext()) {
         $files[] = new MediaFile($this, $records->next());
     }
     $mediaFiles = new HarmoniIterator($files);
     return $mediaFiles;
 }
 /**
  * Select the next id in the TraversalInfoIterator that corresponds to a
  * Group.
  * 
  * @return void
  * @access private
  * @since 8/30/05
  */
 private function _selectNextAgent()
 {
     // We just want to change the reference, leaving any existing references
     // untouched.
     $null = null;
     $this->_nextAgent = $null;
     while ($this->_nextAgent == null && parent::hasNext()) {
         $agent = parent::next();
         if (!in_array($agent->getId()->getIdString(), $this->_seen)) {
             $this->_nextAgent = $agent;
             $this->_seen[] = $agent->getId()->getIdString();
             break;
         }
     }
 }
 /**
  * Function for printing the asset block of the slideshow XML file
  * 
  * @param object Asset $asset
  * @param optional object Id $recordId
  * @return void
  * @access public
  * @since 10/14/05
  */
 function printAssetXML(Asset $asset, Id $recordId = null)
 {
     $assetId = $asset->getId();
     $repository = $asset->getRepository();
     $repositoryId = $repository->getId();
     $idManager = Services::getService("Id");
     // ------------------------------------------
     print "\t<slide>\n";
     // Title
     print "\t\t<title><![CDATA[";
     print htmlspecialchars($asset->getDisplayName(), ENT_COMPAT, 'UTF-8');
     print "]]></title>\n";
     // Caption
     print "\t\t<caption><![CDATA[";
     $this->printAsset($asset);
     print "]]></caption>\n";
     // Text-Position
     print "\t\t<text-position>";
     print "right";
     print "</text-position>\n";
     $fileRecords = new MultiIteratorIterator();
     $fileRecords->addIterator($asset->getRecordsByRecordStructure($idManager->getId("FILE")));
     $fileRecords->addIterator($asset->getRecordsByRecordStructure($idManager->getId("REMOTE_FILE")));
     /*********************************************************
      * Files
      *********************************************************/
     $harmoni = Harmoni::instance();
     $harmoni->request->startNamespace("polyphony-repository");
     $imgProcessor = Services::getService("ImageProcessor");
     while ($fileRecords->hasNext()) {
         $this->printFileRecord($fileRecords->next(), $repositoryId, $assetId);
     }
     $harmoni->request->endNamespace();
     print "\t</slide>\n";
 }
 /**
  * Answer all of the comments attached to an asset
  * 
  * @param object $assetOrId An Asset object or an Id object
  * @param string $order The constant ASC or DESC for ascending time (oldest 
  *			first) or decending time (recent first).
  * @return object Iterator
  * @access public
  * @since 7/3/07
  */
 function getAllComments($assetOrId, $order = ASC)
 {
     ArgumentValidator::validate($assetOrId, OrValidatorRule::getRule(ExtendsValidatorRule::getRule('Asset'), ExtendsValidatorRule::getRule('Id')));
     if (method_exists($assetOrId, 'getId')) {
         $asset = $assetOrId;
         $assetId = $asset->getId();
     } else {
         $repositoryManager = Services::getService("Repository");
         $idManager = Services::getService("Id");
         $repository = $repositoryManager->getRepository($idManager->getId("edu.middlebury.segue.sites_repository"));
         $asset = $repository->getAsset($assetOrId);
         $assetId = $assetOrId;
     }
     // Load the replies, their creation times into arrays for caching and
     // easy sorting.
     $assetIdString = $assetId->getIdString();
     if (!isset($this->_allComments[$assetIdString])) {
         $this->_allComments[$assetIdString] = array();
         $this->_allComments[$assetIdString]['ids'] = array();
         $this->_allComments[$assetIdString]['times'] = array();
         $rootComments = $this->getRootComments($asset);
         $allComments = new MultiIteratorIterator();
         while ($rootComments->hasNext()) {
             $allComments->addIterator($this->_getDescendentComments($rootComments->next()));
         }
         while ($allComments->hasNext()) {
             $comment = $allComments->next();
             $dateTime = $comment->getCreationDate();
             $this->_allComments[$assetIdString]['ids'][] = $comment->getId();
             $this->_allComments[$assetIdString]['times'][] = $dateTime->asSeconds();
         }
     }
     // Sort the comment Ids based on time.
     array_multisort($this->_allComments[$assetIdString]['times'], SORT_NUMERIC, $order == ASC ? SORT_ASC : SORT_DESC, $this->_allComments[$assetIdString]['ids']);
     $null = null;
     $comments = new HarmoniIterator($null);
     foreach ($this->_allComments[$assetIdString]['ids'] as $id) {
         $comments->add($this->getComment($id));
     }
     return $comments;
 }
 /**
  * Answer the agents that have roles that are greater than or equal to the role passed.
  * 
  * @param object SegueRole $role
  * @param object Id $rootQualifierId
  * @param optional boolean $overrideAzCheck If true, not not check AZs. Used by admin functions to force-set a role.
  * @return array An array of Id objects
  * @access public
  * @since 11/29/07
  */
 public function getAgentsWithRoleAtLeast(SegueRole $role, Id $rootQualifierId, $overrideAzCheck = false)
 {
     $authZ = Services::getService("AuthZ");
     $idMgr = Services::getService("Id");
     if (!$overrideAzCheck) {
         if (!$authZ->isUserAuthorized($idMgr->getId("edu.middlebury.authorization.view_authorizations"), $rootQualifierId)) {
             throw new PermissionDeniedException("Cannot view authorizations here.");
         }
     }
     // Get a list of all of the qualifiers in the site.
     $qualifiers = new MultiIteratorIterator();
     $qualifiers->addIterator(new HarmoniIterator(array($authZ->getQualifier($rootQualifierId))));
     $qualifiers->addIterator($authZ->getQualifierDescendants($rootQualifierId));
     // Go through each qualifier and see who can do all of the functions in the role
     $agentIdStrings = array();
     while ($qualifiers->hasNext()) {
         $qualifier = $qualifiers->next();
         $qualifierId = $qualifier->getId();
         // Build up an array of what agents can do each function
         $agentsForFunctions = array();
         foreach ($role->getFunctions() as $functionId) {
             $agentsForFunctions[$functionId->getIdString()] = array();
             $agentIds = $authZ->getWhoCanDo($functionId, $qualifierId);
             while ($agentIds->hasNext()) {
                 $agentIdString = $agentIds->next()->getIdString();
                 if (!in_array($agentIdString, $agentIdStrings)) {
                     $agentsForFunctions[$functionId->getIdString()][] = $agentIdString;
                 }
             }
         }
         // Loop through the agents that can do the first function, if they can
         // do all the others, then they match the role and can be added to the master list.
         foreach (current($agentsForFunctions) as $agentIdString) {
             $hasAllFunctions = true;
             foreach ($role->getFunctions() as $functionId) {
                 if (!in_array($agentIdString, $agentsForFunctions[$functionId->getIdString()])) {
                     $hasAllFunctions = false;
                     break;
                 }
             }
             if ($hasAllFunctions) {
                 $agentIdStrings[] = $agentIdString;
             }
         }
     }
     $agentIdStrings = array_unique($agentIdStrings);
     $agentIds = array();
     foreach ($agentIdStrings as $idString) {
         $agentIds[] = $idMgr->getId($idString);
     }
     return $agentIds;
 }