dmBridge PHP API
DMInput.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 
00017 class DMInput {
00018 
00019    private static $valid_date_qualifiers = array("from", "after", "before",
00020       "on");
00021 
00023    private $begin_date;
00025    private $collections = array();
00027    private $date_qualifier;
00029    private $end_date;
00031    private $input_terms = array();
00033    private $is_present = false;
00035    private $on_date;
00037    private $proximity;
00039    private $uri;
00040 
00041 
00045    public function __construct(DMURI $uri) {
00046       $this->uri = $uri;
00047       $this->assembleUserInput();
00048    }
00049 
00050    private function assembleUserInput() {
00051       $qt = array();
00052       // simple search input (&q=...)
00053       if ($this->uri->getQueryValue("q")) {
00054          $qt[0]['string'] = $this->uri->getQueryValue("q");
00055          $qt[0]['field'] = "any";
00056          $qt[0]['mode'] = "all";
00057          $this->collections = DMCollection::getAuthorized();
00058          if (count($this->collections) < 1) {
00059             $this->collections[] = DMCollectionFactory::getCollection("/dmdefault");
00060          }
00061       } else { // CONTENTdm search (&CISOBLAH=...)
00062          for ($i = 1; $i < 5; $i++) {
00063             if ($this->uri->getQueryValue("CISOBOX" . $i)) {
00064                $qt[$i]['string'] = $this->uri->getQueryValue("CISOBOX" . $i);
00065             } else {
00066                break;
00067             }
00068 
00069             if ($this->uri->getQueryValue("CISOFIELD" . $i)) {
00070                $qt[$i]['field'] = $this->uri->getQueryValue("CISOFIELD" . $i);
00071             } else {
00072                break;
00073             }
00074 
00075             if ($this->uri->getQueryValue("CISOOP" . $i)) {
00076                $qt[$i]['mode'] = $this->uri->getQueryValue("CISOOP" . $i);
00077             } else {
00078                break;
00079             }
00080          } // for
00081          if ($this->uri->getQueryValue("CISOROOT")) {
00082             // CISOROOT may be a comma-delimited string, or an array.
00083             $aliases = array();
00084             if (is_array($this->uri->getQueryValue("CISOROOT"))) {
00085                $aliases = $this->uri->getQueryValue("CISOROOT");
00086             } else {
00087                $aliases = explode(",",
00088                      $this->uri->getQueryValue("CISOROOT"));
00089             }
00090             if (in_array("all", $aliases)) {
00091                $this->collections[] = DMCollectionFactory::getCollection("/dmdefault");
00092             } else {
00093                foreach ($aliases as $a) {
00094                   if ($a) {
00095                      $this->collections[] = DMCollectionFactory::getCollection($a);
00096                   }
00097                }
00098             }
00099          } // if
00100       } // else
00101 
00102       // check for presence of CISOROOT, CISOFIELD, CISOOP, or CISOBOX
00103       foreach ($this->uri->getQuery() as $kv) {
00104          if (substr($kv['key'], 0, 8) == "CISOROOT"
00105                || substr($kv['key'], 0, 9) == "CISOFIELD"
00106                || substr($kv['key'], 0, 6) == "CISOOP"
00107                || substr($kv['key'], 0, 7) == "CISOBOX") {
00108             $this->is_present = true;
00109             break;
00110          }
00111       }
00112 
00113       foreach ($qt as $t) {
00114          if (!array_key_exists("field", $t)) {
00115             continue;
00116          }
00117          if (!array_key_exists("mode", $t)) {
00118             continue;
00119          }
00120          $f = new DMDCElement($t['field']);
00121          $f->setCollection(DMCollectionFactory::getCollection("/dmdefault"));
00122          $term = new DMQueryPredicate();
00123          $term->setString($t['string']);
00124          $term->setField(new DMDCElement($f->getNick()));
00125          $term->setMode($t['mode']);
00126          if ($term->isValid()) {
00127             $this->input_terms[] = $term;
00128          }
00129       }
00130 
00131       // date stuff
00132       if ($this->uri->getQueryValue("date_qualifier")) {
00133          $this->setDateQualifier(
00134                substr($this->uri->getQueryValue("date_qualifier"), 0, 6));
00135       }
00136       if ($this->uri->getQueryValue("proximity")) {
00137          $this->setProximity(
00138                (int) substr($this->uri->getQueryValue("proximity"), 0, 3));
00139       }
00140 
00141       if (in_array($this->getDateQualifier(), array("from", "after"))) {
00142          if (strlen($this->uri->getQueryValue("y1")) > 0
00143                && strlen($this->uri->getQueryValue("y1")) <= 8) {
00144             $this->setBeginDate(
00145                new DMDateTime(sprintf("%d-%d-%d",
00146                      $this->uri->getQueryValue("y1"),
00147                      $this->uri->getQueryValue("m1"),
00148                      $this->uri->getQueryValue("d1"))));
00149          }
00150       }
00151       if (in_array($this->getDateQualifier(), array("from", "before"))) {
00152          if (strlen($this->uri->getQueryValue("y2")) > 0
00153                && strlen($this->uri->getQueryValue("y2")) <= 8) {
00154             $this->setEndDate(
00155                new DMDateTime(sprintf('%d-%d-%d',
00156                      $this->uri->getQueryValue("y2"),
00157                      $this->uri->getQueryValue("m2"),
00158                      $this->uri->getQueryValue("d2"))));
00159          }
00160       }
00161       if ($this->getDateQualifier() == "on") {
00162          if (strlen($this->uri->getQueryValue("y1")) > 0
00163                && strlen($this->uri->getQueryValue("y1")) <= 8) {
00164             $this->setOnDate(
00165                new DMDateTime(sprintf('%d-%d-%d',
00166                      $this->uri->getQueryValue("y1"),
00167                      $this->uri->getQueryValue("m1"),
00168                      $this->uri->getQueryValue("d1"))));
00169          }
00170       }
00171    }
00172 
00176    public function isPresent() {
00177       return $this->is_present;
00178    }
00179 
00184    public function getBeginDate() {
00185       return $this->begin_date;
00186    }
00187 
00188    private function setBeginDate(DMDateTime $date) {
00189       $this->begin_date = $date;
00190    }
00191 
00196    public function getCollections() {
00197       return $this->collections;
00198    }
00199 
00204    public function getDateQualifier() {
00205       return $this->date_qualifier;
00206    }
00207 
00208    private function setDateQualifier($q) {
00209       $valid = self::$valid_date_qualifiers;
00210       $valid[] = null;
00211       if (!in_array($q, $valid)) {
00212          throw new DMIllegalArgumentException(
00213             sprintf(DMLocalizedString::getString("INVALID_DATE_QUALIFIER"),
00214                implode(", ", self::$valid_date_qualifiers)));
00215       }
00216       $this->date_qualifier = $q;
00217    }
00218 
00223    public function getEndDate() {
00224       return $this->end_date;
00225    }
00226 
00227    private function setEndDate(DMDateTime $date) {
00228       $this->end_date = $date;
00229    }
00230 
00235    public function getOnDate() {
00236       return $this->on_date;
00237    }
00238 
00239    private function setOnDate(DMDateTime $date) {
00240       $this->on_date = $date;
00241    }
00242 
00246    public function getProximity() {
00247       return $this->proximity;
00248    }
00249 
00250    private function setProximity($int) {
00251       $this->proximity = $int;
00252    }
00253 
00259    public function getPredicate($index) {
00260       $terms = $this->getTerms();
00261       if ($index + 1 > count($terms)) {
00262          return false;
00263       }
00264       return ($terms[$index] instanceof DMQueryPredicate)
00265          ? $terms[$index] : null;
00266    }
00267 
00272    public function getTerms() {
00273       $begin_date = "00000000";
00274       if ($this->getBeginDate() instanceof DMDateTime) {
00275          $begin_date = $this->getBeginDate()->format("Ymd");
00276       }
00277 
00278       $end_date = "99999999";
00279       if ($this->getEndDate() instanceof DMDateTime) {
00280          $end_date = $this->getEndDate()->format("Ymd");
00281       }
00282 
00283       $terms = array();
00284       foreach ($this->input_terms as $t) {
00285          $terms[] = clone($t);
00286       }
00287 
00288       if (count($terms) < 1) {
00289          return array();
00290       }
00291 
00292       $on_date = null;
00293       if ($this->getOnDate() instanceof DMDateTime) {
00294          $on_date = $this->getOnDate()->format("Ymd");
00295       }
00296 
00297       // date search
00298       if (!($begin_date == "00000000" && $end_date == "99999999"
00299             && empty($on_date))) {
00300          if (!$this->collections[0] instanceof DMCollection) {
00301             return array();
00302          }
00303          $nick = $this->collections[0]->getDateSearchField()->getNick();
00304          $m = "exact";
00305          $s = ($on_date) ? $on_date : $begin_date . "-" . $end_date;
00306          if ($terms[1] instanceof DMQueryPredicate) {
00307             $terms[1]->setDate(true);
00308             $terms[1]->setString($s);
00309             $terms[1]->setField(new DMDCElement($nick));
00310             $terms[1]->setMode($m);
00311          } else {
00312             $term = new DMQueryPredicate();
00313             $term->setString($s);
00314             $term->setField(new DMDCElement($nick));
00315             $term->setMode($m);
00316             $term->setDate(true);
00317             $terms[] = $term;
00318          }
00319       } else if ($this->getProximity() > 0) { // proximity search
00320          $s = sprintf("%s near%d %s",
00321             $terms[0]->getString(),
00322             $this->getProximity(),
00323             $terms[1]->getString()
00324          );
00325          $m = "exact";
00326          $term = new DMQueryPredicate();
00327          $term->setString($s);
00328          $term->setField(new DMDCElement("any"));
00329          $term->setMode($m);
00330          $term->setProximity(true);
00331          $terms = array($term);
00332       }
00333 
00334       return $terms;
00335    }
00336 
00342    public function validate() {
00343       // if no date is set, make sure all fields have been filled in
00344       if (!$this->getBeginDate() instanceof DMDateTime
00345             && !$this->getEndDate() instanceof DMDateTime
00346             && !$this->getOnDate() instanceof DMDateTime) {
00347          $i = 0;
00348          foreach ($this->getTerms() as $t) {
00349             if (strlen($t->getString()) < 1) {
00350                $i++;
00351             }
00352          }
00353          if ($i == count($this->getTerms())) {
00354             throw new DMIllegalArgumentException(
00355                DMLocalizedString::getString("MISSING_SEARCH_TERM"));
00356          }
00357       }
00358       // make sure end date is always >= begin date
00359       if ($this->getBeginDate() instanceof DMDateTime
00360             && $this->getEndDate() instanceof DMDateTime) {
00361          if ($this->getBeginDate() > $this->getEndDate()) {
00362             throw new DMIllegalArgumentException(
00363                DMLocalizedString::getString("FROM_DATE_LATER"));
00364          }
00365       }
00366       // if a date is chosen...
00367       if ($this->getBeginDate() instanceof DMDateTime
00368             || $this->getEndDate() instanceof DMDateTime) {
00369          // make sure there is only one term
00370          // (count is 2 because the date is always the 2nd term)
00371          if (count($this->getTerms()) > 2) {
00372             throw new DMIllegalArgumentException(
00373                DMLocalizedString::getString("MAX_TERMS_IN_DATE_SEARCH"));
00374          }
00375          // make sure a specific field is being searched (not "any")
00376          foreach ($this->getTerms() as $t) {
00377             if ($t->getField()->getNick() == "any") {
00378                throw new DMIllegalArgumentException(
00379                   DMLocalizedString::getString("ANY_FIELD_IN_DATE_SEARCH"));
00380             }
00381          }
00382       }
00383       // if 'none' is selected as a mode, make sure another mode has been
00384       // selected as well (cdm doesn't like the "naked none")
00385       $tmp = array();
00386       foreach ($this->getTerms() as $t) {
00387          $tmp[] = $t->getMode();
00388       }
00389       $tmp = array_unique($tmp);
00390       if (in_array("none", $tmp) && count($tmp) == 1) {
00391          throw new DMIllegalArgumentException(
00392             DMLocalizedString::getString("NAKED_NONE_OPERAND"));
00393       }
00394       // if a proximity int is supplied, make sure both strings exist
00395       if ($this->getProximity() > 0) {
00396          $i = 0;
00397          foreach ($this->input_terms as $t) {
00398             if (strlen($t->getString()) > 0) {
00399                $i++;
00400             }
00401          }
00402          if ($i < 2) {
00403             throw new DMIllegalArgumentException(
00404                DMLocalizedString::getString("MISSING_PROXIMITY_STRING"));
00405          }
00406       }
00407 
00408       return true;
00409    }
00410 
00411 }
 All Data Structures Functions Variables