. * * For more information, contact Colosa Inc, 5304 Ventura Drive, * Delray Beach, FL, 33484, USA, or email info@colosa.com. */ /** * Class used as interface to have access to the search index services * * @author Herbert Saal Gutierrez * */ class BpmnEngine_Services_SearchIndex { private $_solrIsEnabled = false; private $_solrHost = ""; public function __construct ($solrIsEnabled = false, $solrHost = "") { // check if Zend Library is available // if(class_exists("Zend_Registry")){ // $registry = Zend_Registry::getInstance(); // //check if configuration is enabled // $this->solrIsEnabled = $registry->isRegistered('solrEnabled') && // $registry->get('solrEnabled') == 1; // $this->solrHost = // $registry->isRegistered('solrHost')?$registry->get('solrHost'):""; // } // else{ // //use the parameters to initialize class $this->_solrIsEnabled = $solrIsEnabled; $this->_solrHost = $solrHost; // } } /** * Verify if the Solr service is available * @gearman = false * @rest = false * @background = false * * no input parameters @param[in] * * @param [out] bool true if index service is enabled false in other case */ public function isEnabled () { // require_once (ROOT_PATH . // '/businessLogic/modules/SearchIndexAccess/Solr.php'); require_once ('class.solr.php'); $solr = new BpmnEngine_SearchIndexAccess_Solr( $this->_solrIsEnabled, $this->_solrHost ); return $solr->isEnabled(); } /** * Get the list of facets in base to the specified query and filter * @gearman = true * @rest = false * @background = false * * @param [in] Entity_FacetRequest facetRequestEntity Facet request entity * @param [out] array FacetGroup */ public function getFacetsList ($facetRequestEntity) { require_once ('class.solr.php'); // require_once (ROOT_PATH . // '/businessLogic/modules/SearchIndexAccess/Solr.php'); require_once ('entities/FacetGroup.php'); require_once ('entities/FacetItem.php'); require_once ('entities/SelectedFacetGroupItem.php'); require_once ('entities/FacetResult.php'); /** * *************************************************************** */ // get array of selected facet groups $facetRequestEntity->selectedFacetsString = str_replace( ',,', ',', $facetRequestEntity->selectedFacetsString ); // remove descriptions of selected facet groups $aGroups = explode( ',', $facetRequestEntity->selectedFacetsString ); $aGroups = array_filter( $aGroups ); // remove empty items $aSelectedFacetGroups = array (); foreach ($aGroups as $i => $value) { $gi = explode( ':::', $value ); $gr = explode( '::', $gi[0] ); $it = explode( '::', $gi[1] ); // create string for remove condition $count = 0; $removeCondition = str_replace( $value . ',', '', $facetRequestEntity->selectedFacetsString, $count ); if ($count == 0) { $removeCondition = str_replace( $value, '', $facetRequestEntity->selectedFacetsString, $count ); } $selectedFacetGroupData = array ('selectedFacetGroupName' => $gr[0],'selectedFacetGroupPrintName' => $gr[1],'selectedFacetItemName' => $it[0],'selectedFacetItemPrintName' => $it[1],'selectedFacetRemoveCondition' => $removeCondition ); $aSelectedFacetGroups[] = Entity_SelectedFacetGroupItem::createForRequest( $selectedFacetGroupData ); } /** * *************************************************************** */ // convert request to index request // create filters $filters = array (); if (! empty( $aSelectedFacetGroups )) { // exclude facetFields and facetDates included in filter from the next // list of facets foreach ($aSelectedFacetGroups as $value) { $facetRequestEntity->facetFields = array_diff( $facetRequestEntity->facetFields, array ($value->selectedFacetGroupName ) ); $facetRequestEntity->facetDates = array_diff( $facetRequestEntity->facetDates, array ($value->selectedFacetGroupName ) ); } // $facetFields = array_diff($facetFields, // $facetInterfaceRequestEntity->selectedFacetGroups); // $facetDates = array_diff($facetDates, // $facetInterfaceRequestEntity->selectedFacetGroups); foreach ($aSelectedFacetGroups as $group) { $filters[] = $group->selectedFacetGroupName . ':' . urlencode( $group->selectedFacetItemName ); } } $facetRequestEntity->filters = $filters; $solr = new BpmnEngine_SearchIndexAccess_Solr( $this->_solrIsEnabled, $this->_solrHost ); // create list of facets $facetsList = $solr->getFacetsList( $facetRequestEntity ); $numFound = $facetsList->response->numFound; $facetCounts = $facetsList->facet_counts; $facetGroups = array (); // convert facet fields result to objects /** * ********************************************************************* */ // include facet field results $facetFieldsResult = $facetsList->facet_counts->facet_fields; if (! empty( $facetFieldsResult )) { foreach ($facetFieldsResult as $facetGroup => $facetvalues) { if (count( $facetvalues ) > 0) // if the group have facets included { $data = array ('facetGroupName' => $facetGroup ); $data['facetGroupPrintName'] = $facetGroup; $data['facetGroupType'] = 'field'; $facetItems = array (); for ($i = 0; $i < count( $facetvalues ); $i += 2) { $dataItem = array (); $dataItem['facetName'] = $facetvalues[$i]; $dataItem['facetPrintName'] = $facetvalues[$i]; $dataItem['facetCount'] = $facetvalues[$i + 1]; $dataItem['facetSelectCondition'] = $facetRequestEntity->selectedFacetsString . (empty( $facetRequestEntity->selectedFacetsString ) ? '' : ',') . $data['facetGroupName'] . '::' . $data['facetGroupPrintName'] . ':::' . $dataItem['facetName'] . '::' . $dataItem['facetPrintName']; $newFacetItem = Entity_FacetItem::createForInsert( $dataItem ); $facetItems[] = $newFacetItem; } $data['facetItems'] = $facetItems; $newFacetGroup = Entity_FacetGroup::createForInsert( $data ); $facetGroups[] = $newFacetGroup; } } } /** * ********************************************************************* */ // include facet date ranges results $facetDatesResult = $facetsList->facet_counts->facet_dates; if (! empty( $facetDatesResult )) { foreach ($facetDatesResult as $facetGroup => $facetvalues) { if (count( (array) $facetvalues ) > 3) // if the group have any facets included // besides start, end and gap { $data = array ('facetGroupName' => $facetGroup ); $data['facetGroupPrintName'] = $facetGroup; $data['facetGroupType'] = 'daterange'; $facetItems = array (); $facetvalueskeys = array_keys( (array) $facetvalues ); foreach ($facetvalueskeys as $i => $k) { if ($k != 'gap' && $k != 'start' && $k != 'end') { $dataItem = array (); if ($i < count( $facetvalueskeys ) - 4) { $dataItem['facetName'] = '[' . $k . '%20TO%20' . $facetvalueskeys[$i + 1] . ']'; $dataItem['facetPrintName'] = '[' . $k . '%20TO%20' . $facetvalueskeys[$i + 1] . ']'; } else { // the last group $dataItem['facetName'] = '[' . $k . '%20TO%20' . $facetvalues->end . ']'; $dataItem['facetPrintName'] = '[' . $k . '%20TO%20' . $facetvalues->end . ']'; } $dataItem['facetCount'] = $facetvalues->$k; $dataItem['facetSelectCondition'] = $facetRequestEntity->selectedFacetsString . (empty( $facetRequestEntity->selectedFacetsString ) ? '' : ',') . $data['facetGroupName'] . '::' . $data['facetGroupPrintName'] . ':::' . $dataItem['facetName'] . '::' . $dataItem['facetPrintName']; $newFacetItem = Entity_FacetItem::createForInsert( $dataItem ); $facetItems[] = $newFacetItem; } } $data['facetItems'] = $facetItems; $newFacetGroup = Entity_FacetGroup::createForInsert( $data ); $facetGroups[] = $newFacetGroup; } } } // TODO:convert facet queries // ----- /** * *************************************************************** */ // Create a filter string used in the filter of results of a datatable $filterText = ''; // the list of selected filters used for filtering result, // send in ajax foreach ($aSelectedFacetGroups as $selectedFacetGroup) { $filterText .= $selectedFacetGroup->selectedFacetGroupName . ':' . urlencode( $selectedFacetGroup->selectedFacetItemName ) . ','; } $filterText = substr_replace( $filterText, '', - 1 ); // $filterText = ($filterText == '')?'':'&filterText='.$filterText; /** * *************************************************************** */ // Create result $dataFacetResult = array ('aFacetGroups' => $facetGroups,'aSelectedFacetGroups' => $aSelectedFacetGroups,'sFilterText' => $filterText ); $facetResult = Entity_FacetResult::createForRequest( $dataFacetResult ); return $facetResult; } /** * Get the total number of documents in search server * * @param string $workspace * @return integer number of documents * */ public function getNumberDocuments ($workspace) { require_once ('class.solr.php'); // require_once (ROOT_PATH . // '/businessLogic/modules/SearchIndexAccess/Solr.php'); $solr = new BpmnEngine_SearchIndexAccess_Solr( $this->_solrIsEnabled, $this->_solrHost ); // create list of facets $numberDocuments = $solr->getNumberDocuments( $workspace ); return $numberDocuments; } /** * Update document Index * * @param SolrUpdateDocumentEntity $solrUpdateDocumentEntity */ public function updateIndexDocument ($solrUpdateDocumentEntity) { G::LoadClass( 'solr' ); $solr = new BpmnEngine_SearchIndexAccess_Solr( $this->_solrIsEnabled, $this->_solrHost ); // create list of facets $solr->updateDocument( $solrUpdateDocumentEntity ); } /** * Delete document from index * * @param string $workspace * @param string $idQuery */ public function deleteDocumentFromIndex ($workspace, $idQuery) { G::LoadClass( 'solr' ); $solr = new BpmnEngine_SearchIndexAccess_Solr( $this->_solrIsEnabled, $this->_solrHost ); // create list of facets $solr->deleteDocument( $workspace, $idQuery ); } /** * Commit index changes * * @param string $workspace */ public function commitIndexChanges ($workspace) { G::LoadClass( 'solr' ); $solr = new BpmnEngine_SearchIndexAccess_Solr( $this->_solrIsEnabled, $this->_solrHost ); // commit $solr->commitChanges( $workspace ); } /** * Optimize index changes * * @param string $workspace */ public function optimizeIndexChanges ($workspace) { G::LoadClass( 'solr' ); $solr = new BpmnEngine_SearchIndexAccess_Solr( $this->_solrIsEnabled, $this->_solrHost ); // commit $solr->optimizeChanges( $workspace ); } /** * Call Solr server to return the list of paginated pages. * * @param FacetRequest $solrRequestData * @return Entity_SolrQueryResult */ public function getDataTablePaginatedList ($solrRequestData) { require_once ('class.solr.php'); require_once ('entities/SolrRequestData.php'); require_once ('entities/SolrQueryResult.php'); // prepare the list of sorted columns // verify if the data of sorting is available if (isset( $solrRequestData->sortCols[0] )) { for ($i = 0; $i < $solrRequestData->numSortingCols; $i ++) { // verify if column is sortable if ($solrRequestData->includeCols[$solrRequestData->sortCols[$i]] != '' && $solrRequestData->sortableCols[$i] == "true") { // change sorting column index to column names $solrRequestData->sortCols[$i] = $solrRequestData->includeCols[$solrRequestData->sortCols[$i]]; // define the direction of the sorting columns $solrRequestData->sortDir[$i] = $solrRequestData->sortDir[$i]; } } } // remove placeholder fields // the placeholder doesn't affect the the solr's response // $solrRequestData->includeCols = array_diff($solrRequestData->includeCols, // array('')); // execute query $solr = new BpmnEngine_SearchIndexAccess_Solr( $this->_solrIsEnabled, $this->_solrHost ); $solrPaginatedResult = $solr->executeQuery( $solrRequestData ); // get total number of documents in index $numTotalDocs = $solr->getNumberDocuments( $solrRequestData->workspace ); // create the Datatable response of the query $numFound = $solrPaginatedResult->response->numFound; $docs = $solrPaginatedResult->response->docs; // print_r($docs); // insert list of names in docs result $data = array ("sEcho" => '', // must be completed in response "iTotalRecords" => intval( $numTotalDocs ), // we must get the // total number of // documents "iTotalDisplayRecords" => $numFound,"aaData" => array () ); // copy result document or add placeholders to result foreach ($docs as $i => $doc) { $data['aaData'][$i] = array (); foreach ($solrRequestData->includeCols as $columnName) { if ($columnName == '') { $data['aaData'][$i][] = ''; // placeholder } else { if (isset( $doc->$columnName )) { $data['aaData'][$i][] = $doc->$columnName; } else { $data['aaData'][$i][] = ''; } } } } $solrQueryResponse = Entity_SolrQueryResult::createForRequest( $data ); // return $solrQueryResponse; } /** * Return the list of stored fields in the index. * * @param string $workspace * @return array of index fields */ public function getIndexFields ($workspace) { require_once ('class.solr.php'); $solr = new BpmnEngine_SearchIndexAccess_Solr( $this->_solrIsEnabled, $this->_solrHost ); // print "SearchIndex!!!!"; // create list of facets $solrFieldsData = $solr->getListIndexedStoredFields( $workspace ); // copy list of arrays $listFields = array (); foreach ($solrFieldsData->fields as $key => $fieldData) { if (array_key_exists( 'dynamicBase', $fieldData )) { $originalFieldName = substr( $key, 0, - strlen( $fieldData->dynamicBase ) + 1 ); // $listFields[strtolower($originalFieldName)] = $key; //in case of case insentive strings // Maintain case sensitive variable names $listFields[$originalFieldName] = $key; } else { // $listFields[strtolower($key)] = $key; // Maintain case sensitive variable names $listFields[$key] = $key; } } return $listFields; } }