vid; } $query = db_select('taxonomy_term_data', 't'); $query->addTag('translatable'); $query->addTag('term_access'); // Select rows that match by term name. $tags_return = $query ->fields('t', array('tid', 'name')) ->condition('t.vid', $vids) ->condition('t.name', '%' . db_like($typed) . '%', 'LIKE') ->range(0, 10) ->execute() ->fetchAllKeyed(); $term_matches = array(); foreach ($tags_return as $tid => $name) { $n = $name; // Term names containing commas or quotes must be wrapped in quotes. // if (strpos($name, ',') !== FALSE || strpos($name, '"') !== FALSE) { // $n = '"' . str_replace('"', '""', $name) . '"'; // } $term_matches[$n] = check_plain($name); } } drupal_json_output($term_matches); } /** * materio_search_api_autocomplete_searchapi($typed = '') * * GOOD one using searchapi (SOLR) */ function materio_search_api_autocomplete_searchapi($typed = ''){ // If the request has a '/' in the search text, then the menu system will have // split it into multiple arguments, recover the intended $tags_typed. $args = func_get_args(); $typed = implode('/', $args); // dsm($typed, 'typed'); if ($typed != '') { // search for patterns like key -another key +lastkey // and provide auto completion for the last key preg_match_all('/\s?[\+|-]?[^\s]+/', $typed, $adv_search_q); // dsm($adv_search_q, "adv_search_q"); preg_match('/^(\+|-)?(.*)$/', trim(array_pop($adv_search_q[0])), $last); // dsm($last, "last"); $tosearch = isset($last[2]) ? $last[2] : $typed; // build the query global $language; $index_machine_name = variable_get('autocompletesearchindex_'.$language->language, -1); $query = search_api_query($index_machine_name); // $query_filter = $query->createFilter(); // $query_filter->condition('name', $tosearch); // $query_filter->condition('type', 'article'); // $query->filter($query_filter); $query->keys($tosearch); $tags_return = $query->execute(); // dsm($tags_return, '$tags_return'); if($tags_return['result count']){ $term_matches = array(); $index = search_api_index_load($index_machine_name); $delta = 0; foreach ($index->loadItems(array_keys($tags_return['results'])) as $item) { //dsm($item, '$item'); //$term_matches[$item->tid] = check_plain($item->name); // $term_matches[check_plain($item->name)] = check_plain($item->name); // TODO: leave tags with nodes $itemname = $item->name; $term_matches[trim(implode(' ', $adv_search_q[0]).' "'.$last[1].$itemname).'"'] = check_plain($itemname); $delta++; if($delta > 15) break; } drupal_json_output($term_matches); }else{ drupal_json_output(array()); } }else{ return; } // dsm($term_matches, 'term_matches'); // return 'debug mode of materio_search_api_autocomplete_searchapi'; } /** * materio_search_api_results_search() * * */ function materio_search_api_results_search(){ //dsm("materio_search_api_results_search"); // retreive typed words separated by slashes as a sentence $args = func_get_args(); // dsm($args, 'materio_search_api_results_search :: args'); $filters_search = false; if(isset($args[0]) && $args[0] == "filters"){ $filters_search = array_shift($args); } $keys = $args; // $keys = explode(' ',implode(' ',$args)); // dsm($keys, 'keys'); $typed = implode(' ', $keys); // dsm($typed, 'typed'); # with parse mode terms we use a single string of words seperated by spaces wich will be OR or AND regarding the conjunction query option # had to add q.op = OR on solr requesthandler on solrconfig.xml // remove query page params preg_match_all('/\?page=([0-9]+)/', $typed, $pages); //dsm($pages, '$pages'); if($pages[0]){ $typed = str_replace($pages[0][0], '', $typed); } // dsm($typed, 'typed'); if ($typed) { global $language; global $user; # retrieve viewmode and then use it to define the query range $viewmode = isset($user->data['materiosearchapi_viewmode']) ? $user->data['materiosearchapi_viewmode'] : variable_get('defaultviewmode', 'full'); $limit = variable_get($viewmode.'_limite', '10'); // dsm($limit, "limit"); $offset = pager_find_page() * $limit; //$page*$limit;// // dsm($offset, "offset"); # Normal search if(user_access('use materio search api')){ // dsm('normal search'); // TODO: this two following functions calls should be merged, it's not clean as it is if(!$filters_search){ $results = msa_solrquery_materiauxbreves($typed, $language, $user, $offset, $limit); $human_readable_keywords = $typed; }else{ // $keys = explode("+", $typed); // foreach ($keys as $value) { // $tids[] = intval($value); // } $tids = array_map('intval', explode('+', $typed)); $results = msa_solrquery_filterssearch($tids, $language, $user, $offset, $limit); foreach ($tids as $tid) { $tnames[] = taxonomy_term_load($tid)->name; } $human_readable_keywords = implode(" + ", $tnames); } } # only breves search (+ related materials) # not used anymore as free users not exists anymore else if(user_access('use materio search api for breves')){ // dsm('limited search'); $results = msa_solrquery_breves($typed, $language, $user, $offset, $limit); } // for all case $ret['results']['#results'] = $results; $ret['results']['#items'] = $results['items']; // $ret['results']['#index'] = $results['index']; $ret['results']['#theme'] = 'materio_search_api_results'; $ret['results']['#keys'] = $human_readable_keywords; $ret['results']['#view_mode'] = $viewmode; // page title drupal_set_title(''.check_plain($human_readable_keywords), PASS_THROUGH); // render results if(isset($results)){ // Load pager. // if ($results['result count'] > $page->options['per_page']) { pager_default_initialize($results['result count'], $limit); $ret['results']['#pager'] = theme('pager'); // } if (!empty($results['ignored'])) { drupal_set_message( t('The following search keys are too short or too common and were therefore ignored: "@list".', array( '@list' => implode(t('", "'), $results['ignored']) ) ), 'warning' ); } if (!empty($results['warnings'])) { foreach ($results['warnings'] as $warning) { drupal_set_message($warning, 'warning'); } } } } // dsm($ret, 'ret'); return $ret; } function msa_solrquery_materiauxbreves($keys, $language, $user, $offset, $limit){ // dsm($offset, 'offset'); // dsm($limit, 'limit'); // -- communs --// # define default bundle option (materiaux, breves) $default_bundles = array(); // TODO: this can't work as $taxo_index is not defined yet if(isset($taxo_index->options['data_alter_callbacks']['search_api_alter_bundle_filter']['settings']['bundles'])){ $indexed_bundles = $taxo_index->options['data_alter_callbacks']['search_api_alter_bundle_filter']['settings']['bundles']; foreach ($indexed_bundles as $bundle) { $default_bundles[] = $bundle; } } # choose solr query bundle option $bundles_filter = isset($user->data['materiosearchapi_bundlesfilter']) ? $user->data['materiosearchapi_bundlesfilter'] : $default_bundles; // -- -- taxo search AND -- -- // # define search api solr index $taxo_index_machine_name = variable_get('taxonomysearchindex_'.$language->language, -1); $taxo_index = search_api_index_load($taxo_index_machine_name); # choose solr query options $query_options = array('conjunction'=>'AND', 'parse mode'=>'terms'); #create the solr query for taxonomy search $taxo_query = search_api_query($taxo_index_machine_name, $query_options) ->keys($keys); # apply bundle options to solr query if usefull if(count($bundles_filter)){ $filter = $taxo_query->createFilter('OR'); foreach ($bundles_filter as $type) $filter->condition('type', $type, '='); $taxo_query->filter($filter); } // $query->setOption('search_api_bypass_access', true); # add user access solr query option $taxo_query->setOption('search_api_access_account', $user); // $taxo_query->setOption('q.op', 'OR'); #execute first time to get the all items, to be able to filter the full text research $taxo_total_results = $taxo_query->execute(); // dsm($taxo_total_results, "taxo total results"); $return = array( "results" => $taxo_total_results['results'] ); // -- -- full text search -- -- // #define search api solr index $fulltxt_index_machine_name = variable_get('fulltextsearchindex_'.$language->language, -1); $fulltxt_index = search_api_index_load($fulltxt_index_machine_name); # choose solr query options $query_options = array('conjunction'=>'OR', 'parse mode'=>'terms'); #create the solr query for taxonomy search $fulltxt_query = search_api_query($fulltxt_index_machine_name, $query_options) ->keys($keys); # apply bundle options to solr query if usefull if(count($bundles_filter)){ $filter = $fulltxt_query->createFilter('OR'); foreach ($bundles_filter as $type) $filter->condition('type', $type, '='); $fulltxt_query->filter($filter); } # filter to remove precedent search query $nid_filter = $fulltxt_query->createFilter('AND'); foreach ($results['results'] as $nid => $item) $nid_filter->condition('nid', $nid, '<>'); $fulltxt_query->filter($nid_filter); # add user access solr query option $fulltxt_query->setOption('search_api_access_account', $user); # execute solr query and record results $fulltxt_results = $fulltxt_query->execute(); // dsm($fulltxt_results, "fulltxt_results"); // -- -- merge taxo and full text search -- -- // # add the fulltext search results to the global results $return['results'] += $fulltxt_results['results']; # count global results $return['result count'] = count($return['results']); # create items array with the good range $return['items'] = array(); $o = -1; foreach ($return['results'] as $nid => $value) { $o++; if( $o < $offset ) continue; if ($o >= $offset+$limit) break; $return['items'][$nid] = node_load($nid); } # TODO: cache the results with cache graceful : http://drupal.org/project/cache_graceful // dsm($return, 'return'); return $return; } function msa_solrquery_filterssearch($tids, $language, $user, $offset, $limit){ // dsm($tids, "tids"); // dsm($offset, 'offset'); // dsm($limit, 'limit'); // init empty results array in wich we will concaten different queries $return = array( "results" => array() ); # define search api solr index $advancedsearch_index_machine_name = variable_get('advancedsearchindex_'.$language->language, -1); // dsm($advancedsearch_index_machine_name); $taxo_index = search_api_index_load($advancedsearch_index_machine_name); # choose solr query options $query_options = array('conjunction'=>'AND'); // get searchable field names and run one by one the search // eventualy concat all results $fields = msa_get_custom_onto_taxo_searchable_fields(); // run a search for each tag (results will be intersected later) foreach ($tids as $i => $tid) { $tmps_results[$i] = array(); // run a search for a tag for each field foreach ($fields['tid'] as $field) { # create the solr query for taxonomy search $query = search_api_query($advancedsearch_index_machine_name, $query_options); // ->keys("*:*"); // ->range($offset, $limit); // https://www.drupal.org/node/2596523 $filter = $query->createFilter('AND'); $filter->condition($field['name'], $tid); $query->filter($filter); # add user access solr query option $query->setOption('search_api_access_account', $user); // $query->setOption('search_api_bypass_access', true); # execute $results = $query->execute(); // dsm($results, "results"); // concat each field results for one tag $tmps_results[$i] += $results['results']; } } // dsm($tmps_results, "tmp_resuslts"); // do the intersect and score routine if (count($tmps_results) > 1) { // if we have more than one tag $results_intersected = array_intersect_key($tmps_results[0], $tmps_results[1]); if(count($tmps_results > 2)){ // if we have more than 2 tags for ($i=2; $i < count($tmps_results); $i++) { $results_intersected = array_intersect_key($results_intersected, $tmps_results[$i]); } } // dsm($results_intersected, 'results_intersected'); foreach ($results_intersected as $tid => $v) { $scores = array(); for ($j=0; $j < count($tmps_results); $j++) { $i = 0; foreach ($tmps_results[$j] as $key => $vv) { if ($tid === $key) { $scores[] = $i; break; } $i++; } } $results_intersected[$tid]['score'] = array_sum($scores) / count($scores); } uasort($results_intersected, "msa_cmp_filtered_results"); // dsm($results_intersected, 'results_intersected scored'); } else{ $results_intersected = $tmps_results[0]; } $return['results'] = $results_intersected; # count global results $return['result count'] = count($results_intersected); # create items array with the good range $return['items'] = array(); $o = -1; foreach ($return['results'] as $nid => $value) { $o++; if( $o < $offset ) continue; if ($o >= $offset+$limit) break; $return['items'][$nid] = node_load($nid); } # TODO: cache the results with cache graceful : http://drupal.org/project/cache_graceful // dsm($return, 'return'); return $return; } function msa_cmp_filtered_results($a, $b){ if ($a['score'] == $b['score']) { return 0; } return ($a['score'] < $b['score']) ? -1 : 1; } # not used anymore as free users not exists anymore function msa_solrquery_breves($typed, $language, $user, $offset, $limit){ $index_machine_name = variable_get('brevessearchindex_'.$language->language, -1); // dsm($index_machine_name, '$index_machine_name'); $index = search_api_index_load($index_machine_name); # choose solr query options $query_options = array('conjunction'=>'OR', 'parse mode'=>'direct'); #create the solr query $query = search_api_query($index_machine_name, $query_options) ->keys($typed) ->range($offset, $limit); // $query->setOption('search_api_bypass_access', true); # add user access solr query option $query->setOption('search_api_access_account', $user); # execute solr query and record results $results = $query->execute(); // dsm($results, 'results'); $results['index'] = $index;//search_api_index_load($index_machine_name); #could $could_index_machine_name = variable_get('fulltextsearchindex_'.$language->language, -1); $could_index = search_api_index_load($could_index_machine_name); # in case of free user search, run a real search to indicate how much items you could find $could_query = search_api_query($could_index_machine_name, array('conjunction'=>'OR', 'parse mode'=>'direct')) ->keys($typed); $could_results = $could_query->execute(); // dsm($could_results, 'could_results'); $results['could results'] = $could_results; # add items : breve + materials wich are in the could result $items = array(); $breves = $index->loadItems(array_keys($results['results'])); foreach ($breves as $nid => $breve) { if(!node_access('view', $breve)) continue; $items[] = $breve; $materiaux = field_get_items('node',$breve,'field_materiau_ref'); // dsm($materiaux, 'materiaux'); if($materiaux){ foreach ($materiaux as $value) { if(!isset($could_results['results'][$value['target_id']])) continue; $materiau = node_load($value['target_id']); if(node_access('view', $materiau)) $items[] = $materiau; } } } $results['items'] = $items; $results['breves count'] = $results['result count']; $results['result count'] = count($items); // dsm($results, "results"); # TODO: cache the results with cache graceful : http://drupal.org/project/cache_graceful return $results; } /** * materio_search_api_actuality() * */ # only breves search (+ related materials) # NOT USED ANYMORE as free users not exists anymore function materio_search_api_actuality(){ global $user; $useraccess = !isset($user->roles[10]) // student && !isset($user->roles[11]) // alphatesteur && !isset($user->roles[6]) // adherent && !isset($user->roles[8]) // premium && !isset($user->roles[12]) // translator && !isset($user->roles[13]) // admin showroom && !isset($user->roles[3]) // admin && !isset($user->roles[4]); // root if($useraccess){ $date_limit = strtotime('-4 month'); // dsm(date('d m y', $date_limit)); } # retrieve viewmode and then use it to define the query range $viewmode = user_access('access to materio database') ? isset($user->data['materiosearchapi_viewmode']) ? $user->data['materiosearchapi_viewmode'] : variable_get('defaultviewmode', 'cardmedium') : 'cardbig'; $limit = 10;//variable_get($viewmode.'_limite', '10'); $offset = pager_find_page() * $limit; // dsm($offset); $query = new EntityFieldQuery; $query ->entityCondition('entity_type', 'node') ->propertyCondition('status', 1) ->entityCondition('bundle', array('breve')) ->propertyOrderBy('created', 'DESC') ->range($offset,$limit); if($useraccess){ $query->propertyCondition('created', $date_limit, '>'); } $result = $query->execute(); // dsm($result, '$result'); $count_query = new EntityFieldQuery; $count_query ->entityCondition('entity_type', 'node') ->propertyCondition('status', 1) ->entityCondition('bundle', array('breve')); // dsm($count, 'count'); if($useraccess){ $count_query->propertyCondition('created', $date_limit, '>'); } $count = $count_query->count()->execute(); pager_default_initialize($count, $limit); $items = array(); if(isset($result['node'])){ foreach ($result['node'] as $nid => $n) { $breve = node_load($nid); if(!node_access('view', $breve)) continue; $items[] = $breve; // if(user_access('access to materio database')){ $materiaux = field_get_items('node',$breve,'field_materiau_ref'); // dsm($materiaux, 'materiaux'); if($materiaux){ foreach ($materiaux as $value) { $materiau = node_load($value['target_id']); if(node_access('view', $materiau)) $items[] = $materiau; } } // } } } // drupal_set_title(t('Actualities')); drupal_set_title(t('')); return theme('materio_search_api_actuality', array( 'items' => $items, 'view_mode' => $viewmode, 'count' => $count, 'pager' => theme('pager'), )); } function materio_search_api_viewmode_change($vm){ //dsm($vm, 'materio_search_api_viewmode_change'); $rep = _materio_search_api_change_viewmode($vm); //return 'debug mode for materio_search_api_viewmode_change'; // drupal_json_output($rep); drupal_goto(); }