dmBridge PHP API
DMGenericTemplateHelper.php
00001 <?php
00002 #
00003 # dmBridge: a data access framework for CONTENTdm(R)
00004 #
00005 # Copyright © 2009, 2010, 2011 Board of Regents of the Nevada System of Higher
00006 # Education, on behalf of the University of Nevada, Las Vegas
00007 #
00008 
00019 class DMGenericTemplateHelper extends DMAbstractTemplateHelper
00020 implements DMTemplateHelper {
00021 
00026    private $body_scripts = array();
00027 
00031    private $head_scripts = array();
00032 
00036    private $meta_tags = array();
00037 
00041    private $stylesheets = array();
00042 
00048    private static function sortScriptsByWeight(&$arr) {
00049       $did_swap = false;
00050       for ($i = 0, $count = count($arr); $i < $count; $i++) {
00051          if ($i < $count - 1) {
00052             if ($arr[$i]['weight'] < $arr[$i+1]['weight']) {
00053                $tmp = $arr[$i];
00054                $arr[$i] = $arr[$i+1];
00055                $arr[$i+1] = $tmp;
00056                $did_swap = true;
00057             }
00058          }
00059       }
00060       if ($did_swap) {
00061          self::sortScriptsByWeight($arr);
00062       }
00063    }
00064 
00069    public function __construct(DMAbstractView $view,
00070          DMSession $session = null) {
00071       parent::__construct($view, $session);
00072       $this->addMetaTag("text/html; charset=utf-8", null, "Content-Type");
00073       $this->addMetaTag("public", null, "Cache-Control");
00074       $this->addMetaTag("public", null, "Pragma");
00075       $this->addMetaTag(DMConfigXML::getInstance()->getFeedCopyright(),
00076             "copyright");
00077    }
00078 
00086    public function  __call($method, $args) {
00087       // check for non-module template helpers
00088       $all_helpers = $this->getView()->getAllHelpers();
00089       foreach ($all_helpers as $helper) {
00090          if (method_exists($helper, $method)) {
00091             return call_user_func_array(array($helper, $method), $args);
00092          }
00093       }
00094       throw new DMNoSuchMethodException($method);
00095    }
00096 
00104    public function getHtmlAtomFeedURL() {
00105       return $this->getFeedURL("atom");
00106    }
00107 
00125    public function addBodyScriptCode($code, $type = "text/javascript",
00126          $weight = 0) {
00127       $this->body_scripts[] = array(
00128          'code' => $code,
00129          'type' => $type,
00130          'weight' => $weight
00131       );
00132    }
00133 
00152    public function addBodyScriptTag($src, $type = "text/javascript",
00153          $weight = 0) {
00154       $tagvals = array(
00155          'src' => $src,
00156          'type' => $type,
00157          'weight' => $weight
00158       );
00159 
00160       // if the script already exists, overwrite it
00161       $count = count($this->body_scripts);
00162       for ($i = 0; $i < $count; $i++) {
00163          if (array_key_exists("src", $this->body_scripts[$i])) {
00164             if ($src == $this->body_scripts[$i]['src']) {
00165                $this->body_scripts[$i] = $tagvals;
00166                return;
00167             }
00168          }
00169       }
00170 
00171       // it doesn't exist, so add it
00172       $this->body_scripts[] = $tagvals;
00173    }
00174 
00183    public function getHtmlBodyScriptTags(array $exclude_filenames = array()) {
00184       $body_scripts = $this->body_scripts;
00185       self::sortScriptsByWeight($body_scripts);
00186       
00187       $tags = "";
00188       foreach ($body_scripts as $script) {
00189          if (array_key_exists("src", $script)) {
00190             if (!in_array(basename($script['src']), $exclude_filenames)) {
00191                $tags .= sprintf('<script type="%s" src="%s"></script>',
00192                      $script['type'], $script['src']);
00193             }
00194          } else if (array_key_exists("code", $script)) {
00195             $tags .= sprintf('<script type="%s">%s</script>',
00196                   $script['type'], $script['code']);
00197          }
00198       }
00199       return $tags;
00200    }
00201 
00211    public function removeBodyScriptTag($src) {
00212       $count = count($this->body_scripts);
00213       for ($i = 0; $i < $count; $i++) {
00214          if ($src == $this->body_scripts[$i]['src']) {
00215             unset($this->body_scripts[$i]);
00216             return true;
00217          }
00218       }
00219       return false;
00220    }
00221 
00229    public function getHtmlCollectionsAsPulldown() {
00230       $cols = array();
00231       $cols = DMCollection::getAuthorized();
00232       $dxml = new DMDOMDocument("1.0", "utf-8");
00233       $dxml->loadXML("<form/>");
00234       $select = $dxml->createElement("select");
00235       $select->setAttribute("id", "dmSelectCollection");
00236       $select->setAttribute("class", "dmCollections");
00237       $select->setAttribute("onchange", "window.location = this.value");
00238 
00239       $option = $dxml->createElement("option", "Select a collection...");
00240       $select->appendChild($option);
00241 
00242       foreach ($cols as $c) {
00243          $query = new DMObjectQuery();
00244          $query->addCollection($c);
00245          $option = $dxml->createElement(
00246             "option", DMString::websafe($c->getName()));
00247          $option->setAttribute("value", $query->getURI());
00248          $collection = $this->getView()->getCollection();
00249          if ($collection) {
00250             if ($c->getAlias() == $collection->getAlias()) {
00251                $option->setAttribute("selected", "selected");
00252             }
00253          }
00254          $select->appendChild($option);
00255       }
00256       $dxml->documentElement->appendChild($select);
00257 
00258       $noscript = $dxml->createElement("noscript");
00259       $input = $dxml->createElement("input");
00260       $input->setAttribute("type", "submit");
00261       $input->setAttribute("value", "Go");
00262       $noscript->appendChild($input);
00263       $dxml->documentElement->appendChild($noscript);
00264 
00265       $dxml->formatOutput = true;
00266       return $dxml->saveHTML($dxml->documentElement);
00267    }
00268 
00280    public function getHtmlFormattedFlash() {
00281       $tmp = DMHTTPRequest::getCurrent()->getSession()->getFlash();
00282       if (!$tmp instanceof DMFlash) {
00283          return false;
00284       }
00285       $flash = clone $tmp;
00286       DMHTTPRequest::getCurrent()->getSession()->unsetFlash();
00287       $status = "dmNeutral";
00288       if ($flash->getStatus() === true) {
00289          $status = "dmSuccess";
00290       } else if ($flash->getStatus() === false) {
00291          $status = "dmFailure";
00292       }
00293       $msg = sprintf('<p class="%s">%s</p>',
00294          trim("dmFlash " . $status),
00295          DMString::websafe($flash->getValue()));
00296       return $msg;
00297    }
00298 
00314    public function addHeadScriptTag($src, $type = "text/javascript") {
00315       $tagvals = array(
00316          'src' => $src,
00317          'type' => $type
00318       );
00319 
00320       // if the script already exists, overwrite it
00321       $count = count($this->head_scripts);
00322       for ($i = 0; $i < $count; $i++) {
00323          if ($src == $this->head_scripts[$i]['src']) {
00324             $this->head_scripts[$i] = $tagvals;
00325             return;
00326          }
00327       }
00328 
00329       // it doesn't exist, so add it
00330       $this->head_scripts[] = $tagvals;
00331    }
00332 
00341    public function getHtmlHeadScriptTags(array $exclude_filenames = array()) {
00342       $scripts = $this->head_scripts;
00343       self::sortScriptsByWeight($scripts);
00344 
00345       $tags = "";
00346       foreach ($scripts as $script) {
00347          if (!in_array(basename($script['src']), $exclude_filenames)) {
00348             $tags .= sprintf('<script type="%s" src="%s"></script>',
00349                   $script['type'], $script['src']);
00350          }
00351       }
00352       return $tags;
00353    }
00354 
00364    public function removeHeadScriptTag($src) {
00365       $count = count($this->head_scripts);
00366       for ($i = 0; $i < $count; $i++) {
00367          if ($src == $this->head_scripts[$i]['src']) {
00368             unset($this->head_scripts[$i]);
00369             return true;
00370          }
00371       }
00372       return false;
00373    }
00374 
00386    public function getHtmlLoginPageLink(
00387          $login_text = "Login", $logout_text = "Logout") {
00388       if (DMHTTPRequest::getCurrent()->getSession()->getUser()) {
00389          $dest = $this->getView()->getLogoutURI();
00390          $text = $logout_text;
00391       } else {
00392          $dest = $this->getView()->getLoginView()->getURI();
00393          $text = $login_text;
00394       }
00395       return sprintf('<a href="%s">%s</a>',
00396          DMString::websafe($dest), DMString::websafe($text));
00397    }
00398 
00405    public function getHtmlLoginForm() {
00406       $html = sprintf('<form action="%s" method="post">
00407             <fieldset id="dmLoginForm">
00408                <legend>Login</legend>
00409 
00410                <label for="username">Username:</label>
00411                <input id="dmLoginUsername" type="text" name="username"
00412                   size="20" maxlength="30">
00413                <br>
00414 
00415                <label for="password">Password:</label>
00416                <input id="dmLoginPassword" type="password" name="password"
00417                   size="20" maxlength="30">
00418                <br>
00419 
00420                <input type="submit" value="Login">
00421             </fieldset>
00422          </form>',
00423          DMInternalURI::getURIWithParams("objects/login"));
00424       return $html;
00425    }
00426 
00439    public function addMetaTag($content, $name, $http_equiv = null) {
00440       $tagvals = array(
00441          'content' => $content,
00442          'name' => $name,
00443          'http-equiv' => $http_equiv
00444       );
00445 
00446       // if the tag already exists, overwrite it
00447       $count = count($this->meta_tags);
00448       for ($i = 0; $i < $count; $i++) {
00449          if ($name == $this->meta_tags[$i]['name']
00450                || $http_equiv == $this->meta_tags[$i]['http-equiv']) {
00451             $this->meta_tags[$i] = $tagvals;
00452             return;
00453          }
00454       }
00455 
00456       // it doesn't already exist, so add it
00457       $this->meta_tags[] = $tagvals;
00458    }
00459 
00463    public function getHtmlMetaTags() {
00464       $tags = "";
00465       foreach ($this->meta_tags as $mt) {
00466          $tag = sprintf('<meta content="%s"', $mt['content']);
00467          if ($mt['name']) {
00468             $tag .= sprintf(' name="%s"', $mt['name']);
00469          }
00470          if ($mt['http-equiv']) {
00471             $tag .= sprintf(' http-equiv="%s"', $mt['http-equiv']);
00472          }
00473          $tags .= $tag .= '>';
00474       }
00475       return $tags;
00476    }
00477 
00487    public function removeMetaTag($name = null, $http_equiv = null) {
00488       $count = count($this->meta_tags);
00489       for ($i = 0; $i < $count; $i++) {
00490          if ((!is_null($name) && $name == $this->meta_tags[$i]['name'])
00491                || (!is_null($http_equiv) && $http_equiv == $this->meta_tags[$i]['http-equiv'])) {
00492             unset($this->meta_tags[$i]);
00493             return true;
00494          }
00495       }
00496       return false;
00497    }
00498 
00510    public function getHtmlRecentlyViewedObjectsAsList($limit = 5, $thumbs = false) {
00511       $dxml = new DMDOMDocument("1.0", "utf-8");
00512       $dxml->loadXML("<ol/>");
00513       $dxml->documentElement->setAttribute("class", "dmRecentObjectLinks");
00514 
00515       $objects = $this->getView()->getRecentlyViewedObjects($limit);
00516 
00517       foreach (array_reverse($objects) as $obj) {
00518          $li = $dxml->createElement("li");
00519          $dxml->documentElement->appendChild($li);
00520 
00521          $a = $dxml->createElement("a");
00522          $a->setAttribute("href", $obj->getURI());
00523 
00524          $frag = $dxml->createDocumentFragment();
00525          if ($thumbs) {
00526             $img = $dxml->createElement("img");
00527             $img->setAttribute("class", "dmThumbnail");
00528             $img->setAttribute("src", $obj->getThumbnailURL());
00529             $img->setAttribute("alt", "Page thumbnail");
00530             $frag->appendChild($img);
00531          }
00532          $frag->appendChild($dxml->createTextNode(
00533                $obj->getMetadata("title")));
00534          $a->appendChild($frag);
00535          $li->appendChild($a);
00536       }
00537 
00538       return $dxml->saveHTML($dxml->documentElement);
00539    }
00540    
00552    public function addStylesheetTag($href, $type = "text/css",
00553          $media = "screen") {
00554       $tagvals = array(
00555          'type' => $type,
00556          'media' => $media,
00557          'href' => $href
00558       );
00559 
00560       // if the stylesheet already exists, overwrite it
00561       $count = count($this->stylesheets);
00562       for ($i = 0; $i < $count; $i++) {
00563          if ($href == $this->stylesheets[$i]['href']) {
00564             $this->stylesheets[$i] = $tagvals;
00565             return;
00566          }
00567       }
00568 
00569       // it doesn't exist, so add it
00570       $this->stylesheets[] = $tagvals;
00571    }
00572 
00577    public function getHtmlStylesheetTags() {
00578       $tags = "";
00579       foreach ($this->stylesheets as $sheet) {
00580          $tags .= sprintf(
00581                '<link rel="stylesheet" type="%s" media="%s" href="%s">',
00582                $sheet['type'], $sheet['media'], $sheet['href']);
00583       }
00584       return $tags;
00585    }
00586 
00596    public function removeStylesheetTag($href) {
00597       $count = count($this->stylesheets);
00598       for ($i = 0; $i < $count; $i++) {
00599          if ($href == $this->stylesheets[$i]['href']) {
00600             unset($this->stylesheets[$i]);
00601             return true;
00602          }
00603       }
00604       return false;
00605    }
00606 
00618    public function getHtmlTagsAsCloud($tag_limit = 20, $num_classes = 10,
00619          $randomize = true) {
00620       $tq = new DMTagQuery(DMDataStoreFactory::getDataStore());
00621       $tq->setNumResultsPerPage($tag_limit);
00622       $tq->addCollection($this->getView()->getCollection());
00623       $tq->setApproved(1);
00624       $tq->setSortByFrequency(true);
00625 
00626       $tags = $tq->getSearchResultsAsCounts();
00627       $counts = array_slice($tags, 0, $tag_limit, true);
00628       if (!count($counts)) {
00629          return "<!-- no results for cloud -->";
00630       }
00631 
00632       // calculate class numbering interval
00633       $min = min($counts);
00634       $max = max($counts);
00635       $diff = ($max - $min > 0) ? $max - $min : 1;
00636       $interval = ($num_classes - 1) / $diff;
00637 
00638       // generate the tags
00639       $tags = array();
00640       foreach ($counts as $value => $count) {
00641          // generate the query string
00642          $qs = array(
00643             'CISOBOX1' => $value,
00644             'CISOFIELD1' => "any",
00645             'CISOROOT' => $this->getView()->getCollection()->getAlias(),
00646             'CISOOP1' => "all"
00647          );
00648          $class_no = round(1 + ($count - $min) * $interval);
00649          $uri = DMInternalURI::getURIWithParams("objects", $qs);
00650          $tags[] = sprintf('<a class="dmTag dmTag%d" href="%s">%s</a>',
00651             $class_no,
00652             $uri,
00653             DMString::websafe($value));
00654          unset($qs);
00655       }
00656       return implode("\n", $tags);
00657    }
00658 
00665    public function getHtmlTermLinkedToSearch($text_to_link,
00666          DMObjectQuery $query) {
00667       // The basic idea is to build a DMObjectQuery based on the supplied
00668       // method parameters, and then use the return value of its getURI()
00669       // method.
00670       return sprintf('<a class="dmSearchTermLink" href="%s">%s</a>',
00671          $query->getURI(), $text_to_link);
00672    }
00673 
00692    public function getHtmlVocabularyAsCloud(array $field_nicks,
00693          $tag_limit = 20, $num_classes = 10, $sample_size = 512,
00694          $randomize = true) {
00695       /* Unfortunately cdm doesn't have a direct way of retrieving frequency
00696       data using the API. We will compile it ourselves here */
00697       $query = new DMObjectQuery();
00698       $query->addCollection($this->getView()->getCollection());
00699       $maxresults = ($sample_size > 1024) ? 1024 : $sample_size;
00700       $maxresults = ($sample_size < 10) ? 10 : $sample_size;
00701       $query->setNumResultsPerPage($maxresults);
00702       foreach ($field_nicks as $nick) {
00703          $predicate = new DMQueryPredicate();
00704          $predicate->setField(new DMDCElement($nick));
00705          $query->addPredicate($predicate);
00706       }
00707       $results = $query->getSearchResults();
00708 
00709       if (!count($results)) {
00710          return "<!-- no results for cloud -->";
00711       }
00712 
00713       // compile all unique terms in the $vocab array
00714       $vocab = array();
00715       foreach ($results as $obj) {
00716          foreach ($field_nicks as $nick) {
00717             $value = $obj->getField($nick);
00718             if ($value) {
00719                // split up semicolon-separated terms
00720                $tmp = explode("; ", $value);
00721                foreach ($tmp as &$t) {
00722                   $t = rtrim(trim($t), ".,;");
00723                   if (strlen($t) < 1) {
00724                      unset($t);
00725                   }
00726                }
00727                $vocab = array_merge($vocab, $tmp);
00728             }
00729          }
00730       }
00731 
00732       $counts = array_count_values($vocab);
00733       // enforce $tag_limit
00734       arsort($counts, SORT_NUMERIC);
00735       $counts = array_slice($counts, 0, $tag_limit, true);
00736 
00737       if (!count($counts)) {
00738          return "<!-- no results for cloud -->";
00739       }
00740 
00741       if ($randomize) {
00742          $tmp = array();
00743          $keys = array_keys($counts);
00744          shuffle($keys);
00745          foreach($keys as $key) {
00746             $tmp[$key] = $counts[$key];
00747             //unset($array[$key]);
00748          }
00749          $counts = $tmp;
00750       }
00751 
00752       // calculate class numbering interval
00753       $min = min($counts);
00754       $max = max($counts);
00755       $diff = ($max - $min > 0) ? $max - $min : 1;
00756       $interval = ($num_classes - 1) / $diff;
00757 
00758       // generate the tags
00759       $tags = array();
00760       foreach ($counts as $term => $c) {
00761          // generate the query string
00762          $qs = array(
00763             'CISOBOX1' => $term,
00764             'CISOFIELD1' => 'any',
00765             'CISOROOT' => $this->getView()->getCollection()->getAlias(),
00766             'CISOOP1' => 'all'
00767          );
00768          $class_no = round(1 + ($c - $min) * $interval);
00769          $uri = DMInternalURI::getURIWithParams("objects", $qs);
00770          $tags[] = sprintf('<a class="dmTag dmTag%d" href="%s">%s</a>',
00771             $class_no,
00772             $uri,
00773             DMString::websafe($term));
00774          unset($qs);
00775       }
00776       return implode("\n", $tags);
00777    }
00778 
00790    public function getHtmlVocabularyAsList(DMDCElement $field,
00791          $linked = true) {
00792       $vocab = $field->getVocabulary(false);
00793       natcasesort($vocab);
00794 
00795       $dxml = new DMDOMDocument("1.0", "utf-8");
00796       $dxml->loadXML("<ul/>");
00797       $dxml->documentElement->setAttribute("class", "dmVocabList");
00798 
00799       for ($i = 0; $i < count($vocab); $i++) {
00800          $li = $dxml->createElement('li');
00801          $li->setAttribute('class', 'dmVocabTerm');
00802          if ($linked) {
00803             $qs = array(
00804                'CISOBOX1' => $vocab[$i],
00805                'CISOFIELD1' => $field->getNick(),
00806                'CISOOP1' => "exact",
00807                'CISOROOT' => $field->getCollection()->getAlias()
00808             );
00809             $a = $dxml->createElement("a", DMString::websafe($vocab[$i]));
00810             $a->setAttribute("href",
00811                sprintf("/%s/?%s",
00812                   DMString::websafe(trim(dirname($_SERVER['PHP_SELF']), "/")),
00813                   DMString::websafe(urldecode(http_build_query($qs)))));
00814             $li->appendChild($a);
00815          } else {
00816             $li->nodeValue = DMString::websafe($vocab[$i]);
00817          }
00818          $dxml->documentElement->appendChild($li);
00819       }
00820       return $dxml->saveHTML($dxml->documentElement);
00821    }
00822 
00831    public function getHtmlVocabularyForSelect(DMDCElement $field) {
00832       $vocab = $field->getVocabulary(false);
00833       natcasesort($vocab);
00834       $terms = array();
00835       foreach ($vocab as $term) {
00836          $terms[] = sprintf("<option>%s</option>", DMString::websafe($term));
00837       }
00838       return implode("\n", $terms);
00839    }
00840 
00845    protected function getFeedURL($format) {
00846       $uri = DMHTTPRequest::getCurrent()->getURI();
00847       $uri->setExtension($format);
00848       return $uri->__toString();
00849    }
00850 
00851 }
 All Data Structures Functions Variables