示例#1
0
 public function doExecute()
 {
     $objSearch = $this->getSearchObject();
     // metalib search object
     $bolRedirect = false;
     // final determination to redirect on merge
     $objStatus = new DOMDocument();
     // search status
     $objMerge = new DOMDocument();
     // merge information
     $iProgress = null;
     // number of times metalib status polled
     // params from the request
     $id = $this->request->getProperty("group");
     $strGroup = $this->getGroupNumber();
     $strMergeRedirect = $this->request->getProperty("mergeRedirect");
     // configuration options
     $configShowMergedResults = $this->registry->getConfig("IMMEDIATELY_SHOW_MERGED_RESULTS", false, true);
     $configApplication = $this->registry->getConfig("APPLICATION_SID", false, "calstate.edu:xerxes");
     $configFacets = $this->registry->getConfig("FACETS", false, false);
     $configRecordsPerPage = $this->registry->getConfig("RECORDS_PER_PAGE", false, 10);
     $iRefreshSeconds = $this->registry->getConfig("SEARCH_PROGRESS_CAP", false, 35);
     $configHitsCap = (string) $iRefreshSeconds / 5;
     $configSortPrimary = $this->registry->getConfig("SORT_ORDER_PRIMARY", false, "rank");
     $configSortSecondary = $this->registry->getConfig("SORT_ORDER_SECONDARY", false, "year");
     // access control
     $objSearchXml = $this->getCache($id, "search", "DOMDocument");
     Xerxes_Helper::checkDbListSearchableByUser($objSearchXml, $this->request, $this->registry);
     // redirect link base
     $arrParams = array("base" => "metasearch", "action" => "results", "group" => $id);
     // determine if redirect after merge
     if ($configShowMergedResults == true) {
         $bolRedirect = true;
     }
     if ($strMergeRedirect == "false") {
         $bolRedirect = false;
     } else {
         if ($strMergeRedirect == "true") {
             $bolRedirect = true;
         }
     }
     // get status of the search and cache result
     $objStatus = $objSearch->searchStatus($strGroup);
     $this->setCache($id, "group", $objStatus);
     // cap the number of refreshes
     if ($this->request->getSession("refresh-{$strGroup}") != null) {
         // get refresh count
         $iProgress = (int) $this->request->getSession("refresh-{$strGroup}");
         // if we hit limit, set metalib finish flag to true
         if ($iProgress >= (int) $configHitsCap) {
             $objSearch->setFinished(true);
         } else {
             $iProgress++;
             $this->request->setSession("refresh-{$strGroup}", $iProgress);
         }
     } else {
         $this->request->setSession("refresh-{$strGroup}", 1);
     }
     // if done see if there are results and merge and redirect,
     // otherwise this will fall thru and continue with auto refreshing
     if ($objSearch->getFinished() == true) {
         $this->request->setSession("refresh-{$strGroup}", 10);
         // check to see if there are any documents to merge, and then merge
         // and create facets
         $iGroupTotal = 0;
         // total number of hits in the group
         $arrDatabaseHits = array();
         // total number of databases with hits
         $objSimpleXml = simplexml_import_dom($objStatus->documentElement);
         $bolSearchLinkHit = false;
         $strSearchLinkSet = "";
         foreach ($objSimpleXml->xpath("//base_info") as $objBase) {
             if ((string) $objBase->no_of_documents == "888888888") {
                 $bolSearchLinkHit = true;
                 $strSearchLinkSet = (string) $objBase->set_number;
             } elseif ((int) $objBase->no_of_documents > 0) {
                 // we'll only count the databases with hits
                 $iGroupTotal += (int) $objBase->no_of_documents;
                 array_push($arrDatabaseHits, (string) $objBase->set_number);
             }
         }
         // only got a search-and-link database
         if ($iGroupTotal == 0 && $bolSearchLinkHit == true) {
             $arrParams["resultSet"] = $strSearchLinkSet;
             $this->request->setRedirect($this->request->url_for($arrParams));
             return 1;
         }
         // got hits
         if ($iGroupTotal > 0) {
             // we'll only issue the merge command if there is more than one database
             // with hits, otherwise there's no point
             if (count($arrDatabaseHits) == 1) {
                 $strSetNumber = $arrDatabaseHits[0];
                 // redirect to results page
                 $arrParams["resultSet"] = $strSetNumber;
                 $this->cache->save();
                 $this->request->setRedirect($this->request->url_for($arrParams));
                 return 1;
             } else {
                 $strMergeSet = "";
                 // merge set identifier
                 $iMergeCount = 0;
                 // count of documents in the merge set
                 // merge the top results
                 $objMerge = $objSearch->merge($strGroup, $configSortPrimary, $configSortSecondary);
                 // get the newly updated status that resulted from that merge
                 // operation and cache
                 $objStatus = $objSearch->searchStatus($strGroup);
                 $this->setCache($id, "group", $objStatus);
                 $objXPath = new DOMXPath($objMerge);
                 // extract new merge set number and total hits for merge set
                 if ($objXPath->query("//new_set_number")->item(0) != null) {
                     $strMergeSet = $objXPath->query("//new_set_number")->item(0)->nodeValue;
                 }
                 if ($objXPath->query("//no_of_documents")->item(0) != null) {
                     $iMergeCount = (int) $objXPath->query("//no_of_documents")->item(0)->nodeValue;
                 }
                 if ($strMergeSet == "") {
                     //throw new Exception( "Result from Metalib returned no set number" );
                 }
                 // cache the facets response, but only if there are more results than a single page
                 // and facets have been turned on
                 if ($iMergeCount > $configRecordsPerPage && $configFacets == true) {
                     $objFacetXml = $objSearch->facets($strMergeSet, "all", $configApplication);
                     $this->setCache($id, "facets", $objFacetXml);
                     // cache a slimmed down version of the facets as well
                     // to ease the load on the interface
                     $strFacetSlim = Xerxes_Framework_Parser::transform($objFacetXml, "xsl/utility/facets-slim.xsl");
                     $this->setCache($id, "facets_slim", $strFacetSlim);
                 }
             }
             // redirect to results page with merge set
             if ($bolRedirect == true) {
                 // catch no hits
                 if ($iMergeCount == 0) {
                     // check to see if any of the individual dbs had a search-and-link with
                     // a 'results found' indicator
                     $bolIndividual = false;
                     $strIndividualSet = "";
                     foreach ($objStatus->getElementsByTagName("base_info") as $objDb) {
                         foreach ($objDb->getElementsByTagName("no_of_documents") as $objDocs) {
                             if ((int) $objDocs->nodeValue > 0) {
                                 $bolIndividual = true;
                                 if ($objDb->getElementsByTagName("set_number")->item(0) != null) {
                                     $strIndividualSet = $objDb->getElementsByTagName("set_number")->item(0)->nodeValue;
                                     break 2;
                                 }
                             }
                         }
                     }
                     if ($bolIndividual == true) {
                         // redirect to individual results page
                         $arrParams["resultSet"] = $strIndividualSet;
                         $this->cache->save();
                         $this->request->setRedirect($this->request->url_for($arrParams));
                         return 1;
                     }
                 } else {
                     // redirect to merged results page
                     $arrParams["resultSet"] = $strMergeSet;
                     $this->cache->save();
                     $this->request->setRedirect($this->request->url_for($arrParams));
                     return 1;
                 }
             }
         }
     }
     // build the response from previous cached data
     $objXml = new DOMDocument();
     $objXml = $this->documentElement();
     $objXml = $this->addSearchInfo($objXml, $id);
     $objXml = $this->addStatus($objXml, $id);
     $objXml = $this->addProgress($objXml, $this->request->getSession("refresh-{$strGroup}"));
     $this->request->addDocument($objXml);
     $this->saveCache();
     return 1;
 }
 public function doExecute()
 {
     $start = microtime(true);
     $arrFields = array();
     // fields to return in response
     $iMaximumRecords = 10;
     // maximum number of records to return
     $iTotalHits = 0;
     // total number of hits in response
     $arrResults = array();
     // holds results returned
     // metalib search object
     $objSearch = $this->getSearchObject();
     // parameters from request
     $id = $this->request->getProperty("group");
     $strGroup = $this->getGroupNumber();
     $strResultSet = $this->request->getProperty("resultSet");
     $iStartRecord = (int) $this->request->getProperty("startRecord");
     // access control
     $objSearchXml = $this->getCache($id, "search", "DOMDocument");
     Xerxes_Helper::checkDbListSearchableByUser($objSearchXml, $this->request, $this->registry);
     // marc fields to return from metalib; we specify these here in order to keep
     // the response size as small (and thus as fast) as possible
     $strMarcFields = self::MARC_FIELDS_BRIEF;
     // $strMarcFields = "#####, OPURL";
     // configuration options
     $configRecordPerPage = $this->registry->getConfig("RECORDS_PER_PAGE", false, self::DEFAULT_RECORDS_PER_PAGE);
     $configMarcFields = $this->registry->getConfig("MARC_FIELDS_BRIEF", false);
     $configIncludeMarcRecord = $this->registry->getConfig("XERXES_BRIEF_INCLUDE_MARC", false, false);
     $configFacets = $this->registry->getConfig("FACETS", false, false);
     // add additional marc fields specified in the config file
     if ($configMarcFields != null) {
         $configMarcFields .= ", " . $strMarcFields;
     } else {
         $configMarcFields = $strMarcFields;
     }
     // empty querystring values will return as 0, so fix here in case
     if ($iStartRecord == 0) {
         $iStartRecord = 1;
     }
     $iMaximumRecords = (int) $configRecordPerPage;
     // extract total hits from this result set
     $objXml = $this->getCache($id, "group", "SimpleXML");
     foreach ($objXml->xpath("//base_info") as $base_info) {
         if ($base_info->set_number == $strResultSet) {
             $strTotalHits = $base_info->no_of_documents;
             if ($strTotalHits == "888888888") {
                 $iTotalHits = 1;
             } else {
                 $iTotalHits = (int) $strTotalHits;
             }
         }
     }
     // set marc fields to return in response
     $arrFields = explode(",", $configMarcFields);
     // get results from metalib
     $objResultsXml = $objSearch->retrieve($strResultSet, $iStartRecord, $iMaximumRecords, $iTotalHits, "customize", $arrFields);
     // build the response, including previous cached data
     $objXml = new DOMDocument();
     $objXml = $this->documentElement();
     $objXml = $this->addSearchInfo($objXml, $id);
     $objXml = $this->addStatus($objXml, $id, $strResultSet, $iTotalHits);
     $objXml = $this->addProgress($objXml, $this->request->getSession("refresh-{$strGroup}"));
     // if this is a search-and-link resource add the original xml that contains the link
     if ($objResultsXml->getElementsByTagName("search_and_link")->item(0) != null) {
         $objImport = $objXml->importNode($objResultsXml->documentElement, true);
         $objXml->documentElement->appendChild($objImport);
         // this is a http post submission, so we need to see if we have added the post
         // data to the alternate record link in the IRD, since X-Server bug prevents this
         // from coming through in the response
         $objSearchType = $objResultsXml->getElementsByTagName("search_and_link_type")->item(0);
         if ($objSearchType != null) {
             if ($objSearchType->nodeValue == "POST") {
                 $objSearchXml = $this->getCache($id, "search", "SimpleXML");
                 $objGroupXml = $this->getCache($id, "group", "SimpleXML");
                 $databases_id = $objGroupXml->xpath("//base_info[set_number = '{$strResultSet}']/base_001");
                 if (count($databases_id) != 1) {
                     throw new Exception("cannot find search-and-link database in group cache");
                 }
                 $metalib_id = (string) $databases_id[0];
                 $databases = $objSearchXml->xpath("//database[@metalib_id='{$metalib_id}']");
                 if (count($databases) != 1) {
                     throw new Exception("cannot find database '{$metalib_id}' in search cache");
                 }
                 $database = $databases[0];
                 // the form action
                 $post = (string) $database->link_search_post;
                 // the data to be posted
                 $data = (string) $database->link_native_record_alternative;
                 if ($post == "" || $data == "") {
                     throw new Exception("cannot create http post elements for search-and-link database");
                 }
                 // xml close to what we need in html, just to make this easy
                 $objPostXML = $objXml->createElement("post");
                 $objXml->documentElement->appendChild($objPostXML);
                 $objForm = $objXml->createElement("form");
                 $objForm->setAttribute("action", Xerxes_Framework_Parser::escapeXml($post));
                 $objPostXML->appendChild($objForm);
                 foreach (explode("&", $data) as $pair) {
                     $arrKeys = explode("=", $pair);
                     $key = $arrKeys[0];
                     $value = $arrKeys[1];
                     // metalib docs say only TERM1 is used in the 'URL mask',
                     if ($value == "TERM1") {
                         $value = (string) $objSearchXml->pair[0]->query;
                     }
                     $objInput = $objXml->createElement("input");
                     $objInput->setAttribute("name", $key);
                     $objInput->setAttribute("value", $value);
                     $objForm->appendChild($objInput);
                 }
             }
         }
     } else {
         // add the records themselves
         foreach ($objResultsXml->getElementsByTagName("record") as $objRecord) {
             array_push($arrResults, $objRecord);
         }
         // this will also convert the marc-xml to xerxes_record, and check for an already
         // saved record
         $objXml = $this->addRecords($objXml, $arrResults, $configIncludeMarcRecord);
     }
     $objXml = $this->addFacets($objXml, $id, $configFacets);
     $this->request->addDocument($objXml);
     // echo time(true) - $start . "<br>";
     return 1;
 }