dmBridge PHP API
DMTEObjectController.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 
00015 class DMTEObjectController extends DMAbstractController {
00016 
00018    private $query;
00019 
00025    public function comments($aliasptr) {
00026       $tmp = explode(",", $aliasptr);
00027       $col = DMCollectionFactory::getCollection(
00028             DMCollection::getSanitizedAlias($tmp[0]));
00029       $ptr = (int) $tmp[1];
00030 
00031       try {
00032          // make sure we aren't viewing something we shouldn't be
00033          if (!is_numeric($ptr)) {
00034             throw new DMUnavailableModelException(
00035                DMLocalizedString::getString("NONEXISTENT_OBJECT"));
00036          }
00037          $obj = DMObjectFactory::getObject($col, $ptr);
00038 
00039          $response = new DMHTTPResponse();
00040          $rep = new DMHTTPRepresentation();
00041          $rep->setMediaType(new DMMediaType("application", "atom+xml"));
00042          $trans = new DMAtomRepresentationTransformer();
00043          $rep->setBody($trans->transformObjectComments($obj));
00044          $response->setRepresentation($rep);
00045          $response->send();
00046          die;
00047       } catch (DMException $e) {
00048          require_once($this->getTemplateSet()->getErrorTemplate()
00049                ->getAbsolutePathname());
00050          die;
00051       }
00052    }
00053 
00062    public function index($alias) {
00063       $alias = DMCollection::getSanitizedAlias($alias);
00064       if (strlen($alias) < 2) {
00065          $alias = "/dmdefault";
00066       }
00067 
00068       $response = new DMHTTPResponse();
00069       $rep = DMHTTPResponseFactory::getRepresentation();
00070       $trans = DMHTTPResponseFactory::getTransformer();
00071       $response->setRepresentation($rep);
00072 
00073       try {
00074          $ts = $this->getTemplateSet();
00075          if (!$ts) {
00076             throw new DMUnavailableModelException(
00077                   DMLocalizedString::getString("INVALID_TPL_SET"));
00078          }
00079 
00080          $specified_collection = $displayed_collection
00081          = DMCollectionFactory::getCollection($alias);
00082 
00083          if (!$specified_collection) {
00084             throw new DMUnavailableModelException(
00085                   DMLocalizedString::getString("INVALID_COLLECTION"));
00086          }
00087 
00088          if ($specified_collection->isDefault()) {
00089             $input = $this->getSession()->getSearchInput();
00090             if (!$input || !$input->isPresent()) {
00091                // Set the current collection to the current template set's
00092                // default collection so that we have something to view
00093                if ($ts->getDefaultCollection()) {
00094                   $displayed_collection = $ts->getDefaultCollection();
00095                } else {
00096                   throw new DMUnavailableModelException(
00097                      DMLocalizedString::getString("NO_ALIAS_SUPPLIED"));
00098                }
00099             }
00100          }
00101          // make sure we aren't viewing something we shouldn't be
00102          if ($ts && !$ts->isAuthorizedToViewCollection(
00103                $displayed_collection)) {
00104             throw new DMSecurityException(
00105                DMLocalizedString::getString("ACCESS_DENIED_TO_COL"));
00106          }
00107 
00108          if (!$this->getHTTPRequest()->getURI()->getExtension()
00109                && $rep->getMediaType()->equals(
00110                      new DMMediaType("application", "xml"))) {
00111             $rep->setMediaType(new DMMediaType("text", "html"));
00112          }
00113 
00114          // check for user input from a search
00115          $uri = $this->getHTTPRequest()->getURI();
00116          $this->getSession()->setSearchInput(new DMInput($uri));
00117          if ($this->getSession()->getSearchInput()->isPresent()) {
00118             $this->search($displayed_collection, $rep);
00119          } else {
00120             $this->browse($displayed_collection, $rep);
00121          }
00122          $this->query->getSearchResults();
00123 
00124          // figure out which view template to load
00125          $path = (count($this->query->getFacetTerms()))
00126                ? "/templates/object/results_faceted.html.php"
00127                : "/templates/object/results.html.php";
00128          $path = $this->query->getNumResults()
00129                ? $path : "/templates/object/no_results.html.php";
00130 
00131          $tpl = $ts->getTemplateAtPathname($path);
00132          global $view;
00133          $view = new DMResultsView($tpl,
00134                $this->getSession(),
00135                $specified_collection, $this->query);
00136 
00137          if ($rep->getMediaType()->equals(new DMMediaType("text", "html"))) {
00138             // store results page url in session to facilitate "back to
00139             // results" link
00140             $this->getSession()->setResultsView($view);
00141          } else {
00142             $rep->setBody($trans->transformResults($this->query));
00143             $response->send();
00144             die;
00145          }
00146       } catch (DMException $e) {
00147          if (!$this->getTemplateSet()) {
00148             throw $e;
00149          }
00150          $tpl = $this->getTemplateSet()->getTemplateAtPathname(
00151                "/templates/error/view.html.php");
00152          global $view;
00153          $view = new DMSystemErrorView($tpl,
00154                $this->getSession(), $e);
00155          return;
00156       }
00157    }
00158 
00162    private function browse(DMCollection $col, DMHTTPRepresentation $rep) {
00163       $sort = $order = $page = $rpp = null;
00164       $uri = $this->getHTTPRequest()->getURI();
00165       $rpp = $this->getTemplateSet()->getNumResultsPerPage();
00166       if (!$rpp) {
00167          $rpp = $uri->getQueryValue("rpp");
00168          $rpp = ($rpp < 10) ? 20 : $rpp;
00169          $rpp = ($rpp > 50) ? 50 : $rpp;
00170       }
00171       if ($rep->getMediaType()->equals(
00172             new DMMediaType("application", "atom+xml"))) {
00173          $sort = "dmmodified";
00174          $order = "desc";
00175          $page = 1;
00176       } else if ($rep->getMediaType()->equals(
00177             new DMMediaType("application", "xml"))) {
00178          $sort = "dmmodified";
00179          $order = "desc";
00180          $page = abs($uri->getQueryValue("page"));
00181          $rpp = 50;
00182       } else { // DMObjectQuery setters will handle remaining validation
00183          $sort = $uri->getQueryValue("sort");
00184          $order = $uri->getQueryValue("order");
00185          $page = abs($uri->getQueryValue("page"));
00186       }
00187 
00188       // browse mode should wipe any saved query
00189       $this->getSession()->unsetQuery();
00190       // as well as any saved search input
00191       $this->getSession()->unsetSearchInput();
00192 
00193       $this->query = new DMObjectQuery();
00194       $this->query->setCollections(array($col));
00195       $this->query->setSortFields(array($sort => $order));
00196       $this->query->setPage($page);
00197       $this->query->setNumResultsPerPage($rpp);
00198    }
00199 
00203    private function search(DMCollection $col, DMHTTPRepresentation $rep) {
00204       // if there are any collection aliases in the search that we do not have
00205       // access to, bail out
00206       try {
00207          if (!$this->isAuthorizedToSearch()) {
00208             throw new DMSecurityException(
00209                DMLocalizedString::getString("ACCESS_DENIED_TO_COL"));
00210          }
00211       } catch (DMSecurityException $e) {
00212          require_once($this->getTemplateSet()->getErrorTemplate()
00213                ->getAbsolutePathname());
00214          die;
00215       }
00216 
00217       try {
00218          $this->getSession()->getSearchInput()->validate();
00219       } catch (DMIllegalArgumentException $e) {
00220          $this->getSession()->setFlash(
00221                new DMFlash($e->getMessage(), false));
00222       }
00223 
00224       $uri = $this->getHTTPRequest()->getURI();
00225       $sort = $order = $page = $rpp = null;
00226       if ($rep->getMediaType()->equals(new DMMediaType("application", "atom+xml"))) {
00227          $sort = "dmmodified";
00228          $order = "desc";
00229          $page = 1;
00230          $rpp = 30;
00231       } else { // DMObjectQuery setters will handle validation
00232          $sort = $uri->getQueryValue("sort");
00233          $order = $uri->getQueryValue("order");
00234          $page = $uri->getQueryValue("page");
00235          $rpp = $this->getTemplateSet()->getNumResultsPerPage();
00236          if (!$rpp) {
00237             $rpp = $uri->getQueryValue("rpp");
00238             $rpp = ($rpp < 10) ? 20 : $rpp;
00239             $rpp = ($rpp > 50) ? 50 : $rpp;
00240          }
00241       }
00242 
00243       $this->query = new DMObjectQuery();
00244       $this->query->setCollections(
00245             $this->getSession()->getSearchInput()->getCollections());
00246       $this->query->setPredicates(
00247             $this->getSession()->getSearchInput()->getTerms());
00248       $this->query->setSortFields(array($sort => $order));
00249       $this->query->setPage($page);
00250       $this->query->setNumResultsPerPage($rpp);
00251       $this->getSession()->setQuery($this->query);
00252    }
00253 
00254    protected function isAuthorizedToSearch() {
00255       if (!$this->getSession()->getSearchInput()
00256             instanceof DMInput) {
00257          return true;
00258       }
00259       foreach ($this->getSession()->getSearchInput()
00260             ->getCollections() as $c) {
00261          if (!$this->getTemplateSet()->isAuthorizedToViewCollection($c)) {
00262             return false;
00263          }
00264       }
00265       return true;
00266    }
00267 
00271    public function compoundSearch($aliasptr) {
00272       $tmp = explode(",", $aliasptr);
00273       $col = DMCollectionFactory::getCollection(
00274             DMCollection::getSanitizedAlias($tmp[0]));
00275       $ptr = (int) $tmp[1];
00276       $uri = $this->getHTTPRequest()->getURI();
00277 
00278       $page = (int) substr($uri->getQueryValue("page"), 0, 4);
00279       $rpp = (int) $uri->getQueryValue("rpp");
00280       $rpp = ($rpp > 100) ? 100 : $rpp;
00281       $rpp = ($rpp < 10) ? 10 : $rpp;
00282 
00283       try {
00284          // instantiate an object so we can find its parent to search within
00285          $obj = DMObjectFactory::getObject($col, $ptr);
00286          $parent = $obj->getParent() ? $obj->getParent() : $obj;
00287 
00288          $qt = new DMQueryPredicate();
00289          $qt->setString($uri->getQueryValue("term"));
00290          $qt->setField(new DMDCElement("full"));
00291          $qt->setMode("exact");
00292 
00293          $this->query = new DMObjectQuery();
00294          $this->query->setPage($page);
00295          $this->query->setNumResultsPerPage($rpp);
00296          $this->query->addPredicate($qt);
00297          $this->query->addCollection($col);
00298          $this->query->addObject($parent);
00299          $this->query->setSortFields(array("title" => "asc"));
00300 
00301          // need to run getSearchResults() BEFORE getNumResults()
00302          $this->query->getSearchResults();
00303          if ($this->query->getNumResults() < 1) {
00304             $this->getSession()->setFlash(new DMFlash(
00305                   DMLocalizedString::getString("NO_RESULTS_FOR_SEARCH")));
00306             DMHTTPRequest::redirectToParams("objects" . $col->getAlias() . "/" . $ptr);
00307             die;
00308          }
00309 
00310          $ts = $this->getTemplateSet();
00311          if (!$ts) {
00312             throw new DMUnavailableModelException(
00313                   DMLocalizedString::getString("INVALID_TPL_SET"));
00314          }
00315          $path = "/templates/object/results.html.php";
00316          $tpl = $ts->getTemplateAtPathname($path);
00317          global $view;
00318          $view = new DMObjectResultsView($tpl,
00319                $this->getSession(), $obj, $this->query);
00320 
00321          $rep = DMHTTPResponseFactory::getRepresentation();
00322          if (!$rep->getMediaType()->equals(new DMMediaType("text", "html"))) {
00323             $response = new DMHTTPResponse();
00324             $trans = DMHTTPResponseFactory::getTransformer();
00325             $response->setRepresentation($rep);
00326             $rep->setBody($trans->transformObjectResults($this->query));
00327             $response->send();
00328             die;
00329          }
00330       } catch (DMException $e) {
00331          $tpl = $this->getTemplateSet()->getTemplateAtPathname(
00332                "/templates/error/view.html.php");
00333          global $view;
00334          $view = new DMSystemErrorView($tpl,
00335                $this->getSession(), $e);
00336       }
00337    }
00338 
00342    public function view($aliasptr) {
00343       $tmp = explode(",", $aliasptr);
00344       $col = DMCollectionFactory::getCollection(
00345             DMCollection::getSanitizedAlias($tmp[0]));
00346       try {
00347          if (!is_numeric($tmp[1]) || $tmp[1] != round($tmp[1])) {
00348             throw new DMUnavailableModelException(
00349                   DMLocalizedString::getString("ACCESS_DENIED_TO_OBJ"));
00350          }
00351          $ptr = $tmp[1];
00352 
00353          $ts = $this->getTemplateSet();
00354          if (!$ts) {
00355             throw new DMUnavailableModelException(
00356                   DMLocalizedString::getString("INVALID_TPL_SET"));
00357          }
00358          $allowed_collections = $ts->getAuthorizedCollections();
00359          $locked_alias = null;
00360          if (count($allowed_collections) == 1
00361                && strlen($allowed_collections[0]) > 1) {
00362             $locked_alias = $allowed_collections[0];
00363          }
00364 
00365          // make sure we aren't viewing something we shouldn't be
00366          if (($locked_alias && $col->getAlias() != $locked_alias)
00367                || !$ts->isAuthorizedToViewCollection($col)) {
00368             throw new DMSecurityException(
00369                DMLocalizedString::getString("ACCESS_DENIED_TO_OBJ"));
00370          }
00371 
00372          // object view should wipe any saved search
00373          $this->getSession()->unsetSearchInput();
00374 
00375          $obj = DMObjectFactory::getObject($col, $ptr);
00376 
00377          // Render compound or single template depending on what the object is
00378          $path = ($obj->isCompound() || $obj->isChild())
00379                ? "/templates/object/view_compound.html.php"
00380                : "/templates/object/view_simple.html.php";
00381          $tpl = $this->getTemplateSet()->getTemplateAtPathname($path);
00382          global $view;
00383          $view = new DMObjectView($tpl,
00384                $this->getSession(), $obj);
00385          $view->setCommentForm(new DMObjectCommentForm());
00386          $view->setTagForm(new DMTagForm());
00387 
00388          // check for incoming comments/tags
00389          $req = $this->getHTTPRequest();
00390          $rep = $req->getRepresentation();
00391          if ($req->getMethod() == DMHTTPMethod::POST) {
00392             switch ($rep->getFormValue("action")) {
00393             case "comment":
00394                $this->setForm($view->getCommentForm());
00395                $this->postComment($obj);
00396                break;
00397             case "rate":
00398                $this->rate($obj);
00399                break;
00400             case "tag":
00401                $this->setForm($view->getTagForm());
00402                $this->postTag($obj);
00403                break;
00404             }
00405          }
00406 
00407          // Add the object to the list of recently viewed objects
00408          $this->getSession()->addRecentlyViewedObject($obj);
00409 
00410          $rep = DMHTTPResponseFactory::getRepresentation();
00411          if (!$rep->getMediaType()->equals(new DMMediaType("text", "html"))) {
00412             $response = new DMHTTPResponse();
00413             $trans = DMHTTPResponseFactory::getTransformer();
00414             $response->setRepresentation($rep);
00415             $rep->setBody($trans->transformObject($obj));
00416             $response->send();
00417             die;
00418          }
00419       } catch (DMException $e) {
00420          $tpl = $this->getTemplateSet()->getTemplateAtPathname(
00421                "/templates/error/view.html.php");
00422          global $view;
00423          $view = new DMSystemErrorView($tpl, $this->getSession(), $e);
00424       }
00425    }
00426 
00427    private function postComment(DMObject $obj) {
00428       // disallow repeat comment submissions
00429       if ($this->getSession()->hasCommentedOnObject($obj)) {
00430          $this->getSession()->setFlash(new DMFlash(
00431                DMLocalizedString::getString("MULTIPLE_COMMENTS_NOT_ALLOWED"),
00432                false));
00433          header("HTTP/1.1 403 Forbidden");
00434       }
00435 
00436       $key = (DMConfigXML::getInstance()->isCommentModerationEnabled())
00437             ? "MODERATED_COMMENT_ADDED" : "COMMENT_ADDED";
00438       $this->handleForm(DMLocalizedString::getString($key));
00439    }
00440 
00441    private function postTag(DMObject $obj) {
00442       $str = (DMConfigXML::getInstance()->isTagModerationEnabled())
00443             ? "MODERATED_TAG_ADDED" : "TAG_ADDED";
00444       $this->handleForm(DMLocalizedString::getString($str));
00445    }
00446 
00447    private function rate(DMObject $obj) {
00448       $rep = $this->getHTTPRequest()->getRepresentation();
00449       try {
00450          // check for a valid max rating for weighting the submitted rating
00451          $rating = new DMRating(
00452             $rep->getFormValue("value"), $rep->getFormValue("max"));
00453          // check for text in hidden field
00454          if (strlen($rep->getFormValue("fauxrating")) > 0) {
00455             throw new DMIllegalArgumentException(
00456                DMLocalizedString::getString("FAUX_COMMENT_FAIL"), false);
00457          }
00458 
00459          // has the user already rated this object?
00460          if ($this->getSession()->hasRatedObject($obj)) {
00461             $this->getSession()->setFlash(new DMFlash(
00462                   DMLocalizedString::getString("ALREADY_RATED")));
00463          }
00464 
00465          // gauntlet cleared, post
00466          DMDataStoreFactory::getDataStore()->addObjectRating($obj, $rating);
00467          $this->getSession()->addHasRated($obj);
00468          $this->getSession()->setFlash(new DMFlash(
00469                DMLocalizedString::getString("RATING_ADDED"), true));
00470          DMHTTPRequest::reload();
00471          die;
00472       } catch (Exception $e) {
00473          $this->getSession()->setFlash(
00474                new DMFlash($e->getMessage(), false));
00475       }
00476    }
00477 
00478 }
 All Data Structures Functions Variables