From 097cf7fb47eb5f1936c92d3589b8b236d4169693 Mon Sep 17 00:00:00 2001 From: Mehmood Asghar Date: Wed, 17 Apr 2019 13:50:24 -0400 Subject: [PATCH 001/103] add support for SOLR search --- application/config/autoload.php | 3 +- application/config/solr.php | 115 ++ application/controllers/Catalog.php | 4 +- application/controllers/Solr.php | 124 ++ application/controllers/admin/Solr.php | 22 + application/controllers/api/Solr.php | 196 +++ application/helpers/events_helper.php | 60 + application/libraries/Catalog_search.php | 12 + application/libraries/Catalog_search_solr.php | 1059 +++++++++++++++++ application/libraries/Events.php | 88 ++ application/libraries/Solr_manager.php | 980 +++++++++++++++ .../models/Solr_delta_updates_model.php | 56 + application/views/solr/index.php | 179 +++ composer.json | 4 +- composer.lock | 242 +++- vendor/composer/autoload_psr4.php | 4 + vendor/composer/autoload_static.php | 23 + vendor/composer/installed.json | 248 ++++ 18 files changed, 3414 insertions(+), 5 deletions(-) create mode 100644 application/config/solr.php create mode 100644 application/controllers/Solr.php create mode 100644 application/controllers/admin/Solr.php create mode 100644 application/controllers/api/Solr.php create mode 100644 application/helpers/events_helper.php create mode 100644 application/libraries/Catalog_search_solr.php create mode 100644 application/libraries/Events.php create mode 100644 application/libraries/Solr_manager.php create mode 100644 application/models/Solr_delta_updates_model.php create mode 100644 application/views/solr/index.php diff --git a/application/config/autoload.php b/application/config/autoload.php index e5e0f9442..482eeb5c5 100644 --- a/application/config/autoload.php +++ b/application/config/autoload.php @@ -59,7 +59,8 @@ 'DB_Logger', 'MY_Exception', 'ion_auth', - 'breadcrumb' + 'breadcrumb', + 'events' ); /* diff --git a/application/config/solr.php b/application/config/solr.php new file mode 100644 index 000000000..e5d7c14f7 --- /dev/null +++ b/application/config/solr.php @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +*/ \ No newline at end of file diff --git a/application/controllers/Catalog.php b/application/controllers/Catalog.php index 80915d2b0..9980403ad 100644 --- a/application/controllers/Catalog.php +++ b/application/controllers/Catalog.php @@ -265,7 +265,7 @@ function _search() $offset= ($search_options->page-1)*$this->limit; //allowed fields for sort_by and sort_order - $allowed_fields = array('proddate','title','labl','nation','popularity','rank'); + $allowed_fields = array('year','title','labl','nation','popularity','rank'); $allowed_order=array('asc','desc'); //set default sort options, if passed values are not valid @@ -960,7 +960,7 @@ function access_policy($id=NULL) $this->cache->write($html, md5($section.$ddi_file.$language['lang']), 100); } - $html='

'.$survey['nation'].' - '.$survey['titl'].'



'.$html; + $html='

'.$survey['nation'].' - '.$survey['title'].'



'.$html; $this->template->add_css('themes/ddibrowser/ddi.css'); $this->template->add_meta(sprintf('',js_base_url().'catalog/access_policy/'.$id),NULL,'inline'); diff --git a/application/controllers/Solr.php b/application/controllers/Solr.php new file mode 100644 index 000000000..3907621b5 --- /dev/null +++ b/application/controllers/Solr.php @@ -0,0 +1,124 @@ +input->is_cli_request()){ + die("ERROR_NOT-CLI"); + } + + $this->load->library('solr_manager'); + error_reporting(E_ALL); + } + + + function index() + { + echo "SOLR"; + echo ''; + } + + public function ping_test() + { + var_dump($this->solr_manager->ping_test()); + } + + + /** + * + * recursive function to import all surveys + * + * @start_row start importing from a row number or NULL to start from first id + * @limit number of records to read at a time + * @loop whether to recursively call the function till the end of rows + * + * */ + public function full_import_surveys($start_row=NULL, $limit=10, $loop=TRUE) + { + $this->solr_manager->full_import_surveys($start_row, $limit, $loop); + } + + + /** + * + * remove all documents from index + * + **/ + function clean_index(){ + $this->solr_manager->clean_index(); + } + + + function get_total_documents_count() + { + echo $this->solr_manager->get_total_documents_count(); + } + + + + + /** + * + * recursive function to import all variables + * + * @start_row start importing from a row number or NULL to start from first id + * @limit number of records to read at a time + * @loop whether to recursively call the function till the end of rows + * + * */ + public function full_import_variables($start_row=NULL, $limit=100, $loop=TRUE) + { + $this->solr_manager->full_import_variables($start_row, $limit, $loop); + } + + + + /** + * + * recursive function to import all citations + * + * @start_row start importing from a row number or NULL to start from first id + * @limit number of records to read at a time + * @loop whether to recursively call the function till the end of rows + * + * */ + public function full_import_citations($start_row=NULL, $limit=100, $loop=TRUE) + { + $this->solr_manager->full_import_citations($start_row, $limit, $loop); + } + + + function delete_document() + { + die("disabled"); + $query='id:(cit-301 OR cit-302 OR cit-303 OR cit-304 OR cit-305)'; + $this->solr_manager->delete_document($query); + } + + function sync_solr_with_db() + { + die("disabled"); + $this->solr_manager->sync_solr_with_db(); + } + + +}//end-class \ No newline at end of file diff --git a/application/controllers/admin/Solr.php b/application/controllers/admin/Solr.php new file mode 100644 index 000000000..e64a0469d --- /dev/null +++ b/application/controllers/admin/Solr.php @@ -0,0 +1,22 @@ +load->library("Solr_manager"); + $this->template->set_template('admin'); + } + + function index() + { + $options['db_stats']=$this->solr_manager->get_db_counts(); + $options['solr_stats']=$this->solr_manager->get_solr_counts(); + $content=$this->load->view('solr/index',$options,true); + $this->template->write('title', t('resource_manager'),true); + $this->template->write('content', $content,true); + $this->template->render(); + } + +} \ No newline at end of file diff --git a/application/controllers/api/Solr.php b/application/controllers/api/Solr.php new file mode 100644 index 000000000..493536f51 --- /dev/null +++ b/application/controllers/api/Solr.php @@ -0,0 +1,196 @@ +load->library("Solr_manager"); + $this->is_admin_or_die(); + } + + //override authentication to support both session authentication + api keys + function _auth_override_check() + { + //session user id + if ($this->session->userdata('user_id')) + { + //var_dump($this->session->userdata('user_id')); + return true; + } + + parent::_auth_override_check(); + } + + + function ping_get() + { + try{ + $output=$this->solr_manager->ping_test(); + $output=array( + 'status'=>'success', + 'result'=>$output + ); + $this->set_response($output, REST_Controller::HTTP_OK); + } + catch(Exception $e){ + $error_output=array( + 'status'=>'failed', + 'message'=>$e->getMessage() + ); + $this->set_response($error_output, REST_Controller::HTTP_BAD_REQUEST); + } + } + + + /** + * + * recursive function to import all surveys + * + * @start_row start importing from a row number or NULL to start from first id + * @limit number of records to read at a time + * @loop whether to recursively call the function till the end of rows + * + * */ + public function full_import_surveys_get($start_row=NULL, $limit=10) + { + try{ + $output=$this->solr_manager->full_import_surveys($start_row, $limit, $loop=false); + $output=array( + 'status'=>'success', + 'result'=>$output + ); + $this->set_response($output, REST_Controller::HTTP_OK); + } + catch(Exception $e){ + $error_output=array( + 'status'=>'failed', + 'message'=>$e->getMessage() + ); + $this->set_response($error_output, REST_Controller::HTTP_BAD_REQUEST); + } + } + + + /** + * + * recursive function to import all variables + * + * @start_row start importing from a row number or NULL to start from first id + * @limit number of records to read at a time + * @loop whether to recursively call the function till the end of rows + * + * */ + public function full_import_variables_get($start_row=0, $limit=100) + { + try{ + $output=$this->solr_manager->full_import_variables($start_row, $limit, $loop=false); + $output=array( + 'status'=>'success', + 'result'=>$output + ); + $this->set_response($output, REST_Controller::HTTP_OK); + } + catch(Exception $e){ + $error_output=array( + 'status'=>'failed', + 'message'=>$e->getMessage() + ); + $this->set_response($error_output, REST_Controller::HTTP_BAD_REQUEST); + } + + } + + + /** + * + * recursive function to import all variables + * + * @start_row start importing from a row number or NULL to start from first id + * @limit number of records to read at a time + * @loop whether to recursively call the function till the end of rows + * + * */ + public function full_import_citations_get($start_row=0, $limit=5000) + { + try{ + $output=$this->solr_manager->full_import_citations($start_row, $limit, $loop=false); + $output=array( + 'status'=>'success', + 'result'=>$output + ); + $this->set_response($output, REST_Controller::HTTP_OK); + } + catch(Exception $e){ + $error_output=array( + 'status'=>'failed', + 'message'=>$e->getMessage() + ); + $this->set_response($error_output, REST_Controller::HTTP_BAD_REQUEST); + } + + } + + + public function db_counts_get() + { + try{ + $output=$this->solr_manager->get_db_counts(); + $output=array( + 'status'=>'success', + 'result'=>$output + ); + $this->set_response($output, REST_Controller::HTTP_OK); + } + catch(Exception $e){ + $error_output=array( + 'status'=>'failed', + 'message'=>$e->getMessage() + ); + $this->set_response($error_output, REST_Controller::HTTP_BAD_REQUEST); + } + } + + + public function clear_index_get() + { + try{ + $output=$this->solr_manager->clean_index(); + $output=array( + 'status'=>'success', + 'result'=>$output + ); + $this->set_response($output, REST_Controller::HTTP_OK); + } + catch(Exception $e){ + $error_output=array( + 'status'=>'failed', + 'message'=>$e->getMessage() + ); + $this->set_response($error_output, REST_Controller::HTTP_BAD_REQUEST); + } + } + + public function commit_get() + { + try{ + $output=$this->solr_manager->commit(); + $output=array( + 'status'=>'success', + 'result'=>$output + ); + $this->set_response($output, REST_Controller::HTTP_OK); + } + catch(Exception $e){ + $error_output=array( + 'status'=>'failed', + 'message'=>$e->getMessage() + ); + $this->set_response($error_output, REST_Controller::HTTP_BAD_REQUEST); + } + } + + +} \ No newline at end of file diff --git a/application/helpers/events_helper.php b/application/helpers/events_helper.php new file mode 100644 index 000000000..2e338db93 --- /dev/null +++ b/application/helpers/events_helper.php @@ -0,0 +1,60 @@ +events->emit('db.after.update', $object_type, $object_id,$action); + } +} + +if ( ! function_exists('emit_event_db_delete')) +{ + function emit_event_db_delete($object_type,$object_id,$action='atomic') + { + $ci =& get_instance(); + if(!is_events_library_loaded()){ + return false; + } + $ci->events->emit('db.after.delete', $object_type, $object_id,$action); + } +} + +if ( ! function_exists('is_events_library_loaded')) +{ + function is_events_library_loaded() + { + $ci =& get_instance(); + + if($ci->load->is_loaded('events')){ + return true; + } + else{ + return false; + } + } +} + +/* End of file events_helper.php */ +/* Location: ./system/helpers/events_helper.php */ \ No newline at end of file diff --git a/application/libraries/Catalog_search.php b/application/libraries/Catalog_search.php index eddc9cb1a..4563d578c 100644 --- a/application/libraries/Catalog_search.php +++ b/application/libraries/Catalog_search.php @@ -24,6 +24,14 @@ function __construct($params=array()){ //default/base search class require_once dirname(__FILE__) . '/Catalog_search_mysql.php'; + + $search_provider=$ci->config->item('search_provider'); + + //SOLR + if ($search_provider=='solr'){ + $driver='solr'; + } + switch ($driver) { case 'sqlsrv'; //extended sqlsrv class @@ -34,6 +42,10 @@ function __construct($params=array()){ case 'mysqli'; $this->search_obj= new catalog_search_mysql($params); break; + case 'solr'; + require_once dirname(__FILE__) . '/Catalog_search_solr.php'; + $this->search_obj= new catalog_search_solr($params); + break; default: throw new exception(sprintf("DRIVER [%s] NOT SUPPORTED",$driver)); } diff --git a/application/libraries/Catalog_search_solr.php b/application/libraries/Catalog_search_solr.php new file mode 100644 index 000000000..c23b9498e --- /dev/null +++ b/application/libraries/Catalog_search_solr.php @@ -0,0 +1,1059 @@ +'title', + 'nation'=>'nation', + 'year'=>'year_start', + 'popularity'=>'total_views', + 'rank'=>'score' + ); + + var $sort_allowed_order=array('asc','desc'); + + //default sort + var $sort_by='title'; + var $sort_order='ASC'; + + + /** + * Constructor + * + * @access public + * @param array initialization parameters + */ + function __construct($params = array()) + { + $this->ci=& get_instance(); + $this->ci->config->load('solr'); + + //change default sort if regional search is ON + if ($this->ci->config->item("regional_search")=='yes'){ + $this->sort_by='nation'; + } + + if (count($params) > 0){ + $this->initialize($params); + } + //$this->ci->output->enable_profiler(TRUE); + } + + function initialize($params=array()) + { + if (count($params) > 0){ + foreach ($params as $key => $val){ + if (isset($this->$key)){ + $this->$key = $val; + } + } + } + + //intialize solr client + $this->initialize_solr(); + } + + private function initialize_solr() + { + require('vendor/autoload.php'); + + $config = array( + 'endpoint' => array( + 'localhost' => array( + 'host' => $this->ci->config->item('solr_host'), + 'port' => $this->ci->config->item('solr_port'), + 'path' => $this->ci->config->item('solr_collection'), + ) + ) + ); + + // create a client instance + $this->solr_client = new Solarium\Client($config); + + } + + function search($limit=15,$offset=0) + { + $search_query=array(); + $result=array(); + $query = $this->solr_client->createSelect(); + + //set edismax options + $edismax = $query->getEDisMax(); + + $query->createFilterQuery('published')->setQuery('published:1'); + $helper = $query->getHelper(); + + //SK + if($this->study_keywords){ + $search_query[]='_text_:'.$helper->escapeTerm($this->study_keywords); + } + + //VK + if($this->variable_keywords){ + $search_query[]='{!join from=sid to=survey_uid}'.$helper->escapeTerm($this->variable_keywords); + } + + $study=$this->_build_study_query(); + $variable=$this->_build_variable_query(); + $topics=$this->_build_topics_query(); + $countries=$this->_build_countries_query(); + $collections=$this->_build_collections_query(); + $years=$this->_build_years_query(); + $repository=$this->_build_repository_query(); + $dtype=$this->_build_dtype_query(); + + + if ($topics){ + $search_query[]=$topics; + } + + //$sid=$this->_build_sid_query(); + + $sort_order=in_array($this->sort_order,$this->sort_allowed_order) ? $this->sort_order : 'ASC'; + + $sort_by='title'; + if (array_key_exists($this->sort_by,$this->sort_allowed_fields)){ + $sort_by=$this->sort_by; + } + + //years filter + if ($years) { + foreach($years as $key=>$year){ + $query->createFilterQuery('years'.$key)->setQuery($year); + } + } + + //dtype filter + if ($dtype){ + $query->createFilterQuery('dtype')->setQuery($dtype); + + } + + //countries filter + if($countries){ + $query->createFilterQuery('countries')->setQuery($countries); + } + + $sort_options[0]=array('sort_by'=>$sort_by, 'sort_order'=> (strtolower($sort_order)=='asc') ? $query::SORT_ASC : $query::SORT_DESC); + + + //multi-column sort + if ($sort_by=='nation'){ + $sort_options[1]=array('sort_by'=>'year', 'sort_order'=>$query::SORT_DESC); + $sort_options[2]=array('sort_by'=>'title', 'sort_order'=>$query::SORT_ASC); + } + elseif ($sort_by=='title'){ + //$sort_options[1]=array('sort_by'=>'year', 'sort_order'=>$query::SORT_DESC); + //$sort_options[2]=array('sort_by'=>'nation', 'sort_order'=>$query::SORT_ASC); + } + if ($sort_by=='year'){ + $sort_options[2]=array('sort_by'=>'nation', 'sort_order'=>$query::SORT_ASC); + $sort_options[2]=array('sort_by'=>'title', 'sort_order'=>$query::SORT_ASC); + } + + //multi-sort + foreach($sort_options as $sort){ + $query->addSort($this->sort_allowed_fields[$sort['sort_by']], $sort['sort_order']); + } + + /////////////////// variable search /////////////////////////////////////////////////////// + if ($variable!==FALSE){ + //set keyword search query + if (count($search_query)>0){ + $query->setQuery(implode(" AND ",$search_query)); + } + + $query->setStart($offset)->setRows($limit); + $query->setFields(array( + 'id:survey_uid', + 'type:dataset_type', + 'survey_uid', + 'title', + 'nation', + 'formid', + 'form_model', + 'repositoryid', + 'repo_title', + 'total_views', + 'total_downloads', + 'link_da', + 'authoring_entity', + 'created', + 'changed', + 'year_start', + 'year_end', + 'varcount' + )); + + //enable debugging + if ($this->debug){ + $debug = $query->getDebug(); + } + + //execute search + $resultset = $this->solr_client->select($query);//->getData(); + + //get raw query + if($this->debug){ + $request = $this->solr_client->createRequest($query); + $result['request_uri']=$request->getUri(); + $result['debug']=$resultset->getDebug(); + + echo '
';
+				echo ($result['request_uri']);
+				echo '
'; + } + + /* + ///////// DEBUG RESULTS ////////////////////////////////////////////// + $debugResult = $resultset->getDebug(); + + echo '

Debug data

'; + echo 'Querystring: ' . $debugResult->getQueryString() . '
'; + echo 'Parsed query: ' . $debugResult->getParsedQuery() . '
'; + echo 'Query parser: ' . $debugResult->getQueryParser() . '
'; + echo 'Other query: ' . $debugResult->getOtherQuery() . '
'; + + ////////////// END DEBUG //////////////////////////////////////////// + */ + + //get the total number of documents found by solr + $this->search_found_rows=$resultset->getNumFound(); + + //get total survey count from index + $this->total_surveys=$this->solr_total_count($doctype=1); + + //get search result as array + $this->search_result=$resultset->getData(); + + $this->search_result=$this->search_result['response']['docs']; + + $vars_found_per_survey=array(); + + //get variables counts per survey + if ($this->search_found_rows>0) + { + $survey_arr=array(); + foreach($resultset as $doc){ + $survey_arr[]=$doc->survey_uid; + } + + $vars_found_per_survey=$this->get_var_count_by_surveys($survey_arr,$this->variable_keywords); + } + + //add variable counts to the main search result + foreach($this->search_result as $key=>$row){ + if (array_key_exists($row['survey_uid'],$vars_found_per_survey)){ + $this->search_result[$key]['var_found']=$vars_found_per_survey[$row['survey_uid']]; + } + } + + $result['rows']=$this->search_result; + $result['found']=$this->search_found_rows; + $result['total']=$this->total_surveys; + $result['limit']=$limit; + $result['offset']=$offset; + $result['citations']=$this->get_survey_citation(); + + return $result; + } + else + { + //study search ////////////////////////////////////////////////////////////////////////////////////// + $edismax->setQueryFields("title^2.0 nation^20.0 years^30.0"); + + //keywords setMinimumMatch("3<90%"); + + if (count($search_query)>0){ + $query->setQuery(implode(" AND ",$search_query)); + } + + //$debug = $query->getDebug(); + $query->createFilterQuery('study_search')->setQuery('doctype:1'); + $query->setStart($offset)->setRows($limit); + $query->setFields(array( + 'id:survey_uid', + 'type:dataset_type', + 'title', + 'nation', + 'formid', + 'form_model', + 'repositoryid', + 'repo_title', + 'total_views', + 'total_downloads', + 'link_da', + 'created', + 'changed', + 'year_start', + 'year_end', + 'authoring_entity', + 'score' + )); + + //enable debugging + if ($this->debug){ + $debug = $query->getDebug(); + } + + $resultset = $this->solr_client->select($query);//->getData(); + + //get raw query + if($this->debug){ + $request = $this->solr_client->createRequest($query); + $result['request_uri']=$request->getUri(); + $result['debug']=$resultset->getDebug(); + } + } + + //get the total number of documents found by solr + $this->search_found_rows=$resultset->getNumFound(); + + //get total survey count from index + $this->total_surveys=$this->solr_total_count($doctype=1); + + //get search result as array + $this->search_result=$resultset->getData(); + + $this->search_result=$this->search_result['response']['docs']; + + + /* + ///////// DEBUG RESULTS ////////////////////////////////////////////// + + $debugResult = $resultset->getDebug(); + + echo '
';
+			echo $result['request_uri'];
+			echo '
'; + + echo '

Debug data

'; + echo 'Querystring: ' . $debugResult->getQueryString() . '
'; + echo 'Parsed query: ' . $debugResult->getParsedQuery() . '
'; + echo 'Query parser: ' . $debugResult->getQueryParser() . '
'; + echo 'Other query: ' . $debugResult->getOtherQuery() . '
'; + + ////////////// END DEBUG //////////////////////////////////////////// + */ + + //combine into one array + $result['rows']=$this->search_result; + $result['found']=$this->search_found_rows; + $result['total']=$this->total_surveys; + $result['limit']=$limit; + $result['offset']=$offset; + $result['citations']=$this->get_survey_citation(); + + return $result; + } + + + //find variables by survey list + function get_var_count_by_surveys($survey_arr,$variable_keywords) + { + /* + Query to be executed: + + q= doctype:2 AND text:education AND sid:(590 OR ...) + other params: group=true&group.field=sid&group.ngroups=true&group.limit=0 + + ?q=doctype%3A2+AND+text%3Aeducation+AND+sid%3A(590)&wt=json&indent=true&group=true&group.field=sid&group.ngroups=true&group.limit=0 + */ + + //get a select query instance + $query = $this->solr_client->createSelect(); + + //set a query (all prices starting from 12) + $query->setQuery(sprintf('doctype:2 AND _text_:%s AND sid:(%s)',$variable_keywords, implode(" OR ",$survey_arr)) ); + + //set start and rows param (comparable to SQL limit) using fluent interface + $query->setStart(0)->setRows(100); + + //get grouping component and set a field to group by + $groupComponent = $query->getGrouping(); + $groupComponent->addField('sid'); //group by field + $groupComponent->setLimit(0); // maximum number of items per group + $groupComponent->setNumberOfGroups(true); // get a group count + + //execute search + $resultset = $this->solr_client->select($query); + + //get groups resultset + $groups = $resultset->getGrouping(); + + $output=array(); + + foreach ($groups as $groupKey => $fieldGroup) + { + foreach ($fieldGroup as $valueGroup) + { + //format=$output[sid]=num of vars found + $output[(int)$valueGroup->getValue()]=(int)$valueGroup->getNumFound(); + } + } + + return $output; + } + + + + //return total documents county by doctype + //1=survey, 2=variable + function solr_total_count($doctype=1) + { + $query = $this->solr_client->createSelect(); + $query->setQuery('doctype:'.$doctype); + $query->createFilterQuery('published')->setQuery('published:1'); + $query->setStart(0)->setRows(0); + $resultset = $this->solr_client->select($query); + return $resultset->getNumFound(); + } + + + /** + * Build study search + */ + function _build_study_query() + { + if (!$this->study_keywords){ + return false; + } + + return array('title'=>$this->study_keywords); + } + + + function _build_variable_query() + { + $variable_keywords=trim($this->variable_keywords); + $variable_fields=$this->variable_fields(); //cleaned list of variable fields array + + if ($variable_keywords==''){ + return FALSE; + } + + $tmp_where=array(); + + if (strlen($variable_keywords) >3){ + //get fulltext index name + $fulltext_index=$this->get_variable_search_field(TRUE); + + //FULLTEXT + $tmp_where[]=sprintf('MATCH(%s) AGAINST (%s IN BOOLEAN MODE)','v.'.$fulltext_index,$this->ci->db->escape($variable_keywords)); + } + else if (strlen($variable_keywords) ==3){ + //get concatenated fields for wild card/regex search + $regex_fields=$this->get_variable_search_field(FALSE); + + //REGEXP query + $variable_keywords=sprintf("[[:<:]]%s[[:>:]]",$variable_keywords); + $tmp_where[]=sprintf('%s REGEXP (%s)',$regex_fields,$this->ci->db->escape($variable_keywords)); + } + + if (count($tmp_where)>0) + { + return '('.implode(' OR ',$tmp_where).')'; + } + + return FALSE; + } + + /** + * + * build where for topics + */ + function _build_topics_query() + { + $topics=$this->topics;//must always be an array + + if (!is_array($topics)) + { + return FALSE; + } + + //remove topics that are not numeric + $topics_clean=array(); + foreach($topics as $topic) + { + if (is_numeric($topic) ) + { + $topics_clean[]=$topic; + } + } + + if ( count($topics_clean)>0) + { + $topics=implode(' OR ',$topics_clean); + + if ($topics) + { + return sprintf(' topics_id:(%s)',$topics); + } + } + + return FALSE; + } + + + + //returns country IDs by country names + function get_country_id_by_name($country_names=array()) + { + $this->ci->db->select("countryid"); + $this->ci->db->where_in('name',$country_names); + $query= $this->ci->db->get('countries')->result_array(); + + if (!$query) + { + return array(); + } + + $output=NULL; + + foreach($query as $country) + { + $output[]=$country['countryid']; + } + + return $output; + } + + /** + * + * build where for nations + */ + function _build_countries_query() + { + $countries=$this->countries;//must always be an array + + if (!is_array($countries)) + { + return FALSE; + } + + $countries_list=array(); + + //check if country[] param contains the country name instead of country id + if (isset($countries[0]) && !is_numeric($countries[0])) + { + //get country id by name + $countries=$this->get_country_id_by_name($countries); + } + + foreach($countries as $country) + { + if (is_numeric($country)) + { + $countries_list[]=(int)$country; + } + } + + if ( count($countries_list)>0) + { + $countries_str=implode(' OR ',$countries_list); + + if ($countries_str!='') + { + return sprintf(' countries:(%s)',$countries_str); + } + + } + + return FALSE; + } + + + function _build_years_query() + { + $from=(integer)$this->from; + $to=(integer)$this->to; + + if ($from>0 && $to>0) + { + $years=array(); + $years[]=sprintf('years:[%s TO %s]',$from, $to); + return $years; + } + + return FALSE; + } + + function _build_sid_query() + { + $sid=explode(",",$this->sid); + + $sid_list=array(); + foreach($sid as $item) + { + if (is_numeric($item)) + { + $sid_list[]=$item; + } + } + + if (count($sid_list)>0) + { + return sprintf('surveys.id in (%s)',implode(",",$sid_list)); + } + + return FALSE; + } + + + function _build_centers_query() + { + $centers=$this->center;//must always be an array + + if (!is_array($centers)) + { + return FALSE; + } + + $centers_list=array(); + + foreach($centers as $center) + { + //escape country names for db + $centers_list[]=$this->ci->db->escape($center); + } + + if ( count($centers_list)>0) + { + $centers= implode(',',$centers_list); + } + else + { + return FALSE; + } + + if ($centers!='') + { + return sprintf('surveys.id in (select sid from survey_centers where id in (%s) )',$centers); + } + + return FALSE; + } + + + function _build_collections_query() + { + $params=$this->collections;//must always be an array + + if (!is_array($params)) + { + return FALSE; + } + + $param_list=array(); + + foreach($params as $param) + { + //escape country names for db + $param_list[]=$this->ci->db->escape($param); + } + + if ( count($param_list)>0) + { + $params= implode(',',$param_list); + } + else + { + return FALSE; + } + + if ($param!='') + { + return sprintf('surveys.id in (select sid from survey_repos where survey_repos.repositoryid in (%s) )',$params); + } + + return FALSE; + } + + /** + * + * Get the fulltext index or concatenated fields for searching for variables + */ + function get_variable_search_field($is_fulltext=TRUE) + { + $index=array(); + + $variable_fields=$this->variable_fields(); + + //select which index to use + if( in_array('name',$variable_fields) ) + { + $index[]='name'; + } + if( in_array('labl',$variable_fields) ) + { + $index[]='labl'; + } + if( in_array('qstn',$variable_fields) ) + { + $index[]='qstn'; + } + if( in_array('catgry',$variable_fields) ) + { + $index[]='catgry'; + } + + if (count($index)==0) + { + $index[]='name,labl,qstn,catgry'; + } + + if ($is_fulltext==TRUE) + { + //fulltext + return implode(',',$index); + } + else + { + //concatenated fields + return 'concat(' . implode(",' ',",$index) .')'; + } + } + + /* + * setup variable fields + * + * Note: sets a variable field to search on. If no field selected by the user, selects the default field. + * the function will always return an array of variable field(s) + */ + function variable_fields() + { + $vf=$this->variable_fields; + + if (!is_array($vf)) + { + //default search field if nothing is selected + return array('labl,qstn,catgry'); + } + + $tmp=NULL; + foreach($vf as $field) + { + if (in_array($field,$this->variable_allowed_fields)) + { + $tmp[]=$field; + } + } + + //no allowed fields found + if ($tmp==NULL) + { + return array('labl'); + } + else + { + return $tmp; + } + } + + /** + * + * returns an array of surveys with citations + * + */ + function get_survey_citation() + { + if (!is_array($this->search_result)) + { + return FALSE; + } + else if (count($this->search_result)==0) + { + return FALSE; + } + + //build a list of survey IDs + foreach($this->search_result as $row) + { + $survey_id_list[]=$row['id']; + } + + $surveys=implode(',',$survey_id_list); + $this->ci->db->select('sid,count(sid) as total'); + $this->ci->db->where("sid in ($surveys)"); + $this->ci->db->group_by('sid'); + $query=$this->ci->db->get('survey_citations'); + + if ($query) + { + $citation_rows=$query->result_array(); + + $result=array(); + + foreach($citation_rows as $row) + { + $result[$row['sid']]=$row['total']; + } + return $result; + } + + return FALSE; + } + + //search on variables + function vsearch($limit = 15, $offset = 0) + { + $countries=$this->_build_countries_query(); + $years=$this->_build_years_query(); + $dtype=$this->_build_dtype_query(); + + //get a select query instance + $query = $this->solr_client->createSelect(); + + $query->setFields(array( + 'vid', + 'labl', + 'name', + 'qstn', + 'sid' + )); + + //vk + if($this->variable_keywords) + { + //$search_query[]='{!join from=sid to=survey_uid}'.$this->variable_keywords; + //{!join from=survey_uid to=sid}survey AND countries:1 + + //join FQ must have all the other filters for countries, years, topics, data access types in the same FQ to work + + $join_fq=array(); + + $sk=$this->study_keywords; + + if (trim($sk)=="") + { + $sk="*"; + } + + //survey keyword search + $var_survey_join=sprintf("{!join from=survey_uid to=sid} %s",$sk); + + //published content only + $join_fq[]='published:1'; + + //countries filter + if($countries){ + $join_fq[]=$countries; + } + + //years filter + if ($years) { + foreach($years as $key=>$year){ + $join_fq[]=$year; + } + } + + //dtype filter + if($dtype){ + $join_fq[]=$dtype; + } + + $join_query=$var_survey_join . ' AND '.implode(" AND ",$join_fq); + $query->createFilterQuery('variable_join')->setQuery($join_query); + } + + // create a filterquery + $query->createFilterQuery('doctype_vsearch')->setQuery('doctype:2'); + // {!join from=survey_uid to=sid}survey AND countries:1 + + //set a query (all prices starting from 12) + $query->setQuery(sprintf('_text_:%s',$this->variable_keywords) ); + $query->setStart($offset)->setRows($limit); //get 0-100 rows + + //execute search + $resultset = $this->solr_client->select($query); + + //get the total number of documents found by solr + $found_rows=$resultset->getNumFound(); + + //get search result as array + $this->search_result=$resultset->getData(); + + if ($found_rows>0) + { + //get the survey title, country info for all found variables + $survey_list=array(); + foreach($this->search_result['response']['docs'] as $row) + { + $survey_list[]=$row['sid']; + } + + //get survey info from db + $surveys=$this->_get_survey_by_id($survey_list); + + //update the resultset with survey info + foreach($this->search_result['response']['docs'] as $key=>$row) + { + $this->search_result['response']['docs'][$key]['title']=$surveys[$row['sid']]['title']; + $this->search_result['response']['docs'][$key]['nation']=$surveys[$row['sid']]['nation']; + } + } + + $tmp['total']=$this->ci->db->count_all('variables'); + $tmp['found']=$found_rows; + $tmp['limit']=$limit; + $tmp['offset']=$offset; + $tmp['rows']=$this->search_result['response']['docs']; + return $tmp; + } + + //search for variables for a single survey + function v_quick_search($surveyid=NULL,$limit=50,$offset=0) + { + //get a select query instance + $query = $this->solr_client->createSelect(); + + //set Edismax + $edismax = $query->getEDisMax(); + + + $query->setFields(array( + 'vid', + 'labl', + 'name' + )); + + //set a query (all prices starting from 12) + $query->setQuery(sprintf('doctype:2 AND _text_:%s AND sid:(%s)',$this->variable_keywords, $surveyid ) ); + $query->setStart(0)->setRows(100); //get 0-100 rows + + if($this->debug){ + $request = $this->solr_client->createRequest($query); + echo 'Request URI: ' . $request->getUri() . '
'; + } + + //execute search + $resultset = $this->solr_client->select($query); + + //get the total number of documents found by solr + $this->search_found_rows=$resultset->getNumFound(); + + //get search result as array + $this->search_result=$resultset->getData(); + return $this->search_result['response']['docs']; + } + + + /* + * find surveys by survey ID + * + * @id_arr - array of survey ids + */ + private function _get_survey_by_id($id_arr) + { + //create filter query for survey IDs + $survey_fq=implode(" OR ", $id_arr); + $survey_fq= sprintf(' survey_uid:(%s)',$survey_fq); + + //get a select query instance + $query = $this->solr_client->createSelect(); + + $query->setFields(array( + 'id:survey_uid', + 'title:title', + 'nation' + )); + + //filter on survey id + $query->createFilterQuery('survey_list')->setQuery($survey_fq); + + //set to return surveys only + $query->createFilterQuery('survey_doctype_1')->setQuery('doctype:1'); + + $query->setRows(count($id_arr)); //get 0-100 rows + + //execute search + $resultset = $this->solr_client->select($query); + + //get the total number of documents found by solr + $found_rows=$resultset->getNumFound(); + + $output=array(); + + $search_result=$resultset->getData(); + + //get search result as array + foreach($search_result['response']['docs'] as $row){ + $output[$row['id']]=$row; + } + + return $output; + } + + + function _build_repository_query() + { + $repo=(string)$this->repo; + + if ($repo!='') + { + return sprintf('survey_repos.repositoryid = %s',$this->ci->db->escape($repo)); + } + return FALSE; + } + + function _build_dtype_query() + { + $dtypes=$this->dtype; + + if (!is_array($dtypes) || count($dtypes)<1) + { + return FALSE; + } + + foreach($dtypes as $key=>$value) + { + if (!is_numeric($value)) + { + unset($dtypes[$key]); + } + } + + $types_str=implode(" OR ",$dtypes); + + if ($types_str!='') + { + return sprintf(' formid:(%s)',$types_str); + } + + return FALSE; + } + +}// END Search class + +/* End of file Catalog_search_solr.php */ +/* Location: ./application/libraries/Catalog_search_solr.php */ \ No newline at end of file diff --git a/application/libraries/Events.php b/application/libraries/Events.php new file mode 100644 index 000000000..02ff89dba --- /dev/null +++ b/application/libraries/Events.php @@ -0,0 +1,88 @@ +events->emit('db.after.update', 'param value', 'param2'); + * + * + */ + +class Events extends Emitter { + + private $ci; + + function __construct() + { + $this->ci=&get_instance(); + $this->solr_listeners(); + } + + + /** + * + * + * Event listeners for SOLR indexing + * + */ + function solr_listeners() + { + $search_provider=$this->ci->config->item("search_provider"); + + if($search_provider!='solr'){ + return false; + } + + $this->ci->load->library("Solr_manager"); + + /** + * + * @object_type - table name + * @object_id - id or array of ids + * @action - import, refresh, add, update, delete, etc + * + */ + $this->addListener('db.after.update', function ($event, $object_type, $object_id, $action='atomic') { + log_message('info',"event - ".print_r(array($object_type, $object_id, $action),TRUE)); + + try{ + if(is_array($object_id)){ + foreach($object_id as $single_id){ + $this->ci->solr_manager->run_delta_update($table=$object_type, $delta_op=$action, $obj_id=$single_id); + } + }else{ + $this->ci->solr_manager->run_delta_update($table=$object_type, $delta_op=$action, $obj_id=$object_id); + } + } catch (Exception $e) { + throw new exception($e->getMessage()); + die(); + log_message('error',"event-exception - ".$e->getMessage()); + } + }); + + //delete + $this->addListener('db.after.delete', function ($event, $object_type, $object_id, $action='atomic') { + log_message('info',"event - ".print_r(array($object_type, $object_id, $action),TRUE)); + + try{ + if(is_array($object_id)){ + foreach($object_id as $single_id){ + $this->ci->solr_manager->run_delta_update($table=$object_type, $delta_op=$action, $obj_id=$single_id); + } + }else{ + $this->ci->solr_manager->run_delta_update($table=$object_type, $delta_op=$action, $obj_id=$object_id); + } + } catch (Exception $e) { + throw new exception($e->getMessage()); + die(); + log_message('error',"event-exception - ".$e->getMessage()); + } + }); + } + +} \ No newline at end of file diff --git a/application/libraries/Solr_manager.php b/application/libraries/Solr_manager.php new file mode 100644 index 000000000..ee746af65 --- /dev/null +++ b/application/libraries/Solr_manager.php @@ -0,0 +1,980 @@ +ci=& get_instance(); + $this->ci->config->load('solr'); + $this->ci->load->model('solr_delta_updates_model'); + + $this->initialize_solr(); + + log_message('debug', "Solr Class Initialized"); + //$this->ci->output->enable_profiler(TRUE); + } + + + + private function initialize_solr() + { + require('vendor/autoload.php'); + $this->solr_config = array( + 'endpoint' => array( + 'localhost' => array( + 'host' => $this->ci->config->item('solr_host'), + 'port' => $this->ci->config->item('solr_port'), + 'path' => $this->ci->config->item('solr_collection'), + ) + ) + ); + //$this->solr_client = new Solarium\Client($this->solr_config); + } + + + public function ping_test() + { + $client=new Solarium\Client($this->solr_config); + $ping = $client->createPing(); + $result = $client->ping($ping); + return $result->getData(); + } + + + /** + * + * recursive function to import all surveys + * + * @start_row start importing from a row number or NULL to start from first id + * @limit number of records to read at a time + * @loop whether to recursively call the function till the end of rows + * + * */ + public function full_import_surveys($start_row=NULL, $limit=10, $loop=TRUE) + { + $start_time=date("h:i:s"); + set_time_limit(0); + $this->ci->load->model("Dataset_model"); + $this->ci->load->helper('array'); + + //concat('survey-', surveys.id) as id, + $this->ci->db->select(" + 1 as doctype, + surveys.id, + surveys.type as dataset_type, + surveys.id as survey_uid, + surveys.idno as idno, + surveys.formid, + forms.model as form_model, + surveys.title as title, + nation, + surveys.year_start, + surveys.year_end, + surveys.repositoryid as repositoryid, + repositories.title as repo_title, + surveys.created, + surveys.changed, + surveys.varcount, + surveys.published, + surveys.total_views, + surveys.keywords, + surveys.authoring_entity, + surveys.total_downloads",FALSE); + $this->ci->db->join("forms","surveys.formid=forms.formid","left"); + $this->ci->db->join('repositories', 'surveys.repositoryid= repositories.repositoryid','left'); + $this->ci->db->limit($limit); + $this->ci->db->order_by('surveys.id ASC'); + + if ($start_row){ + $this->ci->db->where("surveys.id >",$start_row,false); + } + + //echo "start time= ".date("H:i:s")."\r\n"; + + $rows=$this->ci->db->get("surveys")->result_array(); + ////echo $this->ci->db->last_query();die(); + //echo "\r\n".count($rows). "rows found\r\n"; + + //echo "finished reading db rows= ".date("H:i:s")."\r\n"; + //die(); + + if (!$rows){ + return false; + } + + $last_row_id=NULL; + + foreach($rows as $key=>$row) + { + //survey topics + //survey countries + $rows[$key]['countries']=$this->get_survey_countries($row['survey_uid']); + //survey repositories + $rows[$key]['repositories']=$this->get_survey_repositories($row['survey_uid']); + //survey years + $rows[$key]['years']=$this->get_survey_years($row['survey_uid']); + + //metadata + //$rows[$key]['metadata']=array_to_plain_text($this->ci->Dataset_model->decode_metadata($row['metadata'])); + + //array of variable keywords + $rows[$key]['var_keywords']=$this->get_survey_variables($row['survey_uid']); + + //row survey id + $last_row_id=$row['survey_uid']; + + //print_r($row);die(); + } + + $this->add_documents($rows,$id_prefix='survey-'); + + //echo "finish time= ".date("H:i:s")."\r\n"; + + if ($loop==true){ + //recursively call to fetch next batch of rows + $this->full_import_surveys($last_row_id,$limit,$loop); + } + + return array( + 'rows_processed'=>count($rows), + 'last_row_id'=>$last_row_id, + 'start_time'=>$start_time, + 'end_time'=>date("h:i:s") + ); + } + + + function delete_document($query) + { + $client = new Solarium\Client($this->solr_config); + $update = $client->createUpdate(); + $update->addDeleteQuery($query); + $update->addCommit(); + $result = $client->update($update); + } + + + //Sync SOLR index with DB + function sync_solr_with_db($dry_run=false) + { + $doctypes=array(1,3);//doc types that will be synced + + foreach($doctypes as $doctype) + { + $result=$this->sync_solr_with_db_by_doctype($doctype,$dry_run); + + echo "
";
+				print_r($result);
+			}
+
+	}
+
+
+	//Sync SOLR index with DB
+	function sync_solr_with_db_by_doctype($doctype,$dry_run=true)
+	{
+		switch($doctype)
+		{
+				case '1':
+					$prefix='survey';
+				break;
+
+				case '2':
+					$prefix='v';
+				break;
+
+				case '3':
+					$prefix='cit';
+				break;
+		}
+
+		//get document count from SOLR
+		$solr_total=$this->get_total_documents_count($doctype);
+
+		//get a list of all documents in SOLR
+		$solr_documents=$this->get_all_solr_documents($doctype,$solr_total);
+
+		//get all database records list
+		$db_documents=$this->get_all_db_documents($doctype);
+
+		//find deleted records in SOLR index
+		$solr_deleted=array_diff($solr_documents,$db_documents);
+
+		//find new documents not in SOLR yet
+		$new_documents=array_diff($db_documents,$solr_documents);
+
+		if (count($solr_deleted)>0 && $dry_run!=true)
+		{
+			//remove deleted items from SOLR
+			$delete_query=array();
+
+			foreach($solr_deleted as $del_item)
+			{
+				$delete_query[]=$prefix.'-'.$del_item;
+			}
+
+			$delete_query='id:('.implode(" OR ",$delete_query).')';
+
+			//run delete query
+			$this->delete_document($delete_query);
+		}
+
+		//add new documents to SOLR
+		if (count($new_documents) && $dry_run!=true)
+		{
+
+			if ($doctype==1)
+			{
+				foreach($new_documents as $doc_id)
+				{
+					$this->add_survey($doc_id);
+				}
+			}
+			else if($doctype==3)
+			{
+				$this->add_citation($new_documents);
+			}
+		}
+
+		return array(
+				'solr_deleted'=>$solr_deleted,
+				'new_docs'=>$new_documents,
+				//'solr_documents'=>$solr_documents
+		);
+		/*
+			echo "
";
+			print_r($delete_query);
+			echo "
"; + print_r($solr_deleted); + echo "
"; + print_r($new_documents); + echo "
"; + */ + } + + + + function get_all_db_documents($doctype=1) + { + if ($doctype==1) + { + //survey + $id_column="id"; + $this->ci->db->select("id"); + $rows=$this->ci->db->get("surveys")->result_array(); + return array_column($rows, $id_column); + } + else if ($doctype==3) + { + //citations + $id_column="id"; + $this->ci->db->select("id"); + $rows=$this->ci->db->get("citations")->result_array(); + return array_column($rows, $id_column); + } + } + + + /** + * get an array of all documents stored in SOLR index + * returns only the ID field + **/ + function get_all_solr_documents($doctype=1,$limit=1000) + { + $field='id'; + + switch($doctype) + { + case '1': + $field='survey_uid'; + break; + + case '2': + $field='var_uid'; + break; + + case '3': + $field='citation_id'; + break; + } + + //var_dump($field); + + $select = array( + 'query' => '*:*', + 'start' => 0, + 'rows' => $limit, + 'fields' => array($field), + 'filterquery' => array( + 'doctype' => array( + 'query' => 'doctype:'.$doctype + ) + ) + ); + + // create a client instance + $client = new Solarium\Client($this->solr_config); + + // get a select query instance based on the config + $query = $client->createSelect($select); + + // this executes the query and returns the result + $resultset = $client->select($query); + + // display the total number of documents found by solr + $documents_found=$resultset->getNumFound(); + + $doc_list=array(); + + // show documents using the resultset iterator + foreach ($resultset as $document) { + $doc_list[]=$document->{$field}; + } + + return $doc_list; + } + + + + /** + * get an array of all documents stored in SOLR index + * returns only the ID field + **/ + function get_total_documents_count($doctype=1,$published=null) + { + $select = array( + 'query' => '*:*', + 'start' => 0, + 'rows' => 0, + 'fields' => array('id'), + 'filterquery' => array( + 'doctype' => array( + 'query' => 'doctype:'.$doctype + ) + ) + ); + + if ($published!==NULL){ + $select['filterquery']['published']['query']='published:'.$published; + } + + $client = new Solarium\Client($this->solr_config); + $query = $client->createSelect($select); + $resultset = $client->select($query); + $documents_found=$resultset->getNumFound(); + return $documents_found; + } + + + //add documents to index + function add_documents($rows,$id_prefix='',$apply_commit=true) + { + $client = new Solarium\Client($this->solr_config); + $update = $client->createUpdate(); + + $docs=array(); + foreach($rows as $row) + { + $doc=NULL; + // create a new document for the data + $doc = $update->createDocument(); + if(isset($row['rownum'])){ + unset($row['rownum']); + } + + foreach($row as $key=>$value){ + if($key=='id'){ + $value=$id_prefix.$value; + } + $doc->setField($key, $value); + } + + $docs[]=$doc; + } + + // add the documents and a commit command to the update query + $update->addDocuments($docs); + + if ($apply_commit){ + $update->addCommit(); + } + + // this executes the query and returns the result + $result = $client->update($update); + + /* + echo " updated applied " .date("H:i:s")."\r\n"; + echo 'Update query executed
'; + echo 'Query status: ' . $result->getStatus(). '
'; + echo 'Query time: ' . $result->getQueryTime(); + */ + unset($client); + } + + + function commit() + { + $client = new Solarium\Client($this->solr_config); + $update = $client->createUpdate(); + $update->addCommit(); + $result = $client->update($update); + unset($client); + return $result->getStatus(); + } + + + function db_update_handler($options) + { + if (!isset($options['table']) && + !isset($options['action']) && + !isset($options['id']) + ) + { + throw exception("DB_UPDATE_HANDER ERROR: options are not set properly"); + } + + $table=$options['table']; + $delta_op=$options['action']; + $obj_id=$options['id']; + $is_processed=1;//to mark this is already passed to SOLR index + + $this->ci->solr_delta_updates_model->apply_updates($table, $delta_op, $obj_id, $is_processed); + $this->run_delta_update($table, $delta_op, $obj_id); + } + + + + /** + * + * Main function for all delta updates + * + * @table - table name + * @delta_op - operation - refresh, import, replace, update, publish, delete + * @obj_id - object id + * + **/ + function run_delta_update($table, $delta_op, $obj_id) + { + switch($table){ + case 'surveys': + if(in_array($delta_op, array('refresh','import','replace','update','create') )){ + return $this->add_survey($obj_id); + } + else if(in_array($delta_op, array('publish','atomic') )){ + return $this->survey_atomic_update($obj_id); + } + else if($delta_op=='delete'){ + return $this->delete_document("survey_uid:$obj_id OR sid:$obj_id"); + } + break; + + case 'citations': + throw new exception("update handler not implemented for citations"); + break; + } + } + + + function delete_document_by_id($id,$doc_type) + { + return $this->run_delta_update($table='surveys', 'delete', $id); + } + + + + function survey_atomic_update($id) + { + $options=$this->get_survey_by_id($id); + if($options){ + $this->atomic_update('id','survey-'.$id,$options); + } + } + + function atomic_update($key_field,$key_value, $options) + { + $client = new Solarium\Client($this->solr_config); + + $update = $client->createUpdate(); + $doc= $update->createDocument(); + + //set key same as unique key in schema.xml + $doc->setKey($key_field, $key_value); + + //set partial update for every field that is given + foreach($options as $key=>$value) { + if($key!=$key_field){ + $doc->setField($key, $value); + $doc->setFieldModifier($key, 'set'); + } + } + + //add document and commit + $update->addDocument($doc)->addCommit(); + + // this executes the query and returns the result + $result = $client->update($update); + return $result; + + /*echo 'Update query executed
'; + echo 'Query status: ' . $result->getStatus(). '
'; + echo 'Query time: ' . $result->getQueryTime();*/ + } + + + //get a single survey + public function get_survey_by_id($id) + { + //get survey record + study level metadata + $this->ci->db->select("1 as doctype, + surveys.id as survey_uid, + surveys.formid, + surveys.idno as surveyid, + surveys.title, + nation, + authoring_entity, + forms.model as form_model, + surveys.year_start, + surveys.year_end, + surveys.repositoryid as repositoryid, + link_da, + repositories.title as repo_title, + surveys.created, + surveys.changed, + surveys.varcount, + surveys.published, + surveys.total_views, + surveys.metadata, + surveys.total_downloads",FALSE); + $this->ci->db->join("forms","surveys.formid=forms.formid","left"); + $this->ci->db->join('repositories', 'surveys.repositoryid= repositories.repositoryid','left'); + $this->ci->db->where_in("surveys.id",$id); + + $survey=$this->ci->db->get("surveys")->row_array(); + + if (!$survey){ + return false; + } + + $survey['id']='survey-'.$survey['survey_uid']; //id column must use the format SURVEY-1234 + //survey topics + //survey countries + $survey['countries']=$this->get_survey_countries($survey['survey_uid']); + //survey repositories + $survey['repositories']=$this->get_survey_repositories($survey['survey_uid']); + //survey years + $survey['years']=$this->get_survey_years($survey['survey_uid']); + //decode metadata and convert to text + if($survey['metadata']){ + $this->ci->load->helper('array'); + $this->ci->load->model("Dataset_model"); + $survey['metadata']=array_to_plain_text($this->ci->Dataset_model->decode_metadata($survey['metadata'])); + } + return $survey; + } + + + + + public function add_survey($id) + { + $documents=array(); + $documents[]=$this->get_survey_by_id($id); + $this->add_documents($documents,$commit=true); + + //delete variables if exist + $this->delete_document('sid:'.$id); + //import survey variables + $this->add_survey_variables($id); + } + + + + public function add_survey_variables($survey_id,$start_row=NULL, $limit=200, $loop=TRUE) + { + set_time_limit(0); + + $this->ci->db->select("2 as doctype, + concat('v-',uid) as id, + vid, + name, + labl, + catgry, + qstn, + sid, + uid as var_uid + ",FALSE); + $this->ci->db->where('sid',$survey_id); + $this->ci->db->limit($limit); + $this->ci->db->order_by('uid ASC'); + + if ($start_row){ + $this->ci->db->where("uid >",$start_row,false); + } + + $rows=$this->ci->db->get("variables")->result_array(); + + if (!$rows){ + return false; + } + + $last_row_id=NULL; + + //row variable id + $last_row_id=$rows[ count($rows)-1]['var_uid']; + + $this->add_documents($rows); + unset($rows); + + if ($loop){ + //recursively call to fetch next batch of rows + $this->add_survey_variables($survey_id,$last_row_id,$limit,$loop); + } + + } + + + public function add_citation($id_array) + { + $this->ci->db->select("3 as doctype, + concat('cit-',id) as id, + id as citation_id, + title, + subtitle, + authors, + ft_keywords, + published, + pub_year as pub_date + ",FALSE); + $this->ci->db->where_in("id",$id_array); + $rows=$this->ci->db->get("citations")->result_array(); + + //echo "\r\n".count($rows). "rows found\r\n"; + + if (!$rows){ + return false; + } + + $this->add_documents($rows); + } + + + + /** + * + * remove all documents from index + * + * other ways to clean index + * https://wiki.apache.org/solr/FAQ#How_can_I_delete_all_documents_from_my_index.3F + * + * + * http://localhost:8983/solr/update?stream.body=*:* + * http://localhost:8983/solr/update?stream.body= + * + * + * + **/ + function clean_index() + { + // create a client instance + $client = new Solarium\Client($this->solr_config); + + // get an update query instance + $update = $client->createUpdate(); + + // add the delete query and a commit command to the update query + $update->addDeleteQuery('*:*'); + $update->addCommit(); + + // this executes the query and returns the result + $result = $client->update($update); + + return array( + 'status'=>$result->getStatus() + ); + //echo 'Update query executed
'; + //echo 'Query status: ' . $result->getStatus(). '
'; + //echo 'Query time: ' . $result->getQueryTime(); + } + + + + + + /** + * + * recursive function to import all variables + * + * @start_row start importing from a row number or NULL to start from first id + * @limit number of records to read at a time + * @loop whether to recursively call the function till the end of rows + * + * */ + public function full_import_variables($start_row=NULL, $limit=100, $loop=TRUE) + { + $this->ci->load->helper('array'); + $this->ci->load->model("Dataset_model"); + + //echo "starting at: ".$start_row."\r\n"; + //echo "before db call " .date("H:i:s")."\r\n"; + + set_time_limit(0); + + $this->ci->db->select(" + 2 as doctype, + uid as id, + vid, + name, + labl, + catgry, + qstn, + sid, + metadata, + uid as var_uid + ",FALSE); + $this->ci->db->limit($limit); + $this->ci->db->order_by('uid ASC'); + + if ($start_row){ + $this->ci->db->where("uid >",$start_row,false); + } + + //echo "start time= ".date("H:i:s")."\r\n"; + //echo "memory usage before=".$this->convert(memory_get_usage())."\r\n"; + + $rows=$this->ci->db->get("variables")->result_array(); + + foreach($rows as $idx=>$row){ + $rows[$idx]['metadata']=array_to_plain_text($this->ci->Dataset_model->decode_metadata($row['metadata'])); + } + + //echo "DB results loaded= ".date("H:i:s")."\r\n"; + //echo $this->ci->db->last_query(); + + //echo "\r\n".count($rows). "rows found\r\n"; + //echo "memory usage after=".$this->convert(memory_get_usage())."\r\n"; + + + if (!$rows){ + return false; + } + + $last_row_id=NULL; + + //row variable id + $last_row_id=$rows[ count($rows)-1]['var_uid']; + + //echo "add docs " .date("H:i:s")."\r\n"; + + $this->add_documents($rows,$id_prefix='v-'); + $row_count=count($rows); + unset($rows); + + if ($loop){ + //recursively call to fetch next batch of rows + $this->full_import_variables($last_row_id,$limit,$loop); + } + + return array( + 'rows_processed'=>$row_count, + 'last_row_id'=>$last_row_id + ); + + } + + + function convert($size) + { + $unit=array('b','kb','mb','gb','tb','pb'); + return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i]; + } + + /** + * + * recursive function to import all citations + * + * @start_row start importing from a row number or NULL to start from first id + * @limit number of records to read at a time + * @loop whether to recursively call the function till the end of rows + * + * */ + public function full_import_citations($start_row=NULL, $limit=100, $loop=TRUE) + { + //echo "starting at: ".$start_row."\r\n"; + + set_time_limit(0); + + $this->ci->db->select(" + 3 as doctype, + id, + id as citation_id, + title, + subtitle, + authors, + ft_keywords, + published, + pub_year as pub_date + ",FALSE); + $this->ci->db->limit($limit); + $this->ci->db->order_by('id ASC'); + + if ($start_row){ + $this->ci->db->where("id >",$start_row,false); + } + + $rows=$this->ci->db->get("citations")->result_array(); + + //echo "\r\n".count($rows). "rows found\r\n"; + + if (!$rows){ + return false; + } + + $last_row_id=NULL; + + //row variable id + $last_row_id=$rows[ count($rows)-1]['citation_id']; + + $this->add_documents($rows,$id_prefix='cit-'); + + if($loop ==true){ + $this->full_import_citations($last_row_id,$limit,$loop); + } + + return array( + 'rows_processed'=>count($rows), + 'last_row_id'=>$last_row_id + ); + } + + + + ////////////////////////////////////////////////////////////////////////////////// + + + + + + + function get_survey_countries($sid) + { + $this->ci->db->select("cid"); + $this->ci->db->where('sid',$sid); + $this->ci->db->where('cid >',0,false); + $result=$this->ci->db->get("survey_countries")->result_array(); + + $output=array(); + + if($result) + { + foreach($result as $row){ + $output[]=$row['cid']; + } + } + + return $output; + } + + + function get_survey_years($sid) + { + $this->ci->db->select("data_coll_year"); + $this->ci->db->where('sid',$sid); + $result=$this->ci->db->get("survey_years")->result_array(); + + $output=array(); + + if($result) + { + foreach($result as $row){ + $output[]=$row['data_coll_year']; + } + } + + return $output; + } + + + function get_survey_repositories($sid) + { + $this->ci->db->select("repositoryid"); + $this->ci->db->where('sid',$sid); + $result=$this->ci->db->get("survey_repos")->result_array(); + + $output=array(); + + if($result) + { + foreach($result as $row){ + $output[]=$row['repositoryid']; + } + } + + return $output; + } + + function get_survey_variables($sid) + { + $this->ci->db->select("uid,name,labl,qstn,catgry"); + $this->ci->db->where('sid',$sid); + $this->ci->db->limit(10000); + $result= $this->ci->db->get("variables")->result_array(); + + $output=array(); + foreach($result as $row){ + //$output[]=$row['name']. ' '. $row['labl']. ' ' . $row['qstn'] . ' ' + $output[]=implode(" ", array_values($row)); + } + return implode(" ",$output); + } + + + /** + * + * Count all documents from db + * + */ + function get_db_counts() + { + $surveys=$this->ci->db->query('select count(id) as total from surveys;')->row_array(); + $variables=$this->ci->db->query('select count(uid) as total from variables;')->row_array(); + $citations=$this->ci->db->query('select count(id) as total from citations;')->row_array(); + + return array( + 'datasets'=>$surveys['total'], + 'variables'=>$variables['total'], + 'citations'=>$citations['total'] + ); + } + + /** + * + * + * Count all documents from solr + * + */ + function get_solr_counts() + { + $datasets=$this->get_total_documents_count(1); + $variables=$this->get_total_documents_count(2); + $citations=$this->get_total_documents_count(3); + + return array( + 'datasets'=>$datasets, + 'variables'=>$variables, + 'citations'=>$citations + ); + } +}// END class + +/* End of file Solr.php */ +/* Location: ./application/libraries/Solr.php */ \ No newline at end of file diff --git a/application/models/Solr_delta_updates_model.php b/application/models/Solr_delta_updates_model.php new file mode 100644 index 000000000..8b95f45e7 --- /dev/null +++ b/application/models/Solr_delta_updates_model.php @@ -0,0 +1,56 @@ +output->enable_profiler(TRUE); + } + + function apply_updates($table, $delta_op, $obj_id, $is_processed) + { + $options=array( + 'obj_id'=>$obj_id, + 'obj_type'=>$table, + 'obj_delta'=>$delta_op, + 'is_processed'=>$is_processed + ); + + $this->insert($options); + } + + + + + + function insert($options) + { + //allowed fields + $valid_fields=array( + 'obj_id', + 'obj_type', + 'obj_delta', + 'is_processed' + ); + + $data=array(); + + foreach($options as $key=>$value) + { + if (in_array($key,$valid_fields) ) + { + $data[$key]=$value; + } + } + + $result=$this->db->insert('solr_delta_updates', $data); + + if ($result===false) + { + throw new MY_Exception($this->db->_error_message()); + } + + return TRUE; + } +} +?> \ No newline at end of file diff --git a/application/views/solr/index.php b/application/views/solr/index.php new file mode 100644 index 000000000..2c5b5f148 --- /dev/null +++ b/application/views/solr/index.php @@ -0,0 +1,179 @@ +
+ +
+
+ + + + + + + +
+ +
+
+
+

Index statistics

+
+
+
+
SOLR index
+ $value):?> + : + +
+
+
+
Database records
+ $value):?> + : + +
+ +
+
+ + +
+ +
+
+

Index datasets -

+
+
+ + +
+
+ +
+ +
+ +
+
+

Index Variables -

+
+
+ + +
+
+ +
+ +
+ +
+
+

Index Citations -

+
+
+ + +
+
+ +
+ + +
+ + +
+ +
+ + + \ No newline at end of file diff --git a/composer.json b/composer.json index 28c578fc0..56a9c0ba2 100644 --- a/composer.json +++ b/composer.json @@ -5,6 +5,8 @@ "phpmailer/phpmailer": "^5.2.26", "violet/streaming-json-encoder": "^1.1", "salsify/json-streaming-parser": "^8.0", - "slim/csrf": "^0.8.3" + "slim/csrf": "^0.8.3", + "solarium/solarium": "^4.2", + "league/event": "^2.2" } } diff --git a/composer.lock b/composer.lock index 747eefa20..ee56a529d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4e403dac56dc7bdc2d5965eeba7a8f77", + "content-hash": "6673bb20bcdbeb5170dccf0f67d13383", "packages": [ { "name": "justinrainbow/json-schema", @@ -72,6 +72,56 @@ ], "time": "2018-02-14T22:26:30+00:00" }, + { + "name": "league/event", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/event.git", + "reference": "d2cc124cf9a3fab2bb4ff963307f60361ce4d119" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/event/zipball/d2cc124cf9a3fab2bb4ff963307f60361ce4d119", + "reference": "d2cc124cf9a3fab2bb4ff963307f60361ce4d119", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "henrikbjorn/phpspec-code-coverage": "~1.0.1", + "phpspec/phpspec": "^2.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Event\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "description": "Event package", + "keywords": [ + "emitter", + "event", + "listener" + ], + "time": "2018-11-26T11:52:41+00:00" + }, { "name": "mpdf/mpdf", "version": "v7.1.7", @@ -573,6 +623,196 @@ ], "time": "2018-08-22T16:12:18+00:00" }, + { + "name": "solarium/solarium", + "version": "4.2.0", + "source": { + "type": "git", + "url": "https://github.com/solariumphp/solarium.git", + "reference": "20cf9e906a4e8e4a29c1ff48a2b145fa31d1064d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/solariumphp/solarium/zipball/20cf9e906a4e8e4a29c1ff48a2b145fa31d1064d", + "reference": "20cf9e906a4e8e4a29c1ff48a2b145fa31d1064d", + "shasum": "" + }, + "require": { + "php": "^7.0", + "symfony/event-dispatcher": "^2.7 || ^3.0 || ^4.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^3.8 || ^6.2", + "php-coveralls/php-coveralls": "^1.0", + "phpunit/phpunit": "^6.5", + "squizlabs/php_codesniffer": "^1.4", + "zendframework/zendframework": "^3.0" + }, + "suggest": { + "minimalcode/search": "Query builder compatible with Solarium, allows simplified solr-query handling" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Solarium\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "See GitHub contributors", + "homepage": "https://github.com/basdenooijer/solarium/contributors" + } + ], + "description": "PHP Solr client", + "homepage": "http://www.solarium-project.org", + "keywords": [ + "php", + "search", + "solr" + ], + "time": "2018-11-24T09:20:30+00:00" + }, + { + "name": "symfony/contracts", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/contracts.git", + "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/contracts/zipball/1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "require-dev": { + "psr/cache": "^1.0", + "psr/container": "^1.0" + }, + "suggest": { + "psr/cache": "When using the Cache contracts", + "psr/container": "When using the Service contracts", + "symfony/cache-contracts-implementation": "", + "symfony/service-contracts-implementation": "", + "symfony/translation-contracts-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\": "" + }, + "exclude-from-classmap": [ + "**/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A set of abstractions extracted out of the Symfony components", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "time": "2018-12-05T08:06:11+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v4.2.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "ca5af306fbc37f3cf597e91bc9cfa0c7d3f33544" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ca5af306fbc37f3cf597e91bc9cfa0c7d3f33544", + "reference": "ca5af306fbc37f3cf597e91bc9cfa0c7d3f33544", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/contracts": "^1.0" + }, + "conflict": { + "symfony/dependency-injection": "<3.4" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/expression-language": "~3.4|~4.0", + "symfony/stopwatch": "~3.4|~4.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "time": "2019-03-30T15:58:42+00:00" + }, { "name": "violet/streaming-json-encoder", "version": "v1.1.1", diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index 3351b4499..812b2f3b6 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -7,10 +7,14 @@ return array( 'Violet\\StreamingJsonEncoder\\' => array($vendorDir . '/violet/streaming-json-encoder/src'), + 'Symfony\\Contracts\\' => array($vendorDir . '/symfony/contracts'), + 'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'), + 'Solarium\\' => array($vendorDir . '/solarium/solarium/src'), 'Slim\\Csrf\\' => array($vendorDir . '/slim/csrf/src'), 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'), 'Mpdf\\' => array($vendorDir . '/mpdf/mpdf/src'), + 'League\\Event\\' => array($vendorDir . '/league/event/src'), 'JsonStreamingParser\\Test\\' => array($vendorDir . '/salsify/json-streaming-parser/tests'), 'JsonStreamingParser\\' => array($vendorDir . '/salsify/json-streaming-parser/src'), 'JsonSchema\\' => array($vendorDir . '/justinrainbow/json-schema/src/JsonSchema'), diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 92344a209..d9ed8eb0d 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -17,6 +17,9 @@ class ComposerStaticInit4b9569c966d6a1d4516363e7ff8c8ece ), 'S' => array ( + 'Symfony\\Contracts\\' => 18, + 'Symfony\\Component\\EventDispatcher\\' => 34, + 'Solarium\\' => 9, 'Slim\\Csrf\\' => 10, ), 'P' => @@ -28,6 +31,10 @@ class ComposerStaticInit4b9569c966d6a1d4516363e7ff8c8ece array ( 'Mpdf\\' => 5, ), + 'L' => + array ( + 'League\\Event\\' => 13, + ), 'J' => array ( 'JsonStreamingParser\\Test\\' => 25, @@ -45,6 +52,18 @@ class ComposerStaticInit4b9569c966d6a1d4516363e7ff8c8ece array ( 0 => __DIR__ . '/..' . '/violet/streaming-json-encoder/src', ), + 'Symfony\\Contracts\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/contracts', + ), + 'Symfony\\Component\\EventDispatcher\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/event-dispatcher', + ), + 'Solarium\\' => + array ( + 0 => __DIR__ . '/..' . '/solarium/solarium/src', + ), 'Slim\\Csrf\\' => array ( 0 => __DIR__ . '/..' . '/slim/csrf/src', @@ -61,6 +80,10 @@ class ComposerStaticInit4b9569c966d6a1d4516363e7ff8c8ece array ( 0 => __DIR__ . '/..' . '/mpdf/mpdf/src', ), + 'League\\Event\\' => + array ( + 0 => __DIR__ . '/..' . '/league/event/src', + ), 'JsonStreamingParser\\Test\\' => array ( 0 => __DIR__ . '/..' . '/salsify/json-streaming-parser/tests', diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 8f9b56eec..0afc10c29 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -67,6 +67,58 @@ "schema" ] }, + { + "name": "league/event", + "version": "2.2.0", + "version_normalized": "2.2.0.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/event.git", + "reference": "d2cc124cf9a3fab2bb4ff963307f60361ce4d119" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/event/zipball/d2cc124cf9a3fab2bb4ff963307f60361ce4d119", + "reference": "d2cc124cf9a3fab2bb4ff963307f60361ce4d119", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "henrikbjorn/phpspec-code-coverage": "~1.0.1", + "phpspec/phpspec": "^2.2" + }, + "time": "2018-11-26T11:52:41+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "League\\Event\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "description": "Event package", + "keywords": [ + "emitter", + "event", + "listener" + ] + }, { "name": "mpdf/mpdf", "version": "v7.1.7", @@ -586,6 +638,202 @@ "slim" ] }, + { + "name": "solarium/solarium", + "version": "4.2.0", + "version_normalized": "4.2.0.0", + "source": { + "type": "git", + "url": "https://github.com/solariumphp/solarium.git", + "reference": "20cf9e906a4e8e4a29c1ff48a2b145fa31d1064d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/solariumphp/solarium/zipball/20cf9e906a4e8e4a29c1ff48a2b145fa31d1064d", + "reference": "20cf9e906a4e8e4a29c1ff48a2b145fa31d1064d", + "shasum": "" + }, + "require": { + "php": "^7.0", + "symfony/event-dispatcher": "^2.7 || ^3.0 || ^4.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^3.8 || ^6.2", + "php-coveralls/php-coveralls": "^1.0", + "phpunit/phpunit": "^6.5", + "squizlabs/php_codesniffer": "^1.4", + "zendframework/zendframework": "^3.0" + }, + "suggest": { + "minimalcode/search": "Query builder compatible with Solarium, allows simplified solr-query handling" + }, + "time": "2018-11-24T09:20:30+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Solarium\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "See GitHub contributors", + "homepage": "https://github.com/basdenooijer/solarium/contributors" + } + ], + "description": "PHP Solr client", + "homepage": "http://www.solarium-project.org", + "keywords": [ + "php", + "search", + "solr" + ] + }, + { + "name": "symfony/contracts", + "version": "v1.0.2", + "version_normalized": "1.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/contracts.git", + "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/contracts/zipball/1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "require-dev": { + "psr/cache": "^1.0", + "psr/container": "^1.0" + }, + "suggest": { + "psr/cache": "When using the Cache contracts", + "psr/container": "When using the Service contracts", + "symfony/cache-contracts-implementation": "", + "symfony/service-contracts-implementation": "", + "symfony/translation-contracts-implementation": "" + }, + "time": "2018-12-05T08:06:11+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Contracts\\": "" + }, + "exclude-from-classmap": [ + "**/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A set of abstractions extracted out of the Symfony components", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ] + }, + { + "name": "symfony/event-dispatcher", + "version": "v4.2.5", + "version_normalized": "4.2.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "ca5af306fbc37f3cf597e91bc9cfa0c7d3f33544" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ca5af306fbc37f3cf597e91bc9cfa0c7d3f33544", + "reference": "ca5af306fbc37f3cf597e91bc9cfa0c7d3f33544", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/contracts": "^1.0" + }, + "conflict": { + "symfony/dependency-injection": "<3.4" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/expression-language": "~3.4|~4.0", + "symfony/stopwatch": "~3.4|~4.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "time": "2019-03-30T15:58:42+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com" + }, { "name": "violet/streaming-json-encoder", "version": "v1.1.1", From 0f2464572d75eb9f49856c1a318d203ad875ae05 Mon Sep 17 00:00:00 2001 From: Mehmood Asghar Date: Wed, 17 Apr 2019 13:56:27 -0400 Subject: [PATCH 002/103] include vendor libraries for league/events and solarium --- .../justinrainbow/json-schema/bin/data.json | 1 + vendor/league/event/LICENSE | 19 + vendor/league/event/composer.json | 37 + vendor/league/event/src/AbstractEvent.php | 64 + vendor/league/event/src/AbstractListener.php | 14 + vendor/league/event/src/BufferedEmitter.php | 49 + vendor/league/event/src/CallbackListener.php | 65 + vendor/league/event/src/Emitter.php | 268 ++++ .../event/src/EmitterAwareInterface.php | 22 + vendor/league/event/src/EmitterAwareTrait.php | 41 + vendor/league/event/src/EmitterInterface.php | 92 ++ vendor/league/event/src/EmitterTrait.php | 113 ++ vendor/league/event/src/Event.php | 43 + vendor/league/event/src/EventInterface.php | 43 + vendor/league/event/src/Generator.php | 10 + .../league/event/src/GeneratorInterface.php | 13 + vendor/league/event/src/GeneratorTrait.php | 40 + vendor/league/event/src/ListenerAcceptor.php | 43 + .../event/src/ListenerAcceptorInterface.php | 59 + vendor/league/event/src/ListenerInterface.php | 24 + .../event/src/ListenerProviderInterface.php | 15 + vendor/league/event/src/OneTimeListener.php | 57 + vendor/solarium/solarium/.coveralls.yml | 1 + vendor/solarium/solarium/.travis.yml | 50 + vendor/solarium/solarium/CHANGELOG.md | 292 ++++ vendor/solarium/solarium/CONTRIBUTING.md | 25 + vendor/solarium/solarium/COPYING | 25 + vendor/solarium/solarium/README.md | 50 + vendor/solarium/solarium/composer.json | 46 + vendor/solarium/solarium/src/Client.php | 99 ++ .../src/Component/AbstractComponent.php | 78 + .../ComponentAwareQueryInterface.php | 148 ++ .../Component/ComponentAwareQueryTrait.php | 152 ++ .../ComponentTraits/SpellcheckTrait.php | 315 ++++ .../ComponentTraits/SuggesterTrait.php | 126 ++ .../Component/ComponentTraits/TermsTrait.php | 326 ++++ .../solarium/solarium/src/Component/Debug.php | 66 + .../solarium/src/Component/DisMax.php | 441 ++++++ .../src/Component/DisMax/BoostQuery.php | 65 + .../src/Component/DistributedSearch.php | 391 +++++ .../solarium/src/Component/EdisMax.php | 203 +++ .../src/Component/Facet/AbstractFacet.php | 44 + .../src/Component/Facet/AbstractField.php | 210 +++ .../src/Component/Facet/AbstractRange.php | 268 ++++ .../Component/Facet/ExcludeTagsInterface.php | 61 + .../src/Component/Facet/ExcludeTagsTrait.php | 117 ++ .../src/Component/Facet/FacetInterface.php | 36 + .../solarium/src/Component/Facet/Field.php | 79 + .../solarium/src/Component/Facet/Interval.php | 103 ++ .../src/Component/Facet/JsonAggregation.php | 86 ++ .../Component/Facet/JsonFacetInterface.php | 18 + .../src/Component/Facet/JsonFacetTrait.php | 183 +++ .../src/Component/Facet/JsonQuery.php | 58 + .../src/Component/Facet/JsonRange.php | 39 + .../src/Component/Facet/JsonTerms.php | 156 ++ .../src/Component/Facet/MultiQuery.php | 283 ++++ .../solarium/src/Component/Facet/Pivot.php | 260 ++++ .../solarium/src/Component/Facet/Query.php | 48 + .../solarium/src/Component/Facet/Range.php | 61 + .../solarium/src/Component/FacetSet.php | 407 +++++ .../src/Component/FacetSetInterface.php | 147 ++ .../solarium/src/Component/FacetSetTrait.php | 207 +++ .../solarium/src/Component/Grouping.php | 552 +++++++ .../src/Component/Highlighting/Field.php | 281 ++++ .../Component/Highlighting/Highlighting.php | 900 +++++++++++ .../solarium/src/Component/MoreLikeThis.php | 314 ++++ .../solarium/src/Component/QueryElevation.php | 315 ++++ .../solarium/src/Component/QueryInterface.php | 28 + .../solarium/src/Component/QueryTrait.php | 39 + .../src/Component/QueryTraits/DebugTrait.php | 23 + .../src/Component/QueryTraits/DisMaxTrait.php | 23 + .../QueryTraits/DistributedSearchTrait.php | 23 + .../Component/QueryTraits/EDisMaxTrait.php | 23 + .../Component/QueryTraits/FacetSetTrait.php | 23 + .../Component/QueryTraits/GroupingTrait.php | 23 + .../QueryTraits/HighlightingTrait.php | 23 + .../QueryTraits/MoreLikeThisTrait.php | 23 + .../QueryTraits/QueryElevationTrait.php | 23 + .../QueryTraits/ReRankQueryTrait.php | 23 + .../Component/QueryTraits/SpatialTrait.php | 23 + .../Component/QueryTraits/SpellcheckTrait.php | 23 + .../src/Component/QueryTraits/StatsTrait.php | 23 + .../Component/QueryTraits/SuggesterTrait.php | 23 + .../src/Component/QueryTraits/TermsTrait.php | 23 + .../solarium/src/Component/ReRankQuery.php | 79 + .../ComponentRequestBuilderInterface.php | 22 + .../src/Component/RequestBuilder/Debug.php | 29 + .../src/Component/RequestBuilder/DisMax.php | 46 + .../RequestBuilder/DistributedSearch.php | 47 + .../src/Component/RequestBuilder/EdisMax.php | 52 + .../src/Component/RequestBuilder/FacetSet.php | 280 ++++ .../src/Component/RequestBuilder/Grouping.php | 41 + .../Component/RequestBuilder/Highlighting.php | 90 ++ .../Component/RequestBuilder/MoreLikeThis.php | 42 + .../RequestBuilder/QueryElevation.php | 42 + .../Component/RequestBuilder/ReRankQuery.php | 32 + .../RequestBuilder/RequestParamsInterface.php | 84 ++ .../RequestBuilder/RequestParamsTrait.php | 163 ++ .../src/Component/RequestBuilder/Spatial.php | 29 + .../Component/RequestBuilder/Spellcheck.php | 46 + .../src/Component/RequestBuilder/Stats.php | 46 + .../Component/RequestBuilder/SubRequest.php | 65 + .../Component/RequestBuilder/Suggester.php | 33 + .../src/Component/RequestBuilder/Terms.php | 46 + .../ComponentParserInterface.php | 22 + .../src/Component/ResponseParser/Debug.php | 152 ++ .../src/Component/ResponseParser/FacetSet.php | 319 ++++ .../src/Component/ResponseParser/Grouping.php | 125 ++ .../Component/ResponseParser/Highlighting.php | 38 + .../Component/ResponseParser/MoreLikeThis.php | 48 + .../Component/ResponseParser/Spellcheck.php | 187 +++ .../src/Component/ResponseParser/Stats.php | 45 + .../Component/ResponseParser/Suggester.php | 61 + .../src/Component/ResponseParser/Terms.php | 44 + .../src/Component/Result/Debug/Detail.php | 95 ++ .../src/Component/Result/Debug/Document.php | 79 + .../Component/Result/Debug/DocumentSet.php | 70 + .../src/Component/Result/Debug/Result.php | 172 +++ .../src/Component/Result/Debug/Timing.php | 89 ++ .../Component/Result/Debug/TimingPhase.php | 98 ++ .../Component/Result/Facet/Aggregation.php | 36 + .../src/Component/Result/Facet/Bucket.php | 101 ++ .../src/Component/Result/Facet/Buckets.php | 60 + .../src/Component/Result/Facet/Field.php | 60 + .../src/Component/Result/Facet/Interval.php | 14 + .../src/Component/Result/Facet/MultiQuery.php | 14 + .../Component/Result/Facet/Pivot/Pivot.php | 58 + .../Result/Facet/Pivot/PivotItem.php | 103 ++ .../src/Component/Result/Facet/Query.php | 39 + .../src/Component/Result/Facet/Range.php | 155 ++ .../src/Component/Result/FacetSet.php | 72 + .../Component/Result/Grouping/FieldGroup.php | 98 ++ .../Component/Result/Grouping/QueryGroup.php | 143 ++ .../src/Component/Result/Grouping/Result.php | 72 + .../Component/Result/Grouping/ValueGroup.php | 143 ++ .../Result/Highlighting/Highlighting.php | 70 + .../Component/Result/Highlighting/Result.php | 72 + .../Result/MoreLikeThis/MoreLikeThis.php | 70 + .../Component/Result/MoreLikeThis/Result.php | 101 ++ .../Component/Result/Spellcheck/Collation.php | 102 ++ .../Component/Result/Spellcheck/Result.php | 131 ++ .../Result/Spellcheck/Suggestion.php | 109 ++ .../src/Component/Result/Stats/FacetValue.php | 135 ++ .../src/Component/Result/Stats/Result.php | 157 ++ .../src/Component/Result/Stats/Stats.php | 70 + .../src/Component/Result/Suggester/Result.php | 93 ++ .../src/Component/Result/Terms/Field.php | 56 + .../src/Component/Result/Terms/Result.php | 91 ++ .../solarium/src/Component/Spatial.php | 87 ++ .../solarium/src/Component/Spellcheck.php | 48 + .../src/Component/SpellcheckInterface.php | 237 +++ .../solarium/src/Component/Stats/Field.php | 249 +++ .../solarium/src/Component/Stats/Stats.php | 333 +++++ .../solarium/src/Component/Suggester.php | 48 + .../src/Component/SuggesterInterface.php | 105 ++ .../solarium/solarium/src/Component/Terms.php | 50 + .../solarium/src/Component/TermsInterface.php | 225 +++ .../src/Core/Client/Adapter/AdapterHelper.php | 30 + .../Core/Client/Adapter/AdapterInterface.php | 36 + .../solarium/src/Core/Client/Adapter/Curl.php | 234 +++ .../src/Core/Client/Adapter/Guzzle.php | 150 ++ .../src/Core/Client/Adapter/Guzzle3.php | 146 ++ .../solarium/src/Core/Client/Adapter/Http.php | 163 ++ .../src/Core/Client/Adapter/PeclHttp.php | 192 +++ .../src/Core/Client/Adapter/Zend2Http.php | 238 +++ .../src/Core/Client/Adapter/ZendHttp.php | 241 +++ .../solarium/src/Core/Client/Client.php | 1331 +++++++++++++++++ .../src/Core/Client/ClientInterface.php | 615 ++++++++ .../solarium/src/Core/Client/Endpoint.php | 299 ++++ .../solarium/src/Core/Client/Request.php | 348 +++++ .../solarium/src/Core/Client/Response.php | 126 ++ .../solarium/src/Core/Configurable.php | 171 +++ .../src/Core/ConfigurableInterface.php | 49 + .../solarium/src/Core/Event/Events.php | 105 ++ .../src/Core/Event/PostCreateQuery.php | 71 + .../src/Core/Event/PostCreateRequest.php | 55 + .../src/Core/Event/PostCreateResult.php | 73 + .../solarium/src/Core/Event/PostExecute.php | 55 + .../src/Core/Event/PostExecuteRequest.php | 73 + .../src/Core/Event/PreCreateQuery.php | 79 + .../src/Core/Event/PreCreateRequest.php | 65 + .../src/Core/Event/PreCreateResult.php | 81 + .../solarium/src/Core/Event/PreExecute.php | 63 + .../src/Core/Event/PreExecuteRequest.php | 91 ++ .../src/Core/Plugin/AbstractPlugin.php | 45 + .../src/Core/Plugin/PluginInterface.php | 22 + .../solarium/src/Core/Query/AbstractQuery.php | 269 ++++ .../src/Core/Query/AbstractRequestBuilder.php | 115 ++ .../src/Core/Query/AbstractResponseParser.php | 67 + .../solarium/src/Core/Query/Helper.php | 492 ++++++ .../src/Core/Query/QueryInterface.php | 97 ++ .../Core/Query/RequestBuilderInterface.php | 20 + .../Core/Query/ResponseParserInterface.php | 26 + .../src/Core/Query/Result/QueryType.php | 54 + .../solarium/src/Core/Query/Result/Result.php | 122 ++ .../src/Core/Query/Result/ResultInterface.php | 37 + .../src/Exception/ExceptionInterface.php | 12 + .../solarium/src/Exception/HttpException.php | 85 ++ .../Exception/InvalidArgumentException.php | 10 + .../src/Exception/OutOfBoundsException.php | 10 + .../src/Exception/RuntimeException.php | 10 + .../src/Exception/StreamException.php | 34 + .../Exception/UnexpectedValueException.php | 10 + .../src/Plugin/BufferedAdd/BufferedAdd.php | 282 ++++ .../Plugin/BufferedAdd/Event/AddDocument.php | 37 + .../src/Plugin/BufferedAdd/Event/Events.php | 54 + .../Plugin/BufferedAdd/Event/PostCommit.php | 38 + .../Plugin/BufferedAdd/Event/PostFlush.php | 38 + .../Plugin/BufferedAdd/Event/PreCommit.php | 147 ++ .../src/Plugin/BufferedAdd/Event/PreFlush.php | 97 ++ .../Plugin/CustomizeRequest/Customization.php | 198 +++ .../CustomizeRequest/CustomizeRequest.php | 251 ++++ .../Loadbalancer/Event/EndpointFailure.php | 51 + .../src/Plugin/Loadbalancer/Event/Events.php | 18 + .../src/Plugin/Loadbalancer/Loadbalancer.php | 530 +++++++ .../Loadbalancer/WeightedRandomChoice.php | 116 ++ .../Plugin/MinimumScoreFilter/Document.php | 169 +++ .../src/Plugin/MinimumScoreFilter/Filter.php | 46 + .../MinimumScoreFilter/MinimumScoreFilter.php | 28 + .../src/Plugin/MinimumScoreFilter/Query.php | 127 ++ .../MinimumScoreFilter/QueryGroupResult.php | 70 + .../src/Plugin/MinimumScoreFilter/Result.php | 31 + .../MinimumScoreFilter/ValueGroupResult.php | 70 + .../Plugin/ParallelExecution/Event/Events.php | 27 + .../ParallelExecution/Event/ExecuteEnd.php | 14 + .../ParallelExecution/Event/ExecuteStart.php | 14 + .../ParallelExecution/ParallelExecution.php | 160 ++ .../solarium/src/Plugin/PostBigRequest.php | 81 + .../solarium/src/Plugin/PrefetchIterator.php | 254 ++++ .../Analysis/Query/AbstractQuery.php | 37 + .../src/QueryType/Analysis/Query/Document.php | 120 ++ .../src/QueryType/Analysis/Query/Field.php | 126 ++ .../Analysis/RequestBuilder/Document.php | 75 + .../Analysis/RequestBuilder/Field.php | 31 + .../RequestBuilder/RequestBuilder.php | 29 + .../Analysis/ResponseParser/Document.php | 30 + .../Analysis/ResponseParser/Field.php | 114 ++ .../QueryType/Analysis/Result/Document.php | 116 ++ .../src/QueryType/Analysis/Result/Field.php | 100 ++ .../src/QueryType/Analysis/Result/Item.php | 174 +++ .../QueryType/Analysis/Result/ResultList.php | 75 + .../src/QueryType/Analysis/Result/Types.php | 44 + .../solarium/src/QueryType/Extract/Query.php | 396 +++++ .../src/QueryType/Extract/RequestBuilder.php | 81 + .../solarium/src/QueryType/Extract/Result.php | 13 + .../solarium/src/QueryType/Graph/Query.php | 72 + .../solarium/src/QueryType/Graph/Result.php | 43 + .../ManagedResources/Query/Resources.php | 69 + .../ManagedResources/Query/Stopwords.php | 173 +++ .../Stopwords/Command/AbstractCommand.php | 39 + .../Query/Stopwords/Command/Add.php | 76 + .../Query/Stopwords/Command/Delete.php | 66 + .../Query/Stopwords/Command/Exists.php | 66 + .../Query/Stopwords/Stopword.php | 27 + .../ManagedResources/Query/Synonyms.php | 197 +++ .../Synonyms/Command/AbstractCommand.php | 39 + .../Query/Synonyms/Command/Add.php | 81 + .../Query/Synonyms/Command/Delete.php | 66 + .../Query/Synonyms/Command/Exists.php | 66 + .../Query/Synonyms/Synonyms.php | 55 + .../RequestBuilder/Resources.php | 9 + .../RequestBuilder/Stopwords.php | 65 + .../RequestBuilder/Synonyms.php | 65 + .../ResponseParser/Resources.php | 33 + .../ResponseParser/Stopwords.php | 38 + .../ResponseParser/Synonyms.php | 47 + .../Result/Resources/Resource.php | 107 ++ .../Result/Resources/ResourceList.php | 79 + .../Result/Stopwords/WordSet.php | 117 ++ .../Result/Synonyms/SynonymMappings.php | 132 ++ .../Result/Synonyms/Synonyms.php | 67 + .../src/QueryType/MoreLikeThis/Query.php | 411 +++++ .../QueryType/MoreLikeThis/RequestBuilder.php | 49 + .../QueryType/MoreLikeThis/ResponseParser.php | 45 + .../src/QueryType/MoreLikeThis/Result.php | 90 ++ .../solarium/src/QueryType/Ping/Query.php | 54 + .../src/QueryType/Ping/RequestBuilder.php | 28 + .../solarium/src/QueryType/Ping/Result.php | 27 + .../src/QueryType/RealtimeGet/Query.php | 192 +++ .../QueryType/RealtimeGet/RequestBuilder.php | 29 + .../src/QueryType/RealtimeGet/Result.php | 26 + .../QueryType/Select/Query/FilterQuery.php | 171 +++ .../src/QueryType/Select/Query/Query.php | 813 ++++++++++ .../src/QueryType/Select/RequestBuilder.php | 73 + .../src/QueryType/Select/ResponseParser.php | 88 ++ .../Select/Result/AbstractDocument.php | 125 ++ .../src/QueryType/Select/Result/Document.php | 48 + .../Select/Result/DocumentInterface.php | 16 + .../src/QueryType/Select/Result/Result.php | 329 ++++ .../QueryType/Server/AbstractServerQuery.php | 12 + .../CoreAdmin/Query/Action/AbstractAction.php | 18 + .../Query/Action/AbstractAsyncAction.php | 28 + .../Query/Action/AbstractCoreAction.php | 26 + .../Server/CoreAdmin/Query/Action/Create.php | 224 +++ .../CoreAdmin/Query/Action/MergeIndexes.php | 62 + .../Server/CoreAdmin/Query/Action/Reload.php | 18 + .../Server/CoreAdmin/Query/Action/Rename.php | 40 + .../Query/Action/RequestRecovery.php | 18 + .../CoreAdmin/Query/Action/RequestStatus.php | 45 + .../Server/CoreAdmin/Query/Action/Split.php | 109 ++ .../Server/CoreAdmin/Query/Action/Status.php | 41 + .../Server/CoreAdmin/Query/Action/Swap.php | 40 + .../Server/CoreAdmin/Query/Action/Unload.php | 87 ++ .../Server/CoreAdmin/Query/Query.php | 282 ++++ .../Server/CoreAdmin/RequestBuilder.php | 38 + .../Server/CoreAdmin/ResponseParser.php | 81 + .../Server/CoreAdmin/Result/Result.php | 85 ++ .../Server/CoreAdmin/Result/StatusResult.php | 135 ++ .../src/QueryType/Spellcheck/Query.php | 64 + .../QueryType/Spellcheck/RequestBuilder.php | 31 + .../QueryType/Spellcheck/ResponseParser.php | 76 + .../QueryType/Spellcheck/Result/Result.php | 158 ++ .../src/QueryType/Spellcheck/Result/Term.php | 113 ++ .../src/QueryType/Stream/Expression.php | 67 + .../solarium/src/QueryType/Stream/Query.php | 101 ++ .../src/QueryType/Stream/RequestBuilder.php | 31 + .../src/QueryType/Stream/ResponseParser.php | 78 + .../solarium/src/QueryType/Stream/Result.php | 173 +++ .../src/QueryType/Suggester/Query.php | 66 + .../QueryType/Suggester/RequestBuilder.php | 31 + .../QueryType/Suggester/ResponseParser.php | 66 + .../QueryType/Suggester/Result/Dictionary.php | 72 + .../src/QueryType/Suggester/Result/Result.php | 137 ++ .../src/QueryType/Suggester/Result/Term.php | 75 + .../solarium/src/QueryType/Terms/Query.php | 62 + .../src/QueryType/Terms/RequestBuilder.php | 31 + .../src/QueryType/Terms/ResponseParser.php | 50 + .../solarium/src/QueryType/Terms/Result.php | 118 ++ .../Update/Query/Command/AbstractCommand.php | 18 + .../QueryType/Update/Query/Command/Add.php | 143 ++ .../QueryType/Update/Query/Command/Commit.php | 89 ++ .../QueryType/Update/Query/Command/Delete.php | 137 ++ .../Update/Query/Command/Optimize.php | 89 ++ .../Update/Query/Command/Rollback.php | 23 + .../Update/Query/Document/Document.php | 485 ++++++ .../Query/Document/DocumentInterface.php | 18 + .../src/QueryType/Update/Query/Query.php | 470 ++++++ .../src/QueryType/Update/RequestBuilder.php | 244 +++ .../src/QueryType/Update/ResponseParser.php | 26 + .../solarium/src/QueryType/Update/Result.php | 63 + .../src/Support/DataFixtures/Executor.php | 36 + .../Support/DataFixtures/FixtureInterface.php | 16 + .../Support/DataFixtures/FixtureLoader.php | 53 + .../src/Support/DataFixtures/Loader.php | 87 ++ .../src/Support/DataFixtures/Purger.php | 44 + vendor/symfony/contracts/.gitignore | 3 + vendor/symfony/contracts/CHANGELOG.md | 12 + .../contracts/Cache/CacheInterface.php | 57 + vendor/symfony/contracts/Cache/CacheTrait.php | 71 + .../contracts/Cache/CallbackInterface.php | 30 + .../symfony/contracts/Cache/ItemInterface.php | 60 + .../Cache/TagAwareCacheInterface.php | 38 + vendor/symfony/contracts/LICENSE | 19 + vendor/symfony/contracts/README.md | 70 + .../contracts/Service/ResetInterface.php | 30 + .../contracts/Service/ServiceLocatorTrait.php | 97 ++ .../Service/ServiceSubscriberInterface.php | 53 + .../Service/ServiceSubscriberTrait.php | 61 + .../contracts/Tests/Cache/CacheTraitTest.php | 165 ++ .../Tests/Service/ServiceLocatorTest.php | 94 ++ .../Service/ServiceSubscriberTraitTest.php | 65 + .../Tests/Translation/TranslatorTest.php | 353 +++++ .../Translation/LocaleAwareInterface.php | 31 + .../Translation/TranslatorInterface.php | 65 + .../contracts/Translation/TranslatorTrait.php | 255 ++++ vendor/symfony/contracts/composer.json | 44 + vendor/symfony/contracts/phpunit.xml.dist | 31 + vendor/symfony/event-dispatcher/.gitignore | 3 + vendor/symfony/event-dispatcher/CHANGELOG.md | 55 + .../Debug/TraceableEventDispatcher.php | 353 +++++ .../TraceableEventDispatcherInterface.php | 37 + .../Debug/WrappedListener.php | 125 ++ .../RegisterListenersPass.php | 136 ++ vendor/symfony/event-dispatcher/Event.php | 58 + .../event-dispatcher/EventDispatcher.php | 236 +++ .../EventDispatcherInterface.php | 93 ++ .../EventSubscriberInterface.php | 46 + .../symfony/event-dispatcher/GenericEvent.php | 175 +++ .../ImmutableEventDispatcher.php | 91 ++ vendor/symfony/event-dispatcher/LICENSE | 19 + vendor/symfony/event-dispatcher/README.md | 15 + .../Tests/AbstractEventDispatcherTest.php | 442 ++++++ .../Debug/TraceableEventDispatcherTest.php | 305 ++++ .../Tests/Debug/WrappedListenerTest.php | 59 + .../RegisterListenersPassTest.php | 206 +++ .../Tests/EventDispatcherTest.php | 22 + .../event-dispatcher/Tests/EventTest.php | 55 + .../Tests/GenericEventTest.php | 136 ++ .../Tests/ImmutableEventDispatcherTest.php | 106 ++ vendor/symfony/event-dispatcher/composer.json | 48 + .../symfony/event-dispatcher/phpunit.xml.dist | 31 + 391 files changed, 41761 insertions(+) create mode 100644 vendor/justinrainbow/json-schema/bin/data.json create mode 100644 vendor/league/event/LICENSE create mode 100644 vendor/league/event/composer.json create mode 100644 vendor/league/event/src/AbstractEvent.php create mode 100644 vendor/league/event/src/AbstractListener.php create mode 100644 vendor/league/event/src/BufferedEmitter.php create mode 100644 vendor/league/event/src/CallbackListener.php create mode 100644 vendor/league/event/src/Emitter.php create mode 100644 vendor/league/event/src/EmitterAwareInterface.php create mode 100644 vendor/league/event/src/EmitterAwareTrait.php create mode 100644 vendor/league/event/src/EmitterInterface.php create mode 100644 vendor/league/event/src/EmitterTrait.php create mode 100644 vendor/league/event/src/Event.php create mode 100644 vendor/league/event/src/EventInterface.php create mode 100644 vendor/league/event/src/Generator.php create mode 100644 vendor/league/event/src/GeneratorInterface.php create mode 100644 vendor/league/event/src/GeneratorTrait.php create mode 100644 vendor/league/event/src/ListenerAcceptor.php create mode 100644 vendor/league/event/src/ListenerAcceptorInterface.php create mode 100644 vendor/league/event/src/ListenerInterface.php create mode 100644 vendor/league/event/src/ListenerProviderInterface.php create mode 100644 vendor/league/event/src/OneTimeListener.php create mode 100644 vendor/solarium/solarium/.coveralls.yml create mode 100644 vendor/solarium/solarium/.travis.yml create mode 100644 vendor/solarium/solarium/CHANGELOG.md create mode 100644 vendor/solarium/solarium/CONTRIBUTING.md create mode 100644 vendor/solarium/solarium/COPYING create mode 100644 vendor/solarium/solarium/README.md create mode 100644 vendor/solarium/solarium/composer.json create mode 100644 vendor/solarium/solarium/src/Client.php create mode 100644 vendor/solarium/solarium/src/Component/AbstractComponent.php create mode 100644 vendor/solarium/solarium/src/Component/ComponentAwareQueryInterface.php create mode 100644 vendor/solarium/solarium/src/Component/ComponentAwareQueryTrait.php create mode 100644 vendor/solarium/solarium/src/Component/ComponentTraits/SpellcheckTrait.php create mode 100644 vendor/solarium/solarium/src/Component/ComponentTraits/SuggesterTrait.php create mode 100644 vendor/solarium/solarium/src/Component/ComponentTraits/TermsTrait.php create mode 100644 vendor/solarium/solarium/src/Component/Debug.php create mode 100644 vendor/solarium/solarium/src/Component/DisMax.php create mode 100644 vendor/solarium/solarium/src/Component/DisMax/BoostQuery.php create mode 100644 vendor/solarium/solarium/src/Component/DistributedSearch.php create mode 100644 vendor/solarium/solarium/src/Component/EdisMax.php create mode 100644 vendor/solarium/solarium/src/Component/Facet/AbstractFacet.php create mode 100644 vendor/solarium/solarium/src/Component/Facet/AbstractField.php create mode 100644 vendor/solarium/solarium/src/Component/Facet/AbstractRange.php create mode 100644 vendor/solarium/solarium/src/Component/Facet/ExcludeTagsInterface.php create mode 100644 vendor/solarium/solarium/src/Component/Facet/ExcludeTagsTrait.php create mode 100644 vendor/solarium/solarium/src/Component/Facet/FacetInterface.php create mode 100644 vendor/solarium/solarium/src/Component/Facet/Field.php create mode 100644 vendor/solarium/solarium/src/Component/Facet/Interval.php create mode 100644 vendor/solarium/solarium/src/Component/Facet/JsonAggregation.php create mode 100644 vendor/solarium/solarium/src/Component/Facet/JsonFacetInterface.php create mode 100644 vendor/solarium/solarium/src/Component/Facet/JsonFacetTrait.php create mode 100644 vendor/solarium/solarium/src/Component/Facet/JsonQuery.php create mode 100644 vendor/solarium/solarium/src/Component/Facet/JsonRange.php create mode 100644 vendor/solarium/solarium/src/Component/Facet/JsonTerms.php create mode 100644 vendor/solarium/solarium/src/Component/Facet/MultiQuery.php create mode 100644 vendor/solarium/solarium/src/Component/Facet/Pivot.php create mode 100644 vendor/solarium/solarium/src/Component/Facet/Query.php create mode 100644 vendor/solarium/solarium/src/Component/Facet/Range.php create mode 100644 vendor/solarium/solarium/src/Component/FacetSet.php create mode 100644 vendor/solarium/solarium/src/Component/FacetSetInterface.php create mode 100644 vendor/solarium/solarium/src/Component/FacetSetTrait.php create mode 100644 vendor/solarium/solarium/src/Component/Grouping.php create mode 100644 vendor/solarium/solarium/src/Component/Highlighting/Field.php create mode 100644 vendor/solarium/solarium/src/Component/Highlighting/Highlighting.php create mode 100644 vendor/solarium/solarium/src/Component/MoreLikeThis.php create mode 100644 vendor/solarium/solarium/src/Component/QueryElevation.php create mode 100644 vendor/solarium/solarium/src/Component/QueryInterface.php create mode 100644 vendor/solarium/solarium/src/Component/QueryTrait.php create mode 100644 vendor/solarium/solarium/src/Component/QueryTraits/DebugTrait.php create mode 100644 vendor/solarium/solarium/src/Component/QueryTraits/DisMaxTrait.php create mode 100644 vendor/solarium/solarium/src/Component/QueryTraits/DistributedSearchTrait.php create mode 100644 vendor/solarium/solarium/src/Component/QueryTraits/EDisMaxTrait.php create mode 100644 vendor/solarium/solarium/src/Component/QueryTraits/FacetSetTrait.php create mode 100644 vendor/solarium/solarium/src/Component/QueryTraits/GroupingTrait.php create mode 100644 vendor/solarium/solarium/src/Component/QueryTraits/HighlightingTrait.php create mode 100644 vendor/solarium/solarium/src/Component/QueryTraits/MoreLikeThisTrait.php create mode 100644 vendor/solarium/solarium/src/Component/QueryTraits/QueryElevationTrait.php create mode 100644 vendor/solarium/solarium/src/Component/QueryTraits/ReRankQueryTrait.php create mode 100644 vendor/solarium/solarium/src/Component/QueryTraits/SpatialTrait.php create mode 100644 vendor/solarium/solarium/src/Component/QueryTraits/SpellcheckTrait.php create mode 100644 vendor/solarium/solarium/src/Component/QueryTraits/StatsTrait.php create mode 100644 vendor/solarium/solarium/src/Component/QueryTraits/SuggesterTrait.php create mode 100644 vendor/solarium/solarium/src/Component/QueryTraits/TermsTrait.php create mode 100644 vendor/solarium/solarium/src/Component/ReRankQuery.php create mode 100644 vendor/solarium/solarium/src/Component/RequestBuilder/ComponentRequestBuilderInterface.php create mode 100644 vendor/solarium/solarium/src/Component/RequestBuilder/Debug.php create mode 100644 vendor/solarium/solarium/src/Component/RequestBuilder/DisMax.php create mode 100644 vendor/solarium/solarium/src/Component/RequestBuilder/DistributedSearch.php create mode 100644 vendor/solarium/solarium/src/Component/RequestBuilder/EdisMax.php create mode 100644 vendor/solarium/solarium/src/Component/RequestBuilder/FacetSet.php create mode 100644 vendor/solarium/solarium/src/Component/RequestBuilder/Grouping.php create mode 100644 vendor/solarium/solarium/src/Component/RequestBuilder/Highlighting.php create mode 100644 vendor/solarium/solarium/src/Component/RequestBuilder/MoreLikeThis.php create mode 100644 vendor/solarium/solarium/src/Component/RequestBuilder/QueryElevation.php create mode 100644 vendor/solarium/solarium/src/Component/RequestBuilder/ReRankQuery.php create mode 100644 vendor/solarium/solarium/src/Component/RequestBuilder/RequestParamsInterface.php create mode 100644 vendor/solarium/solarium/src/Component/RequestBuilder/RequestParamsTrait.php create mode 100644 vendor/solarium/solarium/src/Component/RequestBuilder/Spatial.php create mode 100644 vendor/solarium/solarium/src/Component/RequestBuilder/Spellcheck.php create mode 100644 vendor/solarium/solarium/src/Component/RequestBuilder/Stats.php create mode 100644 vendor/solarium/solarium/src/Component/RequestBuilder/SubRequest.php create mode 100644 vendor/solarium/solarium/src/Component/RequestBuilder/Suggester.php create mode 100644 vendor/solarium/solarium/src/Component/RequestBuilder/Terms.php create mode 100644 vendor/solarium/solarium/src/Component/ResponseParser/ComponentParserInterface.php create mode 100644 vendor/solarium/solarium/src/Component/ResponseParser/Debug.php create mode 100644 vendor/solarium/solarium/src/Component/ResponseParser/FacetSet.php create mode 100644 vendor/solarium/solarium/src/Component/ResponseParser/Grouping.php create mode 100644 vendor/solarium/solarium/src/Component/ResponseParser/Highlighting.php create mode 100644 vendor/solarium/solarium/src/Component/ResponseParser/MoreLikeThis.php create mode 100644 vendor/solarium/solarium/src/Component/ResponseParser/Spellcheck.php create mode 100644 vendor/solarium/solarium/src/Component/ResponseParser/Stats.php create mode 100644 vendor/solarium/solarium/src/Component/ResponseParser/Suggester.php create mode 100644 vendor/solarium/solarium/src/Component/ResponseParser/Terms.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Debug/Detail.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Debug/Document.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Debug/DocumentSet.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Debug/Result.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Debug/Timing.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Debug/TimingPhase.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Facet/Aggregation.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Facet/Bucket.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Facet/Buckets.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Facet/Field.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Facet/Interval.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Facet/MultiQuery.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Facet/Pivot/Pivot.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Facet/Pivot/PivotItem.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Facet/Query.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Facet/Range.php create mode 100644 vendor/solarium/solarium/src/Component/Result/FacetSet.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Grouping/FieldGroup.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Grouping/QueryGroup.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Grouping/Result.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Grouping/ValueGroup.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Highlighting/Highlighting.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Highlighting/Result.php create mode 100644 vendor/solarium/solarium/src/Component/Result/MoreLikeThis/MoreLikeThis.php create mode 100644 vendor/solarium/solarium/src/Component/Result/MoreLikeThis/Result.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Spellcheck/Collation.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Spellcheck/Result.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Spellcheck/Suggestion.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Stats/FacetValue.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Stats/Result.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Stats/Stats.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Suggester/Result.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Terms/Field.php create mode 100644 vendor/solarium/solarium/src/Component/Result/Terms/Result.php create mode 100644 vendor/solarium/solarium/src/Component/Spatial.php create mode 100644 vendor/solarium/solarium/src/Component/Spellcheck.php create mode 100644 vendor/solarium/solarium/src/Component/SpellcheckInterface.php create mode 100644 vendor/solarium/solarium/src/Component/Stats/Field.php create mode 100644 vendor/solarium/solarium/src/Component/Stats/Stats.php create mode 100644 vendor/solarium/solarium/src/Component/Suggester.php create mode 100644 vendor/solarium/solarium/src/Component/SuggesterInterface.php create mode 100644 vendor/solarium/solarium/src/Component/Terms.php create mode 100644 vendor/solarium/solarium/src/Component/TermsInterface.php create mode 100644 vendor/solarium/solarium/src/Core/Client/Adapter/AdapterHelper.php create mode 100644 vendor/solarium/solarium/src/Core/Client/Adapter/AdapterInterface.php create mode 100644 vendor/solarium/solarium/src/Core/Client/Adapter/Curl.php create mode 100644 vendor/solarium/solarium/src/Core/Client/Adapter/Guzzle.php create mode 100644 vendor/solarium/solarium/src/Core/Client/Adapter/Guzzle3.php create mode 100644 vendor/solarium/solarium/src/Core/Client/Adapter/Http.php create mode 100644 vendor/solarium/solarium/src/Core/Client/Adapter/PeclHttp.php create mode 100644 vendor/solarium/solarium/src/Core/Client/Adapter/Zend2Http.php create mode 100644 vendor/solarium/solarium/src/Core/Client/Adapter/ZendHttp.php create mode 100644 vendor/solarium/solarium/src/Core/Client/Client.php create mode 100644 vendor/solarium/solarium/src/Core/Client/ClientInterface.php create mode 100644 vendor/solarium/solarium/src/Core/Client/Endpoint.php create mode 100644 vendor/solarium/solarium/src/Core/Client/Request.php create mode 100644 vendor/solarium/solarium/src/Core/Client/Response.php create mode 100644 vendor/solarium/solarium/src/Core/Configurable.php create mode 100644 vendor/solarium/solarium/src/Core/ConfigurableInterface.php create mode 100644 vendor/solarium/solarium/src/Core/Event/Events.php create mode 100644 vendor/solarium/solarium/src/Core/Event/PostCreateQuery.php create mode 100644 vendor/solarium/solarium/src/Core/Event/PostCreateRequest.php create mode 100644 vendor/solarium/solarium/src/Core/Event/PostCreateResult.php create mode 100644 vendor/solarium/solarium/src/Core/Event/PostExecute.php create mode 100644 vendor/solarium/solarium/src/Core/Event/PostExecuteRequest.php create mode 100644 vendor/solarium/solarium/src/Core/Event/PreCreateQuery.php create mode 100644 vendor/solarium/solarium/src/Core/Event/PreCreateRequest.php create mode 100644 vendor/solarium/solarium/src/Core/Event/PreCreateResult.php create mode 100644 vendor/solarium/solarium/src/Core/Event/PreExecute.php create mode 100644 vendor/solarium/solarium/src/Core/Event/PreExecuteRequest.php create mode 100644 vendor/solarium/solarium/src/Core/Plugin/AbstractPlugin.php create mode 100644 vendor/solarium/solarium/src/Core/Plugin/PluginInterface.php create mode 100644 vendor/solarium/solarium/src/Core/Query/AbstractQuery.php create mode 100644 vendor/solarium/solarium/src/Core/Query/AbstractRequestBuilder.php create mode 100644 vendor/solarium/solarium/src/Core/Query/AbstractResponseParser.php create mode 100644 vendor/solarium/solarium/src/Core/Query/Helper.php create mode 100644 vendor/solarium/solarium/src/Core/Query/QueryInterface.php create mode 100644 vendor/solarium/solarium/src/Core/Query/RequestBuilderInterface.php create mode 100644 vendor/solarium/solarium/src/Core/Query/ResponseParserInterface.php create mode 100644 vendor/solarium/solarium/src/Core/Query/Result/QueryType.php create mode 100644 vendor/solarium/solarium/src/Core/Query/Result/Result.php create mode 100644 vendor/solarium/solarium/src/Core/Query/Result/ResultInterface.php create mode 100644 vendor/solarium/solarium/src/Exception/ExceptionInterface.php create mode 100644 vendor/solarium/solarium/src/Exception/HttpException.php create mode 100644 vendor/solarium/solarium/src/Exception/InvalidArgumentException.php create mode 100644 vendor/solarium/solarium/src/Exception/OutOfBoundsException.php create mode 100644 vendor/solarium/solarium/src/Exception/RuntimeException.php create mode 100644 vendor/solarium/solarium/src/Exception/StreamException.php create mode 100644 vendor/solarium/solarium/src/Exception/UnexpectedValueException.php create mode 100644 vendor/solarium/solarium/src/Plugin/BufferedAdd/BufferedAdd.php create mode 100644 vendor/solarium/solarium/src/Plugin/BufferedAdd/Event/AddDocument.php create mode 100644 vendor/solarium/solarium/src/Plugin/BufferedAdd/Event/Events.php create mode 100644 vendor/solarium/solarium/src/Plugin/BufferedAdd/Event/PostCommit.php create mode 100644 vendor/solarium/solarium/src/Plugin/BufferedAdd/Event/PostFlush.php create mode 100644 vendor/solarium/solarium/src/Plugin/BufferedAdd/Event/PreCommit.php create mode 100644 vendor/solarium/solarium/src/Plugin/BufferedAdd/Event/PreFlush.php create mode 100644 vendor/solarium/solarium/src/Plugin/CustomizeRequest/Customization.php create mode 100644 vendor/solarium/solarium/src/Plugin/CustomizeRequest/CustomizeRequest.php create mode 100644 vendor/solarium/solarium/src/Plugin/Loadbalancer/Event/EndpointFailure.php create mode 100644 vendor/solarium/solarium/src/Plugin/Loadbalancer/Event/Events.php create mode 100644 vendor/solarium/solarium/src/Plugin/Loadbalancer/Loadbalancer.php create mode 100644 vendor/solarium/solarium/src/Plugin/Loadbalancer/WeightedRandomChoice.php create mode 100644 vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/Document.php create mode 100644 vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/Filter.php create mode 100644 vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/MinimumScoreFilter.php create mode 100644 vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/Query.php create mode 100644 vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/QueryGroupResult.php create mode 100644 vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/Result.php create mode 100644 vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/ValueGroupResult.php create mode 100644 vendor/solarium/solarium/src/Plugin/ParallelExecution/Event/Events.php create mode 100644 vendor/solarium/solarium/src/Plugin/ParallelExecution/Event/ExecuteEnd.php create mode 100644 vendor/solarium/solarium/src/Plugin/ParallelExecution/Event/ExecuteStart.php create mode 100644 vendor/solarium/solarium/src/Plugin/ParallelExecution/ParallelExecution.php create mode 100644 vendor/solarium/solarium/src/Plugin/PostBigRequest.php create mode 100644 vendor/solarium/solarium/src/Plugin/PrefetchIterator.php create mode 100644 vendor/solarium/solarium/src/QueryType/Analysis/Query/AbstractQuery.php create mode 100644 vendor/solarium/solarium/src/QueryType/Analysis/Query/Document.php create mode 100644 vendor/solarium/solarium/src/QueryType/Analysis/Query/Field.php create mode 100644 vendor/solarium/solarium/src/QueryType/Analysis/RequestBuilder/Document.php create mode 100644 vendor/solarium/solarium/src/QueryType/Analysis/RequestBuilder/Field.php create mode 100644 vendor/solarium/solarium/src/QueryType/Analysis/RequestBuilder/RequestBuilder.php create mode 100644 vendor/solarium/solarium/src/QueryType/Analysis/ResponseParser/Document.php create mode 100644 vendor/solarium/solarium/src/QueryType/Analysis/ResponseParser/Field.php create mode 100644 vendor/solarium/solarium/src/QueryType/Analysis/Result/Document.php create mode 100644 vendor/solarium/solarium/src/QueryType/Analysis/Result/Field.php create mode 100644 vendor/solarium/solarium/src/QueryType/Analysis/Result/Item.php create mode 100644 vendor/solarium/solarium/src/QueryType/Analysis/Result/ResultList.php create mode 100644 vendor/solarium/solarium/src/QueryType/Analysis/Result/Types.php create mode 100644 vendor/solarium/solarium/src/QueryType/Extract/Query.php create mode 100644 vendor/solarium/solarium/src/QueryType/Extract/RequestBuilder.php create mode 100644 vendor/solarium/solarium/src/QueryType/Extract/Result.php create mode 100644 vendor/solarium/solarium/src/QueryType/Graph/Query.php create mode 100644 vendor/solarium/solarium/src/QueryType/Graph/Result.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Resources.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Stopwords.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Stopwords/Command/AbstractCommand.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Stopwords/Command/Add.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Stopwords/Command/Delete.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Stopwords/Command/Exists.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Stopwords/Stopword.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Synonyms.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Synonyms/Command/AbstractCommand.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Synonyms/Command/Add.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Synonyms/Command/Delete.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Synonyms/Command/Exists.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Synonyms/Synonyms.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/RequestBuilder/Resources.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/RequestBuilder/Stopwords.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/RequestBuilder/Synonyms.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/ResponseParser/Resources.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/ResponseParser/Stopwords.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/ResponseParser/Synonyms.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/Result/Resources/Resource.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/Result/Resources/ResourceList.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/Result/Stopwords/WordSet.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/Result/Synonyms/SynonymMappings.php create mode 100644 vendor/solarium/solarium/src/QueryType/ManagedResources/Result/Synonyms/Synonyms.php create mode 100644 vendor/solarium/solarium/src/QueryType/MoreLikeThis/Query.php create mode 100644 vendor/solarium/solarium/src/QueryType/MoreLikeThis/RequestBuilder.php create mode 100644 vendor/solarium/solarium/src/QueryType/MoreLikeThis/ResponseParser.php create mode 100644 vendor/solarium/solarium/src/QueryType/MoreLikeThis/Result.php create mode 100644 vendor/solarium/solarium/src/QueryType/Ping/Query.php create mode 100644 vendor/solarium/solarium/src/QueryType/Ping/RequestBuilder.php create mode 100644 vendor/solarium/solarium/src/QueryType/Ping/Result.php create mode 100644 vendor/solarium/solarium/src/QueryType/RealtimeGet/Query.php create mode 100644 vendor/solarium/solarium/src/QueryType/RealtimeGet/RequestBuilder.php create mode 100644 vendor/solarium/solarium/src/QueryType/RealtimeGet/Result.php create mode 100644 vendor/solarium/solarium/src/QueryType/Select/Query/FilterQuery.php create mode 100644 vendor/solarium/solarium/src/QueryType/Select/Query/Query.php create mode 100644 vendor/solarium/solarium/src/QueryType/Select/RequestBuilder.php create mode 100644 vendor/solarium/solarium/src/QueryType/Select/ResponseParser.php create mode 100644 vendor/solarium/solarium/src/QueryType/Select/Result/AbstractDocument.php create mode 100644 vendor/solarium/solarium/src/QueryType/Select/Result/Document.php create mode 100644 vendor/solarium/solarium/src/QueryType/Select/Result/DocumentInterface.php create mode 100644 vendor/solarium/solarium/src/QueryType/Select/Result/Result.php create mode 100644 vendor/solarium/solarium/src/QueryType/Server/AbstractServerQuery.php create mode 100644 vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/AbstractAction.php create mode 100644 vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/AbstractAsyncAction.php create mode 100644 vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/AbstractCoreAction.php create mode 100644 vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Create.php create mode 100644 vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/MergeIndexes.php create mode 100644 vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Reload.php create mode 100644 vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Rename.php create mode 100644 vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/RequestRecovery.php create mode 100644 vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/RequestStatus.php create mode 100644 vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Split.php create mode 100644 vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Status.php create mode 100644 vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Swap.php create mode 100644 vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Unload.php create mode 100644 vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Query.php create mode 100644 vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/RequestBuilder.php create mode 100644 vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/ResponseParser.php create mode 100644 vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Result/Result.php create mode 100644 vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Result/StatusResult.php create mode 100644 vendor/solarium/solarium/src/QueryType/Spellcheck/Query.php create mode 100644 vendor/solarium/solarium/src/QueryType/Spellcheck/RequestBuilder.php create mode 100644 vendor/solarium/solarium/src/QueryType/Spellcheck/ResponseParser.php create mode 100644 vendor/solarium/solarium/src/QueryType/Spellcheck/Result/Result.php create mode 100644 vendor/solarium/solarium/src/QueryType/Spellcheck/Result/Term.php create mode 100644 vendor/solarium/solarium/src/QueryType/Stream/Expression.php create mode 100644 vendor/solarium/solarium/src/QueryType/Stream/Query.php create mode 100644 vendor/solarium/solarium/src/QueryType/Stream/RequestBuilder.php create mode 100644 vendor/solarium/solarium/src/QueryType/Stream/ResponseParser.php create mode 100644 vendor/solarium/solarium/src/QueryType/Stream/Result.php create mode 100644 vendor/solarium/solarium/src/QueryType/Suggester/Query.php create mode 100644 vendor/solarium/solarium/src/QueryType/Suggester/RequestBuilder.php create mode 100644 vendor/solarium/solarium/src/QueryType/Suggester/ResponseParser.php create mode 100644 vendor/solarium/solarium/src/QueryType/Suggester/Result/Dictionary.php create mode 100644 vendor/solarium/solarium/src/QueryType/Suggester/Result/Result.php create mode 100644 vendor/solarium/solarium/src/QueryType/Suggester/Result/Term.php create mode 100644 vendor/solarium/solarium/src/QueryType/Terms/Query.php create mode 100644 vendor/solarium/solarium/src/QueryType/Terms/RequestBuilder.php create mode 100644 vendor/solarium/solarium/src/QueryType/Terms/ResponseParser.php create mode 100644 vendor/solarium/solarium/src/QueryType/Terms/Result.php create mode 100644 vendor/solarium/solarium/src/QueryType/Update/Query/Command/AbstractCommand.php create mode 100644 vendor/solarium/solarium/src/QueryType/Update/Query/Command/Add.php create mode 100644 vendor/solarium/solarium/src/QueryType/Update/Query/Command/Commit.php create mode 100644 vendor/solarium/solarium/src/QueryType/Update/Query/Command/Delete.php create mode 100644 vendor/solarium/solarium/src/QueryType/Update/Query/Command/Optimize.php create mode 100644 vendor/solarium/solarium/src/QueryType/Update/Query/Command/Rollback.php create mode 100644 vendor/solarium/solarium/src/QueryType/Update/Query/Document/Document.php create mode 100644 vendor/solarium/solarium/src/QueryType/Update/Query/Document/DocumentInterface.php create mode 100644 vendor/solarium/solarium/src/QueryType/Update/Query/Query.php create mode 100644 vendor/solarium/solarium/src/QueryType/Update/RequestBuilder.php create mode 100644 vendor/solarium/solarium/src/QueryType/Update/ResponseParser.php create mode 100644 vendor/solarium/solarium/src/QueryType/Update/Result.php create mode 100644 vendor/solarium/solarium/src/Support/DataFixtures/Executor.php create mode 100644 vendor/solarium/solarium/src/Support/DataFixtures/FixtureInterface.php create mode 100644 vendor/solarium/solarium/src/Support/DataFixtures/FixtureLoader.php create mode 100644 vendor/solarium/solarium/src/Support/DataFixtures/Loader.php create mode 100644 vendor/solarium/solarium/src/Support/DataFixtures/Purger.php create mode 100644 vendor/symfony/contracts/.gitignore create mode 100644 vendor/symfony/contracts/CHANGELOG.md create mode 100644 vendor/symfony/contracts/Cache/CacheInterface.php create mode 100644 vendor/symfony/contracts/Cache/CacheTrait.php create mode 100644 vendor/symfony/contracts/Cache/CallbackInterface.php create mode 100644 vendor/symfony/contracts/Cache/ItemInterface.php create mode 100644 vendor/symfony/contracts/Cache/TagAwareCacheInterface.php create mode 100644 vendor/symfony/contracts/LICENSE create mode 100644 vendor/symfony/contracts/README.md create mode 100644 vendor/symfony/contracts/Service/ResetInterface.php create mode 100644 vendor/symfony/contracts/Service/ServiceLocatorTrait.php create mode 100644 vendor/symfony/contracts/Service/ServiceSubscriberInterface.php create mode 100644 vendor/symfony/contracts/Service/ServiceSubscriberTrait.php create mode 100644 vendor/symfony/contracts/Tests/Cache/CacheTraitTest.php create mode 100644 vendor/symfony/contracts/Tests/Service/ServiceLocatorTest.php create mode 100644 vendor/symfony/contracts/Tests/Service/ServiceSubscriberTraitTest.php create mode 100644 vendor/symfony/contracts/Tests/Translation/TranslatorTest.php create mode 100644 vendor/symfony/contracts/Translation/LocaleAwareInterface.php create mode 100644 vendor/symfony/contracts/Translation/TranslatorInterface.php create mode 100644 vendor/symfony/contracts/Translation/TranslatorTrait.php create mode 100644 vendor/symfony/contracts/composer.json create mode 100644 vendor/symfony/contracts/phpunit.xml.dist create mode 100644 vendor/symfony/event-dispatcher/.gitignore create mode 100644 vendor/symfony/event-dispatcher/CHANGELOG.md create mode 100644 vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php create mode 100644 vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php create mode 100644 vendor/symfony/event-dispatcher/Debug/WrappedListener.php create mode 100644 vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php create mode 100644 vendor/symfony/event-dispatcher/Event.php create mode 100644 vendor/symfony/event-dispatcher/EventDispatcher.php create mode 100644 vendor/symfony/event-dispatcher/EventDispatcherInterface.php create mode 100644 vendor/symfony/event-dispatcher/EventSubscriberInterface.php create mode 100644 vendor/symfony/event-dispatcher/GenericEvent.php create mode 100644 vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php create mode 100644 vendor/symfony/event-dispatcher/LICENSE create mode 100644 vendor/symfony/event-dispatcher/README.md create mode 100644 vendor/symfony/event-dispatcher/Tests/AbstractEventDispatcherTest.php create mode 100644 vendor/symfony/event-dispatcher/Tests/Debug/TraceableEventDispatcherTest.php create mode 100644 vendor/symfony/event-dispatcher/Tests/Debug/WrappedListenerTest.php create mode 100644 vendor/symfony/event-dispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php create mode 100644 vendor/symfony/event-dispatcher/Tests/EventDispatcherTest.php create mode 100644 vendor/symfony/event-dispatcher/Tests/EventTest.php create mode 100644 vendor/symfony/event-dispatcher/Tests/GenericEventTest.php create mode 100644 vendor/symfony/event-dispatcher/Tests/ImmutableEventDispatcherTest.php create mode 100644 vendor/symfony/event-dispatcher/composer.json create mode 100644 vendor/symfony/event-dispatcher/phpunit.xml.dist diff --git a/vendor/justinrainbow/json-schema/bin/data.json b/vendor/justinrainbow/json-schema/bin/data.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/vendor/justinrainbow/json-schema/bin/data.json @@ -0,0 +1 @@ +{} diff --git a/vendor/league/event/LICENSE b/vendor/league/event/LICENSE new file mode 100644 index 000000000..eba956497 --- /dev/null +++ b/vendor/league/event/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2014 Frank de Jonge + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/league/event/composer.json b/vendor/league/event/composer.json new file mode 100644 index 000000000..5d144ad09 --- /dev/null +++ b/vendor/league/event/composer.json @@ -0,0 +1,37 @@ +{ + "name": "league/event", + "description": "Event package", + "keywords": ["event", "emitter", "listener"], + "license": "MIT", + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "henrikbjorn/phpspec-code-coverage": "~1.0.1", + "phpspec/phpspec": "^2.2" + }, + "autoload": { + "psr-4": { + "League\\Event\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "League\\Event\\Stub\\": "stubs/" + } + }, + "config": { + "bin-dir": "bin" + }, + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + } + } +} diff --git a/vendor/league/event/src/AbstractEvent.php b/vendor/league/event/src/AbstractEvent.php new file mode 100644 index 000000000..dab2f584c --- /dev/null +++ b/vendor/league/event/src/AbstractEvent.php @@ -0,0 +1,64 @@ +emitter = $emitter; + + return $this; + } + + /** + * @inheritdoc + */ + public function getEmitter() + { + return $this->emitter; + } + + /** + * @inheritdoc + */ + public function stopPropagation() + { + $this->propagationStopped = true; + + return $this; + } + + /** + * @inheritdoc + */ + public function isPropagationStopped() + { + return $this->propagationStopped; + } + + /** + * @inheritdoc + */ + public function getName() + { + return get_class($this); + } +} diff --git a/vendor/league/event/src/AbstractListener.php b/vendor/league/event/src/AbstractListener.php new file mode 100644 index 000000000..95077a083 --- /dev/null +++ b/vendor/league/event/src/AbstractListener.php @@ -0,0 +1,14 @@ +bufferedEvents[] = $event; + + return $event; + } + + /** + * @inheritdoc + */ + public function emitBatch(array $events) + { + foreach ($events as $event) { + $this->bufferedEvents[] = $event; + } + + return $events; + } + + /** + * Emit the buffered events. + * + * @return array + */ + public function emitBufferedEvents() + { + $result = []; + + while ($event = array_shift($this->bufferedEvents)) { + $result[] = parent::emit($event); + } + + return $result; + } +} diff --git a/vendor/league/event/src/CallbackListener.php b/vendor/league/event/src/CallbackListener.php new file mode 100644 index 000000000..31eb58905 --- /dev/null +++ b/vendor/league/event/src/CallbackListener.php @@ -0,0 +1,65 @@ +callback = $callback; + } + + /** + * Get the callback. + * + * @return callable + */ + public function getCallback() + { + return $this->callback; + } + + /** + * @inheritdoc + */ + public function handle(EventInterface $event) + { + call_user_func_array($this->callback, func_get_args()); + } + + /** + * @inheritdoc + */ + public function isListener($listener) + { + if ($listener instanceof CallbackListener) { + $listener = $listener->getCallback(); + } + + return $this->callback === $listener; + } + + /** + * Named constructor + * + * @param callable $callable + * + * @return static + */ + public static function fromCallable(callable $callable) + { + return new static($callable); + } +} diff --git a/vendor/league/event/src/Emitter.php b/vendor/league/event/src/Emitter.php new file mode 100644 index 000000000..1cfe7b4be --- /dev/null +++ b/vendor/league/event/src/Emitter.php @@ -0,0 +1,268 @@ +ensureListener($listener); + $this->listeners[$event][$priority][] = $listener; + $this->clearSortedListeners($event); + + return $this; + } + + /** + * @inheritdoc + */ + public function addOneTimeListener($event, $listener, $priority = self::P_NORMAL) + { + $listener = $this->ensureListener($listener); + $listener = new OneTimeListener($listener); + + return $this->addListener($event, $listener, $priority); + } + + /** + * @inheritdoc + */ + public function useListenerProvider(ListenerProviderInterface $provider) + { + $acceptor = new ListenerAcceptor($this); + $provider->provideListeners($acceptor); + + return $this; + } + + /** + * @inheritdoc + */ + public function removeListener($event, $listener) + { + $this->clearSortedListeners($event); + $listeners = $this->hasListeners($event) + ? $this->listeners[$event] + : []; + + $filter = function ($registered) use ($listener) { + return ! $registered->isListener($listener); + }; + + foreach ($listeners as $priority => $collection) { + $listeners[$priority] = array_filter($collection, $filter); + } + + $this->listeners[$event] = $listeners; + + + return $this; + } + + /** + * @inheritdoc + */ + public function removeAllListeners($event) + { + $this->clearSortedListeners($event); + + if ($this->hasListeners($event)) { + unset($this->listeners[$event]); + } + + return $this; + } + + /** + * Ensure the input is a listener. + * + * @param ListenerInterface|callable $listener + * + * @throws InvalidArgumentException + * + * @return ListenerInterface + */ + protected function ensureListener($listener) + { + if ($listener instanceof ListenerInterface) { + return $listener; + } + + if (is_callable($listener)) { + return CallbackListener::fromCallable($listener); + } + + throw new InvalidArgumentException('Listeners should be ListenerInterface, Closure or callable. Received type: '.gettype($listener)); + } + + /** + * @inheritdoc + */ + public function hasListeners($event) + { + if (! isset($this->listeners[$event]) || count($this->listeners[$event]) === 0) { + return false; + } + + return true; + } + + /** + * @inheritdoc + */ + public function getListeners($event) + { + if (array_key_exists($event, $this->sortedListeners)) { + return $this->sortedListeners[$event]; + } + + return $this->sortedListeners[$event] = $this->getSortedListeners($event); + } + + /** + * Get the listeners sorted by priority for a given event. + * + * @param string $event + * + * @return ListenerInterface[] + */ + protected function getSortedListeners($event) + { + if (! $this->hasListeners($event)) { + return []; + } + + $listeners = $this->listeners[$event]; + krsort($listeners); + + return call_user_func_array('array_merge', $listeners); + } + + /** + * @inheritdoc + */ + public function emit($event) + { + list($name, $event) = $this->prepareEvent($event); + $arguments = [$event] + func_get_args(); + $this->invokeListeners($name, $event, $arguments); + $this->invokeListeners('*', $event, $arguments); + + return $event; + } + + /** + * @inheritdoc + */ + public function emitBatch(array $events) + { + $results = []; + + foreach ($events as $event) { + $results[] = $this->emit($event); + } + + return $results; + } + + /** + * @inheritdoc + */ + public function emitGeneratedEvents(GeneratorInterface $generator) + { + $events = $generator->releaseEvents(); + + return $this->emitBatch($events); + } + + /** + * Invoke the listeners for an event. + * + * @param string $name + * @param EventInterface $event + * @param array $arguments + * + * @return void + */ + protected function invokeListeners($name, EventInterface $event, array $arguments) + { + $listeners = $this->getListeners($name); + + foreach ($listeners as $listener) { + if ($event->isPropagationStopped()) { + break; + } + + call_user_func_array([$listener, 'handle'], $arguments); + } + } + + /** + * Prepare an event for emitting. + * + * @param string|EventInterface $event + * + * @return array + */ + protected function prepareEvent($event) + { + $event = $this->ensureEvent($event); + $name = $event->getName(); + $event->setEmitter($this); + + return [$name, $event]; + } + + /** + * Ensure event input is of type EventInterface or convert it. + * + * @param string|EventInterface $event + * + * @throws InvalidArgumentException + * + * @return EventInterface + */ + protected function ensureEvent($event) + { + if (is_string($event)) { + return Event::named($event); + } + + if (! $event instanceof EventInterface) { + throw new InvalidArgumentException('Events should be provides as Event instances or string, received type: '.gettype($event)); + } + + return $event; + } + + /** + * Clear the sorted listeners for an event + * + * @param $event + */ + protected function clearSortedListeners($event) + { + unset($this->sortedListeners[$event]); + } +} diff --git a/vendor/league/event/src/EmitterAwareInterface.php b/vendor/league/event/src/EmitterAwareInterface.php new file mode 100644 index 000000000..58e14021e --- /dev/null +++ b/vendor/league/event/src/EmitterAwareInterface.php @@ -0,0 +1,22 @@ +emitter = $emitter; + + return $this; + } + + /** + * Get the Emitter. + * + * @return EmitterInterface + */ + public function getEmitter() + { + if (! $this->emitter) { + $this->emitter = new Emitter(); + } + + return $this->emitter; + } +} diff --git a/vendor/league/event/src/EmitterInterface.php b/vendor/league/event/src/EmitterInterface.php new file mode 100644 index 000000000..4f0fded2a --- /dev/null +++ b/vendor/league/event/src/EmitterInterface.php @@ -0,0 +1,92 @@ +getEmitter()->addListener($event, $listener, $priority); + + return $this; + } + + /** + * Add a one time listener for an event. + * + * The first parameter should be the event name, and the second should be + * the event listener. It may implement the League\Event\ListenerInterface + * or simply be "callable". + * + * @param string $event + * @param ListenerInterface|callable $listener + * @param int $priority + * + * @return $this + */ + public function addOneTimeListener($event, $listener, $priority = ListenerAcceptorInterface::P_NORMAL) + { + $this->getEmitter()->addOneTimeListener($event, $listener, $priority); + + return $this; + } + + /** + * Remove a specific listener for an event. + * + * The first parameter should be the event name, and the second should be + * the event listener. It may implement the League\Event\ListenerInterface + * or simply be "callable". + * + * @param string $event + * @param ListenerInterface|callable $listener + * + * @return $this + */ + public function removeListener($event, $listener) + { + $this->getEmitter()->removeListener($event, $listener); + + return $this; + } + + /** + * Remove all listeners for an event. + * + * The first parameter should be the event name. All event listeners will + * be removed. + * + * @param string $event + * + * @return $this + */ + public function removeAllListeners($event) + { + $this->getEmitter()->removeAllListeners($event); + + return $this; + } + + /** + * Add listeners from a provider. + * + * @param ListenerProviderInterface $provider + * + * @return $this + */ + public function useListenerProvider(ListenerProviderInterface $provider) + { + $this->getEmitter()->useListenerProvider($provider); + + return $this; + } + + /** + * Emit an event. + * + * @param string|EventInterface $event + * + * @return EventInterface + */ + public function emit($event) + { + $emitter = $this->getEmitter(); + $arguments = [$event] + func_get_args(); + + return call_user_func_array([$emitter, 'emit'], $arguments); + } +} diff --git a/vendor/league/event/src/Event.php b/vendor/league/event/src/Event.php new file mode 100644 index 000000000..826b00ae9 --- /dev/null +++ b/vendor/league/event/src/Event.php @@ -0,0 +1,43 @@ +name = $name; + } + + /** + * @inheritdoc + */ + public function getName() + { + return $this->name; + } + + /** + * Create a new event instance. + * + * @param string $name + * + * @return static + */ + public static function named($name) + { + return new static($name); + } +} diff --git a/vendor/league/event/src/EventInterface.php b/vendor/league/event/src/EventInterface.php new file mode 100644 index 000000000..84f29725c --- /dev/null +++ b/vendor/league/event/src/EventInterface.php @@ -0,0 +1,43 @@ +events[] = $event; + + return $this; + } + + /** + * Release all the added events. + * + * @return EventInterface[] + */ + public function releaseEvents() + { + $events = $this->events; + $this->events = []; + + return $events; + } +} diff --git a/vendor/league/event/src/ListenerAcceptor.php b/vendor/league/event/src/ListenerAcceptor.php new file mode 100644 index 000000000..259b86d5c --- /dev/null +++ b/vendor/league/event/src/ListenerAcceptor.php @@ -0,0 +1,43 @@ +emitter = $emitter; + } + + /** + * @inheritdoc + */ + public function addListener($event, $listener, $priority = self::P_NORMAL) + { + $this->emitter->addListener($event, $listener, $priority); + + return $this; + } + + /** + * @inheritdoc + */ + public function addOneTimeListener($event, $listener, $priority = self::P_NORMAL) + { + $this->emitter->addOneTimeListener($event, $listener, $priority); + + return $this; + } +} diff --git a/vendor/league/event/src/ListenerAcceptorInterface.php b/vendor/league/event/src/ListenerAcceptorInterface.php new file mode 100644 index 000000000..758c273f1 --- /dev/null +++ b/vendor/league/event/src/ListenerAcceptorInterface.php @@ -0,0 +1,59 @@ +listener = $listener; + } + + /** + * Get the wrapped listener. + * + * @return ListenerInterface + */ + public function getWrappedListener() + { + return $this->listener; + } + + /** + * @inheritdoc + */ + public function handle(EventInterface $event) + { + $name = $event->getName(); + $emitter = $event->getEmitter(); + $emitter->removeListener($name, $this->listener); + + return call_user_func_array([$this->listener, 'handle'], func_get_args()); + } + + /** + * @inheritdoc + */ + public function isListener($listener) + { + if ($listener instanceof OneTimeListener) { + $listener = $listener->getWrappedListener(); + } + + return $this->listener->isListener($listener); + } +} diff --git a/vendor/solarium/solarium/.coveralls.yml b/vendor/solarium/solarium/.coveralls.yml new file mode 100644 index 000000000..91600595a --- /dev/null +++ b/vendor/solarium/solarium/.coveralls.yml @@ -0,0 +1 @@ +service_name: travis-ci diff --git a/vendor/solarium/solarium/.travis.yml b/vendor/solarium/solarium/.travis.yml new file mode 100644 index 000000000..716a3ff56 --- /dev/null +++ b/vendor/solarium/solarium/.travis.yml @@ -0,0 +1,50 @@ +language: php + +dist: trusty + +php: + - 7.2 + - 7.1 + - 7.0 + - nightly + +env: + - SYMFONY_VERSION=2.7.* SOLR_VERSION=6.6.5 + - SYMFONY_VERSION=3.3.* SOLR_VERSION=6.6.5 + - SYMFONY_VERSION=4.0.* SOLR_VERSION=6.6.5 + - SYMFONY_VERSION=4.0.* SOLR_VERSION=7.5.0 + +cache: + directories: + - $HOME/.composer/cache + - solr_downloads + +before_install: + - composer global require "hirak/prestissimo:^0.3" + - ls solr_downloads/ + - wget -nc --continue -v --tries=3 --directory-prefix=solr_downloads "http://ftp.halifax.rwth-aachen.de/apache/lucene/solr/${SOLR_VERSION}/solr-${SOLR_VERSION}.tgz" + - tar -xzf solr_downloads/solr-${SOLR_VERSION}.tgz + +before_script: +# - pecl install pecl_http + - composer require --prefer-source --dev symfony/event-dispatcher:${SYMFONY_VERSION} + - solr-${SOLR_VERSION}/bin/solr start -e techproducts + # make configSet's available for techproducts instance + - cp -R solr-${SOLR_VERSION}/server/solr/configsets solr-${SOLR_VERSION}/example/techproducts/solr/ + +script: + - vendor/bin/phpunit -c phpunit.xml.travis -v + +after_success: + - travis_retry php vendor/bin/coveralls -v + +matrix: + exclude: + - php: 7.0 + env: SYMFONY_VERSION=4.0.* SOLR_VERSION=6.6.5 + - php: 7.0 + env: SYMFONY_VERSION=4.0.* SOLR_VERSION=7.5.0 + allow_failures: + - php: nightly + +sudo: false diff --git a/vendor/solarium/solarium/CHANGELOG.md b/vendor/solarium/solarium/CHANGELOG.md new file mode 100644 index 000000000..49c6cedba --- /dev/null +++ b/vendor/solarium/solarium/CHANGELOG.md @@ -0,0 +1,292 @@ +# CHANGELOG +All notable changes to the solarium library will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## [4.2.0] +### Fixed +- If a term contains a space, the space needs to be quoted by Helper::escapeTerm() +- Typos + + +## [4.2.0-rc.1] +### Added +- Support for managed resources +- Support for add-distinct and removeregex modifiers + +## [4.2.0-beta.1] +### Added +- Basic support for PUT requests in the HttpAdapter layer +- Support for managed resources +- Core Admin Queries +- Endpoint::getServerUri +- Endpoint::getCoreBaseUri +- Expression::indent +- BufferedAdd::setCommitWithin +- BufferedAdd::setOverwrite +- Set erroneous expression on StreamException +- Managed resources, stopwords and synonyms query types + +### Deprecated +- Endpoint::getBaseUri is deprecated. Please use getServerUri or getCoreBaseUri now. + +### Fixed +- Allow multiple Field Facets for the same field by dynamically using local facet params if required + + +## [4.1.0] +### Added +- Method AbstractQuery::removeParam() to remove a custom parameter or to reset a required but modified parameter +- Basic support for DELETE requests in the HttpAdapter layer +- Introduced an AdapterHelper class to start unifying implementations across all HTTP adapters + +### Changed +- To unify the file extraction across all HTTP Adapters, the filename is now always reduced to its basepath + + +### Fixed +- Guzzle Integration tests +- Don't modify the time zone of DateTime objects passed by reference +- Extract request rejected because of missing multipart boundary + + +## [4.1.0-rc.1] +### Added +- Every component that has a 'query' option is now able to bind parameters to a query string via its setQuery() function +- Tests for cursormark +- Support for ReRankQuery + +### Changed +- Renamed option 'q' to 'query' in Solarium\Component\Facet\JsonQuery for consistency + +### Fixed +- Random test failures caused by different timestamps + + +## [4.1.0-beta.1] +### Added +- Query Elevation Component +- Option 'min' for JsonAggregation +- Support for NOW and TZ parameters + +### Changed +- Test coverage and docs for cursor functionality +- Test coverage for JSON facets +- Branch aliases for composer + +### Fixed +- Filter empty buckets from JSON facets during result parsing +- Cover 'contains' and 'containsignorecase' in FacetSet docs + + +## [4.1.0-alpha.1] +### Added +- Support for JSON Facet API + +### Changed +- Constants FacetSet::FACET_* became FacetSetInterface::FACET_* + + +## [4.0.0] +### Added +- Support "sow" parameter (Split On Whitespace) in select queries + + +## [4.0.0-rc.1] +### Added +- Basic support for Solr Cloud streaming expressions + + +## [4.0.0-beta.1] +### Fixed +- Return type of Solarium\Component\QueryTraits\SuggesterTrait::getSuggester() +- Type hints in Solarium\Component\AbstractComponent + + +## [4.0.0-alpha.2] +### Added +- getSuggester() convenience method on Solarium\QueryType\Select\Query\Query +- More integration tests + +### Removed +- Outdated symfony versions on test environment + +### Fixed +- Don't escape the '*' in range queries +- Return type of getHighlighting() on Solarium\QueryType\Select\Result\Result +- Return type of getFacetSet() on Solarium\QueryType\Select\Result\Result + + +## [4.0.0-alpha.1] +### Added +- Terms component +- Spellcheck component +- Spellcheck query type +- Added missing parameters to the Spellcheck query type and the component (compared to the 3.x Suggester) +- Support for deep paging with a cursor +- Symfony 4 support +- Nightly builds / tests +- Basic Integration tests running real Solr queries against Solr's techproducts example + +### Changed +- Renamed folder library to src +- Use PSR-4 class loading +- Updated PHPUnit to v6.5 +- Updated required PHP version to >= v7.0 +- Isolated search components from the select query type and made them re-usable +- BC break: Suggester component is now compatible to Solr v6/7 (the existing one was renamed to Spellcheck) +- BC break: Suggester query type is now compatible to Solr v6/7 (the existing one was renamed to Spellcheck) +- Lots of source code re-structuring and clean-up + +### Removed +- Phar support +- Exclude test suite from distribution +- Dropped support for Solr versions before 6 +- Obsolete Autoloader.php +- Deprecated Solarium\Core\Plugin\Plugin in favor of Solarium\Core\Plugin\AbstractPlugin +- Deprecated Solarium\Core\Query\Query in favor of Solarium\Core\Query\AbstractQuery +- Deprecated Solarium\Core\Query\RequestBuilder in favor of Solarium\Core\Query\AbstractRequestBuilder +- Deprecated Solarium\Core\Query\ResponseParser in favor of Solarium\Core\Query\AbstractResponseParser +- Deprecated Solarium\QueryType\Analysis\Query\Query in favor of Solarium\QueryType\Analysis\Query\AbstractQuery + +### Security +- Prevented query injection inside range queries + + +## [3.8.1] +### Fixed +- Restore PHP 5.3 compatibility (remove short array syntax) + + +## [3.8.0] +### Added +- Support for simple group format in response parser +- Helper for fetching ValueGroup from a Grouped result +- Guzzle 3 and Guzzle 6 client adapters + +### Changed +- Various fixes in documentation + +### Fixed +- Use GET request for extracting remote files +- Prevent ParallelExecution Curl spinloop + + +## [3.7.0] +### Added +- Support for nested documents in update query +- Spatial component for select query +- Support for keys and excludes in interval facet +- Support for grouping using a function (group.func) +- Included suggestion in composer file for a query builder library + +### Changed +- Lots of fixes in documentation markup + +### Fixed +- Spellcheck collation parsing for Solr 5+ + + +## [3.6.0] +### Added +- Support for replicas in distributed search +- Support for multiple boost queries in dismax +- Support for additional stats values like percentiles +- Added Symfony 3.x components to CI tests for PHP 5.5+ + +### Changed +- No longer allow failures for HHVM in continuous integration +- ClientInterface now also used for standard Client class + +### Fixed +- Several typo / markup fixes in documentation +- Several docblock fixes + + +## [3.5.1] +### Fixed +- backwards incompatible change in classnames + + +## [3.5.0] +### Added +- Make it possible to bypass (system-wide) proxy setting in Curl adapter +- ClientInterface +- Support for facet.contains settings +- Docs in repository (markdown format) +- SensioLabs Insight (including lots of fixed in the code based on report) + +### Changed +- Lots of code style fixes +- Refactored 'base' plugin class to AbstractPlugin +- Removed old PHP environments for Travis, added PHP7 +- Set license to a valid SPDX license identifier +- Set hard paths in .gitignore to prevent tree lookups +- Updated Symfony event dispatcher dependency to a maintained version + +### Fixed +- PHAR generator updated to support namespacing +- Collations broken for Solr 5 data format + + +## [3.4.0] +### Added +- Facet interval support +- ZF2 http adapter +- Stats for pivot facet +- Support for calling empty() and isset() on result document properties +- Composer test script +- 'contributing' file + +### Changed +- Lots of code style fixes, using the SF2 code style + +### Fixed +- Docblock fixes in grouping component facets +- Only check type for added documents to add query if provided as an array +- Curl file upload handling +- Spellcheck 'collations' and 'correctlyspelled' updated to support Solr 5 format +- Curl adapter now uses Solr 5 compatible headers for a GET request + + +## [3.3.0] +### Added +- Support for data fixtures +- MinimumScoreFilter plugin, also for grouping +- Support for nested debug-info in the debug query + +### Changed +- Filter control characters in update documents by default +- Facet range now supports the mincount parameter +- Spellcheck response parser can now handle multiple suggestions +- Prefetch iterator now resets if prefetch or query settings are changed +- Added matchoffset setting to MLT querytype +- PreFetchIterator plugin now supports setting an endpoint +- BufferedAdd plugin now supports an endpoint supplied as a config +- Updated curl adapter file handling to prevent warnings in php >=5.5.0 +- Added remote file streaming support to extract request handler +- Query result now also supports maxscore +- MoreLikeThis now allows for individual boosts on query fields +- Select query component MoreLikeThis now supports boosting multiple fields +- Added PHP 5.5, 5.6 and HHVM to Travis config +- Solarium now uses Coveralls for test coverage reports +- If a config object does not supply a toArray method, the object is converted by Solarium +- Highlighting now supports hl.preserveMulti param +- Stats component now supports exludes +- Range query helper now supports wildcards +- Support HTTPS scheme for endpoints +- CURL and PECL_HTTP adapters now set connection timeout and dns cache timeout +- Extract query now supports ExtractOnly +- The event dispatcher can now be injected +- PSR-0 and PSR-2 code fixes + +### Fixed +- Fixes in build.xml (use phpunit in vendor directory) +- Pivot facet does not accept extra parameters +- Pivot facet uses the wrong key in result parsing +- Wrong handling of boolean values in update documents +- Highlight query should only set hl.fl param if there are any fields set +- Curl crash when open_basedir is set +- Fix suggester parser with duplicates +- Removed constructor from interface Solarium/Core/ConfigurableInterface.php diff --git a/vendor/solarium/solarium/CONTRIBUTING.md b/vendor/solarium/solarium/CONTRIBUTING.md new file mode 100644 index 000000000..61603b727 --- /dev/null +++ b/vendor/solarium/solarium/CONTRIBUTING.md @@ -0,0 +1,25 @@ +# Contributing to Solarium + +So you consider contributing to Solarium? That’s great! +Here are some pointers to hopefully get a good result. + +If you are uncertain about any part or need help please feel free to ask for help. + +## Bug reports + +* Bugs are intended for problems in the code or missing / faulty documentation. Not for issues with your own environment, questions in how to use feature X etcetera. +* Include info about your environment: the version of Solarium you are using, PHP version, Solr version +* If you get a specific error, include as much info as possible. The PHP exception, a Solr error log line, etcetera. +* When something doesn't work as expected for you, also describe the behaviour you expect. +* Do a quick search to check if the issue has already been reported +* Describe your issue well, especially the title. Instead of ‘Select query exception’ use ‘Using a dash in a filterquery tag causes an exception’. +* Provide steps to reproduce the issue. A unittest is ideal, but a description of manual steps is also very helpful. + +## Pull requests + +* Your pull requests should target the master branch. +* A pull request should be mergeable (fast-forward) if not, you will be asked to update it. +* Ideally any change should include updated or new unittests to cover the changes. You can submit a PR without tests, but it will take longer to merge as someone else will need to fix the test coverage. +* Solarium follows the Symfony2 code standards: http://symfony.com/doc/current/contributing/code/standards.html +* Each PR will be checked for code standards violations. Of course anything other than a 'green' status needs to be fixed before a PR can be merged. +* Each PR will be checked by the CI environment automatically. Of course anything other than a 'green' status needs to be fixed before a PR can be merged. diff --git a/vendor/solarium/solarium/COPYING b/vendor/solarium/solarium/COPYING new file mode 100644 index 000000000..7364e8398 --- /dev/null +++ b/vendor/solarium/solarium/COPYING @@ -0,0 +1,25 @@ +Copyright 2011 Bas de Nooijer. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of the copyright holder. \ No newline at end of file diff --git a/vendor/solarium/solarium/README.md b/vendor/solarium/solarium/README.md new file mode 100644 index 000000000..ee5ac3572 --- /dev/null +++ b/vendor/solarium/solarium/README.md @@ -0,0 +1,50 @@ +# Solarium PHP Solr client library + + +## What is Solarium? + +Solarium is a PHP Solr client library that accurately model Solr concepts. Where many other Solr libraries only handle +the communication with Solr, Solarium also relieves you of handling all the complex Solr query parameters using a +well documented API. + +Please see the docs for a more detailed description. + +## Requirements + +Solarium only supports PHP 7.0 and up. + +It's highly recommended to have Curl enabled in your PHP environment. However if you don't have Curl available you can +switch from using Curl (the default) to another client adapter. The other adapters don't support all the features of the +Curl adapter. + +## Getting started + +The preferred way to install Solarium is by using Composer. Solarium is available on Packagist. + +Example: +``` + composer require solarium/solarium +``` + +## More information + +* Docs + http://solarium.readthedocs.io/en/stable/ + +* Issue tracker + http://github.com/solariumphp/solarium/issues + +* Contributors + https://github.com/solariumphp/solarium/contributors + +* License + See the COPYING file or view online: + https://github.com/solariumphp/solarium/blob/master/COPYING + +## Continuous Integration status + +* 4.x branch (master) [![Develop build status](https://secure.travis-ci.org/solariumphp/solarium.png?branch=master)](http://travis-ci.org/solariumphp/solarium?branch=master) [![Coverage Status](https://coveralls.io/repos/solariumphp/solarium/badge.png?branch=master)](https://coveralls.io/r/solariumphp/solarium?branch=master) +* 3.x branch [![Develop build status](https://secure.travis-ci.org/solariumphp/solarium.png?branch=3.x)](http://travis-ci.org/solariumphp/solarium?branch=3.x) [![Coverage Status](https://coveralls.io/repos/solariumphp/solarium/badge.png?branch=3.x)](https://coveralls.io/r/solariumphp/solarium?branch=3.x) +* [![SensioLabsInsight](https://insight.sensiolabs.com/projects/292e29f7-10a9-4685-b9ac-37925ebef9ae/small.png)](https://insight.sensiolabs.com/projects/292e29f7-10a9-4685-b9ac-37925ebef9ae) +* [![Total Downloads](https://poser.pugx.org/solarium/solarium/downloads.svg)](https://packagist.org/packages/solarium/solarium) + diff --git a/vendor/solarium/solarium/composer.json b/vendor/solarium/solarium/composer.json new file mode 100644 index 000000000..009226e91 --- /dev/null +++ b/vendor/solarium/solarium/composer.json @@ -0,0 +1,46 @@ +{ + "name": "solarium/solarium", + "type": "library", + "description": "PHP Solr client", + "keywords": ["solr", "search", "php"], + "homepage": "http://www.solarium-project.org", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "See GitHub contributors", + "homepage": "https://github.com/basdenooijer/solarium/contributors" + } + ], + "require": { + "php": "^7.0", + "symfony/event-dispatcher": "^2.7 || ^3.0 || ^4.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^3.8 || ^6.2", + "phpunit/phpunit": "^6.5", + "php-coveralls/php-coveralls": "^1.0", + "squizlabs/php_codesniffer": "^1.4", + "zendframework/zendframework": "^3.0" + }, + "suggest": { + "minimalcode/search": "Query builder compatible with Solarium, allows simplified solr-query handling" + }, + "config": { + "sort-packages": true + }, + "autoload": { + "psr-4": { + "Solarium\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Solarium\\Tests\\": "tests/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "4.1.x-dev" + } + } +} diff --git a/vendor/solarium/solarium/src/Client.php b/vendor/solarium/solarium/src/Client.php new file mode 100644 index 000000000..555b4255d --- /dev/null +++ b/vendor/solarium/solarium/src/Client.php @@ -0,0 +1,99 @@ +='); + } +} diff --git a/vendor/solarium/solarium/src/Component/AbstractComponent.php b/vendor/solarium/solarium/src/Component/AbstractComponent.php new file mode 100644 index 000000000..0f1ceeac0 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/AbstractComponent.php @@ -0,0 +1,78 @@ +queryInstance = $instance; + + return $this; + } + + /** + * Get parent query instance. + * + * @return AbstractQuery + */ + public function getQueryInstance() + { + return $this->queryInstance; + } + + /** + * Returns a query helper. + * + * @return \Solarium\Core\Query\Helper + */ + public function getHelper() + { + if ($queryInstance = $this->getQueryInstance()) { + return $this->getQueryInstance()->getHelper(); + } else { + return new Helper(); + } + } +} diff --git a/vendor/solarium/solarium/src/Component/ComponentAwareQueryInterface.php b/vendor/solarium/solarium/src/Component/ComponentAwareQueryInterface.php new file mode 100644 index 000000000..a3c196e41 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/ComponentAwareQueryInterface.php @@ -0,0 +1,148 @@ +componentTypes; + } + + /** + * Register a component type. + * + * @param string $key + * @param string $component + * + * @return self Provides fluent interface + */ + public function registerComponentType($key, $component) + { + $this->componentTypes[$key] = $component; + + return $this; + } + + /** + * Get all registered components. + * + * @return AbstractComponent[] + */ + public function getComponents() + { + return $this->components; + } + + /** + * Get a component instance by key. + * + * You can optionally supply an autoload class to create a new component + * instance if there is no registered component for the given key yet. + * + * + * @param string $key Use one of the constants + * @param string|bool $autoload Class to autoload if component needs to be created + * @param array|null $config Configuration to use for autoload + * + * @throws OutOfBoundsException + * + * @return object|null + */ + public function getComponent($key, $autoload = false, $config = null) + { + if (isset($this->components[$key])) { + return $this->components[$key]; + } elseif (true === $autoload) { + if (!isset($this->componentTypes[$key])) { + throw new OutOfBoundsException('Cannot autoload unknown component: '.$key); + } + + $className = $this->componentTypes[$key]; + $className = class_exists($className) ? $className : $className.strrchr($className, '\\'); + $component = new $className($config); + $this->setComponent($key, $component); + + return $component; + } + + return null; + } + + /** + * Set a component instance. + * + * This overwrites any existing component registered with the same key. + * + * @param string $key + * @param AbstractComponent $component + * + * @return self Provides fluent interface + */ + public function setComponent($key, $component) + { + $component->setQueryInstance($this); + $this->components[$key] = $component; + + return $this; + } + + /** + * Remove a component instance. + * + * You can remove a component by passing its key or the component instance. + * + * @param string|AbstractComponent $component + * + * @return self Provides fluent interface + */ + public function removeComponent($component) + { + if (is_object($component)) { + foreach ($this->components as $key => $instance) { + if ($instance === $component) { + unset($this->components[$key]); + break; + } + } + } else { + if (isset($this->components[$component])) { + unset($this->components[$component]); + } + } + + return $this; + } + + /** + * Build component instances based on config. + * + * @param array $configs + */ + protected function createComponents($configs) + { + foreach ($configs as $type => $config) { + $this->getComponent($type, true, $config); + } + } +} diff --git a/vendor/solarium/solarium/src/Component/ComponentTraits/SpellcheckTrait.php b/vendor/solarium/solarium/src/Component/ComponentTraits/SpellcheckTrait.php new file mode 100644 index 000000000..baec098ea --- /dev/null +++ b/vendor/solarium/solarium/src/Component/ComponentTraits/SpellcheckTrait.php @@ -0,0 +1,315 @@ +setOption('build', $build); + } + + /** + * Get build option. + * + * @return bool|null + */ + public function getBuild() + { + return $this->getOption('build'); + } + + /** + * Set reload option. + * + * Reload the dictionary? + * + * @param bool $reload + * + * @return self Provides fluent interface + */ + public function setReload($reload) + { + return $this->setOption('reload', $reload); + } + + /** + * Get fragsize option. + * + * @return bool|null + */ + public function getReload() + { + return $this->getOption('reload'); + } + + /** + * Set dictionary option. + * + * The name of the dictionary to use + * + * @param string $dictionary + * + * @return self Provides fluent interface + */ + public function setDictionary($dictionary) + { + return $this->setOption('dictionary', $dictionary); + } + + /** + * Get dictionary option. + * + * @return string|null + */ + public function getDictionary() + { + return $this->getOption('dictionary'); + } + + /** + * Set count option. + * + * The maximum number of suggestions to return + * + * @param int $count + * + * @return self Provides fluent interface + */ + public function setCount($count) + { + return $this->setOption('count', $count); + } + + /** + * Get count option. + * + * @return int|null + */ + public function getCount() + { + return $this->getOption('count'); + } + + /** + * Set onlyMorePopular option. + * + * Only return suggestions that result in more hits for the query than the existing query + * + * @param bool $onlyMorePopular + * + * @return self Provides fluent interface + */ + public function setOnlyMorePopular($onlyMorePopular) + { + return $this->setOption('onlymorepopular', $onlyMorePopular); + } + + /** + * Get onlyMorePopular option. + * + * @return bool|null + */ + public function getOnlyMorePopular() + { + return $this->getOption('onlymorepopular'); + } + + /** + * Set extendedResults option. + * + * @param bool $extendedResults + * + * @return self Provides fluent interface + */ + public function setExtendedResults($extendedResults) + { + return $this->setOption('extendedresults', $extendedResults); + } + + /** + * Get extendedResults option. + * + * @return bool|null + */ + public function getExtendedResults() + { + return $this->getOption('extendedresults'); + } + + /** + * Set collate option. + * + * @param bool $collate + * + * @return self Provides fluent interface + */ + public function setCollate($collate) + { + return $this->setOption('collate', $collate); + } + + /** + * Get collate option. + * + * @return bool|null + */ + public function getCollate() + { + return $this->getOption('collate'); + } + + /** + * Set maxCollations option. + * + * @param int $maxCollations + * + * @return self Provides fluent interface + */ + public function setMaxCollations($maxCollations) + { + return $this->setOption('maxcollations', $maxCollations); + } + + /** + * Get maxCollations option. + * + * @return int|null + */ + public function getMaxCollations() + { + return $this->getOption('maxcollations'); + } + + /** + * Set maxCollationTries option. + * + * @param string $maxCollationTries + * + * @return self Provides fluent interface + */ + public function setMaxCollationTries($maxCollationTries) + { + return $this->setOption('maxcollationtries', $maxCollationTries); + } + + /** + * Get maxCollationTries option. + * + * @return string|null + */ + public function getMaxCollationTries() + { + return $this->getOption('maxcollationtries'); + } + + /** + * Set maxCollationEvaluations option. + * + * @param int $maxCollationEvaluations + * + * @return self Provides fluent interface + */ + public function setMaxCollationEvaluations($maxCollationEvaluations) + { + return $this->setOption('maxcollationevaluations', $maxCollationEvaluations); + } + + /** + * Get maxCollationEvaluations option. + * + * @return int|null + */ + public function getMaxCollationEvaluations() + { + return $this->getOption('maxcollationevaluations'); + } + + /** + * Set collateExtendedResults option. + * + * @param string $collateExtendedResults + * + * @return self Provides fluent interface + */ + public function setCollateExtendedResults($collateExtendedResults) + { + return $this->setOption('collateextendedresults', $collateExtendedResults); + } + + /** + * Get collateExtendedResults option. + * + * @return string|null + */ + public function getCollateExtendedResults() + { + return $this->getOption('collateextendedresults'); + } + + /** + * Set accuracy option. + * + * @param float $accuracy + * + * @return self Provides fluent interface + */ + public function setAccuracy($accuracy) + { + return $this->setOption('accuracy', $accuracy); + } + + /** + * Get accuracy option. + * + * @return float|null + */ + public function getAccuracy() + { + return $this->getOption('accuracy'); + } + + /** + * Set a collation param. + * + * @param string $param + * @param mixed $value + * + * @return self Provides fluent interface + */ + public function setCollateParam($param, $value) + { + $this->collateParams[$param] = $value; + + return $this; + } + + /** + * Returns the array of collate params. + * + * @return array + */ + public function getCollateParams() + { + return $this->collateParams; + } +} diff --git a/vendor/solarium/solarium/src/Component/ComponentTraits/SuggesterTrait.php b/vendor/solarium/solarium/src/Component/ComponentTraits/SuggesterTrait.php new file mode 100644 index 000000000..28847fc3a --- /dev/null +++ b/vendor/solarium/solarium/src/Component/ComponentTraits/SuggesterTrait.php @@ -0,0 +1,126 @@ +setOption('dictionary', $dictionary); + } + + /** + * Get dictionary option. + * + * @return string|null + */ + public function getDictionary() + { + return $this->getOption('dictionary'); + } + + /** + * Set count option. + * + * The maximum number of suggestions to return + * + * @param int $count + * + * @return self Provides fluent interface + */ + public function setCount($count) + { + return $this->setOption('count', $count); + } + + /** + * Get count option. + * + * @return int|null + */ + public function getCount() + { + return $this->getOption('count'); + } + + /** + * Set cfq option. + * + * A Context Filter Query used to filter suggestions based on the context field, if supported by the suggester. + * + * @param string $cfq + * + * @return self Provides fluent interface + */ + public function setContextFilterQuery($cfq) + { + return $this->setOption('cfq', $cfq); + } + + /** + * Get cfq option. + * + * @return string|null + */ + public function getContextFilterQuery() + { + return $this->getOption('cfq'); + } + + /** + * Set build option. + * + * @param bool $build + * + * @return self Provides fluent interface + */ + public function setBuild($build) + { + return $this->setOption('build', $build); + } + + /** + * Get build option. + * + * @return bool|null + */ + public function getBuild() + { + return $this->getOption('build'); + } + + /** + * Set reload option. + * + * @param bool $build + * @param mixed $reload + * + * @return self Provides fluent interface + */ + public function setReload($reload) + { + return $this->setOption('reload', $reload); + } + + /** + * Get reload option. + * + * @return bool|null + */ + public function getReload() + { + return $this->getOption('reload'); + } +} diff --git a/vendor/solarium/solarium/src/Component/ComponentTraits/TermsTrait.php b/vendor/solarium/solarium/src/Component/ComponentTraits/TermsTrait.php new file mode 100644 index 000000000..cbd0da4f8 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/ComponentTraits/TermsTrait.php @@ -0,0 +1,326 @@ +setOption('fields', $value); + } + + /** + * Get the field name(s) to get the terms from. + * + * @return array + */ + public function getFields() + { + $value = $this->getOption('fields'); + if (null === $value) { + $value = []; + } + + return $value; + } + + /** + * Set the lowerbound term to start at. + * + * @param string $value + * + * @return self Provides fluent interface + */ + public function setLowerbound($value) + { + return $this->setOption('lowerbound', $value); + } + + /** + * Get the lowerbound term to start at. + * + * @return string + */ + public function getLowerbound() + { + return $this->getOption('lowerbound'); + } + + /** + * Set lowerboundinclude. + * + * @param bool $value + * + * @return self Provides fluent interface + */ + public function setLowerboundInclude($value) + { + return $this->setOption('lowerboundinclude', $value); + } + + /** + * Get lowerboundinclude. + * + * @return bool + */ + public function getLowerboundInclude() + { + return $this->getOption('lowerboundinclude'); + } + + /** + * Set mincount (the minimum doc frequency for terms in order to be included). + * + * @param int $value + * + * @return self Provides fluent interface + */ + public function setMinCount($value) + { + return $this->setOption('mincount', $value); + } + + /** + * Get mincount. + * + * @return int + */ + public function getMinCount() + { + return $this->getOption('mincount'); + } + + /** + * Set maxcount (the maximum doc frequency for terms in order to be included). + * + * @param int $value + * + * @return self Provides fluent interface + */ + public function setMaxCount($value) + { + return $this->setOption('maxcount', $value); + } + + /** + * Get maxcount. + * + * @return int + */ + public function getMaxCount() + { + return $this->getOption('maxcount'); + } + + /** + * Set prefix for terms. + * + * @param string $value + * + * @return self Provides fluent interface + */ + public function setPrefix($value) + { + return $this->setOption('prefix', $value); + } + + /** + * Get maxcount. + * + * @return string + */ + public function getPrefix() + { + return $this->getOption('prefix'); + } + + /** + * Set regex to restrict terms. + * + * @param string $value + * + * @return self Provides fluent interface + */ + public function setRegex($value) + { + return $this->setOption('regex', $value); + } + + /** + * Get regex. + * + * @return string + */ + public function getRegex() + { + return $this->getOption('regex'); + } + + /** + * Set regex flags. + * + * Use a comma-separated string or array for multiple entries + * + * @param string|array $value + * + * @return self Provides fluent interface + */ + public function setRegexFlags($value) + { + if (is_string($value)) { + $value = explode(',', $value); + $value = array_map('trim', $value); + } + + return $this->setOption('regexflags', $value); + } + + /** + * Get regex flags. + * + * @return array + */ + public function getRegexFlags() + { + $value = $this->getOption('regexflags'); + if (null === $value) { + $value = []; + } + + return $value; + } + + /** + * Set limit. + * + * If < 0 all terms are included + * + * @param int $value + * + * @return self Provides fluent interface + */ + public function setLimit($value) + { + return $this->setOption('limit', $value); + } + + /** + * Get limit. + * + * @return int + */ + public function getLimit() + { + return $this->getOption('limit'); + } + + /** + * Set the upperbound term to start at. + * + * @param string $value + * + * @return self Provides fluent interface + */ + public function setUpperbound($value) + { + return $this->setOption('upperbound', $value); + } + + /** + * Get the upperbound term to start at. + * + * @return string + */ + public function getUpperbound() + { + return $this->getOption('upperbound'); + } + + /** + * Set upperboundinclude. + * + * @param bool $value + * + * @return self Provides fluent interface + */ + public function setUpperboundInclude($value) + { + return $this->setOption('upperboundinclude', $value); + } + + /** + * Get upperboundinclude. + * + * @return bool + */ + public function getUpperboundInclude() + { + return $this->getOption('upperboundinclude'); + } + + /** + * Set raw option. + * + * @param bool $value + * + * @return self Provides fluent interface + */ + public function setRaw($value) + { + return $this->setOption('raw', $value); + } + + /** + * Get raw option. + * + * @return bool + */ + public function getRaw() + { + return $this->getOption('raw'); + } + + /** + * Set sort option. + * + * @param string $value + * + * @return self Provides fluent interface + */ + public function setSort($value) + { + return $this->setOption('sort', $value); + } + + /** + * Get sort option. + * + * @return string + */ + public function getSort() + { + return $this->getOption('sort'); + } +} diff --git a/vendor/solarium/solarium/src/Component/Debug.php b/vendor/solarium/solarium/src/Component/Debug.php new file mode 100644 index 000000000..955b6fe01 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Debug.php @@ -0,0 +1,66 @@ +getOption('explainother'); + } + + /** + * Set the explainOther query. + * + * @param string $query + * + * @return self Provides fluent interface + */ + public function setExplainOther($query) + { + return $this->setOption('explainother', $query); + } +} diff --git a/vendor/solarium/solarium/src/Component/DisMax.php b/vendor/solarium/solarium/src/Component/DisMax.php new file mode 100644 index 000000000..6f8a04c33 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/DisMax.php @@ -0,0 +1,441 @@ + 'dismax', + ]; + + /** + * Boostqueries. + * + * @var BoostQuery[] + */ + protected $boostQueries = []; + + /** + * Get component type. + * + * @return string + */ + public function getType() + { + return ComponentAwareQueryInterface::COMPONENT_DISMAX; + } + + /** + * Get a requestbuilder for this query. + * + * @return RequestBuilder + */ + public function getRequestBuilder() + { + return new RequestBuilder(); + } + + /** + * Set QueryAlternative option. + * + * If specified, this query will be used (and parsed by default using + * standard query parsing syntax) when the main query string is not + * specified or blank. + * + * @param string $queryAlternative + * + * @return self Provides fluent interface + */ + public function setQueryAlternative($queryAlternative) + { + return $this->setOption('queryalternative', $queryAlternative); + } + + /** + * Get QueryAlternative option. + * + * @return string|null + */ + public function getQueryAlternative() + { + return $this->getOption('queryalternative'); + } + + /** + * Set QueryFields option. + * + * List of fields and the "boosts" to associate with each of them when + * building DisjunctionMaxQueries from the user's query. + * + * The format supported is "fieldOne^2.3 fieldTwo fieldThree^0.4" + * + * @param string $queryFields + * + * @return self Provides fluent interface + */ + public function setQueryFields($queryFields) + { + return $this->setOption('queryfields', $queryFields); + } + + /** + * Get QueryFields option. + * + * @return string|null + */ + public function getQueryFields() + { + return $this->getOption('queryfields'); + } + + /** + * Set MinimumMatch option. + * + * This option makes it possible to say that a certain minimum number of + * clauses must match. See Solr manual for details. + * + * @param string $minimumMatch + * + * @return self Provides fluent interface + */ + public function setMinimumMatch($minimumMatch) + { + return $this->setOption('minimummatch', $minimumMatch); + } + + /** + * Get MinimumMatch option. + * + * @return string|null + */ + public function getMinimumMatch() + { + return $this->getOption('minimummatch'); + } + + /** + * Set PhraseFields option. + * + * This param can be used to "boost" the score of documents in cases + * where all of the terms in the "q" param appear in close proximity. + * + * Format is: "fieldA^1.0 fieldB^2.2" + * + * @param string $phraseFields + * + * @return self Provides fluent interface + */ + public function setPhraseFields($phraseFields) + { + return $this->setOption('phrasefields', $phraseFields); + } + + /** + * Get PhraseFields option. + * + * @return string|null + */ + public function getPhraseFields() + { + return $this->getOption('phrasefields'); + } + + /** + * Set PhraseSlop option. + * + * Amount of slop on phrase queries built for "pf" fields + * (affects boosting) + * + * @param string $phraseSlop + * + * @return self Provides fluent interface + */ + public function setPhraseSlop($phraseSlop) + { + return $this->setOption('phraseslop', $phraseSlop); + } + + /** + * Get PhraseSlop option. + * + * @return string|null + */ + public function getPhraseSlop() + { + return $this->getOption('phraseslop'); + } + + /** + * Set QueryPhraseSlop option. + * + * Amount of slop on phrase queries explicitly included in the user's + * query string (in qf fields; affects matching) + * + * @param string $queryPhraseSlop + * + * @return self Provides fluent interface + */ + public function setQueryPhraseSlop($queryPhraseSlop) + { + return $this->setOption('queryphraseslop', $queryPhraseSlop); + } + + /** + * Get QueryPhraseSlop option. + * + * @return string|null + */ + public function getQueryPhraseSlop() + { + return $this->getOption('queryphraseslop'); + } + + /** + * Set Tie option. + * + * Float value to use as tiebreaker in DisjunctionMaxQueries + * + * @param float $tie + * + * @return self Provides fluent interface + */ + public function setTie($tie) + { + return $this->setOption('tie', $tie); + } + + /** + * Get Tie option. + * + * @return float|null + */ + public function getTie() + { + return $this->getOption('tie'); + } + + /** + * Set BoostQuery option. + * + * A raw query string (in the SolrQuerySyntax) that will be included + * with the user's query to influence the score. + * + * @param string $boostQuery + * + * @return self Provides fluent interface + */ + public function setBoostQuery($boostQuery) + { + $this->clearBoostQueries(); + $this->addBoostQuery(['key' => 0, 'query' => $boostQuery]); + + return $this; + } + + /** + * Get BoostQuery option. + * + * @param string $key + * + * @return string|null + */ + public function getBoostQuery($key = null) + { + if (null !== $key) { + if (array_key_exists($key, $this->boostQueries)) { + return $this->boostQueries[$key]->getQuery(); + } + } elseif (!empty($this->boostQueries)) { + /** @var BoostQuery[] $boostQueries */ + $boostQueries = array_values($this->boostQueries); + + return $boostQueries[0]->getQuery(); + } elseif (array_key_exists('boostquery', $this->options)) { + return $this->options['boostquery']; + } + + return null; + } + + /** + * Add a boost query. + * + * Supports a boostquery instance or a config array, in that case a new + * boostquery instance wil be created based on the options. + * + * + * @param BoostQuery|array $boostQuery + * + * @throws InvalidArgumentException + * + * @return self Provides fluent interface + */ + public function addBoostQuery($boostQuery) + { + if (is_array($boostQuery)) { + $boostQuery = new BoostQuery($boostQuery); + } + + $key = $boostQuery->getKey(); + + if (0 === strlen($key)) { + throw new InvalidArgumentException('A boostquery must have a key value'); + } + + //double add calls for the same BQ are ignored, but non-unique keys cause an exception + if (array_key_exists($key, $this->boostQueries) && $this->boostQueries[$key] !== $boostQuery) { + throw new InvalidArgumentException('A boostquery must have a unique key value within a query'); + } + + $this->boostQueries[$key] = $boostQuery; + + return $this; + } + + /** + * Add multiple boostqueries. + * + * @param array $boostQueries + * + * @return self Provides fluent interface + */ + public function addBoostQueries(array $boostQueries) + { + foreach ($boostQueries as $key => $boostQuery) { + // in case of a config array: add key to config + if (is_array($boostQuery) && !isset($boostQuery['key'])) { + $boostQuery['key'] = $key; + } + + $this->addBoostQuery($boostQuery); + } + + return $this; + } + + /** + * Get all boostqueries. + * + * @return BoostQuery[] + */ + public function getBoostQueries() + { + return $this->boostQueries; + } + + /** + * Remove a single boostquery. + * + * You can remove a boostquery by passing its key, or by passing the boostquery instance + * + * @param string|BoostQuery $boostQuery + * + * @return self Provides fluent interface + */ + public function removeBoostQuery($boostQuery) + { + if (is_object($boostQuery)) { + $boostQuery = $boostQuery->getKey(); + } + + if (isset($this->boostQueries[$boostQuery])) { + unset($this->boostQueries[$boostQuery]); + } + + return $this; + } + + /** + * Remove all boostqueries. + * + * @return self Provides fluent interface + */ + public function clearBoostQueries() + { + $this->boostQueries = []; + + return $this; + } + + /** + * Set multiple boostqueries. + * + * This overwrites any existing boostqueries + * + * @param array $boostQueries + */ + public function setBoostQueries($boostQueries) + { + $this->clearBoostQueries(); + $this->addBoostQueries($boostQueries); + } + + /** + * Set BoostFunctions option. + * + * Functions (with optional boosts) that will be included in the + * user's query to influence the score. + * + * Format is: "funcA(arg1,arg2)^1.2 funcB(arg3,arg4)^2.2" + * + * @param string $boostFunctions + * + * @return self Provides fluent interface + */ + public function setBoostFunctions($boostFunctions) + { + return $this->setOption('boostfunctions', $boostFunctions); + } + + /** + * Get BoostFunctions option. + * + * @return string|null + */ + public function getBoostFunctions() + { + return $this->getOption('boostfunctions'); + } + + /** + * Set QueryParser option. + * + * Can be used to enable edismax + * + * @since 2.1.0 + * + * @param string $parser + * + * @return self Provides fluent interface + */ + public function setQueryParser($parser) + { + return $this->setOption('queryparser', $parser); + } + + /** + * Get QueryParser option. + * + * @since 2.1.0 + * + * @return string + */ + public function getQueryParser() + { + return $this->getOption('queryparser'); + } +} diff --git a/vendor/solarium/solarium/src/Component/DisMax/BoostQuery.php b/vendor/solarium/solarium/src/Component/DisMax/BoostQuery.php new file mode 100644 index 000000000..4b0ca7e78 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/DisMax/BoostQuery.php @@ -0,0 +1,65 @@ +getOption('key'); + } + + /** + * Set key value. + * + * @param string $value + * + * @return self Provides fluent interface + */ + public function setKey($value) + { + return $this->setOption('key', $value); + } + + /** + * Returns a query helper. + * + * @return \Solarium\Core\Query\Helper + */ + public function getHelper() + { + return new Helper(); + } + + /** + * Initialize options. + */ + protected function init() + { + foreach ($this->options as $name => $value) { + switch ($name) { + case 'key': + $this->setKey($value); + break; + case 'query': + $this->setQuery($value); + break; + } + } + } +} diff --git a/vendor/solarium/solarium/src/Component/DistributedSearch.php b/vendor/solarium/solarium/src/Component/DistributedSearch.php new file mode 100644 index 000000000..7ff6ed345 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/DistributedSearch.php @@ -0,0 +1,391 @@ +shards[$key] = $shard; + + return $this; + } + + /** + * Add multiple shards. + * + * Example usage: + * + * $client = new Solarium\Client; + * $query = $client->createSelect(); + * $distributedSearch = $query->getDistributedSearch(); + * $distributedSearch->addShards(array( + * 'core0' => 'localhost:8983/solr/core0', + * 'core1' => 'localhost:8983/solr/core1' + * )); + * $result = $client->select($query); + * + * + * @param array $shards + * + * @return self Provides fluent interface + */ + public function addShards(array $shards) + { + foreach ($shards as $key => $shard) { + $this->addShard($key, $shard); + } + + return $this; + } + + /** + * Remove a shard. + * + * @param string $key + * + * @return self Provides fluent interface + */ + public function removeShard($key) + { + if (isset($this->shards[$key])) { + unset($this->shards[$key]); + } + + return $this; + } + + /** + * Remove all shards. + * + * @return self Provides fluent interface + */ + public function clearShards() + { + $this->shards = []; + + return $this; + } + + /** + * Set multiple shards. + * + * This overwrites any existing shards + * + * Example usage: + * + * $client = new Solarium\Client; + * $query = $client->createSelect(); + * $distributedSearch = $query->getDistributedSearch(); + * $distributedSearch->setShards(array( + * 'core0' => 'localhost:8983/solr/core0', + * 'core1' => 'localhost:8983/solr/core1' + * )); + * $result = $client->select($query); + * + * + * @param array $shards Associative array of shards + * + * @return self Provides fluent interface + */ + public function setShards(array $shards) + { + $this->clearShards(); + $this->addShards($shards); + + return $this; + } + + /** + * Get a list of the shards. + * + * @return array + */ + public function getShards() + { + return $this->shards; + } + + /** + * A sharded request will go to the standard request handler + * (not necessarily the original); this can be overridden via shards.qt. + * + * @param string $handler + * + * @return self Provides fluent interface + */ + public function setShardRequestHandler($handler) + { + $this->setOption('shardhandler', $handler); + + return $this; + } + + /** + * Get a shard request handler (shards.qt). + * + * @return self Provides fluent interface + */ + public function getShardRequestHandler() + { + return $this->getOption('shardhandler'); + } + + /** + * Add a collection. + * + * @param string $key unique string + * @param string $collection The syntax is host:port/base_url + * + * @return self Provides fluent interface + * + * @see http://wiki.apache.org/solr/SolrCloud/ + */ + public function addCollection($key, $collection) + { + $this->collections[$key] = $collection; + + return $this; + } + + /** + * Add multiple collections. + * + * @param array $collections + * + * @return self Provides fluent interface + */ + public function addCollections(array $collections) + { + foreach ($collections as $key => $collection) { + $this->addCollection($key, $collection); + } + + return $this; + } + + /** + * Remove a collection. + * + * @param string $key + * + * @return self Provides fluent interface + */ + public function removeCollection($key) + { + if (isset($this->collections[$key])) { + unset($this->collections[$key]); + } + + return $this; + } + + /** + * Remove all collections. + * + * @return self Provides fluent interface + */ + public function clearCollections() + { + $this->collections = []; + + return $this; + } + + /** + * Set multiple collections. + * + * This overwrites any existing collections + * + * @param array $collections Associative array of collections + * + * @return self Provides fluent interface + */ + public function setCollections(array $collections) + { + $this->clearCollections(); + $this->addCollections($collections); + + return $this; + } + + /** + * Get a list of the collections. + * + * @return array + */ + public function getCollections() + { + return $this->collections; + } + + /** + * Add a replica. + * + * @param string $key unique string + * @param string $replica The syntax is host:port/base_url + * + * @return self Provides fluent interface + * + * @see https://cwiki.apache.org/confluence/display/solr/Distributed+Requests + */ + public function addReplica($key, $replica) + { + $this->replicas[$key] = $replica; + + return $this; + } + + /** + * Add multiple replicas. + * + * @param array $replicas + * + * @return self Provides fluent interface + */ + public function addReplicas(array $replicas) + { + foreach ($replicas as $key => $replica) { + $this->addReplica($key, $replica); + } + + return $this; + } + + /** + * Remove a replica. + * + * @param string $key + * + * @return self Provides fluent interface + */ + public function removeReplica($key) + { + if (isset($this->replicas[$key])) { + unset($this->replicas[$key]); + } + + return $this; + } + + /** + * Remove all replicas. + * + * @return self Provides fluent interface + */ + public function clearReplicas() + { + $this->replicas = []; + + return $this; + } + + /** + * Set multiple replicas. + * + * This overwrites any existing replicas + * + * @param array $replicas Associative array of collections + * + * @return self Provides fluent interface + */ + public function setReplicas(array $replicas) + { + $this->clearReplicas(); + $this->addReplicas($replicas); + + return $this; + } + + /** + * Get a list of the replicas. + * + * @return array + */ + public function getReplicas() + { + return $this->replicas; + } + + /** + * Initialize options. + * + * Several options need some extra checks or setup work, for these options + * the setters are called. + */ + protected function init() + { + foreach ($this->options as $name => $value) { + switch ($name) { + case 'shards': + $this->setShards($value); + break; + case 'collections': + $this->setCollections($value); + break; + case 'replicas': + $this->setReplicas($value); + break; + } + } + } +} diff --git a/vendor/solarium/solarium/src/Component/EdisMax.php b/vendor/solarium/solarium/src/Component/EdisMax.php new file mode 100644 index 000000000..7323c48e4 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/EdisMax.php @@ -0,0 +1,203 @@ + 'edismax', + ]; + + /** + * Get component type. + * + * @return string + */ + public function getType() + { + return ComponentAwareQueryInterface::COMPONENT_EDISMAX; + } + + /** + * Get a requestbuilder for this query. + * + * @return RequestBuilder + */ + public function getRequestBuilder() + { + return new RequestBuilder(); + } + + /** + * Set BoostFunctionsMult option. + * + * Functions (with optional boosts) that will be included in the + * user's query to influence the score by multiplying its value. + * + * Format is: "funcA(arg1,arg2)^1.2 funcB(arg3,arg4)^2.2" + * + * @param string $boostFunctionsMult + * + * @return self Provides fluent interface + */ + public function setBoostFunctionsMult($boostFunctionsMult) + { + return $this->setOption('boostfunctionsmult', $boostFunctionsMult); + } + + /** + * Get BoostFunctionsMult option. + * + * @return string|null + */ + public function getBoostFunctionsMult() + { + return $this->getOption('boostfunctionsmult'); + } + + /** + * Set PhraseFields option. + * + * As with 'pf' but chops the input into bi-grams, + * e.g. "the brown fox jumped" is queried as "the brown" "brown fox" "fox jumped" + * + * Format is: "fieldA^1.0 fieldB^2.2 fieldC^3.5" + * + * @param string $phraseBigramFields + * + * @return self Provides fluent interface + */ + public function setPhraseBigramFields($phraseBigramFields) + { + return $this->setOption('phrasebigramfields', $phraseBigramFields); + } + + /** + * Get PhraseBigramFields option. + * + * @return string|null + */ + public function getPhraseBigramFields() + { + return $this->getOption('phrasebigramfields'); + } + + /** + * Set PhraseBigramSlop option. + * + * As with 'ps' but sets default slop factor for 'pf2'. + * If not specified, 'ps' will be used. + * + * @param string $phraseBigramSlop + * + * @return self Provides fluent interface + */ + public function setPhraseBigramSlop($phraseBigramSlop) + { + return $this->setOption('phrasebigramslop', $phraseBigramSlop); + } + + /** + * Get PhraseBigramSlop option. + * + * @return string|null + */ + public function getPhraseBigramSlop() + { + return $this->getOption('phrasebigramslop'); + } + + /** + * Set PhraseFields option. + * + * As with 'pf' but chops the input into tri-grams, + * e.g. "the brown fox jumped" is queried as "the brown fox" "brown fox jumped" + * + * Format is: "fieldA^1.0 fieldB^2.2 fieldC^3.5" + * + * @param string $phraseTrigramFields + * + * @return self Provides fluent interface + */ + public function setPhraseTrigramFields($phraseTrigramFields) + { + return $this->setOption('phrasetrigramfields', $phraseTrigramFields); + } + + /** + * Get PhraseTrigramFields option. + * + * @return string|null + */ + public function getPhraseTrigramFields() + { + return $this->getOption('phrasetrigramfields'); + } + + /** + * Set PhraseTrigramSlop option. + * + * As with 'ps' but sets default slop factor for 'pf3'. + * If not specified, 'ps' will be used. + * + * @param string $phraseTrigramSlop + * + * @return self Provides fluent interface + */ + public function setPhraseTrigramSlop($phraseTrigramSlop) + { + return $this->setOption('phrasetrigramslop', $phraseTrigramSlop); + } + + /** + * Get PhraseTrigramSlop option. + * + * @return string|null + */ + public function getPhraseTrigramSlop() + { + return $this->getOption('phrasetrigramslop'); + } + + /** + * Set UserFields option. + * + * Specifies which schema fields the end user shall be allowed to query for explicitly. + * This parameter supports wildcards. + * + * The default is to allow all fields, equivalent to &uf=*. + * To allow only title field, use &uf=title, to allow title and all fields ending with _s, use &uf=title *_s. + * To allow all fields except title, use &uf=* -title. To disallow all fielded searches, use &uf=-*. + * The uf parameter was introduced in Solr3.6 + * + * @param string $userFields + * + * @return self Provides fluent interface + */ + public function setUserFields($userFields) + { + return $this->setOption('userfields', $userFields); + } + + /** + * Get UserFields option. + * + * @return string|null + */ + public function getUserFields() + { + return $this->getOption('userfields'); + } +} diff --git a/vendor/solarium/solarium/src/Component/Facet/AbstractFacet.php b/vendor/solarium/solarium/src/Component/Facet/AbstractFacet.php new file mode 100644 index 000000000..e8690fdf8 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Facet/AbstractFacet.php @@ -0,0 +1,44 @@ +getOption('key'); + } + + /** + * Set key value. + * + * @param string $value + * + * @return self Provides fluent interface + */ + public function setKey($value) + { + return $this->setOption('key', $value); + } +} diff --git a/vendor/solarium/solarium/src/Component/Facet/AbstractField.php b/vendor/solarium/solarium/src/Component/Facet/AbstractField.php new file mode 100644 index 000000000..cf83ec28a --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Facet/AbstractField.php @@ -0,0 +1,210 @@ + 'id', + ]; + + /** + * Set the field name. + * + * @param string $field + * + * @return self Provides fluent interface + */ + public function setField($field) + { + return $this->setOption('field', $field); + } + + /** + * Get the field name. + * + * @return string + */ + public function getField() + { + return $this->getOption('field'); + } + + /** + * Set the facet sort order. + * + * Use one of the SORT_* constants as the value + * + * @param string $sort + * + * @return self Provides fluent interface + */ + public function setSort($sort) + { + return $this->setOption('sort', $sort); + } + + /** + * Get the facet sort order. + * + * @return string + */ + public function getSort() + { + return $this->getOption('sort'); + } + + /** + * Limit the terms for faceting by a prefix. + * + * @param string $prefix + * + * @return self Provides fluent interface + */ + public function setPrefix($prefix) + { + return $this->setOption('prefix', $prefix); + } + + /** + * Get the facet prefix. + * + * @return string + */ + public function getPrefix() + { + return $this->getOption('prefix'); + } + + /** + * Set the facet limit. + * + * @param mixed $limit + * + * @return self Provides fluent interface + */ + public function setLimit($limit) + { + return $this->setOption('limit', $limit); + } + + /** + * Get the facet limit. + * + * @return string + */ + public function getLimit() + { + return $this->getOption('limit'); + } + + /** + * Set the facet offset. + * + * @param int $offset + * + * @return self Provides fluent interface + */ + public function setOffset($offset) + { + return $this->setOption('offset', $offset); + } + + /** + * Get the facet offset. + * + * @return int + */ + public function getOffset() + { + return $this->getOption('offset'); + } + + /** + * Set the facet mincount. + * + * @param int $minCount + * + * @return self Provides fluent interface + */ + public function setMinCount($minCount) + { + return $this->setOption('mincount', $minCount); + } + + /** + * Get the facet mincount. + * + * @return int + */ + public function getMinCount() + { + return $this->getOption('mincount'); + } + + /** + * Set the missing count option. + * + * @param bool $missing + * + * @return self Provides fluent interface + */ + public function setMissing($missing) + { + return $this->setOption('missing', $missing); + } + + /** + * Get the facet missing option. + * + * @return bool + */ + public function getMissing() + { + return $this->getOption('missing'); + } + + /** + * Set the facet method. + * + * Use one of the METHOD_* constants as value + * + * @param string $method + * + * @return self Provides fluent interface + */ + public function setMethod($method) + { + return $this->setOption('method', $method); + } + + /** + * Get the facet method. + * + * @return string + */ + public function getMethod() + { + return $this->getOption('method'); + } +} diff --git a/vendor/solarium/solarium/src/Component/Facet/AbstractRange.php b/vendor/solarium/solarium/src/Component/Facet/AbstractRange.php new file mode 100644 index 000000000..5f68dbf08 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Facet/AbstractRange.php @@ -0,0 +1,268 @@ +setOption('field', $field); + } + + /** + * Get the field name. + * + * @return string + */ + public function getField() + { + return $this->getOption('field'); + } + + /** + * Set the lower bound of the range. + * + * @param string $start + * + * @return self Provides fluent interface + */ + public function setStart($start) + { + return $this->setOption('start', $start); + } + + /** + * Get the lower bound of the range. + * + * @return string + */ + public function getStart() + { + return $this->getOption('start'); + } + + /** + * Set the upper bound of the range. + * + * @param string $end + * + * @return self Provides fluent interface + */ + public function setEnd($end) + { + return $this->setOption('end', $end); + } + + /** + * Get the upper bound of the range. + * + * @return string + */ + public function getEnd() + { + return $this->getOption('end'); + } + + /** + * Set range gap. + * + * The size of each range expressed as a value to be added to the lower bound + * + * @param string $gap + * + * @return self Provides fluent interface + */ + public function setGap($gap) + { + return $this->setOption('gap', $gap); + } + + /** + * Get range gap. + * + * The size of each range expressed as a value to be added to the lower bound + * + * @return string + */ + public function getGap() + { + return $this->getOption('gap'); + } + + /** + * Set hardend option. + * + * A Boolean parameter instructing Solr what to do in the event that facet.range.gap + * does not divide evenly between facet.range.start and facet.range.end + * + * @param bool $hardend + * + * @return self Provides fluent interface + */ + public function setHardend($hardend) + { + return $this->setOption('hardend', $hardend); + } + + /** + * Get hardend option. + * + * @return bool + */ + public function getHardend() + { + return $this->getOption('hardend'); + } + + /** + * Set other counts. + * + * Use one of the constants as value. + * If you want to use multiple values supply an array or comma separated string + * + * @param string|array $other + * + * @return self Provides fluent interface + */ + public function setOther($other) + { + if (is_string($other)) { + $other = explode(',', $other); + $other = array_map('trim', $other); + } + + return $this->setOption('other', $other); + } + + /** + * Get other counts. + * + * @return array + */ + public function getOther() + { + $other = $this->getOption('other'); + if (null === $other) { + $other = []; + } + + return $other; + } + + /** + * Set include option. + * + * Use one of the constants as value. + * If you want to use multiple values supply an array or comma separated string + * + * @param string|array $include + * + * @return self Provides fluent interface + */ + public function setInclude($include) + { + if (is_string($include)) { + $include = explode(',', $include); + $include = array_map('trim', $include); + } + + return $this->setOption('include', $include); + } + + /** + * Get include option. + * + * @return array + */ + public function getInclude() + { + $include = $this->getOption('include'); + if (null === $include) { + $include = []; + } + + return $include; + } + + /** + * Initialize options. + * + * Several options need some extra checks or setup work, for these options + * the setters are called. + */ + protected function init() + { + foreach ($this->options as $name => $value) { + switch ($name) { + case 'include': + $this->setInclude($value); + break; + case 'other': + $this->setOther($value); + break; + } + } + } +} diff --git a/vendor/solarium/solarium/src/Component/Facet/ExcludeTagsInterface.php b/vendor/solarium/solarium/src/Component/Facet/ExcludeTagsInterface.php new file mode 100644 index 000000000..c312f74be --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Facet/ExcludeTagsInterface.php @@ -0,0 +1,61 @@ +excludes[$tag] = true; + + return $this; + } + + /** + * Add multiple exclude tags. + * + * @param array $excludes + * + * @return self Provides fluent interface + */ + public function addExcludes(array $excludes) + { + foreach ($excludes as $exclude) { + $this->addExclude($exclude); + } + + return $this; + } + + /** + * Get all excludes. + * + * @return array + */ + public function getExcludes() + { + return array_keys($this->excludes); + } + + /** + * Remove a single exclude tag. + * + * @param string $exclude + * + * @return self Provides fluent interface + */ + public function removeExclude($exclude) + { + if (isset($this->excludes[$exclude])) { + unset($this->excludes[$exclude]); + } + + return $this; + } + + /** + * Remove all excludes. + * + * @return self Provides fluent interface + */ + public function clearExcludes() + { + $this->excludes = []; + + return $this; + } + + /** + * Set multiple excludes. + * + * This overwrites any existing excludes + * + * @param array $excludes + */ + public function setExcludes($excludes) + { + $this->clearExcludes(); + $this->addExcludes($excludes); + } + + /** + * Initialize options. + */ + protected function init() + { + foreach ($this->options as $name => $value) { + switch ($name) { + case 'exclude': + if (!is_array($value)) { + $value = explode(',', $value); + } + $this->setExcludes($value); + unset($this->options['exclude']); + break; + } + } + } +} diff --git a/vendor/solarium/solarium/src/Component/Facet/FacetInterface.php b/vendor/solarium/solarium/src/Component/Facet/FacetInterface.php new file mode 100644 index 000000000..8cc8cce16 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Facet/FacetInterface.php @@ -0,0 +1,36 @@ +setOption('contains', $contains); + } + + /** + * Get the facet contains. + * + * @return string + */ + public function getContains() + { + return $this->getOption('contains'); + } + + /** + * Case sensitivity of matching string that facet terms must contain. Since Solr 5.1. + * + * @param bool $containsIgnoreCase + * + * @return self Provides fluent interface + */ + public function setContainsIgnoreCase($containsIgnoreCase) + { + return $this->setOption('containsignorecase', $containsIgnoreCase); + } + + /** + * Get the case sensitivity of facet contains. + * + * @return bool + */ + public function getContainsIgnoreCase() + { + return $this->getOption('containsignorecase'); + } +} diff --git a/vendor/solarium/solarium/src/Component/Facet/Interval.php b/vendor/solarium/solarium/src/Component/Facet/Interval.php new file mode 100644 index 000000000..5cf3a0e9a --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Facet/Interval.php @@ -0,0 +1,103 @@ +setOption('field', $field); + } + + /** + * Get the field name. + * + * @return string + */ + public function getField() + { + return $this->getOption('field'); + } + + /** + * Set set counts. + * + * Use one of the constants as value. + * If you want to use multiple values supply an array or comma separated string + * + * @param string|array $set + * + * @return self Provides fluent interface + */ + public function setSet($set) + { + if (is_string($set)) { + $set = explode(',', $set); + $set = array_map('trim', $set); + } + + return $this->setOption('set', $set); + } + + /** + * Get set counts. + * + * @return array + */ + public function getSet() + { + $set = $this->getOption('set'); + if (null === $set) { + $set = []; + } + + return $set; + } + + /** + * Initialize options. + * + * Several options need some extra checks or setup work, for these options + * the setters are called. + */ + protected function init() + { + $this->excludeTagsInit(); + + foreach ($this->options as $name => $value) { + switch ($name) { + case 'set': + $this->setSet($value); + break; + } + } + } +} diff --git a/vendor/solarium/solarium/src/Component/Facet/JsonAggregation.php b/vendor/solarium/solarium/src/Component/Facet/JsonAggregation.php new file mode 100644 index 000000000..7778033a0 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Facet/JsonAggregation.php @@ -0,0 +1,86 @@ +setOption('function', $function); + } + + /** + * Get the function string. + * + * @return string + */ + public function getFunction() + { + return $this->getOption('function'); + } + + /** + * Set the min value. + * + * This overwrites the current value. + * This option doesn't exist in Solr originally, but it's useful to filter + * the aggregations returned by Solr. + * + * @param int $min + * + * @return self Provides fluent interface + */ + public function setMin(int $min) + { + return $this->setOption('min', $min); + } + + /** + * Get the min value. + * + * This option doesn't exist in Solr originally, but it's useful to filter + * the aggregations returned by Solr. + * + * @return int + */ + public function getMin() + { + return $this->getOption('min'); + } + + /** + * Serializes nested facets as option "facet" and returns that array structure. + * + * @return array|string + */ + public function serialize() + { + return $this->getFunction(); + } +} diff --git a/vendor/solarium/solarium/src/Component/Facet/JsonFacetInterface.php b/vendor/solarium/solarium/src/Component/Facet/JsonFacetInterface.php new file mode 100644 index 000000000..3b8fb2287 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Facet/JsonFacetInterface.php @@ -0,0 +1,18 @@ + 'Solarium\Component\Facet\JsonTerms', + FacetSetInterface::JSON_FACET_QUERY => 'Solarium\Component\Facet\JsonQuery', + FacetSetInterface::JSON_FACET_RANGE => 'Solarium\Component\Facet\JsonRange', + FacetSetInterface::JSON_FACET_AGGREGATION => 'Solarium\Component\Facet\JsonAggregation', + ]; + + /** + * Get the domain filter. + * + * @return string + */ + public function getDomainFilter() + { + $domain = $this->getOption('domain'); + if ($domain && isset($domain['filter'])) { + return $domain['filter']; + } + } + + /** + * Set the domain filter query string. + * + * This overwrites the current value. + * + * @param string $query + * @param array $bind Bind values for placeholders in the query string + * + * @return self Provides fluent interface + */ + public function setDomainFilterQuery(string $query, array $bind = null) + { + if (null !== $bind) { + $helper = new Helper(); + $query = $helper->assemble($query, $bind); + } + + $filter = $this->getDomainFilter(); + if (!$filter || is_string($filter)) { + return $this->setOption('domain', ['filter' => $query]); + } else { + foreach ($filter as &$param_or_query) { + if (is_string($param_or_query)) { + $param_or_query = $query; + return $this->setOption('domain', ['filter' => $filter]); + } + } + $filter[] = $query; + return $this->setOption('domain', ['filter' => $filter]); + } + } + + /** + * Adds a domain filter parameter. + * + * @param string $param + * + * @return self Provides fluent interface + */ + public function addDomainFilterParameter(string $param) + { + $filter = $this->getDomainFilter(); + if (!$filter) { + return $this->setOption('domain', ['filter' => ['param' => $param]]); + } elseif (is_string($filter) || 1 == count($filter)) { + return $this->setOption('domain', ['filter' => [$filter, ['param' => $param]]]); + } else { + foreach ($filter as &$param_or_query) { + if (is_array($param_or_query) && $param_or_query['param'] == $param) { + return $this; + } + } + $filter[] = ['param' => $param]; + return $this->setOption('domain', ['filter' => $filter]); + } + } + + /** + * Serializes nested facets as option "facet" and returns that array structure. + * + * @return array|string + */ + public function serialize() + { + // Strip 'json_' prefix. + $this->setOption('type', substr($this->getType(), 5)); + + $facets = []; + foreach ($this->getFacets() as $key => $facet) { + $facets[$key] = $facet->serialize(); + } + + if ($facets) { + $this->setOption('facet', $facets); + } elseif (isset($this->options['facet'])) { + unset($this->options['facet']); + } + + $options = $this->getOptions(); + unset($options['key']); + + return $options; + } + + /** + * Add a facet. + * + * + * @param FacetInterface|array $facet + * + * @throws InvalidArgumentException + * + * @return self Provides fluent interface + */ + public function addFacet($facet) + { + if ($facet instanceof JsonFacetInterface) { + $this->facetSetAddFacet($facet); + $this->serialize(); + + return $this; + } else { + throw new InvalidArgumentException('Only JSON facets can be nested.'); + } + } + + /** + * Remove a single facet. + * + * You can remove a facet by passing its key or the facet instance + * + * @param string|FacetInterface $facet + * + * @return self Provides fluent interface + */ + public function removeFacet($facet) + { + $this->facetSetRemoveFacet($facet); + $this->serialize(); + + return $this; + } + + /** + * Remove all facets. + * + * @return self Provides fluent interface + */ + public function clearFacets() + { + $this->facetSetClearFacets(); + $this->serialize(); + + return $this; + } +} diff --git a/vendor/solarium/solarium/src/Component/Facet/JsonQuery.php b/vendor/solarium/solarium/src/Component/Facet/JsonQuery.php new file mode 100644 index 000000000..330132b6b --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Facet/JsonQuery.php @@ -0,0 +1,58 @@ + '*:*', + ]; + + /** + * Get the facet type. + * + * @return string + */ + public function getType() + { + return FacetSetInterface::JSON_FACET_QUERY; + } + + /** + * Returns a query helper. + * + * @return \Solarium\Core\Query\Helper + */ + public function getHelper() + { + return new Helper(); + } + + public function serialize() + { + $options = $this->jsonFacetTraitSerialize(); + $options['q'] = $options['query']; + unset($options['query']); + return $options; + } +} diff --git a/vendor/solarium/solarium/src/Component/Facet/JsonRange.php b/vendor/solarium/solarium/src/Component/Facet/JsonRange.php new file mode 100644 index 000000000..fefc8a756 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Facet/JsonRange.php @@ -0,0 +1,39 @@ +jsonFacetInit(); + } +} diff --git a/vendor/solarium/solarium/src/Component/Facet/JsonTerms.php b/vendor/solarium/solarium/src/Component/Facet/JsonTerms.php new file mode 100644 index 000000000..3d0599046 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Facet/JsonTerms.php @@ -0,0 +1,156 @@ +setOption('refine', $refine); + } + + /** + * Get the refine parameter. + * + * @return bool + */ + public function getRefine() + { + return $this->getOption('refine'); + } + + /** + * Set the overrequest parameter. + * + * Number of buckets beyond the limit to request internally during distributed search. -1 means default. + * + * @param int $overrequest + * + * @return self Provides fluent interface + */ + public function setOverRequest(int $overrequest) + { + return $this->setOption('overrequest', $overrequest); + } + + /** + * Get the refine parameter. + * + * @return int + */ + public function getOverRequest() + { + return $this->getOption('overrequest'); + } + + /** + * Set the numBuckets parameter. + * + * A boolean. If true, adds “numBuckets” to the response, an integer representing the number of buckets for the + * facet (as opposed to the number of buckets returned). Defaults to false. + * + * @param bool $numBuckets + * + * @return self Provides fluent interface + */ + public function setNumBuckets(bool $numBuckets) + { + return $this->setOption('numBuckets', $numBuckets); + } + + /** + * Get the numBuckets parameter. + * + * @return bool + */ + public function getNumBuckets() + { + return $this->getOption('numBuckets'); + } + + /** + * Set the allBuckets parameter. + * + * A boolean. If true, adds an “allBuckets” bucket to the response, representing the union of all of the buckets. + * For multi-valued fields, this is different than a bucket for all of the documents in the domain since a single + * document can belong to multiple buckets. Defaults to false. + * + * @param bool $allBuckets + * + * @return self Provides fluent interface + */ + public function setAllBuckets(bool $allBuckets) + { + return $this->setOption('allBuckets', $allBuckets); + } + + /** + * Get the allBuckets parameter. + * + * @return bool + */ + public function getAllBuckets() + { + return $this->getOption('allBuckets'); + } +} diff --git a/vendor/solarium/solarium/src/Component/Facet/MultiQuery.php b/vendor/solarium/solarium/src/Component/Facet/MultiQuery.php new file mode 100644 index 000000000..66b50f467 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Facet/MultiQuery.php @@ -0,0 +1,283 @@ +getExcludes(), $excludes); + + $facetQuery = new Query(); + $facetQuery->setKey($key); + $facetQuery->setQuery($query); + $facetQuery->setExcludes($excludes); + + return $this->addQuery($facetQuery); + } + + /** + * Add a facetquery. + * + * Supports a facetquery instance or a config array, in that case a new + * facetquery instance wil be created based on the options. + * + * + * @param Query|array $facetQuery + * + * @throws InvalidArgumentException + * + * @return self Provides fluent interface + */ + public function addQuery($facetQuery) + { + if (is_array($facetQuery)) { + $facetQuery = new Query($facetQuery); + } + + $key = $facetQuery->getKey(); + + if (0 === strlen($key)) { + throw new InvalidArgumentException('A facetquery must have a key value'); + } + + if (array_key_exists($key, $this->facetQueries)) { + throw new InvalidArgumentException('A query must have a unique key value within a multiquery facet'); + } + + // forward shared excludes + $facetQuery->addExcludes($this->getExcludes()); + + $this->facetQueries[$key] = $facetQuery; + + return $this; + } + + /** + * Add multiple facetqueries. + * + * @param array $facetQueries Instances or config array + * + * @return self Provides fluent interface + */ + public function addQueries(array $facetQueries) + { + foreach ($facetQueries as $key => $facetQuery) { + // in case of a config array: add key to config + if (is_array($facetQuery) && !isset($facetQuery['key'])) { + $facetQuery['key'] = $key; + } + + $this->addQuery($facetQuery); + } + + return $this; + } + + /** + * Get a facetquery. + * + * @param string $key + * + * @return string + */ + public function getQuery($key) + { + if (isset($this->facetQueries[$key])) { + return $this->facetQueries[$key]; + } + } + + /** + * Get all facetqueries. + * + * @return Query[] + */ + public function getQueries() + { + return $this->facetQueries; + } + + /** + * Remove a single facetquery. + * + * You can remove a facetquery by passing its key or the facetquery instance. + * + * @param string|Query $query + * + * @return self Provides fluent interface + */ + public function removeQuery($query) + { + if (is_object($query)) { + $query = $query->getKey(); + } + + if (isset($this->facetQueries[$query])) { + unset($this->facetQueries[$query]); + } + + return $this; + } + + /** + * Remove all facetqueries. + * + * @return self Provides fluent interface + */ + public function clearQueries() + { + $this->facetQueries = []; + + return $this; + } + + /** + * Set multiple facetqueries. + * + * This overwrites any existing facetqueries + * + * @param array $facetQueries + * + * @return self Provides fluent interface + */ + public function setQueries($facetQueries) + { + $this->clearQueries(); + + return $this->addQueries($facetQueries); + } + + /** + * Add an exclude tag. + * + * Excludes added to the MultiQuery facet a shared by all underlying + * FacetQueries, so they must be forwarded to any existing instances. + * + * If you don't want to share an exclude use the addExclude method of a + * specific FacetQuery instance instead. + * + * @param string $tag + * + * @return self Provides fluent interface + */ + public function addExclude($tag) + { + foreach ($this->facetQueries as $facetQuery) { + $facetQuery->addExclude($tag); + } + + return $this->excludeTagsAddExclude($tag); + } + + /** + * Remove a single exclude tag. + * + * Excludes added to the MultiQuery facet a shared by all underlying + * FacetQueries, so changes must be forwarded to any existing instances. + * + * If you don't want this use the removeExclude method of a + * specific FacetQuery instance instead. + * + * @param string $exclude + * + * @return self Provides fluent interface + */ + public function removeExclude($exclude) + { + foreach ($this->facetQueries as $facetQuery) { + $facetQuery->removeExclude($exclude); + } + + return $this->excludeTagsRemoveExclude($exclude); + } + + /** + * Remove all excludes. + * + * Excludes added to the MultiQuery facet a shared by all underlying + * FacetQueries, so changes must be forwarded to any existing instances. + * + * If you don't want this use the clearExcludes method of a + * specific FacetQuery instance instead. + * + * @return self Provides fluent interface + */ + public function clearExcludes() + { + foreach ($this->facetQueries as $facetQuery) { + $facetQuery->clearExcludes(); + } + + return $this->excludeTagsClearExcludes(); + } + + /** + * Initialize options. + * + * Several options need some extra checks or setup work, for these options + * the setters are called. + */ + protected function init() + { + $this->excludeTagsInit(); + + foreach ($this->options as $name => $value) { + switch ($name) { + case 'query': + if (!is_array($value)) { + $value = [['query' => $value]]; + } + $this->addQueries($value); + break; + } + } + } +} diff --git a/vendor/solarium/solarium/src/Component/Facet/Pivot.php b/vendor/solarium/solarium/src/Component/Facet/Pivot.php new file mode 100644 index 000000000..2c9bbc4b9 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Facet/Pivot.php @@ -0,0 +1,260 @@ +setOption('mincount', $minCount); + } + + /** + * Get the facet mincount. + * + * @return int + */ + public function getMinCount() + { + return $this->getOption('mincount'); + } + + /** + * Specify a field to return in the resultset. + * + * @param string $field + * + * @return self Provides fluent interface + */ + public function addField($field) + { + $field = trim($field); + $this->fields[$field] = true; + + return $this; + } + + /** + * Specify multiple fields to return in the resultset. + * + * @param string|array $fields can be an array or string with comma + * separated fieldnames + * + * @return self Provides fluent interface + */ + public function addFields($fields) + { + if (is_string($fields)) { + $fields = explode(',', $fields); + } + + foreach ($fields as $field) { + $this->addField($field); + } + + return $this; + } + + /** + * Remove a field from the field list. + * + * @param string $field + * + * @return self Provides fluent interface + */ + public function removeField($field) + { + if (isset($this->fields[$field])) { + unset($this->fields[$field]); + } + + return $this; + } + + /** + * Remove all fields from the field list. + * + * @return self Provides fluent interface + */ + public function clearFields() + { + $this->fields = []; + + return $this; + } + + /** + * Get the list of fields. + * + * @return array + */ + public function getFields() + { + return array_keys($this->fields); + } + + /** + * Set multiple fields. + * + * This overwrites any existing fields + * + * @param array $fields + * + * @return self Provides fluent interface + */ + public function setFields($fields) + { + $this->clearFields(); + $this->addFields($fields); + + return $this; + } + + /** + * Add stat. + * + * @param string $stat + * + * @return self Provides fluent interface + */ + public function addStat($stat) + { + $this->stats[$stat] = true; + + return $this; + } + + /** + * Specify multiple Stats. + * + * @param string|array $stats can be an array or string with comma + * separated statnames + * + * @return self Provides fluent interface + */ + public function addStats($stats) + { + if (is_string($stats)) { + $stats = explode(',', $stats); + $stats = array_map('trim', $stats); + } + + foreach ($stats as $stat) { + $this->addStat($stat); + } + + return $this; + } + + /** + * Remove a stat from the stats list. + * + * @param string $stat + * + * @return self Provides fluent interface + */ + public function removeStat($stat) + { + if (isset($this->stats[$stat])) { + unset($this->stats[$stat]); + } + + return $this; + } + + /** + * Remove all stats from the stats list. + * + * @return self Provides fluent interface + */ + public function clearStats() + { + $this->stats = []; + + return $this; + } + + /** + * Get the list of stats. + * + * @return array + */ + public function getStats() + { + return array_keys($this->stats); + } + + /** + * Set multiple stats. + * + * This overwrites any existing stats + * + * @param array $stats + * + * @return self Provides fluent interface + */ + public function setStats($stats) + { + $this->clearStats(); + $this->addStats($stats); + + return $this; + } + + /** + * Initialize options. + */ + protected function init() + { + foreach ($this->options as $name => $value) { + switch ($name) { + case 'fields': + $this->addFields($value); + break; + case 'stats': + $this->setStats($value); + break; + } + } + } +} diff --git a/vendor/solarium/solarium/src/Component/Facet/Query.php b/vendor/solarium/solarium/src/Component/Facet/Query.php new file mode 100644 index 000000000..cba0c98be --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Facet/Query.php @@ -0,0 +1,48 @@ + '*:*', + ]; + + /** + * Get the facet type. + * + * @return string + */ + public function getType() + { + return FacetSetInterface::FACET_QUERY; + } + + /** + * Returns a query helper. + * + * @return \Solarium\Core\Query\Helper + */ + public function getHelper() + { + return new Helper(); + } +} diff --git a/vendor/solarium/solarium/src/Component/Facet/Range.php b/vendor/solarium/solarium/src/Component/Facet/Range.php new file mode 100644 index 000000000..ceb3475a5 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Facet/Range.php @@ -0,0 +1,61 @@ +setOption('mincount', $minCount); + } + + /** + * Get the facet mincount. + * + * @return int + */ + public function getMinCount() + { + return $this->getOption('mincount'); + } + + /** + * Initialize options. + * + * Several options need some extra checks or setup work, for these options + * the setters are called. + */ + protected function init() + { + parent::init(); + $this->excludeTagsInit(); + } +} diff --git a/vendor/solarium/solarium/src/Component/FacetSet.php b/vendor/solarium/solarium/src/Component/FacetSet.php new file mode 100644 index 000000000..263240038 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/FacetSet.php @@ -0,0 +1,407 @@ + 'Solarium\Component\Facet\Field', + FacetSetInterface::FACET_QUERY => 'Solarium\Component\Facet\Query', + FacetSetInterface::FACET_MULTIQUERY => 'Solarium\Component\Facet\MultiQuery', + FacetSetInterface::FACET_RANGE => 'Solarium\Component\Facet\Range', + FacetSetInterface::FACET_PIVOT => 'Solarium\Component\Facet\Pivot', + FacetSetInterface::FACET_INTERVAL => 'Solarium\Component\Facet\Interval', + FacetSetInterface::JSON_FACET_AGGREGATION => 'Solarium\Component\Facet\JsonAggregation', + FacetSetInterface::JSON_FACET_TERMS => 'Solarium\Component\Facet\JsonTerms', + FacetSetInterface::JSON_FACET_QUERY => 'Solarium\Component\Facet\JsonQuery', + FacetSetInterface::JSON_FACET_RANGE => 'Solarium\Component\Facet\JsonRange', + ]; + + /** + * Facets. + * + * @var FacetInterface[] + */ + protected $facets = []; + + /** + * Get component type. + * + * @return string + */ + public function getType() + { + return ComponentAwareQueryInterface::COMPONENT_FACETSET; + } + + /** + * Get a requestbuilder for this query. + * + * @return RequestBuilder + */ + public function getRequestBuilder() + { + return new RequestBuilder(); + } + + /** + * Get a response parser for this query. + * + * @return ResponseParser + */ + public function getResponseParser() + { + return new ResponseParser(); + } + + /** + * Allow extraction of facets without having to define + * them on the query. + * + * @param bool $extract + * + * @return self Provides fluent interface + */ + public function setExtractFromResponse($extract) + { + return $this->setOption('extractfromresponse', $extract); + } + + /** + * Get the extractfromresponse option value. + * + * @return bool + */ + public function getExtractFromResponse() + { + return $this->getOption('extractfromresponse'); + } + + /** + * Limit the terms for faceting by a prefix. + * + * This is a global value for all facets in this facetset + * + * @param string $prefix + * + * @return self Provides fluent interface + */ + public function setPrefix($prefix) + { + return $this->setOption('prefix', $prefix); + } + + /** + * Get the facet prefix. + * + * This is a global value for all facets in this facetset + * + * @return string + */ + public function getPrefix() + { + return $this->getOption('prefix'); + } + + /** + * Limit the terms for faceting by a string they must contain. Since Solr 5.1. + * + * This is a global value for all facets in this facetset + * + * @param string $contains + * + * @return self Provides fluent interface + */ + public function setContains($contains) + { + return $this->setOption('contains', $contains); + } + + /** + * Get the facet contains. + * + * This is a global value for all facets in this facetset + * + * @return string + */ + public function getContains() + { + return $this->getOption('contains'); + } + + /** + * Case sensitivity of matching string that facet terms must contain. Since Solr 5.1. + * + * This is a global value for all facets in this facetset + * + * @param bool $containsIgnoreCase + * + * @return self Provides fluent interface + */ + public function setContainsIgnoreCase($containsIgnoreCase) + { + return $this->setOption('containsignorecase', $containsIgnoreCase); + } + + /** + * Get the case sensitivity of facet contains. + * + * This is a global value for all facets in this facetset + * + * @return bool + */ + public function getContainsIgnoreCase() + { + return $this->getOption('containsignorecase'); + } + + /** + * Set the facet sort order. + * + * Use one of the SORT_* constants as the value + * + * This is a global value for all facets in this facetset + * + * @param string $sort + * + * @return self Provides fluent interface + */ + public function setSort($sort) + { + return $this->setOption('sort', $sort); + } + + /** + * Get the facet sort order. + * + * This is a global value for all facets in this facetset + * + * @return string + */ + public function getSort() + { + return $this->getOption('sort'); + } + + /** + * Set the facet limit. + * + * This is a global value for all facets in this facetset + * + * @param int $limit + * + * @return self Provides fluent interface + */ + public function setLimit($limit) + { + return $this->setOption('limit', $limit); + } + + /** + * Get the facet limit. + * + * This is a global value for all facets in this facetset + * + * @return string + */ + public function getLimit() + { + return $this->getOption('limit'); + } + + /** + * Set the facet mincount. + * + * This is a global value for all facets in this facetset + * + * @param int $minCount + * + * @return self Provides fluent interface + */ + public function setMinCount($minCount) + { + return $this->setOption('mincount', $minCount); + } + + /** + * Get the facet mincount. + * + * This is a global value for all facets in this facetset + * + * @return int + */ + public function getMinCount() + { + return $this->getOption('mincount'); + } + + /** + * Set the missing count option. + * + * This is a global value for all facets in this facetset + * + * @param bool $missing + * + * @return self Provides fluent interface + */ + public function setMissing($missing) + { + return $this->setOption('missing', $missing); + } + + /** + * Get the facet missing option. + * + * This is a global value for all facets in this facetset + * + * @return bool + */ + public function getMissing() + { + return $this->getOption('missing'); + } + + /** + * Get a facet field instance. + * + * @param mixed $options + * @param bool $add + * + * @return \Solarium\Component\Facet\Field + */ + public function createFacetField($options = null, $add = true) + { + return $this->createFacet(FacetSetInterface::FACET_FIELD, $options, $add); + } + + /** + * Get a facet query instance. + * + * @param mixed $options + * @param bool $add + * + * @return \Solarium\Component\Facet\Query + */ + public function createFacetQuery($options = null, $add = true) + { + return $this->createFacet(FacetSetInterface::FACET_QUERY, $options, $add); + } + + /** + * Get a facet multiquery instance. + * + * @param mixed $options + * @param bool $add + * + * @return \Solarium\Component\Facet\MultiQuery + */ + public function createFacetMultiQuery($options = null, $add = true) + { + return $this->createFacet(FacetSetInterface::FACET_MULTIQUERY, $options, $add); + } + + /** + * Get a facet range instance. + * + * @param mixed $options + * @param bool $add + * + * @return \Solarium\Component\Facet\Range + */ + public function createFacetRange($options = null, $add = true) + { + return $this->createFacet(FacetSetInterface::FACET_RANGE, $options, $add); + } + + /** + * Get a facet pivot instance. + * + * @param mixed $options + * @param bool $add + * + * @return \Solarium\Component\Facet\Pivot + */ + public function createFacetPivot($options = null, $add = true) + { + return $this->createFacet(FacetSetInterface::FACET_PIVOT, $options, $add); + } + + /** + * Get a facet interval instance. + * + * @param mixed $options + * @param bool $add + * + * @return \Solarium\Component\Facet\Interval + */ + public function createFacetInterval($options = null, $add = true) + { + return $this->createFacet(FacetSetInterface::FACET_INTERVAL, $options, $add); + } + + /** + * Get a json facet aggregation instance. + * + * @param mixed $options + * @param bool $add + * + * @return \Solarium\Component\Facet\JsonAggregation + */ + public function createJsonFacetAggregation($options = null, $add = true) + { + return $this->createFacet(FacetSetInterface::JSON_FACET_AGGREGATION, $options, $add); + } + + /** + * Get a json facet terms instance. + * + * @param mixed $options + * @param bool $add + * + * @return \Solarium\Component\Facet\JsonTerms + */ + public function createJsonFacetTerms($options = null, $add = true) + { + return $this->createFacet(FacetSetInterface::JSON_FACET_TERMS, $options, $add); + } + + /** + * Get a json facet query instance. + * + * @param mixed $options + * @param bool $add + * + * @return \Solarium\Component\Facet\JsonQuery + */ + public function createJsonFacetQuery($options = null, $add = true) + { + return $this->createFacet(FacetSetInterface::JSON_FACET_QUERY, $options, $add); + } + + /** + * Get a json facet range instance. + * + * @param mixed $options + * @param bool $add + * + * @return \Solarium\Component\Facet\JsonRange + */ + public function createJsonFacetRange($options = null, $add = true) + { + return $this->createFacet(FacetSetInterface::JSON_FACET_RANGE, $options, $add); + } +} diff --git a/vendor/solarium/solarium/src/Component/FacetSetInterface.php b/vendor/solarium/solarium/src/Component/FacetSetInterface.php new file mode 100644 index 000000000..09841808c --- /dev/null +++ b/vendor/solarium/solarium/src/Component/FacetSetInterface.php @@ -0,0 +1,147 @@ +createFacet($facet['type'], $facet, false); + } + + $key = $facet->getKey(); + + if (0 === strlen($key)) { + throw new InvalidArgumentException('A facet must have a key value'); + } + + //double add calls for the same facet are ignored, but non-unique keys cause an exception + if (array_key_exists($key, $this->facets) && $this->facets[$key] !== $facet) { + throw new InvalidArgumentException('A facet must have a unique key value within a query'); + } + + $this->facets[$key] = $facet; + + return $this; + } + + /** + * Add multiple facets. + * + * @param array $facets + * + * @return self Provides fluent interface + */ + public function addFacets(array $facets) + { + foreach ($facets as $key => $facet) { + // in case of a config array: add key to config + if (is_array($facet) && !isset($facet['key'])) { + $facet['key'] = $key; + } + + $this->addFacet($facet); + } + + return $this; + } + + /** + * Get a facet. + * + * @param string $key + * + * @return FacetInterface + */ + public function getFacet($key) + { + if (isset($this->facets[$key])) { + return $this->facets[$key]; + } + } + + /** + * Get all facets. + * + * @return FacetInterface[] + */ + public function getFacets() + { + return $this->facets; + } + + /** + * Remove a single facet. + * + * You can remove a facet by passing its key or the facet instance + * + * @param string|\Solarium\Component\Facet\FacetInterface $facet + * + * @return self Provides fluent interface + */ + public function removeFacet($facet) + { + if (is_object($facet)) { + $facet = $facet->getKey(); + } + + if (isset($this->facets[$facet])) { + unset($this->facets[$facet]); + } + + return $this; + } + + /** + * Remove all facets. + * + * @return self Provides fluent interface + */ + public function clearFacets() + { + $this->facets = []; + + return $this; + } + + /** + * Set multiple facets. + * + * This overwrites any existing facets + * + * @param array $facets + */ + public function setFacets($facets) + { + $this->clearFacets(); + $this->addFacets($facets); + } + + /** + * Create a facet instance. + * + * If you supply a string as the first arguments ($options) it will be used as the key for the facet + * and it will be added to this query. + * If you supply an options array/object that contains a key the facet will also be added to the query. + * + * When no key is supplied the facet cannot be added, in that case you will need to add it manually + * after setting the key, by using the addFacet method. + * + * + * @param string $type + * @param array|object|null $options + * @param bool $add + * + * @throws OutOfBoundsException + * + * @return \Solarium\Component\Facet\FacetInterface + */ + public function createFacet(string $type, $options = null, bool $add = true) + { + $type = strtolower($type); + + if (!isset($this->facetTypes[$type])) { + throw new OutOfBoundsException('Facettype unknown: '.$type); + } + + $class = $this->facetTypes[$type]; + + if (is_string($options)) { + /** @var FacetInterface $facet */ + $facet = new $class(); + $facet->setKey($options); + } else { + $facet = new $class($options); + } + + if ($add && null !== $facet->getKey()) { + $this->addFacet($facet); + } + + return $facet; + } + + /** + * Initialize options. + * + * Several options need some extra checks or setup work, for these options + * the setters are called. + */ + protected function init() + { + if (isset($this->options['facet'])) { + foreach ($this->options['facet'] as $key => $config) { + if (!isset($config['key'])) { + $config['key'] = $key; + } + + $this->addFacet($config); + } + } + } +} diff --git a/vendor/solarium/solarium/src/Component/Grouping.php b/vendor/solarium/solarium/src/Component/Grouping.php new file mode 100644 index 000000000..09e9e0912 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Grouping.php @@ -0,0 +1,552 @@ + 'Solarium\Component\Result\Grouping\QueryGroup', + 'resultvaluegroupclass' => 'Solarium\Component\Result\Grouping\ValueGroup', + ]; + + /** + * Fields for grouping. + * + * @var array + */ + protected $fields = []; + + /** + * Queries for grouping. + * + * @var array + */ + protected $queries = []; + + /** + * Get component type. + * + * @return string + */ + public function getType() + { + return ComponentAwareQueryInterface::COMPONENT_GROUPING; + } + + /** + * Get a requestbuilder for this query. + * + * @return RequestBuilder + */ + public function getRequestBuilder() + { + return new RequestBuilder(); + } + + /** + * Get a response parser for this query. + * + * @return ResponseParser + */ + public function getResponseParser() + { + return new ResponseParser(); + } + + /** + * Add a grouping field. + * + * Group based on the unique values of a field + * + * @param string $field + * + * @return self fluent interface + */ + public function addField($field) + { + $this->fields[] = $field; + + return $this; + } + + /** + * Add multiple grouping fields. + * + * You can use an array or a comma separated string as input + * + * @param array|string $fields + * + * @return self Provides fluent interface + */ + public function addFields($fields) + { + if (is_string($fields)) { + $fields = explode(',', $fields); + $fields = array_map('trim', $fields); + } + + $this->fields = array_merge($this->fields, $fields); + + return $this; + } + + /** + * Get all fields. + * + * @return array + */ + public function getFields() + { + return $this->fields; + } + + /** + * Remove all fields. + * + * @return self fluent interface + */ + public function clearFields() + { + $this->fields = []; + + return $this; + } + + /** + * Set multiple fields. + * + * This overwrites any existing fields + * + * @param array $fields + * + * @return self Provides fluent interface + */ + public function setFields($fields) + { + $this->clearFields(); + $this->addFields($fields); + + return $this; + } + + /** + * Add a grouping query. + * + * Group documents that match the given query + * + * @param string $query + * + * @return self fluent interface + */ + public function addQuery($query) + { + $this->queries[] = $query; + + return $this; + } + + /** + * Add multiple grouping queries. + * + * @param array|string $queries + * + * @return self Provides fluent interface + */ + public function addQueries($queries) + { + if (!is_array($queries)) { + $queries = [$queries]; + } + + $this->queries = array_merge($this->queries, $queries); + + return $this; + } + + /** + * Get all queries. + * + * @return array + */ + public function getQueries() + { + return $this->queries; + } + + /** + * Remove all queries. + * + * @return self fluent interface + */ + public function clearQueries() + { + $this->queries = []; + + return $this; + } + + /** + * Set multiple queries. + * + * This overwrites any existing queries + * + * @param array $queries + */ + public function setQueries($queries) + { + $this->clearQueries(); + $this->addQueries($queries); + } + + /** + * Set limit option. + * + * The number of results (documents) to return for each group + * + * @param int $limit + * + * @return self Provides fluent interface + */ + public function setLimit($limit) + { + return $this->setOption('limit', $limit); + } + + /** + * Get limit option. + * + * @return string|null + */ + public function getLimit() + { + return $this->getOption('limit'); + } + + /** + * Set offset option. + * + * The offset into the document list of each group. + * + * @param int $offset + * + * @return self Provides fluent interface + */ + public function setOffset($offset) + { + return $this->setOption('offset', $offset); + } + + /** + * Get offset option. + * + * @return string|null + */ + public function getOffset() + { + return $this->getOption('offset'); + } + + /** + * Set sort option. + * + * How to sort documents within a single group + * + * @param string $sort + * + * @return self Provides fluent interface + */ + public function setSort($sort) + { + return $this->setOption('sort', $sort); + } + + /** + * Get sort option. + * + * @return string|null + */ + public function getSort() + { + return $this->getOption('sort'); + } + + /** + * Set mainresult option. + * + * If true, the result of the first field grouping command is used as the main + * result list in the response, using group format 'simple' + * + * @param bool $value + * + * @return self Provides fluent interface + */ + public function setMainResult($value) + { + return $this->setOption('mainresult', $value); + } + + /** + * Get mainresult option. + * + * @return bool|null + */ + public function getMainResult() + { + return $this->getOption('mainresult'); + } + + /** + * Set numberofgroups option. + * + * If true, includes the number of groups that have matched the query. + * + * @param bool $value + * + * @return self Provides fluent interface + */ + public function setNumberOfGroups($value) + { + return $this->setOption('numberofgroups', $value); + } + + /** + * Get numberofgroups option. + * + * @return bool|null + */ + public function getNumberOfGroups() + { + return $this->getOption('numberofgroups'); + } + + /** + * Set cachepercentage option. + * + * If > 0 enables grouping cache. Grouping is executed actual two searches. + * This option caches the second search. A value of 0 disables grouping caching. + * + * Tests have shown that this cache only improves search time with boolean queries, + * wildcard queries and fuzzy queries. For simple queries like a term query or + * a match all query this cache has a negative impact on performance + * + * @param int $value + * + * @return self Provides fluent interface + */ + public function setCachePercentage($value) + { + return $this->setOption('cachepercentage', $value); + } + + /** + * Get cachepercentage option. + * + * @return int|null + */ + public function getCachePercentage() + { + return $this->getOption('cachepercentage'); + } + + /** + * Set truncate option. + * + * If true, facet counts are based on the most relevant document of each group matching the query. + * Same applies for StatsComponent. Default is false. Only available from Solr 3.4 + * + * @param bool $value + * + * @return self Provides fluent interface + */ + public function setTruncate($value) + { + return $this->setOption('truncate', $value); + } + + /** + * Get truncate option. + * + * @return bool|null + */ + public function getTruncate() + { + return $this->getOption('truncate'); + } + + /** + * Set function option. + * + * Group based on the unique values of a function query. Only available in Solr 4.0+ + * + * @param string $value + * + * @return self Provides fluent interface + */ + public function setFunction($value) + { + return $this->setOption('function', $value); + } + + /** + * Get truncate option. + * + * @return string|null + */ + public function getFunction() + { + return $this->getOption('function'); + } + + /** + * Set facet option. + * + * Whether to compute grouped facets. + * Grouped facets are computed based on the first specified group. + * This parameter only is supported on Solr 4.0+ + * + * @param bool $value + * + * @return self Provides fluent interface + */ + public function setFacet($value) + { + return $this->setOption('facet', $value); + } + + /** + * Get facet option. + * + * @return bool|null + */ + public function getFacet() + { + return $this->getOption('facet'); + } + + /** + * Set format option. + * + * If simple, the grouped documents are presented in a single flat list. + * The start and rows parameters refer to numbers of documents instead of numbers of groups. + * + * @param string $value + * + * @return self Provides fluent interface + */ + public function setFormat($value) + { + return $this->setOption('format', $value); + } + + /** + * Get format option. + * + * @return string|null + */ + public function getFormat() + { + return $this->getOption('format'); + } + + /** + * Set the query group result class. + * + * @param string $value classname + * + * @return self Provides fluent interface + */ + public function setResultQueryGroupClass($value) + { + return $this->setOption('resultquerygroupclass', $value); + } + + /** + * Get the current resultquerygroupclass option. + * + * The value is a classname, not an instance + * + * @return string + */ + public function getResultQueryGroupClass() + { + return $this->getOption('resultquerygroupclass'); + } + + /** + * Set the value group result class. + * + * @param string $value classname + * + * @return self Provides fluent interface + */ + public function setResultValueGroupClass($value) + { + return $this->setOption('resultvaluegroupclass', $value); + } + + /** + * Get the current resultvaluegroupclass option. + * + * The value is a classname, not an instance + * + * @return string + */ + public function getResultValueGroupClass() + { + return $this->getOption('resultvaluegroupclass'); + } + + /** + * Initialize options. + * + * Several options need some extra checks or setup work, for these options + * the setters are called. + */ + protected function init() + { + foreach ($this->options as $name => $value) { + switch ($name) { + case 'queries': + $this->setQueries($value); + break; + case 'fields': + $this->setFields($value); + break; + } + } + } +} diff --git a/vendor/solarium/solarium/src/Component/Highlighting/Field.php b/vendor/solarium/solarium/src/Component/Highlighting/Field.php new file mode 100644 index 000000000..73059cd4f --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Highlighting/Field.php @@ -0,0 +1,281 @@ +getOption('name'); + } + + /** + * Set name option. + * + * @param string $name + * + * @return self Provides fluent interface + */ + public function setName($name) + { + return $this->setOption('name', $name); + } + + /** + * Set snippets option. + * + * Maximum number of snippets per field + * + * @param int $maximum + * + * @return self Provides fluent interface + */ + public function setSnippets($maximum) + { + return $this->setOption('snippets', $maximum); + } + + /** + * Get snippets option. + * + * @return int|null + */ + public function getSnippets() + { + return $this->getOption('snippets'); + } + + /** + * Set fragsize option. + * + * The size, in characters, of fragments to consider for highlighting + * + * @param int $size + * + * @return self Provides fluent interface + */ + public function setFragSize($size) + { + return $this->setOption('fragsize', $size); + } + + /** + * Get fragsize option. + * + * @return int|null + */ + public function getFragSize() + { + return $this->getOption('fragsize'); + } + + /** + * Set mergeContiguous option. + * + * Collapse contiguous fragments into a single fragment + * + * @param bool $merge + * + * @return self Provides fluent interface + */ + public function setMergeContiguous($merge) + { + return $this->setOption('mergecontiguous', $merge); + } + + /** + * Get mergeContiguous option. + * + * @return bool|null + */ + public function getMergeContiguous() + { + return $this->getOption('mergecontiguous'); + } + + /** + * Set alternatefield option. + * + * @param string $field + * + * @return self Provides fluent interface + */ + public function setAlternateField($field) + { + return $this->setOption('alternatefield', $field); + } + + /** + * Get alternatefield option. + * + * @return string|null + */ + public function getAlternateField() + { + return $this->getOption('alternatefield'); + } + + /** + * Set preserveMulti option. + * + * @param bool $preservemulti + * + * @return self Provides fluent interface + */ + public function setPreserveMulti($preservemulti) + { + return $this->setOption('preservemulti', $preservemulti); + } + + /** + * Get preserveMulti option. + * + * @return bool|null + */ + public function getPreserveMulti() + { + return $this->getOption('preservemulti'); + } + + /** + * Set formatter option. + * + * @param string $formatter + * + * @return self Provides fluent interface + */ + public function setFormatter($formatter = 'simple') + { + return $this->setOption('formatter', $formatter); + } + + /** + * Get formatter option. + * + * @return string|null + */ + public function getFormatter() + { + return $this->getOption('formatter'); + } + + /** + * Set simple prefix option. + * + * Solr option h1.simple.pre + * + * @param string $prefix + * + * @return self Provides fluent interface + */ + public function setSimplePrefix($prefix) + { + return $this->setOption('simpleprefix', $prefix); + } + + /** + * Get simple prefix option. + * + * Solr option hl.simple.pre + * + * @return string|null + */ + public function getSimplePrefix() + { + return $this->getOption('simpleprefix'); + } + + /** + * Set simple postfix option. + * + * Solr option h1.simple.post + * + * @param string $postfix + * + * @return self Provides fluent interface + */ + public function setSimplePostfix($postfix) + { + return $this->setOption('simplepostfix', $postfix); + } + + /** + * Get simple postfix option. + * + * Solr option hl.simple.post + * + * @return string|null + */ + public function getSimplePostfix() + { + return $this->getOption('simplepostfix'); + } + + /** + * Set fragmenter option. + * + * Use one of the constants as value. + * + * @param string $fragmenter + * + * @return self Provides fluent interface + */ + public function setFragmenter($fragmenter) + { + return $this->setOption('fragmenter', $fragmenter); + } + + /** + * Get fragmenter option. + * + * @return string|null + */ + public function getFragmenter() + { + return $this->getOption('fragmenter'); + } + + /** + * Set useFastVectorHighlighter option. + * + * @param bool $use + * + * @return self Provides fluent interface + */ + public function setUseFastVectorHighlighter($use) + { + return $this->setOption('usefastvectorhighlighter', $use); + } + + /** + * Get useFastVectorHighlighter option. + * + * @return bool|null + */ + public function getUseFastVectorHighlighter() + { + return $this->getOption('usefastvectorhighlighter'); + } +} diff --git a/vendor/solarium/solarium/src/Component/Highlighting/Highlighting.php b/vendor/solarium/solarium/src/Component/Highlighting/Highlighting.php new file mode 100644 index 000000000..9b5145830 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Highlighting/Highlighting.php @@ -0,0 +1,900 @@ +fields[$name])) { + return $this->fields[$name]; + } elseif ($autocreate) { + $this->addField($name); + + return $this->fields[$name]; + } + } + + /** + * Add a field for highlighting. + * + * + * @param string|array|Field $field + * + * @throws InvalidArgumentException + * + * @return self Provides fluent interface + */ + public function addField($field) + { + // autocreate object for string input + if (is_string($field)) { + $field = new Field(['name' => $field]); + } elseif (is_array($field)) { + $field = new Field($field); + } + + // validate field + if (null === $field->getName()) { + throw new InvalidArgumentException( + 'To add a highlighting field it needs to have at least a "name" setting' + ); + } + + $this->fields[$field->getName()] = $field; + + return $this; + } + + /** + * Add multiple fields for highlighting. + * + * @param string|array $fields can be an array of object instances or a string with comma + * separated fieldnames + * + * @return self Provides fluent interface + */ + public function addFields($fields) + { + if (is_string($fields)) { + $fields = explode(',', $fields); + $fields = array_map('trim', $fields); + } + + foreach ($fields as $key => $field) { + // in case of a config array without key: add key to config + if (is_array($field) && !isset($field['name'])) { + $field['name'] = $key; + } + + $this->addField($field); + } + + return $this; + } + + /** + * Remove a highlighting field. + * + * @param string $field + * + * @return self Provides fluent interface + */ + public function removeField($field) + { + if (isset($this->fields[$field])) { + unset($this->fields[$field]); + } + + return $this; + } + + /** + * Remove all fields. + * + * @return self Provides fluent interface + */ + public function clearFields() + { + $this->fields = []; + + return $this; + } + + /** + * Get the list of fields. + * + * @return array + */ + public function getFields() + { + return $this->fields; + } + + /** + * Set multiple fields. + * + * This overwrites any existing fields + * + * @param array $fields + * + * @return self Provides fluent interface + */ + public function setFields($fields) + { + $this->clearFields(); + $this->addFields($fields); + + return $this; + } + + /** + * Set snippets option. + * + * Maximum number of snippets per field + * + * @param int $maximum + * + * @return self Provides fluent interface + */ + public function setSnippets($maximum) + { + return $this->setOption('snippets', $maximum); + } + + /** + * Get snippets option. + * + * @return int|null + */ + public function getSnippets() + { + return $this->getOption('snippets'); + } + + /** + * Set fragsize option. + * + * The size, in characters, of fragments to consider for highlighting + * + * @param int $size + * + * @return self Provides fluent interface + */ + public function setFragSize($size) + { + return $this->setOption('fragsize', $size); + } + + /** + * Get fragsize option. + * + * @return int|null + */ + public function getFragSize() + { + return $this->getOption('fragsize'); + } + + /** + * Set mergeContiguous option. + * + * Collapse contiguous fragments into a single fragment + * + * @param bool $merge + * + * @return self Provides fluent interface + */ + public function setMergeContiguous($merge) + { + return $this->setOption('mergecontiguous', $merge); + } + + /** + * Get mergeContiguous option. + * + * @return bool|null + */ + public function getMergeContiguous() + { + return $this->getOption('mergecontiguous'); + } + + /** + * Set requireFieldMatch option. + * + * @param bool $require + * + * @return self Provides fluent interface + */ + public function setRequireFieldMatch($require) + { + return $this->setOption('requirefieldmatch', $require); + } + + /** + * Get requireFieldMatch option. + * + * @return bool|null + */ + public function getRequireFieldMatch() + { + return $this->getOption('requirefieldmatch'); + } + + /** + * Set maxAnalyzedChars option. + * + * How many characters into a document to look for suitable snippets + * + * @param int $chars + * + * @return self Provides fluent interface + */ + public function setMaxAnalyzedChars($chars) + { + return $this->setOption('maxanalyzedchars', $chars); + } + + /** + * Get maxAnalyzedChars option. + * + * @return int|null + */ + public function getMaxAnalyzedChars() + { + return $this->getOption('maxanalyzedchars'); + } + + /** + * Set alternatefield option. + * + * @param string $field + * + * @return self Provides fluent interface + */ + public function setAlternateField($field) + { + return $this->setOption('alternatefield', $field); + } + + /** + * Get alternatefield option. + * + * @return string|null + */ + public function getAlternateField() + { + return $this->getOption('alternatefield'); + } + + /** + * Set maxAlternateFieldLength option. + * + * @param int $length + * + * @return self Provides fluent interface + */ + public function setMaxAlternateFieldLength($length) + { + return $this->setOption('maxalternatefieldlength', $length); + } + + /** + * Get maxAlternateFieldLength option. + * + * @return int|null + */ + public function getMaxAlternateFieldLength() + { + return $this->getOption('maxalternatefieldlength'); + } + + /** + * Set preserveMulti option. + * + * @param bool $preservemulti + * + * @return self Provides fluent interface + */ + public function setPreserveMulti($preservemulti) + { + return $this->setOption('preservemulti', $preservemulti); + } + + /** + * Get preserveMulti option. + * + * @return bool|null + */ + public function getPreserveMulti() + { + return $this->getOption('preservemulti'); + } + + /** + * Set formatter option. + * + * @param string $formatter + * + * @return self Provides fluent interface + */ + public function setFormatter($formatter = 'simple') + { + return $this->setOption('formatter', $formatter); + } + + /** + * Get formatter option. + * + * @return string|null + */ + public function getFormatter() + { + return $this->getOption('formatter'); + } + + /** + * Set simple prefix option. + * + * Solr option h1.simple.pre + * + * @param string $prefix + * + * @return self Provides fluent interface + */ + public function setSimplePrefix($prefix) + { + return $this->setOption('simpleprefix', $prefix); + } + + /** + * Get simple prefix option. + * + * Solr option hl.simple.pre + * + * @return string|null + */ + public function getSimplePrefix() + { + return $this->getOption('simpleprefix'); + } + + /** + * Set simple postfix option. + * + * Solr option h1.simple.post + * + * @param string $postfix + * + * @return self Provides fluent interface + */ + public function setSimplePostfix($postfix) + { + return $this->setOption('simplepostfix', $postfix); + } + + /** + * Get simple postfix option. + * + * Solr option hl.simple.post + * + * @return string|null + */ + public function getSimplePostfix() + { + return $this->getOption('simplepostfix'); + } + + /** + * Set tag prefix option. + * + * Solr option h1.tag.post + * + * @param string $prefix + * + * @return self Provides fluent interface + */ + public function setTagPrefix($prefix) + { + return $this->setOption('tagprefix', $prefix); + } + + /** + * Get tag prefix option. + * + * Solr option hl.tag.pre + * + * @return string|null + */ + public function getTagPrefix() + { + return $this->getOption('tagprefix'); + } + + /** + * Set tag postfix option. + * + * Solr option h1.tag.post + * + * @param string $postfix + * + * @return self Provides fluent interface + */ + public function setTagPostfix($postfix) + { + return $this->setOption('tagpostfix', $postfix); + } + + /** + * Get tag postfix option. + * + * Solr option hl.tag.post + * + * @return string|null + */ + public function getTagPostfix() + { + return $this->getOption('tagpostfix'); + } + + /** + * Set fragmenter option. + * + * Use one of the constants as value. + * + * @param string $fragmenter + * + * @return self Provides fluent interface + */ + public function setFragmenter($fragmenter) + { + return $this->setOption('fragmenter', $fragmenter); + } + + /** + * Get fragmenter option. + * + * @return string|null + */ + public function getFragmenter() + { + return $this->getOption('fragmenter'); + } + + /** + * Set fraglistbuilder option. + * + * @param string $builder + * + * @return self Provides fluent interface + */ + public function setFragListBuilder($builder) + { + return $this->setOption('fraglistbuilder', $builder); + } + + /** + * Get fraglistbuilder option. + * + * @return string|null + */ + public function getFragListBuilder() + { + return $this->getOption('fraglistbuilder'); + } + + /** + * Set fragmentsbuilder option. + * + * @param string $builder + * + * @return self Provides fluent interface + */ + public function setFragmentsBuilder($builder) + { + return $this->setOption('fragmentsbuilder', $builder); + } + + /** + * Get fragmentsbuilder option. + * + * @return string|null + */ + public function getFragmentsBuilder() + { + return $this->getOption('fragmentsbuilder'); + } + + /** + * Set useFastVectorHighlighter option. + * + * @param bool $use + * + * @return self Provides fluent interface + */ + public function setUseFastVectorHighlighter($use) + { + return $this->setOption('usefastvectorhighlighter', $use); + } + + /** + * Get useFastVectorHighlighter option. + * + * @return bool|null + */ + public function getUseFastVectorHighlighter() + { + return $this->getOption('usefastvectorhighlighter'); + } + + /** + * Set usePhraseHighlighter option. + * + * @param bool $use + * + * @return self Provides fluent interface + */ + public function setUsePhraseHighlighter($use) + { + return $this->setOption('usephrasehighlighter', $use); + } + + /** + * Get usePhraseHighlighter option. + * + * @return bool|null + */ + public function getUsePhraseHighlighter() + { + return $this->getOption('usephrasehighlighter'); + } + + /** + * Set HighlightMultiTerm option. + * + * @param bool $highlight + * + * @return self Provides fluent interface + */ + public function setHighlightMultiTerm($highlight) + { + return $this->setOption('highlightmultiterm', $highlight); + } + + /** + * Get HighlightMultiTerm option. + * + * @return bool|null + */ + public function getHighlightMultiTerm() + { + return $this->getOption('highlightmultiterm'); + } + + /** + * Set RegexSlop option. + * + * @param float $slop + * + * @return self Provides fluent interface + */ + public function setRegexSlop($slop) + { + return $this->setOption('regexslop', $slop); + } + + /** + * Get RegexSlop option. + * + * @return float|null + */ + public function getRegexSlop() + { + return $this->getOption('regexslop'); + } + + /** + * Set RegexPattern option. + * + * @param string $pattern + * + * @return self Provides fluent interface + */ + public function setRegexPattern($pattern) + { + return $this->setOption('regexpattern', $pattern); + } + + /** + * Get RegexPattern option. + * + * @return string|null + */ + public function getRegexPattern() + { + return $this->getOption('regexpattern'); + } + + /** + * Set RegexMaxAnalyzedChars option. + * + * @param int $chars + * + * @return self Provides fluent interface + */ + public function setRegexMaxAnalyzedChars($chars) + { + return $this->setOption('regexmaxanalyzedchars', $chars); + } + + /** + * Get RegexMaxAnalyzedChars option. + * + * @return int|null + */ + public function getRegexMaxAnalyzedChars() + { + return $this->getOption('regexmaxanalyzedchars'); + } + + /** + * Set phraselimit option. + * + * @param int $maximum + * + * @return self Provides fluent interface + */ + public function setPhraseLimit($maximum) + { + return $this->setOption('phraselimit', $maximum); + } + + /** + * Get phraselimit option. + * + * @return int|null + */ + public function getPhraseLimit() + { + return $this->getOption('phraselimit'); + } + + /** + * Set MultiValuedSeparatorChar option. + * + * @param string $separator + * + * @return self Provides fluent interface + */ + public function setMultiValuedSeparatorChar($separator) + { + return $this->setOption('multivaluedseparatorchar', $separator); + } + + /** + * Get MultiValuedSeparatorChar option. + * + * @return string + */ + public function getMultiValuedSeparatorChar() + { + return $this->getOption('multivaluedseparatorchar'); + } + + /** + * Set boundaryscannermaxscan option. + * + * @param int $maximum + * + * @return self Provides fluent interface + */ + public function setBoundaryScannerMaxScan($maximum) + { + return $this->setOption('boundaryscannermaxscan', $maximum); + } + + /** + * Get boundaryscannermaxscan option. + * + * @return int|null + */ + public function getBoundaryScannerMaxScan() + { + return $this->getOption('boundaryscannermaxscan'); + } + + /** + * Set boundaryscannerchars option. + * + * @param string $chars + * + * @return self Provides fluent interface + */ + public function setBoundaryScannerChars($chars) + { + return $this->setOption('boundaryscannerchars', $chars); + } + + /** + * Get boundaryscannerchars option. + * + * @return string|null + */ + public function getBoundaryScannerChars() + { + return $this->getOption('boundaryscannerchars'); + } + + /** + * Set boundaryscannertype option. + * + * @param string $type + * + * @return self Provides fluent interface + */ + public function setBoundaryScannerType($type) + { + return $this->setOption('boundaryscannertype', $type); + } + + /** + * Get boundaryscannertype option. + * + * @return string|null + */ + public function getBoundaryScannerType() + { + return $this->getOption('boundaryscannertype'); + } + + /** + * Set boundaryscannerlanguage option. + * + * @param string $language + * + * @return self Provides fluent interface + */ + public function setBoundaryScannerLanguage($language) + { + return $this->setOption('boundaryscannerlanguage', $language); + } + + /** + * Get boundaryscannerlanguage option. + * + * @return string|null + */ + public function getBoundaryScannerLanguage() + { + return $this->getOption('boundaryscannerlanguage'); + } + + /** + * Set boundaryscannercountry option. + * + * @param string $country + * + * @return self Provides fluent interface + */ + public function setBoundaryScannerCountry($country) + { + return $this->setOption('boundaryscannercountry', $country); + } + + /** + * Get boundaryscannercountry option. + * + * @return string|null + */ + public function getBoundaryScannerCountry() + { + return $this->getOption('boundaryscannercountry'); + } + + /** + * Initialize options. + * + * The field option needs setup work + */ + protected function init() + { + foreach ($this->options as $name => $value) { + switch ($name) { + case 'field': + $this->addFields($value); + break; + } + } + } +} diff --git a/vendor/solarium/solarium/src/Component/MoreLikeThis.php b/vendor/solarium/solarium/src/Component/MoreLikeThis.php new file mode 100644 index 000000000..871558795 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/MoreLikeThis.php @@ -0,0 +1,314 @@ +setOption('fields', $fields); + } + + /** + * Get fields option. + * + * @return array + */ + public function getFields() + { + $fields = $this->getOption('fields'); + if (null === $fields) { + $fields = []; + } + + return $fields; + } + + /** + * Set minimumtermfrequency option. + * + * Minimum Term Frequency - the frequency below which terms will be ignored + * in the source doc. + * + * @param int $minimum + * + * @return self Provides fluent interface + */ + public function setMinimumTermFrequency($minimum) + { + return $this->setOption('minimumtermfrequency', $minimum); + } + + /** + * Get minimumtermfrequency option. + * + * @return int|null + */ + public function getMinimumTermFrequency() + { + return $this->getOption('minimumtermfrequency'); + } + + /** + * Set minimumdocumentfrequency option. + * + * Minimum Document Frequency - the frequency at which words will be + * ignored which do not occur in at least this many docs. + * + * @param int $minimum + * + * @return self Provides fluent interface + */ + public function setMinimumDocumentFrequency($minimum) + { + return $this->setOption('minimumdocumentfrequency', $minimum); + } + + /** + * Get minimumdocumentfrequency option. + * + * @return int|null + */ + public function getMinimumDocumentFrequency() + { + return $this->getOption('minimumdocumentfrequency'); + } + + /** + * Set minimumwordlength option. + * + * Minimum word length below which words will be ignored. + * + * @param int $minimum + * + * @return self Provides fluent interface + */ + public function setMinimumWordLength($minimum) + { + return $this->setOption('minimumwordlength', $minimum); + } + + /** + * Get minimumwordlength option. + * + * @return int|null + */ + public function getMinimumWordLength() + { + return $this->getOption('minimumwordlength'); + } + + /** + * Set maximumwordlength option. + * + * Maximum word length above which words will be ignored. + * + * @param int $maximum + * + * @return self Provides fluent interface + */ + public function setMaximumWordLength($maximum) + { + return $this->setOption('maximumwordlength', $maximum); + } + + /** + * Get maximumwordlength option. + * + * @return int|null + */ + public function getMaximumWordLength() + { + return $this->getOption('maximumwordlength'); + } + + /** + * Set maximumqueryterms option. + * + * Maximum number of query terms that will be included in any generated + * query. + * + * @param int $maximum + * + * @return self Provides fluent interface + */ + public function setMaximumQueryTerms($maximum) + { + return $this->setOption('maximumqueryterms', $maximum); + } + + /** + * Get maximumqueryterms option. + * + * @return int|null + */ + public function getMaximumQueryTerms() + { + return $this->getOption('maximumqueryterms'); + } + + /** + * Set maximumnumberoftokens option. + * + * Maximum number of tokens to parse in each example doc field that is not + * stored with TermVector support. + * + * @param int $maximum + * + * @return self Provides fluent interface + */ + public function setMaximumNumberOfTokens($maximum) + { + return $this->setOption('maximumnumberoftokens', $maximum); + } + + /** + * Get maximumnumberoftokens option. + * + * @return int|null + */ + public function getMaximumNumberOfTokens() + { + return $this->getOption('maximumnumberoftokens'); + } + + /** + * Set boost option. + * + * If true the query will be boosted by the interesting term relevance. + * + * @param bool $boost + * + * @return self Provides fluent interface + */ + public function setBoost($boost) + { + return $this->setOption('boost', $boost); + } + + /** + * Get boost option. + * + * @return bool|null + */ + public function getBoost() + { + return $this->getOption('boost'); + } + + /** + * Set queryfields option. + * + * Query fields and their boosts using the same format as that used in + * DisMaxQParserPlugin. These fields must also be specified in fields. + * + * When using string input you can separate multiple fields with commas. + * + * @param string $queryFields + * + * @return self Provides fluent interface + */ + public function setQueryFields($queryFields) + { + if (is_string($queryFields)) { + $queryFields = explode(',', $queryFields); + $queryFields = array_map('trim', $queryFields); + } + + return $this->setOption('queryfields', $queryFields); + } + + /** + * Get queryfields option. + * + * @return array + */ + public function getQueryFields() + { + $queryfields = $this->getOption('queryfields'); + if (null === $queryfields) { + $queryfields = []; + } + + return $queryfields; + } + + /** + * Set count option. + * + * The number of similar documents to return for each result + * + * @param int $count + * + * @return self Provides fluent interface + */ + public function setCount($count) + { + return $this->setOption('count', $count); + } + + /** + * Get count option. + * + * @return int|null + */ + public function getCount() + { + return $this->getOption('count'); + } +} diff --git a/vendor/solarium/solarium/src/Component/QueryElevation.php b/vendor/solarium/solarium/src/Component/QueryElevation.php new file mode 100644 index 000000000..d2a7286c8 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/QueryElevation.php @@ -0,0 +1,315 @@ + '[elevated]', + ]; + + /** + * Document transformers. + * + * @var array + */ + protected $transformers = []; + + /** + * Get component type. + * + * @return string + */ + public function getType() + { + return ComponentAwareQueryInterface::COMPONENT_QUERYELEVATION; + } + + /** + * Get a requestbuilder for this query. + * + * @return RequestBuilder + */ + public function getRequestBuilder() + { + return new RequestBuilder(); + } + + /** + * Add a document transformer. + * + * @param string $transformer + * + * @return self fluent interface + */ + public function addTransformer($transformer) + { + $this->transformers[$transformer] = true; + + return $this; + } + + /** + * Add multiple document transformers. + * + * You can use an array or a comma separated string as input + * + * @param array|string $transformers + * + * @return self Provides fluent interface + */ + public function addTransformers($transformers) + { + if (is_string($transformers)) { + $transformers = explode(',', $transformers); + $transformers = array_map('trim', $transformers); + } + + foreach ($transformers as $transformer) { + $this->addTransformer($transformer); + } + + return $this; + } + + /** + * Remove a document transformer. + * + * @param string $transformer + * + * @return self Provides fluent interface + */ + public function removeTransformer($transformer) + { + if (isset($this->transformers[$transformer])) { + unset($this->transformers[$transformer]); + } + + return $this; + } + + /** + * Remove all document transformers. + * + * @return self fluent interface + */ + public function clearTransformers() + { + $this->transformers = []; + + return $this; + } + + /** + * Get all document transformers. + * + * @return array + */ + public function getTransformers() + { + return array_keys($this->transformers); + } + + /** + * Set multiple document transformers. + * + * This overwrites any existing transformers + * + * @param array|string $transformers + * + * @return self Provides fluent interface + */ + public function setTransformers($transformers) + { + $this->clearTransformers(); + $this->addTransformers($transformers); + + return $this; + } + + /** + * Set enable elevation. + * + * @param bool $enable + * + * @return self Provides fluent interface + */ + public function setEnableElevation($enable) + { + return $this->setOption('enableElevation', $enable); + } + + /** + * Get enable elevation. + * + * @return bool + */ + public function getEnableElevation() + { + return $this->getOption('enableElevation'); + } + + /** + * Set force elevation. + * + * @param bool $force + * + * @return self Provides fluent interface + */ + public function setForceElevation($force) + { + return $this->setOption('forceElevation', $force); + } + + /** + * Get force elevation. + * + * @return bool + */ + public function getForceElevation() + { + return $this->getOption('forceElevation'); + } + + /** + * Set exclusive. + * + * @param bool $exclusive + * + * @return self Provides fluent interface + */ + public function setExclusive($exclusive) + { + return $this->setOption('exclusive', $exclusive); + } + + /** + * Get exclusive. + * + * @return bool + */ + public function getExclusive() + { + return $this->getOption('exclusive'); + } + + /** + * Set mark excludes. + * + * @param bool $mark + * + * @return self Provides fluent interface + */ + public function setMarkExcludes($mark) + { + if (true === $mark || 'true' === $mark) { + $this->addTransformer('[excluded]'); + } else { + $this->removeTransformer('[excluded]'); + } + + return $this->setOption('markExcludes', $mark); + } + + /** + * Get mark excludes. + * + * @return bool + */ + public function getMarkExcludes() + { + return $this->getOption('markExcludes'); + } + + /** + * Set elevated document ids. + * + * @param string|array $ids can be an array or string with comma separated ids + * + * @return self Provides fluent interface + */ + public function setElevateIds($ids) + { + if (is_string($ids)) { + $ids = explode(',', $ids); + $ids = array_map('trim', $ids); + } + + return $this->setOption('elevateIds', $ids); + } + + /** + * Get elevated document ids. + * + * @return null|array + */ + public function getElevateIds() + { + return $this->getOption('elevateIds'); + } + + /** + * Set excluded document ids. + * + * @param string|array $ids can be an array or string with comma separated ids + * + * @return self Provides fluent interface + */ + public function setExcludeIds($ids) + { + if (is_string($ids)) { + $ids = explode(',', $ids); + $ids = array_map('trim', $ids); + } + + return $this->setOption('excludeIds', $ids); + } + + /** + * Get excluded document ids. + * + * @return null|array + */ + public function getExcludeIds() + { + return $this->getOption('excludeIds'); + } + + /** + * Initialize options. + * + * Several options need some extra checks or setup work, for these options + * the setters are called. + */ + protected function init() + { + foreach ($this->options as $name => $value) { + switch ($name) { + case 'transformers': + $this->setTransformers($value); + break; + case 'markExcludes': + $this->setMarkExcludes($value); + break; + case 'elevateIds': + $this->setElevateIds($value); + break; + case 'excludeIds': + $this->setExcludeIds($value); + break; + } + } + } +} diff --git a/vendor/solarium/solarium/src/Component/QueryInterface.php b/vendor/solarium/solarium/src/Component/QueryInterface.php new file mode 100644 index 000000000..da89429f8 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/QueryInterface.php @@ -0,0 +1,28 @@ +getHelper(); + $query = $helper->assemble($query, $bind); + } + + return $this->setOption('query', trim($query)); + } + + /** + * Get query option. + * + * @return string|null + */ + public function getQuery() + { + return $this->getOption('query'); + } +} diff --git a/vendor/solarium/solarium/src/Component/QueryTraits/DebugTrait.php b/vendor/solarium/solarium/src/Component/QueryTraits/DebugTrait.php new file mode 100644 index 000000000..5fbbe3b51 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/QueryTraits/DebugTrait.php @@ -0,0 +1,23 @@ +getComponent(ComponentAwareQueryInterface::COMPONENT_DEBUG, true); + } +} diff --git a/vendor/solarium/solarium/src/Component/QueryTraits/DisMaxTrait.php b/vendor/solarium/solarium/src/Component/QueryTraits/DisMaxTrait.php new file mode 100644 index 000000000..1f35af031 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/QueryTraits/DisMaxTrait.php @@ -0,0 +1,23 @@ +getComponent(ComponentAwareQueryInterface::COMPONENT_DISMAX, true); + } +} diff --git a/vendor/solarium/solarium/src/Component/QueryTraits/DistributedSearchTrait.php b/vendor/solarium/solarium/src/Component/QueryTraits/DistributedSearchTrait.php new file mode 100644 index 000000000..106e7cad0 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/QueryTraits/DistributedSearchTrait.php @@ -0,0 +1,23 @@ +getComponent(ComponentAwareQueryInterface::COMPONENT_DISTRIBUTEDSEARCH, true); + } +} diff --git a/vendor/solarium/solarium/src/Component/QueryTraits/EDisMaxTrait.php b/vendor/solarium/solarium/src/Component/QueryTraits/EDisMaxTrait.php new file mode 100644 index 000000000..34fbdc750 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/QueryTraits/EDisMaxTrait.php @@ -0,0 +1,23 @@ +getComponent(ComponentAwareQueryInterface::COMPONENT_EDISMAX, true); + } +} diff --git a/vendor/solarium/solarium/src/Component/QueryTraits/FacetSetTrait.php b/vendor/solarium/solarium/src/Component/QueryTraits/FacetSetTrait.php new file mode 100644 index 000000000..3c364d15e --- /dev/null +++ b/vendor/solarium/solarium/src/Component/QueryTraits/FacetSetTrait.php @@ -0,0 +1,23 @@ +getComponent(ComponentAwareQueryInterface::COMPONENT_FACETSET, true); + } +} diff --git a/vendor/solarium/solarium/src/Component/QueryTraits/GroupingTrait.php b/vendor/solarium/solarium/src/Component/QueryTraits/GroupingTrait.php new file mode 100644 index 000000000..d5de39e54 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/QueryTraits/GroupingTrait.php @@ -0,0 +1,23 @@ +getComponent(ComponentAwareQueryInterface::COMPONENT_GROUPING, true); + } +} diff --git a/vendor/solarium/solarium/src/Component/QueryTraits/HighlightingTrait.php b/vendor/solarium/solarium/src/Component/QueryTraits/HighlightingTrait.php new file mode 100644 index 000000000..6c3876d14 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/QueryTraits/HighlightingTrait.php @@ -0,0 +1,23 @@ +getComponent(ComponentAwareQueryInterface::COMPONENT_HIGHLIGHTING, true); + } +} diff --git a/vendor/solarium/solarium/src/Component/QueryTraits/MoreLikeThisTrait.php b/vendor/solarium/solarium/src/Component/QueryTraits/MoreLikeThisTrait.php new file mode 100644 index 000000000..3f05d4db9 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/QueryTraits/MoreLikeThisTrait.php @@ -0,0 +1,23 @@ +getComponent(ComponentAwareQueryInterface::COMPONENT_MORELIKETHIS, true); + } +} diff --git a/vendor/solarium/solarium/src/Component/QueryTraits/QueryElevationTrait.php b/vendor/solarium/solarium/src/Component/QueryTraits/QueryElevationTrait.php new file mode 100644 index 000000000..5fd0c215a --- /dev/null +++ b/vendor/solarium/solarium/src/Component/QueryTraits/QueryElevationTrait.php @@ -0,0 +1,23 @@ +getComponent(ComponentAwareQueryInterface::COMPONENT_QUERYELEVATION, true); + } +} diff --git a/vendor/solarium/solarium/src/Component/QueryTraits/ReRankQueryTrait.php b/vendor/solarium/solarium/src/Component/QueryTraits/ReRankQueryTrait.php new file mode 100644 index 000000000..bf89a201a --- /dev/null +++ b/vendor/solarium/solarium/src/Component/QueryTraits/ReRankQueryTrait.php @@ -0,0 +1,23 @@ +getComponent(ComponentAwareQueryInterface::COMPONENT_RERANKQUERY, true); + } +} diff --git a/vendor/solarium/solarium/src/Component/QueryTraits/SpatialTrait.php b/vendor/solarium/solarium/src/Component/QueryTraits/SpatialTrait.php new file mode 100644 index 000000000..80eefd6de --- /dev/null +++ b/vendor/solarium/solarium/src/Component/QueryTraits/SpatialTrait.php @@ -0,0 +1,23 @@ +getComponent(ComponentAwareQueryInterface::COMPONENT_SPATIAL, true); + } +} diff --git a/vendor/solarium/solarium/src/Component/QueryTraits/SpellcheckTrait.php b/vendor/solarium/solarium/src/Component/QueryTraits/SpellcheckTrait.php new file mode 100644 index 000000000..90cf825b9 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/QueryTraits/SpellcheckTrait.php @@ -0,0 +1,23 @@ +getComponent(ComponentAwareQueryInterface::COMPONENT_SPELLCHECK, true); + } +} diff --git a/vendor/solarium/solarium/src/Component/QueryTraits/StatsTrait.php b/vendor/solarium/solarium/src/Component/QueryTraits/StatsTrait.php new file mode 100644 index 000000000..3eebb176b --- /dev/null +++ b/vendor/solarium/solarium/src/Component/QueryTraits/StatsTrait.php @@ -0,0 +1,23 @@ +getComponent(ComponentAwareQueryInterface::COMPONENT_STATS, true); + } +} diff --git a/vendor/solarium/solarium/src/Component/QueryTraits/SuggesterTrait.php b/vendor/solarium/solarium/src/Component/QueryTraits/SuggesterTrait.php new file mode 100644 index 000000000..97af8cc34 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/QueryTraits/SuggesterTrait.php @@ -0,0 +1,23 @@ +getComponent(ComponentAwareQueryInterface::COMPONENT_SUGGESTER, true); + } +} diff --git a/vendor/solarium/solarium/src/Component/QueryTraits/TermsTrait.php b/vendor/solarium/solarium/src/Component/QueryTraits/TermsTrait.php new file mode 100644 index 000000000..93e710ba2 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/QueryTraits/TermsTrait.php @@ -0,0 +1,23 @@ +getComponent(ComponentAwareQueryInterface::COMPONENT_TERMS, true); + } +} diff --git a/vendor/solarium/solarium/src/Component/ReRankQuery.php b/vendor/solarium/solarium/src/Component/ReRankQuery.php new file mode 100644 index 000000000..a391a772e --- /dev/null +++ b/vendor/solarium/solarium/src/Component/ReRankQuery.php @@ -0,0 +1,79 @@ +getOption('docs'); + } + + /** + * Set reRankDocs value. + * + * @param int $value + * + * @return self Provides fluent interface + */ + public function setDocs(int $value) + { + return $this->setOption('docs', $value); + } + + /** + * Get reRankWeight value. + * + * @return float + */ + public function getWeight() + { + return $this->getOption('weight'); + } + + /** + * Set reRankWeight value. + * + * @param float $value + * + * @return self Provides fluent interface + */ + public function setWeight(float $value) + { + return $this->setOption('weight', $value); + } +} diff --git a/vendor/solarium/solarium/src/Component/RequestBuilder/ComponentRequestBuilderInterface.php b/vendor/solarium/solarium/src/Component/RequestBuilder/ComponentRequestBuilderInterface.php new file mode 100644 index 000000000..f344d74f0 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/RequestBuilder/ComponentRequestBuilderInterface.php @@ -0,0 +1,22 @@ +addParam('debugQuery', 'true'); + $request->addParam('debug.explain.structured', 'true'); + $request->addParam('explainOther', $component->getExplainOther()); + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/Component/RequestBuilder/DisMax.php b/vendor/solarium/solarium/src/Component/RequestBuilder/DisMax.php new file mode 100644 index 000000000..b08fe8637 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/RequestBuilder/DisMax.php @@ -0,0 +1,46 @@ +addParam('defType', $component->getQueryParser()); + + $request->addParam('q.alt', $component->getQueryAlternative()); + $request->addParam('qf', $component->getQueryFields()); + $request->addParam('mm', $component->getMinimumMatch()); + $request->addParam('pf', $component->getPhraseFields()); + $request->addParam('ps', $component->getPhraseSlop()); + $request->addParam('qs', $component->getQueryPhraseSlop()); + $request->addParam('tie', $component->getTie()); + + // add boostqueries to request + $boostQueries = $component->getBoostQueries(); + if (0 !== count($boostQueries)) { + foreach ($boostQueries as $boostQuery) { + $request->addParam('bq', $boostQuery->getQuery()); + } + } + + $request->addParam('bf', $component->getBoostFunctions()); + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/Component/RequestBuilder/DistributedSearch.php b/vendor/solarium/solarium/src/Component/RequestBuilder/DistributedSearch.php new file mode 100644 index 000000000..2f714b2ca --- /dev/null +++ b/vendor/solarium/solarium/src/Component/RequestBuilder/DistributedSearch.php @@ -0,0 +1,47 @@ +getShards()); + if (count($shards)) { + $request->addParam('shards', implode(',', $shards)); + } + + $replicas = array_values($component->getReplicas()); + + if (count($replicas)) { + $value = ($request->getParam('shards')) ? $request->getParam('shards').','.implode('|', $replicas) : implode('|', $replicas); + + $request->addParam('shards', $value, true); + } + + $request->addParam('shards.qt', $component->getShardRequestHandler()); + + // add collections to request + $collections = array_values($component->getCollections()); + if (count($collections)) { + $request->addParam('collection', implode(',', $collections)); + } + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/Component/RequestBuilder/EdisMax.php b/vendor/solarium/solarium/src/Component/RequestBuilder/EdisMax.php new file mode 100644 index 000000000..fa70104a4 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/RequestBuilder/EdisMax.php @@ -0,0 +1,52 @@ +addParam('defType', $component->getQueryParser()); + + $request->addParam('q.alt', $component->getQueryAlternative()); + $request->addParam('qf', $component->getQueryFields()); + $request->addParam('mm', $component->getMinimumMatch()); + $request->addParam('pf', $component->getPhraseFields()); + $request->addParam('ps', $component->getPhraseSlop()); + $request->addParam('pf2', $component->getPhraseBigramFields()); + $request->addParam('ps2', $component->getPhraseBigramSlop()); + $request->addParam('pf3', $component->getPhraseTrigramFields()); + $request->addParam('ps3', $component->getPhraseTrigramSlop()); + $request->addParam('qs', $component->getQueryPhraseSlop()); + $request->addParam('tie', $component->getTie()); + + // add boostqueries to request + $boostQueries = $component->getBoostQueries(); + if (0 !== count($boostQueries)) { + foreach ($boostQueries as $boostQuery) { + $request->addParam('bq', $boostQuery->getQuery()); + } + } + + $request->addParam('bf', $component->getBoostFunctions()); + $request->addParam('boost', $component->getBoostFunctionsMult()); + $request->addParam('uf', $component->getUserFields()); + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/Component/RequestBuilder/FacetSet.php b/vendor/solarium/solarium/src/Component/RequestBuilder/FacetSet.php new file mode 100644 index 000000000..50f9579db --- /dev/null +++ b/vendor/solarium/solarium/src/Component/RequestBuilder/FacetSet.php @@ -0,0 +1,280 @@ +getFacets(); + if (0 !== count($facets)) { + $non_json = false; + $json_facets = []; + + // create a list of facet fields + // 1) filter for FACET_FIELD + // 2) get field name + // 3) count occurence + $facet_fields = array_count_values(array_map(function ($value) { + return $value->getField(); + }, array_filter($facets, function ($value) { + return FacetSetInterface::FACET_FIELD == $value->getType(); + }))); + foreach ($facets as $key => $facet) { + switch ($facet->getType()) { + case FacetSetInterface::FACET_FIELD: + /* @var FacetField $facet */ + $this->addFacetField($request, $facet, (1 < $facet_fields[$facet->getField()])); + $non_json = true; + break; + case FacetSetInterface::FACET_QUERY: + /* @var FacetQuery $facet */ + $this->addFacetQuery($request, $facet); + $non_json = true; + break; + case FacetSetInterface::FACET_MULTIQUERY: + /* @var FacetMultiQuery $facet */ + $this->addFacetMultiQuery($request, $facet); + $non_json = true; + break; + case FacetSetInterface::FACET_RANGE: + /* @var FacetRange $facet */ + $this->addFacetRange($request, $facet); + $non_json = true; + break; + case FacetSetInterface::FACET_PIVOT: + /* @var FacetPivot $facet */ + $this->addFacetPivot($request, $facet); + $non_json = true; + break; + case FacetSetInterface::FACET_INTERVAL: + /* @var FacetInterval $facet */ + $this->addFacetInterval($request, $facet); + $non_json = true; + break; + case FacetSetInterface::JSON_FACET_TERMS: + case FacetSetInterface::JSON_FACET_QUERY: + case FacetSetInterface::JSON_FACET_RANGE: + case FacetSetInterface::JSON_FACET_AGGREGATION: + /* @var JsonFacetInterface $facet */ + $json_facets[$key] = $facet->serialize(); + break; + default: + throw new UnexpectedValueException('Unknown facet type'); + } + } + + if ($non_json) { + // enable non-json faceting + $request->addParam('facet', 'true'); + + // global facet params + $request->addParam('facet.sort', $component->getSort()); + $request->addParam('facet.prefix', $component->getPrefix()); + $request->addParam('facet.contains', $component->getContains()); + $request->addParam('facet.contains.ignoreCase', null === ($ignoreCase = $component->getContainsIgnoreCase()) ? null : ($ignoreCase ? 'true' : 'false')); + $request->addParam('facet.missing', $component->getMissing()); + $request->addParam('facet.mincount', $component->getMinCount()); + $request->addParam('facet.limit', $component->getLimit()); + } + + if ($json_facets) { + $request->addParam('json.facet', json_encode($json_facets)); + } + } + + return $request; + } + + /** + * Add params for a field facet to request. + * + * @param Request $request + * @param FacetField $facet + * @param use_local_params $use_local_params TRUE, if local params instead of global field params should be used. Must be set if the same field is used in different facets. Default is keeping the global field params (https://issues.apache.org/jira/browse/SOLR-6193) + */ + public function addFacetField($request, $facet, $use_local_params = false) + { + $field = $facet->getField(); + + if ($use_local_params) { + $local_params = ['key' => $facet->getKey(), + 'ex' => $facet->getExcludes(), + 'facet.limit' => $facet->getLimit(), + 'facet.sort' => $facet->getSort(), + 'facet.prefix' => $facet->getPrefix(), + 'facet.contains' => $facet->getContains(), + 'facet.contains.ignoreCase' => $facet->getContainsIgnoreCase(), + 'facet.offset' => $facet->getOffset(), + 'facet.mincount' => $facet->getMinCount(), + 'facet.missing' => $facet->getMissing(), + 'facet.method' => $facet->getMethod(), + ]; + } else { + $local_params = ['key' => $facet->getKey(), 'ex' => $facet->getExcludes()]; + } + $request->addParam( + 'facet.field', + $this->renderLocalParams( + $field, + $local_params + ) + ); + if (!$use_local_params) { + $request->addParam("f.$field.facet.limit", $facet->getLimit()); + $request->addParam("f.$field.facet.sort", $facet->getSort()); + $request->addParam("f.$field.facet.prefix", $facet->getPrefix()); + $request->addParam("f.$field.facet.contains", $facet->getContains()); + $request->addParam("f.$field.facet.contains.ignoreCase", $facet->getContainsIgnoreCase()); + $request->addParam("f.$field.facet.offset", $facet->getOffset()); + $request->addParam("f.$field.facet.mincount", $facet->getMinCount()); + $request->addParam("f.$field.facet.missing", $facet->getMissing()); + $request->addParam("f.$field.facet.method", $facet->getMethod()); + } + } + + /** + * Add params for a facet query to request. + * + * @param Request $request + * @param FacetQuery $facet + */ + public function addFacetQuery($request, $facet) + { + $request->addParam( + 'facet.query', + $this->renderLocalParams( + $facet->getQuery(), + ['key' => $facet->getKey(), 'ex' => $facet->getExcludes()] + ) + ); + } + + /** + * Add params for a multiquery facet to request. + * + * @param Request $request + * @param FacetMultiQuery $facet + */ + public function addFacetMultiQuery($request, $facet) + { + foreach ($facet->getQueries() as $facetQuery) { + $this->addFacetQuery($request, $facetQuery); + } + } + + /** + * Add params for a range facet to request. + * + * @param Request $request + * @param FacetRange $facet + */ + public function addFacetRange($request, $facet) + { + $field = $facet->getField(); + + $request->addParam( + 'facet.range', + $this->renderLocalParams( + $field, + ['key' => $facet->getKey(), 'ex' => $facet->getExcludes()] + ) + ); + + $request->addParam("f.$field.facet.range.start", $facet->getStart()); + $request->addParam("f.$field.facet.range.end", $facet->getEnd()); + $request->addParam("f.$field.facet.range.gap", $facet->getGap()); + $request->addParam("f.$field.facet.range.hardend", $facet->getHardend()); + $request->addParam("f.$field.facet.mincount", $facet->getMinCount()); + + foreach ($facet->getOther() as $otherValue) { + $request->addParam("f.$field.facet.range.other", $otherValue); + } + + foreach ($facet->getInclude() as $includeValue) { + $request->addParam("f.$field.facet.range.include", $includeValue); + } + } + + /** + * Add params for a range facet to request. + * + * @param Request $request + * @param FacetPivot $facet + */ + public function addFacetPivot($request, $facet) + { + $stats = $facet->getStats(); + + if (count($stats) > 0) { + $key = ['stats' => implode('', $stats)]; + + // when specifying stats, solr sets the field as key + $facet->setKey(implode(',', $facet->getFields())); + } else { + $key = ['key' => $facet->getKey()]; + } + + $request->addParam( + 'facet.pivot', + $this->renderLocalParams( + implode(',', $facet->getFields()), + array_merge($key, ['ex' => $facet->getExcludes()]) + ) + ); + $request->addParam('facet.pivot.mincount', $facet->getMinCount(), true); + } + + /** + * Add params for a interval facet to request. + * + * @param Request $request + * @param FacetInterval $facet + */ + public function addFacetInterval($request, $facet) + { + $field = $facet->getField(); + + $request->addParam( + 'facet.interval', + $this->renderLocalParams( + $field, + ['key' => $facet->getKey(), 'ex' => $facet->getExcludes()] + ) + ); + + foreach ($facet->getSet() as $key => $setValue) { + if (is_string($key)) { + $setValue = '{!key="'.$key.'"}'.$setValue; + } + $request->addParam("f.$field.facet.interval.set", $setValue); + } + } +} diff --git a/vendor/solarium/solarium/src/Component/RequestBuilder/Grouping.php b/vendor/solarium/solarium/src/Component/RequestBuilder/Grouping.php new file mode 100644 index 000000000..dbe4ce556 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/RequestBuilder/Grouping.php @@ -0,0 +1,41 @@ +addParam('group', 'true'); + + $request->addParam('group.field', $component->getFields()); + $request->addParam('group.query', $component->getQueries()); + $request->addParam('group.limit', $component->getLimit()); + $request->addParam('group.offset', $component->getOffset()); + $request->addParam('group.sort', $component->getSort()); + $request->addParam('group.main', $component->getMainResult()); + $request->addParam('group.ngroups', $component->getNumberOfGroups()); + $request->addParam('group.cache.percent', $component->getCachePercentage()); + $request->addParam('group.truncate', $component->getTruncate()); + $request->addParam('group.func', $component->getFunction()); + $request->addParam('group.facet', $component->getFacet()); + $request->addParam('group.format', $component->getFormat()); + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/Component/RequestBuilder/Highlighting.php b/vendor/solarium/solarium/src/Component/RequestBuilder/Highlighting.php new file mode 100644 index 000000000..be512bd5a --- /dev/null +++ b/vendor/solarium/solarium/src/Component/RequestBuilder/Highlighting.php @@ -0,0 +1,90 @@ +addParam('hl', 'true'); + + // set global highlighting params + if (count($component->getFields()) > 0) { + $request->addParam('hl.fl', implode(',', array_keys($component->getFields()))); + } + $request->addParam('hl.snippets', $component->getSnippets()); + $request->addParam('hl.fragsize', $component->getFragSize()); + $request->addParam('hl.mergeContiguous', $component->getMergeContiguous()); + $request->addParam('hl.requireFieldMatch', $component->getRequireFieldMatch()); + $request->addParam('hl.maxAnalyzedChars', $component->getMaxAnalyzedChars()); + $request->addParam('hl.alternateField', $component->getAlternateField()); + $request->addParam('hl.maxAlternateFieldLength', $component->getMaxAlternateFieldLength()); + $request->addParam('hl.preserveMulti', $component->getPreserveMulti()); + $request->addParam('hl.formatter', $component->getFormatter()); + $request->addParam('hl.simple.pre', $component->getSimplePrefix()); + $request->addParam('hl.simple.post', $component->getSimplePostfix()); + $request->addParam('hl.tag.pre', $component->getTagPrefix()); + $request->addParam('hl.tag.post', $component->getTagPostfix()); + $request->addParam('hl.fragmenter', $component->getFragmenter()); + $request->addParam('hl.fragListBuilder', $component->getFragListBuilder()); + $request->addParam('hl.fragmentsBuilder', $component->getFragmentsBuilder()); + $request->addParam('hl.useFastVectorHighlighter', $component->getUseFastVectorHighlighter()); + $request->addParam('hl.usePhraseHighlighter', $component->getUsePhraseHighlighter()); + $request->addParam('hl.highlightMultiTerm', $component->getHighlightMultiTerm()); + $request->addParam('hl.regex.slop', $component->getRegexSlop()); + $request->addParam('hl.regex.pattern', $component->getRegexPattern()); + $request->addParam('hl.regex.maxAnalyzedChars', $component->getRegexMaxAnalyzedChars()); + $request->addParam('hl.q', $component->getQuery()); + $request->addParam('hl.phraseLimit', $component->getPhraseLimit()); + $request->addParam('hl.multiValuedSeparatorChar', $component->getMultiValuedSeparatorChar()); + $request->addParam('hl.bs.maxScan', $component->getBoundaryScannerMaxScan()); + $request->addParam('hl.bs.chars', $component->getBoundaryScannerChars()); + $request->addParam('hl.bs.type', $component->getBoundaryScannerType()); + $request->addParam('hl.bs.language', $component->getBoundaryScannerLanguage()); + $request->addParam('hl.bs.country', $component->getBoundaryScannerCountry()); + + // set per-field highlighting params + foreach ($component->getFields() as $field) { + $this->addFieldParams($field, $request); + } + + return $request; + } + + /** + * Add per-field override options to the request. + * + * @param HighlightingField $field + * @param Request $request + */ + protected function addFieldParams($field, $request) + { + $prefix = 'f.'.$field->getName().'.hl.'; + $request->addParam($prefix.'snippets', $field->getSnippets()); + $request->addParam($prefix.'fragsize', $field->getFragSize()); + $request->addParam($prefix.'mergeContiguous', $field->getMergeContiguous()); + $request->addParam($prefix.'alternateField', $field->getAlternateField()); + $request->addParam($prefix.'preserveMulti', $field->getPreserveMulti()); + $request->addParam($prefix.'formatter', $field->getFormatter()); + $request->addParam($prefix.'simple.pre', $field->getSimplePrefix()); + $request->addParam($prefix.'simple.post', $field->getSimplePostfix()); + $request->addParam($prefix.'fragmenter', $field->getFragmenter()); + $request->addParam($prefix.'useFastVectorHighlighter', $field->getUseFastVectorHighlighter()); + } +} diff --git a/vendor/solarium/solarium/src/Component/RequestBuilder/MoreLikeThis.php b/vendor/solarium/solarium/src/Component/RequestBuilder/MoreLikeThis.php new file mode 100644 index 000000000..83485aa3d --- /dev/null +++ b/vendor/solarium/solarium/src/Component/RequestBuilder/MoreLikeThis.php @@ -0,0 +1,42 @@ +addParam('mlt', 'true'); + + $request->addParam('mlt.fl', count($component->getFields()) ? implode(',', $component->getFields()) : null); + $request->addParam('mlt.mintf', $component->getMinimumTermFrequency()); + $request->addParam('mlt.mindf', $component->getMinimumDocumentFrequency()); + $request->addParam('mlt.minwl', $component->getMinimumWordLength()); + $request->addParam('mlt.maxwl', $component->getMaximumWordLength()); + $request->addParam('mlt.maxqt', $component->getMaximumQueryTerms()); + $request->addParam('mlt.maxntp', $component->getMaximumNumberOfTokens()); + $request->addParam('mlt.boost', $component->getBoost()); + $request->addParam( + 'mlt.qf', + count($component->getQueryFields()) ? $component->getQueryFields() : null + ); + $request->addParam('mlt.count', $component->getCount()); + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/Component/RequestBuilder/QueryElevation.php b/vendor/solarium/solarium/src/Component/RequestBuilder/QueryElevation.php new file mode 100644 index 000000000..d942b3fc7 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/RequestBuilder/QueryElevation.php @@ -0,0 +1,42 @@ +getTransformers())) { + $fl = $request->getParam('fl'); + $fields = implode(',', null === $fl ? $transformers : array_merge([$fl], $transformers)); + $request->addParam('fl', $fields, true); + } + + // add basic params to request + $request->addParam('enableElevation', $component->getEnableElevation()); + $request->addParam('forceElevation', $component->getForceElevation()); + $request->addParam('exclusive', $component->getExclusive()); + $request->addParam('markExcludes', $component->getMarkExcludes()); + + // add overrides for pre-configured elevations + $request->addParam('elevateIds', null === ($ids = $component->getElevateIds()) ? null : implode(',', $ids)); + $request->addParam('excludeIds', null === ($ids = $component->getExcludeIds()) ? null : implode(',', $ids)); + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/Component/RequestBuilder/ReRankQuery.php b/vendor/solarium/solarium/src/Component/RequestBuilder/ReRankQuery.php new file mode 100644 index 000000000..b0e96d014 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/RequestBuilder/ReRankQuery.php @@ -0,0 +1,32 @@ +addParam('reRankQuery', $component->getQuery()); + $subRequest->addParam('reRankDocs', $component->getDocs()); + $subRequest->addParam('reRankWeight', $component->getWeight()); + + $request->addParam('rq', $subRequest->getSubQuery()); + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/Component/RequestBuilder/RequestParamsInterface.php b/vendor/solarium/solarium/src/Component/RequestBuilder/RequestParamsInterface.php new file mode 100644 index 000000000..aded0bbdf --- /dev/null +++ b/vendor/solarium/solarium/src/Component/RequestBuilder/RequestParamsInterface.php @@ -0,0 +1,84 @@ + array('cat:1','published:1') + * + * @var array + */ + protected $params = []; + + /** + * Get a param value. + * + * @param string $key + * + * @return string|array + */ + public function getParam($key) + { + if (isset($this->params[$key])) { + return $this->params[$key]; + } + } + + /** + * Get all params. + * + * @return array + */ + public function getParams() + { + return $this->params; + } + + /** + * Set request params. + * + * @param array $params + * + * @return self Provides fluent interface + */ + public function setParams($params) + { + $this->clearParams(); + $this->addParams($params); + + return $this; + } + + /** + * Add a request param. + * + * If you add a request param that already exists the param will be converted into a multivalue param, + * unless you set the overwrite param to true. + * + * Empty params are not added to the request. If you want to empty a param disable it you should use + * remove param instead. + * + * @param string $key + * @param string|array|SubRequest $value + * @param bool $overwrite + * + * @return self Provides fluent interface + */ + public function addParam($key, $value, $overwrite = false) + { + if (null !== $value) { + if (!$overwrite && isset($this->params[$key])) { + if (!is_array($this->params[$key])) { + $this->params[$key] = [$this->params[$key]]; + } + $this->params[$key][] = $value; + } else { + // not all solr handlers support 0/1 as boolean values... + if (true === $value) { + $value = 'true'; + } elseif (false === $value) { + $value = 'false'; + } + + $this->params[$key] = $value; + } + } + + return $this; + } + + /** + * Add multiple params to the request. + * + * @param array $params + * @param bool $overwrite + * + * @return self Provides fluent interface + */ + public function addParams($params, $overwrite = false) + { + foreach ($params as $key => $value) { + $this->addParam($key, $value, $overwrite); + } + + return $this; + } + + /** + * Remove a param by key. + * + * @param string $key + * + * @return self Provides fluent interface + */ + public function removeParam($key) + { + if (isset($this->params[$key])) { + unset($this->params[$key]); + } + + return $this; + } + + /** + * Clear all request params. + * + * @return self Provides fluent interface + */ + public function clearParams() + { + $this->params = []; + + return $this; + } + + /** + * Get the query string for this request. + * + * @param string $separator + * + * @return string + */ + public function getQueryString(string $separator = '&') + { + $queryString = ''; + if (count($this->params) > 0) { + $queryString = http_build_query($this->params, null, $separator); + $queryString = preg_replace( + '/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', + '=', + $queryString + ); + } + + return $queryString; + } +} diff --git a/vendor/solarium/solarium/src/Component/RequestBuilder/Spatial.php b/vendor/solarium/solarium/src/Component/RequestBuilder/Spatial.php new file mode 100644 index 000000000..657a4abad --- /dev/null +++ b/vendor/solarium/solarium/src/Component/RequestBuilder/Spatial.php @@ -0,0 +1,29 @@ +addParam('sfield', $component->getField()); + $request->addParam('pt', $component->getPoint()); + $request->addParam('d', $component->getDistance()); + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/Component/RequestBuilder/Spellcheck.php b/vendor/solarium/solarium/src/Component/RequestBuilder/Spellcheck.php new file mode 100644 index 000000000..640515caf --- /dev/null +++ b/vendor/solarium/solarium/src/Component/RequestBuilder/Spellcheck.php @@ -0,0 +1,46 @@ +addParam('spellcheck', 'true'); + + $request->addParam('spellcheck.q', $component->getQuery()); + $request->addParam('spellcheck.build', $component->getBuild()); + $request->addParam('spellcheck.reload', $component->getReload()); + $request->addParam('spellcheck.dictionary', $component->getDictionary()); + $request->addParam('spellcheck.count', $component->getCount()); + $request->addParam('spellcheck.onlyMorePopular', $component->getOnlyMorePopular()); + $request->addParam('spellcheck.extendedResults', $component->getExtendedResults()); + $request->addParam('spellcheck.collate', $component->getCollate()); + $request->addParam('spellcheck.maxCollations', $component->getMaxCollations()); + $request->addParam('spellcheck.maxCollationTries', $component->getMaxCollationTries()); + $request->addParam('spellcheck.maxCollationEvaluations', $component->getMaxCollationEvaluations()); + $request->addParam('spellcheck.collateExtendedResults', $component->getCollateExtendedResults()); + $request->addParam('spellcheck.accuracy', $component->getAccuracy()); + + foreach ($component->getCollateParams() as $param => $value) { + $request->addParam('spellcheck.collateParam.'.$param, $value); + } + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/Component/RequestBuilder/Stats.php b/vendor/solarium/solarium/src/Component/RequestBuilder/Stats.php new file mode 100644 index 000000000..90811169b --- /dev/null +++ b/vendor/solarium/solarium/src/Component/RequestBuilder/Stats.php @@ -0,0 +1,46 @@ +addParam('stats', 'true'); + + // add fields + foreach ($component->getFields() as $field) { + $pivots = $field->getPivots(); + + $prefix = (count($pivots) > 0) ? '{!tag='.implode(',', $pivots).'}' : ''; + $request->addParam('stats.field', $prefix.$field->getKey()); + + // add field specific facet stats + foreach ($field->getFacets() as $facet) { + $request->addParam('f.'.$field->getKey().'.stats.facet', $facet); + } + } + + // add facet stats for all fields + foreach ($component->getFacets() as $facet) { + $request->addParam('stats.facet', $facet); + } + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/Component/RequestBuilder/SubRequest.php b/vendor/solarium/solarium/src/Component/RequestBuilder/SubRequest.php new file mode 100644 index 000000000..84b64becf --- /dev/null +++ b/vendor/solarium/solarium/src/Component/RequestBuilder/SubRequest.php @@ -0,0 +1,65 @@ + array('cat:1','published:1') + * + * @var array + */ + protected $queryParser = 'rerank'; + + /** + * Get query parser. + * + * @return string + */ + public function getQueryParser() + { + return $this->queryParser; + } + + /** + * Set query parser. + * + * @param string $value + * + * @return self Provides fluent interface + */ + public function setQueryParser(string $value) + { + $this->queryParser = $value; + + return $this; + } + + /** + * returns the complete sub request as string. + * + * @param string $separator + * + * @return string + */ + public function getSubQuery($separator = ' ') + { + $queryString = ''; + foreach ($this->getParams() as $key => $value) { + $queryString .= $separator.$key.'='.$value; + } + if ($queryString) { + $queryString = '{!'.$this->getQueryParser().$queryString.'}'; + } + + return $queryString; + } +} diff --git a/vendor/solarium/solarium/src/Component/RequestBuilder/Suggester.php b/vendor/solarium/solarium/src/Component/RequestBuilder/Suggester.php new file mode 100644 index 000000000..f55d5eb53 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/RequestBuilder/Suggester.php @@ -0,0 +1,33 @@ +addParam('suggest', 'true'); + $request->addParam('suggest.dictionary', $component->getDictionary()); + $request->addParam('suggest.q', $component->getQuery()); + $request->addParam('suggest.count', $component->getCount()); + $request->addParam('suggest.cfq', $component->getContextFilterQuery()); + $request->addParam('suggest.build', $component->getBuild()); + $request->addParam('suggest.reload', $component->getReload()); + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/Component/RequestBuilder/Terms.php b/vendor/solarium/solarium/src/Component/RequestBuilder/Terms.php new file mode 100644 index 000000000..f7534fd40 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/RequestBuilder/Terms.php @@ -0,0 +1,46 @@ +addParam('terms', true); + $request->addParam('terms.lower', $component->getLowerbound()); + $request->addParam('terms.lower.incl', $component->getLowerboundInclude()); + $request->addParam('terms.mincount', $component->getMinCount()); + $request->addParam('terms.maxcount', $component->getMaxCount()); + $request->addParam('terms.prefix', $component->getPrefix()); + $request->addParam('terms.regex', $component->getRegex()); + $request->addParam('terms.limit', $component->getLimit()); + $request->addParam('terms.upper', $component->getUpperbound()); + $request->addParam('terms.upper.incl', $component->getUpperboundInclude()); + $request->addParam('terms.raw', $component->getRaw()); + $request->addParam('terms.sort', $component->getSort()); + + foreach ($component->getFields() as $field) { + $request->addParam('terms.fl', trim($field)); + } + + foreach ($component->getRegexFlags() as $flag) { + $request->addParam('terms.regex.flag', trim($flag)); + } + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/Component/ResponseParser/ComponentParserInterface.php b/vendor/solarium/solarium/src/Component/ResponseParser/ComponentParserInterface.php new file mode 100644 index 000000000..4428c6c6a --- /dev/null +++ b/vendor/solarium/solarium/src/Component/ResponseParser/ComponentParserInterface.php @@ -0,0 +1,22 @@ +parseDocumentSet($debug['explain']); + } else { + $explain = new DocumentSet([]); + } + + // parse explainOther data + if (isset($debug['explainOther']) && is_array($debug['explainOther'])) { + $explainOther = $this->parseDocumentSet($debug['explainOther']); + } else { + $explainOther = new DocumentSet([]); + } + + // parse timing data + $timing = null; + if (isset($debug['timing']) && is_array($debug['timing'])) { + $time = null; + $timingPhases = []; + foreach ($debug['timing'] as $key => $timingData) { + switch ($key) { + case 'time': + $time = $timingData; + break; + default: + $timingPhases[$key] = $this->parseTimingPhase($key, $timingData); + } + } + $timing = new Timing($time, $timingPhases); + } + + // create result object + $result = new Result( + $queryString, + $parsedQuery, + $queryParser, + $otherQuery, + $explain, + $explainOther, + $timing + ); + } + + return $result; + } + + /** + * Parse data into a documentset. + * + * Used for explain and explainOther + * + * @param array $data + * + * @return DocumentSet + */ + protected function parseDocumentSet($data) + { + $docs = []; + foreach ($data as $key => $documentData) { + $details = []; + if (isset($documentData['details']) && is_array($documentData['details'])) { + foreach ($documentData['details'] as $detailData) { + $detail = new Detail( + $detailData['match'], + $detailData['value'], + $detailData['description'] + ); + + if (isset($detailData['details']) && is_array($detailData['details'])) { + $detail->setSubDetails($detailData['details']); + } + $details[] = $detail; + } + } + + $docs[$key] = new Document( + $key, + $documentData['match'], + $documentData['value'], + $documentData['description'], + $details + ); + } + + return new DocumentSet($docs); + } + + /** + * Parse raw timing phase data into a result class. + * + * @param string $name + * @param array $data + * + * @return TimingPhase + */ + protected function parseTimingPhase($name, $data) + { + $time = 0.0; + $classes = []; + foreach ($data as $key => $timingData) { + switch ($key) { + case 'time': + $time = $timingData; + break; + default: + $classes[$key] = $timingData['time']; + } + } + + return new TimingPhase($name, $time, $classes); + } +} diff --git a/vendor/solarium/solarium/src/Component/ResponseParser/FacetSet.php b/vendor/solarium/solarium/src/Component/ResponseParser/FacetSet.php new file mode 100644 index 000000000..bb81f56e9 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/ResponseParser/FacetSet.php @@ -0,0 +1,319 @@ +getExtractFromResponse()) { + if (false === empty($data['facet_counts'])) { + foreach ($data['facet_counts'] as $key => $facets) { + switch ($key) { + case 'facet_fields': + $method = 'createFacetField'; + break; + case 'facet_queries': + $method = 'createFacetQuery'; + break; + case 'facet_ranges': + $method = 'createFacetRange'; + break; + case 'facet_pivot': + $method = 'createFacetPivot'; + break; + case 'facet_interval': + $method = 'createFacetInterval'; + break; + default: + throw new RuntimeException('Unknown facet class identifier'); + } + foreach ($facets as $k => $facet) { + $facetObject = $facetSet->$method($k); + if ('facet_pivot' == $key) { + /* @var \Solarium\Component\Facet\Pivot $facetObject */ + $facetObject->setFields($k); + } + } + } + } + } + + $facets = []; + foreach ($facetSet->getFacets() as $key => $facet) { + $result = null; + switch ($facet->getType()) { + case FacetSetInterface::FACET_FIELD: + $result = $this->facetField($query, $facet, $data); + break; + case FacetSetInterface::FACET_QUERY: + $result = $this->facetQuery($facet, $data); + break; + case FacetSetInterface::FACET_MULTIQUERY: + $result = $this->facetMultiQuery($facet, $data); + break; + case FacetSetInterface::FACET_RANGE: + $result = $this->facetRange($query, $facet, $data); + break; + case FacetSetInterface::FACET_PIVOT: + $result = $this->facetPivot($query, $facet, $data); + break; + case FacetSetInterface::FACET_INTERVAL: + $result = $this->facetInterval($query, $facet, $data); + break; + case FacetSetInterface::JSON_FACET_AGGREGATION: + case FacetSetInterface::JSON_FACET_QUERY: + case FacetSetInterface::JSON_FACET_RANGE: + case FacetSetInterface::JSON_FACET_TERMS: + break; + default: + throw new RuntimeException(sprintf('Unknown facet type %s', $facet->getType())); + } + + if (null !== $result) { + $facets[$key] = $result; + } + } + + if (!empty($data['facets'])) { + $facets += $this->parseJsonFacetSet($data['facets'], $facetSet->getFacets()); + } + + return $this->createFacetSet($facets); + } + + /** + * Parse JSON facets. + * + * @param array $facet_data + * @param FacetInterface[] $facets + * + * @return array + */ + protected function parseJsonFacetSet($facet_data, $facets) + { + $buckets_and_aggregations = []; + foreach ($facet_data as $key => $values) { + if (is_array($values)) { + if (isset($values['buckets'])) { + $buckets = []; + // Parse buckets. + foreach ($values['buckets'] as $bucket) { + $val = $bucket['val']; + $count = $bucket['count']; + unset($bucket['val']); + unset($bucket['count']); + $buckets[] = new Bucket($val, $count, new ResultFacetSet($this->parseJsonFacetSet($bucket, + (isset($facets[$key]) && $facets[$key] instanceof JsonFacetInterface) ? $facets[$key]->getFacets() : [] + ))); + } + if ($buckets) { + $buckets_and_aggregations[$key] = new Buckets($buckets); + } + } else { + $buckets_and_aggregations[$key] = new ResultFacetSet($this->parseJsonFacetSet($values, + (isset($facets[$key]) && $facets[$key] instanceof JsonFacetInterface) ? $facets[$key]->getFacets() : [] + )); + } + } else { + if (isset($facets[$key]) && $facets[$key] instanceof JsonAggregation) { + $min = $facets[$key]->getMin(); + if (!is_null($min) && $values < $min) { + continue; + } + } + $buckets_and_aggregations[$key] = new Aggregation($values); + } + } + return $buckets_and_aggregations; + } + + /** + * Create a facetset result object. + * + * @param array $facets + * + * @return ResultFacetSet + */ + protected function createFacetSet($facets) + { + return new ResultFacetSet($facets); + } + + /** + * Add a facet result for a field facet. + * + * @param Query $query + * @param QueryFacetField $facet + * @param array $data + * + * @return ResultFacetField|null + */ + protected function facetField($query, $facet, $data) + { + $key = $facet->getKey(); + if (!isset($data['facet_counts']['facet_fields'][$key])) { + return; + } + + if ($query->getResponseWriter() == $query::WT_JSON) { + $data['facet_counts']['facet_fields'][$key] = $this->convertToKeyValueArray( + $data['facet_counts']['facet_fields'][$key] + ); + } + + return new ResultFacetField($data['facet_counts']['facet_fields'][$key]); + } + + /** + * Add a facet result for a facet query. + * + * @param QueryFacetQuery $facet + * @param array $data + * + * @return ResultFacetQuery|null + */ + protected function facetQuery($facet, $data) + { + $key = $facet->getKey(); + if (!isset($data['facet_counts']['facet_queries'][$key])) { + return; + } + + return new ResultFacetQuery($data['facet_counts']['facet_queries'][$key]); + } + + /** + * Add a facet result for a multiquery facet. + * + * @param QueryFacetMultiQuery $facet + * @param array $data + * + * @return ResultFacetMultiQuery|null + */ + protected function facetMultiQuery($facet, $data) + { + $values = []; + foreach ($facet->getQueries() as $query) { + $key = $query->getKey(); + if (isset($data['facet_counts']['facet_queries'][$key])) { + $count = $data['facet_counts']['facet_queries'][$key]; + $values[$key] = $count; + } + } + + if (count($values) <= 0) { + return; + } + + return new ResultFacetMultiQuery($values); + } + + /** + * Add a facet result for a range facet. + * + * @param Query $query + * @param QueryFacetRange $facet + * @param array $data + * + * @return ResultFacetRange|null + */ + protected function facetRange($query, $facet, $data) + { + $key = $facet->getKey(); + if (!isset($data['facet_counts']['facet_ranges'][$key])) { + return; + } + + $data = $data['facet_counts']['facet_ranges'][$key]; + $before = (isset($data['before'])) ? $data['before'] : null; + $after = (isset($data['after'])) ? $data['after'] : null; + $between = (isset($data['between'])) ? $data['between'] : null; + $start = (isset($data['start'])) ? $data['start'] : null; + $end = (isset($data['end'])) ? $data['end'] : null; + $gap = (isset($data['gap'])) ? $data['gap'] : null; + + if ($query->getResponseWriter() == $query::WT_JSON) { + $data['counts'] = $this->convertToKeyValueArray($data['counts']); + } + + return new ResultFacetRange($data['counts'], $before, $after, $between, $start, $end, $gap); + } + + /** + * Add a facet result for a interval facet. + * + * @param Query $query + * @param QueryFacetInterval $facet + * @param array $data + * + * @return ResultFacetInterval|null + */ + protected function facetInterval($query, $facet, $data) + { + $key = $facet->getKey(); + if (!isset($data['facet_counts']['facet_intervals'][$key])) { + return null; + } + + return new ResultFacetInterval($data['facet_counts']['facet_intervals'][$key]); + } + + /** + * Add a facet result for a range facet. + * + * @param Query $query + * @param QueryFacetPivot $facet + * @param array $data + * + * @return ResultFacetPivot|null + */ + protected function facetPivot($query, $facet, $data) + { + $key = $facet->getKey(); + if (!isset($data['facet_counts']['facet_pivot'][$key])) { + return; + } + + return new ResultFacetPivot($data['facet_counts']['facet_pivot'][$key]); + } +} diff --git a/vendor/solarium/solarium/src/Component/ResponseParser/Grouping.php b/vendor/solarium/solarium/src/Component/ResponseParser/Grouping.php new file mode 100644 index 000000000..6f1fe86a0 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/ResponseParser/Grouping.php @@ -0,0 +1,125 @@ +getOption('resultvaluegroupclass'); + $documentClass = $query->getOption('documentclass'); + + // check grouping fields as well as the grouping function (either can be used in the query) + foreach (array_merge($grouping->getFields(), [$grouping->getFunction()]) as $field) { + if (!isset($data['grouped'][$field])) { + continue; + } + + $result = $data['grouped'][$field]; + + $matches = (isset($result['matches'])) ? $result['matches'] : null; + $groupCount = (isset($result['ngroups'])) ? $result['ngroups'] : null; + if (GroupingComponent::FORMAT_SIMPLE === $grouping->getFormat()) { + $valueGroups = [$this->extractValueGroup($valueResultClass, $documentClass, $result, $query)]; + $groups[$field] = new FieldGroup($matches, $groupCount, $valueGroups); + continue; + } + + $valueGroups = []; + foreach ($result['groups'] as $valueGroupResult) { + $valueGroups[] = $this->extractValueGroup($valueResultClass, $documentClass, $valueGroupResult, $query); + } + + $groups[$field] = new FieldGroup($matches, $groupCount, $valueGroups); + } + + // parse query groups + $groupResultClass = $grouping->getOption('resultquerygroupclass'); + foreach ($grouping->getQueries() as $groupQuery) { + if (isset($data['grouped'][$groupQuery])) { + $result = $data['grouped'][$groupQuery]; + + // get statistics + $matches = (isset($result['matches'])) ? $result['matches'] : null; + $numFound = (isset($result['doclist']['numFound'])) ? $result['doclist']['numFound'] : null; + $start = (isset($result['doclist']['start'])) ? $result['doclist']['start'] : null; + $maxScore = (isset($result['doclist']['maxScore'])) ? $result['doclist']['maxScore'] : null; + + // create document instances + $documentClass = $query->getOption('documentclass'); + $documents = []; + if (isset($result['doclist']['docs']) && is_array($result['doclist']['docs'])) { + foreach ($result['doclist']['docs'] as $doc) { + $documents[] = new $documentClass($doc); + } + } + + // create a group result object + $group = new $groupResultClass($matches, $numFound, $start, $maxScore, $documents, $query); + $groups[$groupQuery] = $group; + } + } + + return new Result($groups); + } + + /** + * Helper method to extract a ValueGroup object from the given value group result array. + * + * @param string $valueResultClass the grouping resultvaluegroupclass option + * @param string $documentClass the name of the solr document class to use + * @param array $valueGroupResult the group result from the solr response + * @param Query $query the current solr query + * + * @return object + */ + private function extractValueGroup($valueResultClass, $documentClass, $valueGroupResult, $query) + { + $value = (isset($valueGroupResult['groupValue'])) ? + $valueGroupResult['groupValue'] : null; + + $numFound = (isset($valueGroupResult['doclist']['numFound'])) ? + $valueGroupResult['doclist']['numFound'] : null; + + $start = (isset($valueGroupResult['doclist']['start'])) ? + $valueGroupResult['doclist']['start'] : null; + + $maxScore = (isset($valueGroupResult['doclist']['maxScore'])) ? + $valueGroupResult['doclist']['maxScore'] : null; + + // create document instances + $documents = []; + if (isset($valueGroupResult['doclist']['docs']) && + is_array($valueGroupResult['doclist']['docs'])) { + foreach ($valueGroupResult['doclist']['docs'] as $doc) { + $documents[] = new $documentClass($doc); + } + } + + return new $valueResultClass($value, $numFound, $start, $documents, $maxScore, $query); + } +} diff --git a/vendor/solarium/solarium/src/Component/ResponseParser/Highlighting.php b/vendor/solarium/solarium/src/Component/ResponseParser/Highlighting.php new file mode 100644 index 000000000..4afc64f77 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/ResponseParser/Highlighting.php @@ -0,0 +1,38 @@ + $result) { + $results[$key] = new Result( + $result + ); + } + } + + return new HighlightingResult($results); + } +} diff --git a/vendor/solarium/solarium/src/Component/ResponseParser/MoreLikeThis.php b/vendor/solarium/solarium/src/Component/ResponseParser/MoreLikeThis.php new file mode 100644 index 000000000..ff2df8783 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/ResponseParser/MoreLikeThis.php @@ -0,0 +1,48 @@ +getOption('documentclass'); + + $searchResults = $data['moreLikeThis']; + foreach ($searchResults as $key => $result) { + // create document instances + $docs = []; + foreach ($result['docs'] as $fields) { + $docs[] = new $documentClass($fields); + } + + $results[$key] = new Result( + $result['numFound'], + isset($result['maxScore']) ? $result['maxScore'] : null, + $docs + ); + } + } + + return new MoreLikeThisResult($results); + } +} diff --git a/vendor/solarium/solarium/src/Component/ResponseParser/Spellcheck.php b/vendor/solarium/solarium/src/Component/ResponseParser/Spellcheck.php new file mode 100644 index 000000000..7a20e15f4 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/ResponseParser/Spellcheck.php @@ -0,0 +1,187 @@ + 0 + ) { + $spellcheckResults = $data['spellcheck']['suggestions']; + if ($query->getResponseWriter() == $query::WT_JSON) { + $spellcheckResults = $this->convertToKeyValueArray($spellcheckResults); + } + + $suggestions = []; + $collations = []; + $correctlySpelled = false; + + foreach ($spellcheckResults as $key => $value) { + switch ($key) { + case 'correctlySpelled': + $correctlySpelled = $value; + break; + case 'collation': + $collations = $this->parseCollation($query, $value); + break; + default: + if (array_key_exists(0, $value)) { + foreach ($value as $currentValue) { + $suggestions[] = $this->parseSuggestion($key, $currentValue); + } + } else { + $suggestions[] = $this->parseSuggestion($key, $value); + } + } + } + + /* + * https://issues.apache.org/jira/browse/SOLR-3029 + * Solr5 has moved collations and correctlySpelled + * directly under spellcheck. + */ + if (isset($data['spellcheck']['collations']) && + is_array($data['spellcheck']['collations']) + ) { + foreach ($this->convertToKeyValueArray($data['spellcheck']['collations']) as $collationResult) { + $collations = array_merge($collations, $this->parseCollation($query, $collationResult)); + } + } + + if (isset($data['spellcheck']['correctlySpelled']) + ) { + $correctlySpelled = $data['spellcheck']['correctlySpelled']; + } + + return new Result($suggestions, $collations, $correctlySpelled); + } + + return null; + } + + /** + * Parse collation data into a result object. + * + * @param AbstractQuery $queryObject + * @param array $values + * + * @return Collation[] + */ + protected function parseCollation($queryObject, $values) + { + $collations = []; + if (is_string($values)) { + $collations[] = new Collation($values, null, []); + } elseif (is_array($values) && isset($values[0]) && is_string($values[0]) && 'collationQuery' !== $values[0]) { + foreach ($values as $value) { + $collations[] = new Collation($value, null, []); + } + } else { + if ($queryObject->getResponseWriter() == $queryObject::WT_JSON) { + if (is_array(current($values))) { + foreach ($values as $key => $value) { + if (array_key_exists('collationQuery', $value)) { + $values[$key] = $value; + } else { + $values[$key] = $this->convertToKeyValueArray($value); + } + } + } else { + if (array_key_exists('collationQuery', $values)) { + $values = [$values]; + } else { + $values = [$this->convertToKeyValueArray($values)]; + } + } + } + + foreach ($values as $collationValue) { + $query = null; + $hits = null; + $correctionResult = null; + + foreach ($collationValue as $key => $value) { + switch ($key) { + case 'collationQuery': + $query = $value; + break; + case 'hits': + $hits = $value; + break; + case 'misspellingsAndCorrections': + $correctionResult = $value; + break; + } + } + + $corrections = []; + if (null !== $correctionResult) { + if ($queryObject->getResponseWriter() == $queryObject::WT_JSON) { + $correctionResult = $this->convertToKeyValueArray($correctionResult); + } + + foreach ($correctionResult as $input => $correction) { + $corrections[$input] = $correction; + } + } + + $collations[] = new Collation($query, $hits, $corrections); + } + } + + return $collations; + } + + /** + * Parse suggestion data into a result object. + * + * @param string $key + * @param array $value + * + * @return Suggestion + */ + protected function parseSuggestion($key, $value) + { + $numFound = (isset($value['numFound'])) ? $value['numFound'] : null; + $startOffset = (isset($value['startOffset'])) ? $value['startOffset'] : null; + $endOffset = (isset($value['endOffset'])) ? $value['endOffset'] : null; + $originalFrequency = (isset($value['origFreq'])) ? $value['origFreq'] : null; + + $words = []; + if (isset($value['suggestion']) && is_array($value['suggestion'])) { + foreach ($value['suggestion'] as $suggestion) { + if (is_string($suggestion)) { + $suggestion = [ + 'word' => $suggestion, + 'freq' => null, + ]; + } + $words[] = $suggestion; + } + } + + return new Suggestion($numFound, $startOffset, $endOffset, $originalFrequency, $words); + } +} diff --git a/vendor/solarium/solarium/src/Component/ResponseParser/Stats.php b/vendor/solarium/solarium/src/Component/ResponseParser/Stats.php new file mode 100644 index 000000000..a3326b2d0 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/ResponseParser/Stats.php @@ -0,0 +1,45 @@ + $stats) { + if (isset($stats['facets'])) { + foreach ($stats['facets'] as $facetField => $values) { + foreach ($values as $value => $valueStats) { + $stats['facets'][$facetField][$value] = new ResultStatsFacetValue($value, $valueStats); + } + } + } + + $results[$field] = new ResultStatsResult($field, $stats); + } + } + + return new ResultStats($results); + } +} diff --git a/vendor/solarium/solarium/src/Component/ResponseParser/Suggester.php b/vendor/solarium/solarium/src/Component/ResponseParser/Suggester.php new file mode 100644 index 000000000..f2f60836b --- /dev/null +++ b/vendor/solarium/solarium/src/Component/ResponseParser/Suggester.php @@ -0,0 +1,61 @@ + $dictionaryResults) { + $terms = []; + foreach ($dictionaryResults as $term => $termData) { + $allSuggestions[] = $this->createTerm($termData); + $terms[$term] = $this->createTerm($termData); + } + $dictionaries[$dictionary] = $this->createDictionary($terms); + } + + return new Result($dictionaries, $allSuggestions); + } + + return null; + } + + private function createDictionary(array $terms) + { + return new Dictionary( + $terms + ); + } + + private function createTerm(array $termData) + { + return new Term( + $termData['numFound'], + $termData['suggestions'] + ); + } +} diff --git a/vendor/solarium/solarium/src/Component/ResponseParser/Terms.php b/vendor/solarium/solarium/src/Component/ResponseParser/Terms.php new file mode 100644 index 000000000..28682203c --- /dev/null +++ b/vendor/solarium/solarium/src/Component/ResponseParser/Terms.php @@ -0,0 +1,44 @@ + $termData) { + if ($query->getResponseWriter() == $query::WT_JSON) { + $termData = $this->convertToKeyValueArray($termData); + } + $allTerms[$field] = $termData; + $terms[$field] = new Field($termData); + } + + return new Result($terms, $allTerms); + } + + return null; + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Debug/Detail.php b/vendor/solarium/solarium/src/Component/Result/Debug/Detail.php new file mode 100644 index 000000000..c2ad26680 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Debug/Detail.php @@ -0,0 +1,95 @@ +match = $match; + $this->value = $value; + $this->description = $description; + } + + /** + * Get match status. + * + * @return bool + */ + public function getMatch() + { + return $this->match; + } + + /** + * Get match value (score). + * + * @return float + */ + public function getValue() + { + return $this->value; + } + + /** + * Get description. + * + * @return string + */ + public function getDescription() + { + return $this->description; + } + + /** + * @param array $subDetails + */ + public function setSubDetails($subDetails) + { + $this->subDetails = $subDetails; + } + + /** + * @return array + */ + public function getSubDetails() + { + return $this->subDetails; + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Debug/Document.php b/vendor/solarium/solarium/src/Component/Result/Debug/Document.php new file mode 100644 index 000000000..3ef4ef203 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Debug/Document.php @@ -0,0 +1,79 @@ +key = $key; + $this->details = $details; + } + + /** + * Get key value for this document. + * + * @return string + */ + public function getKey() + { + return $this->key; + } + + /** + * Get details. + * + * @return array + */ + public function getDetails() + { + return $this->details; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->details); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->details); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Debug/DocumentSet.php b/vendor/solarium/solarium/src/Component/Result/Debug/DocumentSet.php new file mode 100644 index 000000000..1ee484433 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Debug/DocumentSet.php @@ -0,0 +1,70 @@ +docs = $docs; + } + + /** + * Get a document by key. + * + * @param mixed $key + * + * @return Document|null + */ + public function getDocument($key) + { + if (isset($this->docs[$key])) { + return $this->docs[$key]; + } + } + + /** + * Get all docs. + * + * @return array + */ + public function getDocuments() + { + return $this->docs; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->docs); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->docs); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Debug/Result.php b/vendor/solarium/solarium/src/Component/Result/Debug/Result.php new file mode 100644 index 000000000..3e2513880 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Debug/Result.php @@ -0,0 +1,172 @@ +queryString = $queryString; + $this->parsedQuery = $parsedQuery; + $this->queryParser = $queryParser; + $this->otherQuery = $otherQuery; + $this->explain = $explain; + $this->explainOther = $explainOther; + $this->timing = $timing; + } + + /** + * Get input querystring. + * + * @return string + */ + public function getQueryString() + { + return $this->queryString; + } + + /** + * Get the result of the queryparser. + * + * @return string + */ + public function getParsedQuery() + { + return $this->parsedQuery; + } + + /** + * Get the used queryparser. + * + * @return string + */ + public function getQueryParser() + { + return $this->queryParser; + } + + /** + * Get other query (only available if set in query). + * + * @return string + */ + public function getOtherQuery() + { + return $this->otherQuery; + } + + /** + * Get explain document set. + * + * @return DocumentSet + */ + public function getExplain() + { + return $this->explain; + } + + /** + * Get explain other document set (only available if otherquery was set in query). + * + * @return DocumentSet + */ + public function getExplainOther() + { + return $this->explainOther; + } + + /** + * Get timing object. + * + * @return Timing + */ + public function getTiming() + { + return $this->timing; + } + + /** + * IteratorAggregate implementation. + * + * Iterates the explain results + * + * @return DocumentSet + */ + public function getIterator() + { + return $this->explain; + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->explain); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Debug/Timing.php b/vendor/solarium/solarium/src/Component/Result/Debug/Timing.php new file mode 100644 index 000000000..3f4c502e3 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Debug/Timing.php @@ -0,0 +1,89 @@ +time = $time; + $this->phases = $phases; + } + + /** + * Get total time. + * + * @return float + */ + public function getTime() + { + return $this->time; + } + + /** + * Get a timing phase by key. + * + * @param mixed $key + * + * @return TimingPhase|null + */ + public function getPhase($key) + { + if (isset($this->phases[$key])) { + return $this->phases[$key]; + } + } + + /** + * Get timings. + * + * @return array + */ + public function getPhases() + { + return $this->phases; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->phases); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->phases); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Debug/TimingPhase.php b/vendor/solarium/solarium/src/Component/Result/Debug/TimingPhase.php new file mode 100644 index 000000000..10e93954e --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Debug/TimingPhase.php @@ -0,0 +1,98 @@ +name = $name; + $this->time = $time; + $this->timings = $timings; + } + + /** + * Get total time. + * + * @return float + */ + public function getTime() + { + return $this->time; + } + + /** + * Get a timing by key. + * + * @param mixed $key + * + * @return float|null + */ + public function getTiming($key) + { + if (isset($this->timings[$key])) { + return $this->timings[$key]; + } + } + + /** + * Get timings. + * + * @return array + */ + public function getTimings() + { + return $this->timings; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->timings); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->timings); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Facet/Aggregation.php b/vendor/solarium/solarium/src/Component/Result/Facet/Aggregation.php new file mode 100644 index 000000000..d95cfca7e --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Facet/Aggregation.php @@ -0,0 +1,36 @@ +value = $value; + } + + /** + * Get value. + * + * @return float|int + */ + public function getValue() + { + return $this->value; + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Facet/Bucket.php b/vendor/solarium/solarium/src/Component/Result/Facet/Bucket.php new file mode 100644 index 000000000..d1f1dfdec --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Facet/Bucket.php @@ -0,0 +1,101 @@ +value = $value; + $this->count = $count; + $this->facetSet = $facets; + } + + /** + * Get the value. + * + * @return string + */ + public function getValue() + { + return $this->value; + } + + /** + * Get the count. + * + * @return int + */ + public function getCount() + { + return $this->count; + } + + /** + * Get nested facets. + * + * @return FacetInterface[] + */ + public function getFacets() + { + return $this->facetSet->getFacets(); + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return $this->facetSet->getIterator(); + } + + /** + * Countable implementation. + * + * @return int the amount of nested facets + */ + public function count() + { + return count($this->facetSet->getFacets()); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Facet/Buckets.php b/vendor/solarium/solarium/src/Component/Result/Facet/Buckets.php new file mode 100644 index 000000000..dbe1e38fc --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Facet/Buckets.php @@ -0,0 +1,60 @@ +buckets = $buckets; + } + + /** + * Get all values. + * + * @return Bucket[] + */ + public function getBuckets() + { + return $this->buckets; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->buckets); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->buckets); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Facet/Field.php b/vendor/solarium/solarium/src/Component/Result/Facet/Field.php new file mode 100644 index 000000000..c28c3b14f --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Facet/Field.php @@ -0,0 +1,60 @@ +values = $values; + } + + /** + * Get all values. + * + * @return array + */ + public function getValues() + { + return $this->values; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->values); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->values); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Facet/Interval.php b/vendor/solarium/solarium/src/Component/Result/Facet/Interval.php new file mode 100644 index 000000000..38b10fc61 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Facet/Interval.php @@ -0,0 +1,14 @@ +pivot[] = new PivotItem($pivotData); + } + } + + /** + * Get pivot results. + * + * @return Pivot[] + */ + public function getPivot() + { + return $this->pivot; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->pivot); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->pivot); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Facet/Pivot/PivotItem.php b/vendor/solarium/solarium/src/Component/Result/Facet/Pivot/PivotItem.php new file mode 100644 index 000000000..c1155ba9e --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Facet/Pivot/PivotItem.php @@ -0,0 +1,103 @@ +field = $data['field']; + $this->value = $data['value']; + $this->count = $data['count']; + + if (isset($data['pivot'])) { + foreach ($data['pivot'] as $pivotData) { + $this->pivot[] = new self($pivotData); + } + } + + if (isset($data['stats'])) { + $this->stats = new Stats($data['stats']); + } + } + + /** + * Get field name. + * + * @return string + */ + public function getField() + { + return $this->field; + } + + /** + * Get field value. + * + * @return mixed + */ + public function getValue() + { + return $this->value; + } + + /** + * Get count. + * + * @return int + */ + public function getCount() + { + return $this->count; + } + + /** + * Get stats. + * + * @return Stats + */ + public function getStats() + { + return $this->stats; + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Facet/Query.php b/vendor/solarium/solarium/src/Component/Result/Facet/Query.php new file mode 100644 index 000000000..fbca151e0 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Facet/Query.php @@ -0,0 +1,39 @@ +value = $value; + } + + /** + * Get the value. + * + * @return mixed + */ + public function getValue() + { + return $this->value; + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Facet/Range.php b/vendor/solarium/solarium/src/Component/Result/Facet/Range.php new file mode 100644 index 000000000..6094349fc --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Facet/Range.php @@ -0,0 +1,155 @@ +before = $before; + $this->after = $after; + $this->between = $between; + $this->start = $start; + $this->end = $end; + $this->gap = $gap; + } + + /** + * Get 'before' count. + * + * Count of all records with field values lower then lower bound of the first range + * Only available if the 'other' setting was used in the query facet. + * + * @return int + */ + public function getBefore() + { + return $this->before; + } + + /** + * Get 'after' count. + * + * Count of all records with field values greater then the upper bound of the last range + * Only available if the 'other' setting was used in the query facet. + * + * @return int + */ + public function getAfter() + { + return $this->after; + } + + /** + * Get 'between' count. + * + * Count all records with field values between the start and end bounds of all ranges + * Only available if the 'other' setting was used in the query facet. + * + * @return int + */ + public function getBetween() + { + return $this->between; + } + + /** + * Get 'start' value of the ranges. + * + * The start value specified in the query facet. + * + * @return string + */ + public function getStart() + { + return $this->start; + } + + /** + * Get 'end' value of the ranges. + * + * The end value specified in the query facet + * + * @return string + */ + public function getEnd() + { + return $this->end; + } + + /** + * Get 'gap' between the start and end of each range. + * + * Get the gap specified in the query facet + * + * @return string + */ + public function getGap() + { + return $this->gap; + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/FacetSet.php b/vendor/solarium/solarium/src/Component/Result/FacetSet.php new file mode 100644 index 000000000..41eecf7c4 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/FacetSet.php @@ -0,0 +1,72 @@ +facets = $facets; + } + + /** + * Get a facet by key. + * + * @param mixed $key + * + * @return FacetInterface + */ + public function getFacet($key) + { + if (isset($this->facets[$key])) { + return $this->facets[$key]; + } + } + + /** + * Get all results. + * + * @return FacetInterface[] + */ + public function getFacets() + { + return $this->facets; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->facets); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->facets); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Grouping/FieldGroup.php b/vendor/solarium/solarium/src/Component/Result/Grouping/FieldGroup.php new file mode 100644 index 000000000..81fccbdfd --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Grouping/FieldGroup.php @@ -0,0 +1,98 @@ +matches = $matches; + $this->numberOfGroups = $numberOfGroups; + $this->valueGroups = $groups; + } + + /** + * Get matches value. + * + * @return int + */ + public function getMatches() + { + return $this->matches; + } + + /** + * Get numberOfGroups value. + * + * Only available if the numberofgroups option in the query was 'true' + * + * @return int + */ + public function getNumberOfGroups() + { + return $this->numberOfGroups; + } + + /** + * Get all value groups. + * + * @return array + */ + public function getValueGroups() + { + return $this->valueGroups; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->valueGroups); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->valueGroups); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Grouping/QueryGroup.php b/vendor/solarium/solarium/src/Component/Result/Grouping/QueryGroup.php new file mode 100644 index 000000000..a53087481 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Grouping/QueryGroup.php @@ -0,0 +1,143 @@ +matches = $matches; + $this->numFound = $numFound; + $this->start = $start; + $this->maximumScore = $maximumScore; + $this->documents = $documents; + $this->query = $query; + } + + /** + * Get matches value. + * + * @return int + */ + public function getMatches() + { + return $this->matches; + } + + /** + * Get numFound value. + * + * @return int + */ + public function getNumFound() + { + return $this->numFound; + } + + /** + * Get start value. + * + * @return int + */ + public function getStart() + { + return $this->start; + } + + /** + * Get maximumScore value. + * + * @return int + */ + public function getMaximumScore() + { + return $this->maximumScore; + } + + /** + * Get all documents. + * + * @return array + */ + public function getDocuments() + { + return $this->documents; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->getDocuments()); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->getDocuments()); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Grouping/Result.php b/vendor/solarium/solarium/src/Component/Result/Grouping/Result.php new file mode 100644 index 000000000..0b98edd17 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Grouping/Result.php @@ -0,0 +1,72 @@ +groups = $groups; + } + + /** + * Get all groups. + * + * @return array + */ + public function getGroups() + { + return $this->groups; + } + + /** + * Get a group. + * + * @param string $key + * + * @return FieldGroup|QueryGroup + */ + public function getGroup($key) + { + if (isset($this->groups[$key])) { + return $this->groups[$key]; + } + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->groups); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->groups); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Grouping/ValueGroup.php b/vendor/solarium/solarium/src/Component/Result/Grouping/ValueGroup.php new file mode 100644 index 000000000..4274c20d3 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Grouping/ValueGroup.php @@ -0,0 +1,143 @@ +value = $value; + $this->numFound = $numFound; + $this->start = $start; + $this->documents = $documents; + $this->maximumScore = $maxScore; + $this->query = $query; + } + + /** + * Get value. + * + * @return string + */ + public function getValue() + { + return $this->value; + } + + /** + * Get numFound. + * + * @return int + */ + public function getNumFound() + { + return $this->numFound; + } + + /** + * Get start. + * + * @return int + */ + public function getStart() + { + return $this->start; + } + + /** + * Get maximumScore value. + * + * @return int + */ + public function getMaximumScore() + { + return $this->maximumScore; + } + + /** + * Get all documents. + * + * @return array + */ + public function getDocuments() + { + return $this->documents; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->getDocuments()); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->getDocuments()); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Highlighting/Highlighting.php b/vendor/solarium/solarium/src/Component/Result/Highlighting/Highlighting.php new file mode 100644 index 000000000..211177168 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Highlighting/Highlighting.php @@ -0,0 +1,70 @@ +results = $results; + } + + /** + * Get a result by key. + * + * @param mixed $key + * + * @return Result|null + */ + public function getResult($key) + { + if (isset($this->results[$key])) { + return $this->results[$key]; + } + } + + /** + * Get all results. + * + * @return Result[] + */ + public function getResults() + { + return $this->results; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->results); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->results); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Highlighting/Result.php b/vendor/solarium/solarium/src/Component/Result/Highlighting/Result.php new file mode 100644 index 000000000..60fde6157 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Highlighting/Result.php @@ -0,0 +1,72 @@ +fields = $fields; + } + + /** + * Get highlights for all fields. + * + * @return array + */ + public function getFields() + { + return $this->fields; + } + + /** + * Get highlights for a single field. + * + * @param string $key + * + * @return array + */ + public function getField($key) + { + if (isset($this->fields[$key])) { + return $this->fields[$key]; + } + + return []; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->fields); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->fields); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/MoreLikeThis/MoreLikeThis.php b/vendor/solarium/solarium/src/Component/Result/MoreLikeThis/MoreLikeThis.php new file mode 100644 index 000000000..e5e182141 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/MoreLikeThis/MoreLikeThis.php @@ -0,0 +1,70 @@ +results = $results; + } + + /** + * Get a result by key. + * + * @param mixed $key + * + * @return Result|null + */ + public function getResult($key) + { + if (isset($this->results[$key])) { + return $this->results[$key]; + } + } + + /** + * Get all results. + * + * @return Result[] + */ + public function getResults() + { + return $this->results; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->results); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->results); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/MoreLikeThis/Result.php b/vendor/solarium/solarium/src/Component/Result/MoreLikeThis/Result.php new file mode 100644 index 000000000..250f98539 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/MoreLikeThis/Result.php @@ -0,0 +1,101 @@ +numFound = $numFound; + $this->maximumScore = $maxScore; + $this->documents = $documents; + } + + /** + * get Solr numFound. + * + * Returns the number of MLT documents found by Solr (this is NOT the + * number of documents fetched from Solr!) + * + * @return int + */ + public function getNumFound() + { + return $this->numFound; + } + + /** + * Get maximum score in the MLT document set. + * + * @return float + */ + public function getMaximumScore() + { + return $this->maximumScore; + } + + /** + * Get all documents. + * + * @return DocumentInterface[] + */ + public function getDocuments() + { + return $this->documents; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->documents); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->documents); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Spellcheck/Collation.php b/vendor/solarium/solarium/src/Component/Result/Spellcheck/Collation.php new file mode 100644 index 000000000..a63488fa1 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Spellcheck/Collation.php @@ -0,0 +1,102 @@ +query = $query; + $this->hits = $hits; + $this->corrections = $corrections; + } + + /** + * Get query string. + * + * @return string + */ + public function getQuery() + { + return $this->query; + } + + /** + * Get hit count. + * + * Only available if ExtendedResults was enabled in your query + * + * @return int|null + */ + public function getHits() + { + return $this->hits; + } + + /** + * Get all corrrections. + * + * Only available if ExtendedResults was enabled in your query + * + * @return array + */ + public function getCorrections() + { + return $this->corrections; + } + + /** + * IteratorAggregate implementation. + * + * Only available if ExtendedResults was enabled in your query + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->corrections); + } + + /** + * Countable implementation. + * + * Only available if ExtendedResults was enabled in your query + * + * @return int + */ + public function count() + { + return count($this->corrections); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Spellcheck/Result.php b/vendor/solarium/solarium/src/Component/Result/Spellcheck/Result.php new file mode 100644 index 000000000..f258fe84d --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Spellcheck/Result.php @@ -0,0 +1,131 @@ +suggestions = $suggestions; + $this->collations = $collations; + $this->correctlySpelled = $correctlySpelled; + } + + /** + * Get the collation result. + * + * @param int $key + * + * @return Collation + */ + public function getCollation($key = null) + { + $nrOfCollations = count($this->collations); + if (0 == $nrOfCollations) { + return; + } + + if (null === $key) { + return reset($this->collations); + } + + return $this->collations[$key]; + } + + /** + * Get all collations. + * + * @return Collation[] + */ + public function getCollations() + { + return $this->collations; + } + + /** + * Get correctly spelled status. + * + * Only available if ExtendedResults was enabled in your query + * + * @return bool + */ + public function getCorrectlySpelled() + { + return $this->correctlySpelled; + } + + /** + * Get a result by key. + * + * @param mixed $key + * + * @return Suggestion|null + */ + public function getSuggestion($key) + { + if (isset($this->suggestions[$key])) { + return $this->suggestions[$key]; + } + } + + /** + * Get all suggestions. + * + * @return Suggestion[] + */ + public function getSuggestions() + { + return $this->suggestions; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->suggestions); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->suggestions); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Spellcheck/Suggestion.php b/vendor/solarium/solarium/src/Component/Result/Spellcheck/Suggestion.php new file mode 100644 index 000000000..8e14d3c38 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Spellcheck/Suggestion.php @@ -0,0 +1,109 @@ +numFound = $numFound; + $this->startOffset = $startOffset; + $this->endOffset = $endOffset; + $this->originalFrequency = $originalFrequency; + $this->words = $words; + } + + /** + * Get numFound value. + * + * @return int + */ + public function getNumFound() + { + return $this->numFound; + } + + /** + * Get startOffset value. + * + * @return int + */ + public function getStartOffset() + { + return $this->startOffset; + } + + /** + * Get endOffset value. + * + * @return int + */ + public function getEndOffset() + { + return $this->endOffset; + } + + /** + * Get originalFrequency value. + * + * Only available if CollateExtendedResults was enabled in your query + * + * @return int + */ + public function getOriginalFrequency() + { + return $this->originalFrequency; + } + + /** + * Get first word. + * + * @return string|null + */ + public function getWord() + { + $word = reset($this->words); + if (isset($word['word'])) { + return $word['word']; + } + + return $word; + } + + /** + * Get all words (and frequencies). + * + * @return array + */ + public function getWords() + { + return $this->words; + } + + /** + * Get frequency value. + * + * Only available if CollateExtendedResults was enabled in your query + * + * @return int + */ + public function getFrequency() + { + $word = reset($this->words); + if (isset($word['freq'])) { + return $word['freq']; + } + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Stats/FacetValue.php b/vendor/solarium/solarium/src/Component/Result/Stats/FacetValue.php new file mode 100644 index 000000000..3c28e5138 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Stats/FacetValue.php @@ -0,0 +1,135 @@ +value = $value; + $this->stats = $stats; + } + + /** + * Get facet value. + * + * @return string + */ + public function getValue() + { + return $this->value; + } + + /** + * Get min value. + * + * @return string + */ + public function getMin() + { + return $this->stats['min']; + } + + /** + * Get max value. + * + * @return string + */ + public function getMax() + { + return $this->stats['max']; + } + + /** + * Get sum value. + * + * @return string + */ + public function getSum() + { + return $this->stats['sum']; + } + + /** + * Get count value. + * + * @return string + */ + public function getCount() + { + return $this->stats['count']; + } + + /** + * Get missing value. + * + * @return string + */ + public function getMissing() + { + return $this->stats['missing']; + } + + /** + * Get sumOfSquares value. + * + * @return string + */ + public function getSumOfSquares() + { + return $this->stats['sumOfSquares']; + } + + /** + * Get mean value. + * + * @return string + */ + public function getMean() + { + return $this->stats['mean']; + } + + /** + * Get stddev value. + * + * @return string + */ + public function getStddev() + { + return $this->stats['stddev']; + } + + /** + * Get facet stats. + * + * @return array + */ + public function getFacets() + { + return $this->stats['facets']; + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Stats/Result.php b/vendor/solarium/solarium/src/Component/Result/Stats/Result.php new file mode 100644 index 000000000..3147c8dcb --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Stats/Result.php @@ -0,0 +1,157 @@ +field = $field; + $this->stats = $stats; + } + + /** + * Get field name. + * + * @return string + */ + public function getName() + { + return $this->field; + } + + /** + * Get min value. + * + * @return string + */ + public function getMin() + { + return $this->getValue('min'); + } + + /** + * Get max value. + * + * @return string + */ + public function getMax() + { + return $this->getValue('max'); + } + + /** + * Get sum value. + * + * @return string + */ + public function getSum() + { + return $this->getValue('sum'); + } + + /** + * Get count value. + * + * @return string + */ + public function getCount() + { + return $this->getValue('count'); + } + + /** + * Get missing value. + * + * @return string + */ + public function getMissing() + { + return $this->getValue('missing'); + } + + /** + * Get sumOfSquares value. + * + * @return string + */ + public function getSumOfSquares() + { + return $this->getValue('sumOfSquares'); + } + + /** + * Get mean value. + * + * @return string + */ + public function getMean() + { + return $this->getValue('mean'); + } + + /** + * Get stddev value. + * + * @return string + */ + public function getStddev() + { + return $this->getValue('stddev'); + } + + /** + * Get facet stats. + * + * @return array + */ + public function getFacets() + { + return $this->getValue('facets'); + } + + /** + * Get percentile stats. + * + * @return array + */ + public function getPercentiles() + { + return $this->getValue('percentiles'); + } + + /** + * Get value by name. + * + * @param mixed $name + * + * @return string + */ + protected function getValue($name) + { + return isset($this->stats[$name]) ? $this->stats[$name] : null; + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Stats/Stats.php b/vendor/solarium/solarium/src/Component/Result/Stats/Stats.php new file mode 100644 index 000000000..7a58de9a4 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Stats/Stats.php @@ -0,0 +1,70 @@ +results = $results; + } + + /** + * Get a result by key. + * + * @param mixed $key + * + * @return Result|null + */ + public function getResult($key) + { + if (isset($this->results[$key])) { + return $this->results[$key]; + } + } + + /** + * Get all results. + * + * @return Result[] + */ + public function getResults() + { + return $this->results; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->results); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->results); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Suggester/Result.php b/vendor/solarium/solarium/src/Component/Result/Suggester/Result.php new file mode 100644 index 000000000..8fa4d328a --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Suggester/Result.php @@ -0,0 +1,93 @@ +results = $results; + $this->all = $all; + } + + /** + * Get all results. + * + * @return array + */ + public function getResults() + { + return $this->results; + } + + /** + * Get flat results. + * + * @return array + */ + public function getAll() + { + return $this->all; + } + + /** + * Get results for a specific dictionary. + * + * @param string $dictionary + * + * @return Dictionary|null + */ + public function getDictionary($dictionary) + { + if (isset($this->results[$dictionary])) { + return $this->results[$dictionary]; + } + + return null; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->results); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->results); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Terms/Field.php b/vendor/solarium/solarium/src/Component/Result/Terms/Field.php new file mode 100644 index 000000000..43368f21c --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Terms/Field.php @@ -0,0 +1,56 @@ +terms = $terms; + } + + /** + * Get Terms. + * + * @return array + */ + public function getTerms() + { + return array_keys($this->terms); + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->terms); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->terms); + } +} diff --git a/vendor/solarium/solarium/src/Component/Result/Terms/Result.php b/vendor/solarium/solarium/src/Component/Result/Terms/Result.php new file mode 100644 index 000000000..d6972341a --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Result/Terms/Result.php @@ -0,0 +1,91 @@ +results = $results; + $this->all = $all; + } + + /** + * Get all results. + * + * @return array + */ + public function getResults() + { + return $this->results; + } + + /** + * Get flat results. + * + * @return array + */ + public function getAll() + { + return $this->all; + } + + /** + * Get results for a specific dictionary. + * + * @param string $field + * + * @return Field|null + */ + public function getField($field) + { + if (isset($this->results[$field])) { + return $this->results[$field]; + } + + return null; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->results); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->results); + } +} diff --git a/vendor/solarium/solarium/src/Component/Spatial.php b/vendor/solarium/solarium/src/Component/Spatial.php new file mode 100644 index 000000000..21e16e988 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Spatial.php @@ -0,0 +1,87 @@ +setOption('sfield', $sfield); + } + + /** + * @param int $distance + */ + public function setDistance($distance) + { + $this->setOption('d', $distance); + } + + /** + * @param string $point + */ + public function setPoint($point) + { + $this->setOption('pt', $point); + } + + /** + * Get sfield option. + * + * @return string|null + */ + public function getField() + { + return $this->getOption('sfield'); + } + + /** + * Get d option. + * + * @return int|null + */ + public function getDistance() + { + return $this->getOption('d'); + } + + /** + * Get pt option. + * + * @return int|null + */ + public function getPoint() + { + return $this->getOption('pt'); + } +} diff --git a/vendor/solarium/solarium/src/Component/Spellcheck.php b/vendor/solarium/solarium/src/Component/Spellcheck.php new file mode 100644 index 000000000..16b3d83fe --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Spellcheck.php @@ -0,0 +1,48 @@ +getOption('key'); + } + + /** + * Set key value. + * + * @param string $value + * + * @return self Provides fluent interface + */ + public function setKey($value) + { + return $this->setOption('key', $value); + } + + /** + * Specify a facet to return in the resultset. + * + * @param string $facet + * + * @return self Provides fluent interface + */ + public function addFacet($facet) + { + $this->facets[$facet] = true; + + return $this; + } + + /** + * Specify multiple facets to return in the resultset. + * + * @param string|array $facets can be an array or string with comma + * separated facetnames + * + * @return self Provides fluent interface + */ + public function addFacets($facets) + { + if (is_string($facets)) { + $facets = explode(',', $facets); + $facets = array_map('trim', $facets); + } + + foreach ($facets as $facet) { + $this->addFacet($facet); + } + + return $this; + } + + /** + * Remove a facet from the facet list. + * + * @param string $facet + * + * @return self Provides fluent interface + */ + public function removeFacet($facet) + { + if (isset($this->facets[$facet])) { + unset($this->facets[$facet]); + } + + return $this; + } + + /** + * Remove all facets from the facet list. + * + * @return self Provides fluent interface + */ + public function clearFacets() + { + $this->facets = []; + + return $this; + } + + /** + * Get the list of facets. + * + * @return array + */ + public function getFacets() + { + return array_keys($this->facets); + } + + /** + * Set multiple facets. + * + * This overwrites any existing facets + * + * @param array $facets + * + * @return self Provides fluent interface + */ + public function setFacets($facets) + { + $this->clearFacets(); + $this->addFacets($facets); + + return $this; + } + + /** + * Add pivot. + * + * @param string $pivot + * + * @return self Provides fluent interface + */ + public function addPivot($pivot) + { + $this->pivots[$pivot] = true; + + return $this; + } + + /** + * Specify multiple Pivots. + * + * @param string|array $pivots can be an array or string with comma + * separated facetnames + * + * @return self Provides fluent interface + */ + public function addPivots($pivots) + { + if (is_string($pivots)) { + $pivots = explode(',', $pivots); + $pivots = array_map('trim', $pivots); + } + + foreach ($pivots as $facet) { + $this->addPivot($facet); + } + + return $this; + } + + /** + * Remove a pivot facet from the pivot list. + * + * @param string $pivot + * + * @return self Provides fluent interface + */ + public function removePivot($pivot) + { + if (isset($this->pivots[$pivot])) { + unset($this->pivots[$pivot]); + } + + return $this; + } + + /** + * Remove all pivot facets from the pivot list. + * + * @return self Provides fluent interface + */ + public function clearPivots() + { + $this->pivots = []; + + return $this; + } + + /** + * Get the list of pivot facets. + * + * @return array + */ + public function getPivots() + { + return array_keys($this->pivots); + } + + /** + * Set multiple pivot facets. + * + * This overwrites any existing pivots + * + * @param array $pivots + * + * @return self Provides fluent interface + */ + public function setPivots($pivots) + { + $this->clearPivots(); + $this->addPivots($pivots); + + return $this; + } + + /** + * Initialize options. + * + * Several options need some extra checks or setup work, for these options + * the setters are called. + */ + protected function init() + { + foreach ($this->options as $name => $value) { + switch ($name) { + case 'facet': + $this->setFacets($value); + break; + case 'pivot': + $this->setPivots($value); + break; + } + } + } +} diff --git a/vendor/solarium/solarium/src/Component/Stats/Stats.php b/vendor/solarium/solarium/src/Component/Stats/Stats.php new file mode 100644 index 000000000..0eced07a0 --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Stats/Stats.php @@ -0,0 +1,333 @@ +setKey($options); + } else { + $fq = new Field($options); + } + + if (null !== $fq->getKey()) { + $this->addField($fq); + } + + return $fq; + } + + /** + * Add a field. + * + * Supports a field instance or a config array, in that case a new + * field instance wil be created based on the options. + * + * + * @param Field|array $field + * + * @throws InvalidArgumentException + * + * @return self Provides fluent interface + */ + public function addField($field) + { + if (is_array($field)) { + $field = new Field($field); + } + + $key = $field->getKey(); + + if (0 === strlen($key)) { + throw new InvalidArgumentException('A field must have a key value'); + } + + //double add calls for the same field are ignored, but non-unique keys cause an exception + if (array_key_exists($key, $this->fields) && $this->fields[$key] !== $field) { + throw new InvalidArgumentException('A field must have a unique key value'); + } + + $this->fields[$key] = $field; + + return $this; + } + + /** + * Add multiple fields. + * + * @param array $fields + * + * @return self Provides fluent interface + */ + public function addFields(array $fields) + { + foreach ($fields as $key => $field) { + // in case of a config array: add key to config + if (is_array($field) && !isset($field['key'])) { + $field['key'] = $key; + } + + $this->addField($field); + } + + return $this; + } + + /** + * Get a field. + * + * @param string $key + * + * @return string + */ + public function getField($key) + { + if (isset($this->fields[$key])) { + return $this->fields[$key]; + } + } + + /** + * Get all fields. + * + * @return Field[] + */ + public function getFields() + { + return $this->fields; + } + + /** + * Remove a single field. + * + * You can remove a field by passing its key, or by passing the field instance + * + * @param string|Field $field + * + * @return self Provides fluent interface + */ + public function removeField($field) + { + if (is_object($field)) { + $field = $field->getKey(); + } + + if (isset($this->fields[$field])) { + unset($this->fields[$field]); + } + + return $this; + } + + /** + * Remove all fields. + * + * @return self Provides fluent interface + */ + public function clearFields() + { + $this->fields = []; + + return $this; + } + + /** + * Set multiple fields. + * + * This overwrites any existing fields + * + * @param array $fields + * + * @return self Provides fluent interface + */ + public function setFields($fields) + { + $this->clearFields(); + $this->addFields($fields); + + return $this; + } + + /** + * Specify a facet to return in the resultset. + * + * @param string $facet + * + * @return self Provides fluent interface + */ + public function addFacet($facet) + { + $this->facets[$facet] = true; + + return $this; + } + + /** + * Specify multiple facets to return in the resultset. + * + * @param string|array $facets can be an array or string with comma + * separated facetnames + * + * @return self Provides fluent interface + */ + public function addFacets($facets) + { + if (is_string($facets)) { + $facets = explode(',', $facets); + $facets = array_map('trim', $facets); + } + + foreach ($facets as $facet) { + $this->addFacet($facet); + } + + return $this; + } + + /** + * Remove a facet from the facet list. + * + * @param string $facet + * + * @return self Provides fluent interface + */ + public function removeFacet($facet) + { + if (isset($this->facets[$facet])) { + unset($this->facets[$facet]); + } + + return $this; + } + + /** + * Remove all facets from the facet list. + * + * @return self Provides fluent interface + */ + public function clearFacets() + { + $this->facets = []; + + return $this; + } + + /** + * Get the list of facets. + * + * @return array + */ + public function getFacets() + { + return array_keys($this->facets); + } + + /** + * Set multiple facets. + * + * This overwrites any existing facets + * + * @param array $facets + * + * @return self Provides fluent interface + */ + public function setFacets($facets) + { + $this->clearFacets(); + $this->addFacets($facets); + + return $this; + } + + /** + * Initialize options. + * + * Several options need some extra checks or setup work, for these options + * the setters are called. + */ + protected function init() + { + foreach ($this->options as $name => $value) { + switch ($name) { + case 'field': + $this->setFields($value); + break; + case 'facet': + $this->setFacets($value); + break; + } + } + } +} diff --git a/vendor/solarium/solarium/src/Component/Suggester.php b/vendor/solarium/solarium/src/Component/Suggester.php new file mode 100644 index 000000000..60264b4ab --- /dev/null +++ b/vendor/solarium/solarium/src/Component/Suggester.php @@ -0,0 +1,48 @@ +getFileUpload()); + $body = "--{$request->getHash()}\r\n"; + $body .= 'Content-Disposition: form-data; name="file"; filename="'.$baseName.'"'; + $body .= "\r\nContent-Type: application/octet-stream\r\n\r\n"; + $body .= file_get_contents($request->getFileUpload(), 'r'); + $body .= "\r\n--{$request->getHash()}--\r\n"; + + return $body; + } +} diff --git a/vendor/solarium/solarium/src/Core/Client/Adapter/AdapterInterface.php b/vendor/solarium/solarium/src/Core/Client/Adapter/AdapterInterface.php new file mode 100644 index 000000000..ab97eb33b --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Client/Adapter/AdapterInterface.php @@ -0,0 +1,36 @@ + + */ +class Curl extends Configurable implements AdapterInterface +{ + /** + * Execute a Solr request using the cURL Http. + * + * @param Request $request + * @param Endpoint $endpoint + * + * @return Response + */ + public function execute($request, $endpoint) + { + return $this->getData($request, $endpoint); + } + + /** + * Get the response for a curl handle. + * + * @param resource $handle + * @param string $httpResponse + * + * @return Response + */ + public function getResponse($handle, $httpResponse) + { + // @codeCoverageIgnoreStart + if (false !== $httpResponse && null !== $httpResponse) { + $data = $httpResponse; + $info = curl_getinfo($handle); + $headers = []; + $headers[] = 'HTTP/1.1 '.$info['http_code'].' OK'; + } else { + $headers = []; + $data = ''; + } + + $this->check($data, $headers, $handle); + curl_close($handle); + + return new Response($data, $headers); + // @codeCoverageIgnoreEnd + } + + /** + * Create curl handle for a request. + * + * + * @param Request $request + * @param Endpoint $endpoint + * + * @throws InvalidArgumentException + * + * @return resource + */ + public function createHandle($request, $endpoint) + { + // @codeCoverageIgnoreStart + $baseUri = $request->getIsServerRequest() ? $endpoint->getServerUri() : $endpoint->getCoreBaseUri(); + $uri = $baseUri.$request->getUri(); + + $method = $request->getMethod(); + $options = $this->createOptions($request, $endpoint); + + $handler = curl_init(); + curl_setopt($handler, CURLOPT_URL, $uri); + curl_setopt($handler, CURLOPT_RETURNTRANSFER, true); + if (!(function_exists('ini_get') && ini_get('open_basedir'))) { + curl_setopt($handler, CURLOPT_FOLLOWLOCATION, true); + } + curl_setopt($handler, CURLOPT_TIMEOUT, $options['timeout']); + curl_setopt($handler, CURLOPT_CONNECTTIMEOUT, $options['timeout']); + + if (null !== ($proxy = $this->getOption('proxy'))) { + curl_setopt($handler, CURLOPT_PROXY, $proxy); + } + + if (!isset($options['headers']['Content-Type'])) { + if (Request::METHOD_GET == $method) { + $options['headers']['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'; + } else { + $options['headers']['Content-Type'] = 'application/xml; charset=utf-8'; + } + } + + // Try endpoint authentication first, fallback to request for backwards compatibility + $authData = $endpoint->getAuthentication(); + if (empty($authData['username'])) { + $authData = $request->getAuthentication(); + } + + if (!empty($authData['username']) && !empty($authData['password'])) { + curl_setopt($handler, CURLOPT_USERPWD, $authData['username'].':'.$authData['password']); + curl_setopt($handler, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + } + + if (count($options['headers'])) { + $headers = []; + foreach ($options['headers'] as $key => $value) { + $headers[] = $key.': '.$value; + } + curl_setopt($handler, CURLOPT_HTTPHEADER, $headers); + } + + if (Request::METHOD_POST == $method) { + curl_setopt($handler, CURLOPT_POST, true); + + if ($request->getFileUpload()) { + $helper = new AdapterHelper(); + $data = $helper->buildUploadBodyFromRequest($request); + curl_setopt($handler, CURLOPT_POSTFIELDS, $data); + } else { + curl_setopt($handler, CURLOPT_POSTFIELDS, $request->getRawData()); + } + } elseif (Request::METHOD_GET == $method) { + curl_setopt($handler, CURLOPT_HTTPGET, true); + } elseif (Request::METHOD_HEAD == $method) { + curl_setopt($handler, CURLOPT_CUSTOMREQUEST, 'HEAD'); + } elseif (Request::METHOD_DELETE == $method) { + curl_setopt($handler, CURLOPT_CUSTOMREQUEST, 'DELETE'); + } elseif (Request::METHOD_PUT == $method) { + curl_setopt($handler, CURLOPT_CUSTOMREQUEST, 'PUT'); + + if ($request->getFileUpload()) { + $helper = new AdapterHelper(); + $data = $helper->buildUploadBodyFromRequest($request); + curl_setopt($handler, CURLOPT_POSTFIELDS, $data); + } else { + curl_setopt($handler, CURLOPT_POSTFIELDS, $request->getRawData()); + } + } else { + throw new InvalidArgumentException("unsupported method: $method"); + } + + return $handler; + // @codeCoverageIgnoreEnd + } + + /** + * Check result of a request. + * + * + * @param string $data + * @param array $headers + * @param resource $handle + * + * @throws HttpException + */ + public function check($data, $headers, $handle) + { + // if there is no data and there are no headers it's a total failure, + // a connection to the host was impossible. + if (empty($data) && 0 == count($headers)) { + throw new HttpException('HTTP request failed, '.curl_error($handle)); + } + } + + /** + * Execute request. + * + * @param Request $request + * @param Endpoint $endpoint + * + * @return Response + */ + protected function getData($request, $endpoint) + { + // @codeCoverageIgnoreStart + $handle = $this->createHandle($request, $endpoint); + $httpResponse = curl_exec($handle); + + return $this->getResponse($handle, $httpResponse); + // @codeCoverageIgnoreEnd + } + + /** + * Initialization hook. + * + * Checks the availability of Curl_http + * + * @throws RuntimeException + */ + protected function init() + { + // @codeCoverageIgnoreStart + if (!function_exists('curl_init')) { + throw new RuntimeException('cURL is not available, install it to use the CurlHttp adapter'); + } + + parent::init(); + // @codeCoverageIgnoreEnd + } + + /** + * Create http request options from request. + * + * @param Request $request + * @param Endpoint $endpoint + * + * @return array + */ + protected function createOptions($request, $endpoint) + { + // @codeCoverageIgnoreStart + $options = [ + 'timeout' => $endpoint->getTimeout(), + ]; + foreach ($request->getHeaders() as $headerLine) { + list($header, $value) = explode(':', $headerLine); + if ($header = trim($header)) { + $options['headers'][$header] = trim($value); + } + } + + return $options; + // @codeCoverageIgnoreEnd + } +} diff --git a/vendor/solarium/solarium/src/Core/Client/Adapter/Guzzle.php b/vendor/solarium/solarium/src/Core/Client/Adapter/Guzzle.php new file mode 100644 index 000000000..1911f6764 --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Client/Adapter/Guzzle.php @@ -0,0 +1,150 @@ + $this->getRequestHeaders($request), + RequestOptions::BODY => $this->getRequestBody($request), + RequestOptions::TIMEOUT => $endpoint->getTimeout(), + RequestOptions::CONNECT_TIMEOUT => $endpoint->getTimeout(), + ]; + + // Try endpoint authentication first, fallback to request for backwards compatibility + $authData = $endpoint->getAuthentication(); + if (empty($authData['username'])) { + $authData = $request->getAuthentication(); + } + + if (!empty($authData['username']) && !empty($authData['password'])) { + $requestOptions[RequestOptions::AUTH] = [$authData['username'], $authData['password']]; + } + + try { + $baseUri = $request->getIsServerRequest() ? $endpoint->getServerUri() : $endpoint->getCoreBaseUri(); + $uri = $baseUri.$request->getUri(); + $guzzleResponse = $this->getGuzzleClient()->request( + $request->getMethod(), + $uri, + $requestOptions + ); + + $responseHeaders = [ + "HTTP/{$guzzleResponse->getProtocolVersion()} {$guzzleResponse->getStatusCode()} " + .$guzzleResponse->getReasonPhrase(), + ]; + + foreach ($guzzleResponse->getHeaders() as $key => $value) { + $responseHeaders[] = "{$key}: ".implode(', ', $value); + } + + return new Response((string) $guzzleResponse->getBody(), $responseHeaders); + } catch (\GuzzleHttp\Exception\RequestException $e) { + $error = $e->getMessage(); + throw new HttpException("HTTP request failed, {$error}"); + } + } + + /** + * Gets the Guzzle HTTP client instance. + * + * @return GuzzleClient + */ + public function getGuzzleClient() + { + if (null === $this->guzzleClient) { + $this->guzzleClient = new GuzzleClient($this->options); + } + + return $this->guzzleClient; + } + + /** + * Helper method to create a request body suitable for a guzzle 3 request. + * + * @param Request $request the incoming solarium request + * + * @return null|resource|string + */ + private function getRequestBody(Request $request) + { + if (Request::METHOD_PUT == $request->getMethod()) { + return $request->getRawData(); + } + + if (Request::METHOD_POST !== $request->getMethod()) { + return null; + } + + if ($request->getFileUpload()) { + $helper = new AdapterHelper(); + return $helper->buildUploadBodyFromRequest($request); + } + + return $request->getRawData(); + } + + /** + * Helper method to extract headers from the incoming solarium request and put them in a format + * suitable for a guzzle 3 request. + * + * @param Request $request the incoming solarium request + * + * @return array + */ + private function getRequestHeaders(Request $request) + { + $headers = []; + foreach ($request->getHeaders() as $headerLine) { + list($header, $value) = explode(':', $headerLine); + if ($header = trim($header)) { + $headers[$header] = trim($value); + } + } + + if (!isset($headers['Content-Type'])) { + if (Request::METHOD_GET == $request->getMethod()) { + $headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'; + } else { + $headers['Content-Type'] = 'application/xml; charset=utf-8'; + } + } + + return $headers; + } +} diff --git a/vendor/solarium/solarium/src/Core/Client/Adapter/Guzzle3.php b/vendor/solarium/solarium/src/Core/Client/Adapter/Guzzle3.php new file mode 100644 index 000000000..69852baa6 --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Client/Adapter/Guzzle3.php @@ -0,0 +1,146 @@ +getIsServerRequest() ? $endpoint->getServerUri() : $endpoint->getCoreBaseUri(); + $uri = $baseUri.$request->getUri(); + $guzzleRequest = $this->getGuzzleClient()->createRequest( + $request->getMethod(), + $uri, + $this->getRequestHeaders($request), + $this->getRequestBody($request), + [ + 'timeout' => $endpoint->getTimeout(), + 'connect_timeout' => $endpoint->getTimeout(), + ] + ); + + // Try endpoint authentication first, fallback to request for backwards compatibility + $authData = $endpoint->getAuthentication(); + if (empty($authData['username'])) { + $authData = $request->getAuthentication(); + } + + if (!empty($authData['username']) && !empty($authData['password'])) { + $guzzleRequest->setAuth($authData['username'], $authData['password']); + } + + try { + $this->getGuzzleClient()->send($guzzleRequest); + + $guzzleResponse = $guzzleRequest->getResponse(); + + $responseHeaders = array_merge( + ["HTTP/1.1 {$guzzleResponse->getStatusCode()} {$guzzleResponse->getReasonPhrase()}"], + $guzzleResponse->getHeaderLines() + ); + + return new Response($guzzleResponse->getBody(true), $responseHeaders); + } catch (\Guzzle\Http\Exception\RequestException $e) { + $error = $e->getMessage(); + if ($e instanceof \Guzzle\Http\Exception\CurlException) { + $error = $e->getError(); + } + + throw new HttpException("HTTP request failed, {$error}"); + } + } + + /** + * Gets the Guzzle HTTP client instance. + * + * @return GuzzleClient + */ + public function getGuzzleClient() + { + if (null === $this->guzzleClient) { + $this->guzzleClient = new GuzzleClient(null, $this->options); + } + + return $this->guzzleClient; + } + + /** + * Helper method to create a request body suitable for a guzzle 3 request. + * + * @param Request $request the incoming solarium request + * + * @return null|resource|string + */ + private function getRequestBody(Request $request) + { + if (Request::METHOD_PUT == $request->getMethod()) { + return $request->getRawData(); + } + + if (Request::METHOD_POST !== $request->getMethod()) { + return null; + } + + if ($request->getFileUpload()) { + $helper = new AdapterHelper(); + $body = $helper->buildUploadBodyFromRequest($request); + return $body; + } + + return $request->getRawData(); + } + + /** + * Helper method to extract headers from the incoming solarium request and put them in a format + * suitable for a guzzle 3 request. + * + * @param Request $request the incoming solarium request + * + * @return array + */ + private function getRequestHeaders(Request $request) + { + $headers = []; + foreach ($request->getHeaders() as $headerLine) { + list($header, $value) = explode(':', $headerLine); + if ($header = trim($header)) { + $headers[$header] = trim($value); + } + } + + if (!isset($headers['Content-Type'])) { + if (Request::METHOD_GET == $request->getMethod()) { + $headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'; + } else { + $headers['Content-Type'] = 'application/xml; charset=utf-8'; + } + } + + return $headers; + } +} diff --git a/vendor/solarium/solarium/src/Core/Client/Adapter/Http.php b/vendor/solarium/solarium/src/Core/Client/Adapter/Http.php new file mode 100644 index 000000000..bbdcf9bd8 --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Client/Adapter/Http.php @@ -0,0 +1,163 @@ +createContext($request, $endpoint); + $baseUri = $request->getIsServerRequest() ? $endpoint->getServerUri() : $endpoint->getCoreBaseUri(); + $uri = $baseUri.$request->getUri(); + + list($data, $headers) = $this->getData($uri, $context); + + $this->check($data, $headers); + + return new Response($data, $headers); + } + + /** + * Check result of a request. + * + * + * @param string $data + * @param array $headers + * + * @throws HttpException + */ + public function check($data, $headers) + { + // if there is no data and there are no headers it's a total failure, + // a connection to the host was impossible. + if (false === $data && 0 == count($headers)) { + throw new HttpException('HTTP request failed'); + } + } + + /** + * Create a stream context for a request. + * + * @param Request $request + * @param Endpoint $endpoint + * + * @return resource + */ + public function createContext($request, $endpoint) + { + $method = $request->getMethod(); + $context = stream_context_create( + ['http' => [ + 'method' => $method, + 'timeout' => $endpoint->getTimeout(), + ], + ] + ); + + // Try endpoint authentication first, fallback to request for backwards compatibility + $authData = $endpoint->getAuthentication(); + if (empty($authData['username'])) { + $authData = $request->getAuthentication(); + } + + if (!empty($authData['username']) && !empty($authData['password'])) { + $request->addHeader( + 'Authorization: Basic '.base64_encode($authData['username'].':'.$authData['password']) + ); + } + + if (Request::METHOD_POST == $method) { + if ($request->getFileUpload()) { + $helper = new AdapterHelper(); + $data = $helper->buildUploadBodyFromRequest($request); + + $content_length = strlen($data); + $request->addHeader("Content-Length: $content_length\r\n"); + stream_context_set_option( + $context, + 'http', + 'content', + $data + ); + } else { + $data = $request->getRawData(); + if (null !== $data) { + stream_context_set_option( + $context, + 'http', + 'content', + $data + ); + + $request->addHeader('Content-Type: text/xml; charset=UTF-8'); + } + } + } elseif (Request::METHOD_PUT == $method) { + $data = $request->getRawData(); + if (null !== $data) { + stream_context_set_option( + $context, + 'http', + 'content', + $data + ); + $request->addHeader('Content-Type: application/json; charset=UTF-8'); + } + } + + $headers = $request->getHeaders(); + if (count($headers) > 0) { + stream_context_set_option( + $context, + 'http', + 'header', + implode("\r\n", $headers) + ); + } + + return $context; + } + + /** + * Execute request. + * + * @param string $uri + * @param resource $context + * + * @return array + */ + protected function getData($uri, $context) + { + // @codeCoverageIgnoreStart + $data = @file_get_contents($uri, false, $context); + + $headers = []; + + if (isset($http_response_header)) { + $headers = $http_response_header; + } + + return [$data, $headers]; + // @codeCoverageIgnoreEnd + } +} diff --git a/vendor/solarium/solarium/src/Core/Client/Adapter/PeclHttp.php b/vendor/solarium/solarium/src/Core/Client/Adapter/PeclHttp.php new file mode 100644 index 000000000..fb509a09c --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Client/Adapter/PeclHttp.php @@ -0,0 +1,192 @@ + + */ +class PeclHttp extends Configurable implements AdapterInterface +{ + /** + * Execute a Solr request using the Pecl Http. + * + * + * @param Request $request + * @param Endpoint $endpoint + * + * @throws HttpException + * + * @return Response + */ + public function execute($request, $endpoint) + { + $httpRequest = $this->toHttpRequest($request, $endpoint); + + try { + $httpMessage = $httpRequest->send(); + } catch (\Exception $e) { + throw new HttpException($e->getMessage()); + } + + return new Response( + $httpMessage->getBody(), + $this->toRawHeaders($httpMessage) + ); + } + + /** + * adapt Request to HttpRequest. + * + * {@link http://us.php.net/manual/en/http.constants.php + * HTTP Predefined Constant} + * + * {@link http://us.php.net/manual/en/http.request.options.php + * HttpRequest options} + * + * + * @param Request $request + * @param Endpoint $endpoint + * + * @throws InvalidArgumentException + * + * @return \HttpRequest + */ + public function toHttpRequest($request, $endpoint) + { + $baseUri = $request->getIsServerRequest() ? $endpoint->getServerUri() : $endpoint->getCoreBaseUri(); + $url = $baseUri.$request->getUri(); + $httpRequest = new \HttpRequest($url); + + $headers = []; + foreach ($request->getHeaders() as $headerLine) { + list($header, $value) = explode(':', $headerLine); + if ($header = trim($header)) { + $headers[$header] = trim($value); + } + } + + // Try endpoint authentication first, fallback to request for backwards compatibility + $authData = $endpoint->getAuthentication(); + if (empty($authData['username'])) { + $authData = $request->getAuthentication(); + } + + if (!empty($authData['username']) && !empty($authData['password'])) { + $headers['Authorization'] = 'Basic '.base64_encode($authData['username'].':'.$authData['password']); + } + + switch ($request->getMethod()) { + case Request::METHOD_GET: + $method = HTTP_METH_GET; + break; + case Request::METHOD_POST: + $method = HTTP_METH_POST; + if ($request->getFileUpload()) { + $httpRequest->addPostFile( + 'content', + $request->getFileUpload(), + 'application/octet-stream; charset=binary' + ); + } else { + $httpRequest->setBody($request->getRawData()); + if (!isset($headers['Content-Type'])) { + $headers['Content-Type'] = 'text/xml; charset=utf-8'; + } + } + break; + case Request::METHOD_HEAD: + $method = HTTP_METH_HEAD; + break; + case Request::METHOD_DELETE: + $method = HTTP_METH_DELETE; + break; + case Request::METHOD_PUT: + $method = HTTP_METH_PUT; + if ($request->getFileUpload()) { + $httpRequest->addPostFile( + 'content', + $request->getFileUpload(), + 'application/octet-stream; charset=binary' + ); + } else { + $httpRequest->setBody($request->getRawData()); + if (!isset($headers['Content-Type'])) { + $headers['Content-Type'] = 'application/json; charset=utf-8'; + } + } + break; + default: + throw new InvalidArgumentException( + 'Unsupported method: '.$request->getMethod() + ); + } + + $httpRequest->setMethod($method); + $httpRequest->setOptions( + [ + 'timeout' => $endpoint->getTimeout(), + 'connecttimeout' => $endpoint->getTimeout(), + 'dns_cache_timeout' => $endpoint->getTimeout(), + ] + ); + $httpRequest->setHeaders($headers); + + return $httpRequest; + } + + /** + * Initialization hook. + * + * Checks the availability of pecl_http + * + * @throws RuntimeException + */ + protected function init() + { + // @codeCoverageIgnoreStart + if (!class_exists('HttpRequest', false)) { + throw new RuntimeException('Pecl_http is not available, install it to use the PeclHttp adapter'); + } + + parent::init(); + // @codeCoverageIgnoreEnd + } + + /** + * Convert key/value pair header to raw header. + * + * + * //before + * $headers['Content-Type'] = 'text/plain'; + * + * ... + * + * //after + * $headers[0] = 'Content-Type: text/plain'; + * + * + * @param $message \HttpMessage + * + * @return array + */ + protected function toRawHeaders($message) + { + $headers[] = 'HTTP/'.$message->getHttpVersion().' '.$message->getResponseCode().' '.$message->getResponseStatus(); + + foreach ($message->getHeaders() as $header => $value) { + $headers[] = "$header: $value"; + } + + return $headers; + } +} diff --git a/vendor/solarium/solarium/src/Core/Client/Adapter/Zend2Http.php b/vendor/solarium/solarium/src/Core/Client/Adapter/Zend2Http.php new file mode 100644 index 000000000..86c06e94a --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Client/Adapter/Zend2Http.php @@ -0,0 +1,238 @@ +zendHttp) { + // forward timeout setting + $adapterOptions = []; + + // forward adapter options if available + if (isset($this->options['options'])) { + $adapterOptions = array_merge($adapterOptions, $this->options['options']); + } + + $this->zendHttp->setOptions($adapterOptions); + } + + return $this; + } + + /** + * Set the Zend\Http\Client instance. + * + * This method is optional, if you don't set a client it will be created + * upon first use, using default and/or custom options (the most common use + * case) + * + * @param \Zend\Http\Client $zendHttp + * + * @return self Provides fluent interface + */ + public function setZendHttp($zendHttp) + { + $this->zendHttp = $zendHttp; + + return $this; + } + + /** + * Get the Zend\Http\Client instance. + * + * If no instance is available yet it will be created automatically based on + * options. + * + * You can use this method to get a reference to the client instance to set + * options, get the last response and use many other features offered by the + * Zend\Http\Client API. + * + * @return \Zend\Http\Client + */ + public function getZendHttp() + { + if (null === $this->zendHttp) { + $options = []; + + // forward zendhttp options + if (isset($this->options['options'])) { + $options = array_merge( + $options, + $this->options['options'] + ); + } + + $this->zendHttp = new \Zend\Http\Client(null, $options); + } + + return $this->zendHttp; + } + + /** + * Execute a Solr request using the Zend\Http\Client instance. + * + * @param Request $request + * @param Endpoint $endpoint + * + * @throws HttpException + * @throws OutOfBoundsException + * + * @return Response + */ + public function execute($request, $endpoint) + { + $client = $this->getZendHttp(); + $client->resetParameters(); + + switch ($request->getMethod()) { + case Request::METHOD_GET: + $client->setMethod('GET'); + $client->setParameterGet($request->getParams()); + break; + case Request::METHOD_POST: + $client->setMethod('POST'); + if ($request->getFileUpload()) { + $this->prepareFileUpload($client, $request); + } else { + $client->setParameterGet($request->getParams()); + $client->setRawBody($request->getRawData()); + $request->addHeader('Content-Type: text/xml; charset=UTF-8'); + } + break; + case Request::METHOD_HEAD: + $client->setMethod('HEAD'); + $client->setParameterGet($request->getParams()); + break; + case Request::METHOD_DELETE: + $client->setMethod('DELETE'); + $client->setParameterGet($request->getParams()); + break; + case Request::METHOD_PUT: + $client->setMethod('PUT'); + if ($request->getFileUpload()) { + $this->prepareFileUpload($client, $request); + } else { + $client->setParameterGet($request->getParams()); + $client->setRawBody($request->getRawData()); + $request->addHeader('Content-Type: application/json; charset=UTF-8'); + } + break; + default: + throw new OutOfBoundsException('Unsupported method: '.$request->getMethod()); + break; + } + + $baseUri = $request->getIsServerRequest() ? $endpoint->getServerUri() : $endpoint->getCoreBaseUri(); + $uri = $baseUri.$request->getUri(); + $client->setUri($uri); + $client->setHeaders($request->getHeaders()); + $this->timeout = $endpoint->getTimeout(); + + $response = $client->send(); + + return $this->prepareResponse( + $request, + $response + ); + } + + /** + * Prepare a solarium response from the given request and client + * response. + * + * @param Request $request + * @param \Zend\Http\Response $response + * + * @throws HttpException + * + * @return Response + */ + protected function prepareResponse($request, $response) + { + if ($response->isClientError()) { + throw new HttpException( + $response->getReasonPhrase(), + $response->getStatusCode() + ); + } + + if (Request::METHOD_HEAD == $request->getMethod()) { + $data = ''; + } else { + $data = $response->getBody(); + } + + // this is used because in ZF2 status line isn't in the headers anymore + $headers = [$response->renderStatusLine()]; + + return new Response($data, $headers); + } + + /** + * Prepare the client to send the file and params in request. + * + * @param \Zend\Http\Client $client + * @param Request $request + */ + protected function prepareFileUpload($client, $request) + { + $filename = $request->getFileUpload(); + $client->setFileUpload( + 'content', + 'content', + file_get_contents($filename), + 'application/octet-stream; charset=binary' + ); + } +} diff --git a/vendor/solarium/solarium/src/Core/Client/Adapter/ZendHttp.php b/vendor/solarium/solarium/src/Core/Client/Adapter/ZendHttp.php new file mode 100644 index 000000000..b8f46a6f0 --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Client/Adapter/ZendHttp.php @@ -0,0 +1,241 @@ +zendHttp) { + // forward timeout setting + $adapterOptions = []; + + // forward adapter options if available + if (isset($this->options['options'])) { + $adapterOptions = array_merge($adapterOptions, $this->options['options']); + } + + $this->zendHttp->setConfig($adapterOptions); + } + + return $this; + } + + /** + * Set the Zend_Http_Client instance. + * + * This method is optional, if you don't set a client it will be created + * upon first use, using default and/or custom options (the most common use + * case) + * + * @param \Zend_Http_Client $zendHttp + * + * @return self Provides fluent interface + */ + public function setZendHttp($zendHttp) + { + $this->zendHttp = $zendHttp; + + return $this; + } + + /** + * Get the Zend_Http_Client instance. + * + * If no instance is available yet it will be created automatically based on + * options. + * + * You can use this method to get a reference to the client instance to set + * options, get the last response and use many other features offered by the + * Zend_Http_Client API. + * + * @return \Zend_Http_Client + */ + public function getZendHttp() + { + if (null === $this->zendHttp) { + $options = []; + + // forward zendhttp options + if (isset($this->options['options'])) { + $options = array_merge( + $options, + $this->options['options'] + ); + } + + $this->zendHttp = new \Zend_Http_Client(null, $options); + } + + return $this->zendHttp; + } + + /** + * Execute a Solr request using the Zend_Http_Client instance. + * + * + * @param Request $request + * @param Endpoint $endpoint + * + * @throws HttpException + * @throws OutOfBoundsException + * + * @return Response + */ + public function execute($request, $endpoint) + { + $client = $this->getZendHttp(); + $client->resetParameters(); + + switch ($request->getMethod()) { + case Request::METHOD_GET: + $client->setMethod(\Zend_Http_Client::GET); + $client->setParameterGet($request->getParams()); + break; + case Request::METHOD_POST: + $client->setMethod(\Zend_Http_Client::POST); + if ($request->getFileUpload()) { + $this->prepareFileUpload($client, $request); + } else { + $client->setParameterGet($request->getParams()); + $client->setRawData($request->getRawData()); + $request->addHeader('Content-Type: text/xml; charset=UTF-8'); + } + break; + case Request::METHOD_HEAD: + $client->setMethod(\Zend_Http_Client::HEAD); + $client->setParameterGet($request->getParams()); + break; + case Request::METHOD_DELETE: + $client->setMethod(\Zend_Http_Client::DELETE); + $client->setParameterGet($request->getParams()); + break; + case Request::METHOD_PUT: + $client->setMethod(\Zend_Http_Client::PUT); + $client->setParameterGet($request->getParams()); + if ($request->getFileUpload()) { + $this->prepareFileUpload($client, $request); + } else { + $client->setParameterGet($request->getParams()); + $client->setRawData($request->getRawData()); + $request->addHeader('Content-Type: application/json; charset=UTF-8'); + } + break; + default: + throw new OutOfBoundsException('Unsupported method: '.$request->getMethod()); + break; + } + + $baseUri = $request->getIsServerRequest() ? $endpoint->getServerUri() : $endpoint->getCoreBaseUri(); + $uri = $baseUri.$request->getUri(); + $client->setUri($uri); + $client->setHeaders($request->getHeaders()); + $this->timeout = $endpoint->getTimeout(); + + $response = $client->request(); + + return $this->prepareResponse( + $request, + $response + ); + } + + /** + * Prepare a solarium response from the given request and client + * response. + * + * + * @param Request $request + * @param \Zend_Http_Response $response + * + * @throws HttpException + * + * @return Response + */ + protected function prepareResponse($request, $response) + { + if ($response->isError()) { + throw new HttpException( + $response->getMessage(), + $response->getStatus() + ); + } + + if (Request::METHOD_HEAD == $request->getMethod()) { + $data = ''; + } else { + $data = $response->getBody(); + } + + // this is used because getHeaders doesn't return the HTTP header... + $headers = explode("\n", $response->getHeadersAsString()); + + return new Response($data, $headers); + } + + /** + * Prepare the client to send the file and params in request. + * + * @param \Zend_Http_Client $client + * @param Request $request + */ + protected function prepareFileUpload($client, $request) + { + $filename = $request->getFileUpload(); + $client->setFileUpload( + 'content', + 'content', + file_get_contents($filename), + 'application/octet-stream; charset=binary' + ); + } +} diff --git a/vendor/solarium/solarium/src/Core/Client/Client.php b/vendor/solarium/solarium/src/Core/Client/Client.php new file mode 100644 index 000000000..cd5608451 --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Client/Client.php @@ -0,0 +1,1331 @@ + + * $client = new Solarium\Client; + * $query = $client->createSelect(); + * $result = $client->select($query); + * + */ +class Client extends Configurable implements ClientInterface +{ + /** + * Querytype select. + */ + const QUERY_SELECT = 'select'; + + /** + * Querytype update. + */ + const QUERY_UPDATE = 'update'; + + /** + * Querytype ping. + */ + const QUERY_PING = 'ping'; + + /** + * Querytype morelikethis. + */ + const QUERY_MORELIKETHIS = 'mlt'; + + /** + * Querytype analysis field. + */ + const QUERY_ANALYSIS_FIELD = 'analysis-field'; + + /** + * Querytype analysis document. + */ + const QUERY_ANALYSIS_DOCUMENT = 'analysis-document'; + + /** + * Querytype terms. + */ + const QUERY_TERMS = 'terms'; + + /** + * Querytype spellcheck. + */ + const QUERY_SPELLCHECK = 'spell'; + + /** + * Querytype suggester. + */ + const QUERY_SUGGESTER = 'suggester'; + + /** + * Querytype stream. + */ + const QUERY_STREAM = 'stream'; + + /** + * Querytype graph. + */ + const QUERY_GRAPH = 'graph'; + + /** + * Querytype extract. + */ + const QUERY_EXTRACT = 'extract'; + + /** + * Querytype get. + */ + const QUERY_REALTIME_GET = 'get'; + + /** + * Querytype cores. + */ + const QUERY_CORE_ADMIN = 'cores'; + + /** + * Querytype managed resource. + */ + const QUERY_MANAGED_RESOURCES = 'resources'; + + /** + * Querytype managed stopwords. + */ + const QUERY_MANAGED_STOPWORDS = 'stopwords'; + + /** + * Querytype managed synonyms. + */ + const QUERY_MANAGED_SYNONYMS = 'synonyms'; + + /** + * Default options. + * + * @var array + */ + protected $options = [ + 'adapter' => 'Solarium\Core\Client\Adapter\Curl', + 'endpoint' => [ + 'localhost' => [], + ], + ]; + + /** + * Querytype mappings. + * + * These can be customized using {@link registerQueryType()} + */ + protected $queryTypes = [ + self::QUERY_SELECT => 'Solarium\QueryType\Select\Query\Query', + self::QUERY_UPDATE => 'Solarium\QueryType\Update\Query\Query', + self::QUERY_PING => 'Solarium\QueryType\Ping\Query', + self::QUERY_MORELIKETHIS => 'Solarium\QueryType\MoreLikeThis\Query', + self::QUERY_ANALYSIS_DOCUMENT => 'Solarium\QueryType\Analysis\Query\Document', + self::QUERY_ANALYSIS_FIELD => 'Solarium\QueryType\Analysis\Query\Field', + self::QUERY_TERMS => 'Solarium\QueryType\Terms\Query', + self::QUERY_SPELLCHECK => 'Solarium\QueryType\Spellcheck\Query', + self::QUERY_SUGGESTER => 'Solarium\QueryType\Suggester\Query', + self::QUERY_STREAM => 'Solarium\QueryType\Stream\Query', + self::QUERY_GRAPH => 'Solarium\QueryType\Graph\Query', + self::QUERY_EXTRACT => 'Solarium\QueryType\Extract\Query', + self::QUERY_REALTIME_GET => 'Solarium\QueryType\RealtimeGet\Query', + self::QUERY_CORE_ADMIN => 'Solarium\QueryType\Server\CoreAdmin\Query\Query', + self::QUERY_MANAGED_RESOURCES => 'Solarium\QueryType\ManagedResources\Query\Resources', + self::QUERY_MANAGED_STOPWORDS => 'Solarium\QueryType\ManagedResources\Query\Stopwords', + self::QUERY_MANAGED_SYNONYMS => 'Solarium\QueryType\ManagedResources\Query\Synonyms', + ]; + + /** + * Plugin types. + * + * @var array + */ + protected $pluginTypes = [ + 'loadbalancer' => 'Solarium\Plugin\Loadbalancer\Loadbalancer', + 'postbigrequest' => 'Solarium\Plugin\PostBigRequest', + 'customizerequest' => 'Solarium\Plugin\CustomizeRequest\CustomizeRequest', + 'parallelexecution' => 'Solarium\Plugin\ParallelExecution\ParallelExecution', + 'bufferedadd' => 'Solarium\Plugin\BufferedAdd\BufferedAdd', + 'prefetchiterator' => 'Solarium\Plugin\PrefetchIterator', + 'minimumscorefilter' => 'Solarium\Plugin\MinimumScoreFilter\MinimumScoreFilter', + ]; + + /** + * EventDispatcher. + * + * @var EventDispatcher + */ + protected $eventDispatcher; + + /** + * Registered plugin instances. + * + * @var PluginInterface[] + */ + protected $pluginInstances = []; + + /** + * Registered endpoints. + * + * @var Endpoint[] + */ + protected $endpoints = []; + + /** + * Default endpoint key. + * + * @var string + */ + protected $defaultEndpoint; + + /** + * Adapter instance. + * + * If an adapter instance is set using {@link setAdapter()} this var will + * contain a reference to that instance. + * + * In all other cases the adapter is lazy-loading, it will be instantiated + * on first use by {@link getAdapter()} based on the 'adapter' entry in + * {@link $options}. This option can be set using {@link setAdapter()} + * + * @var AdapterInterface + */ + protected $adapter; + + /** + * Constructor. + * + * If options are passed they will be merged with {@link $options} using + * the {@link setOptions()} method. + * + * If an EventDispatcher instance is provided this will be used instead of creating a new instance + * + * @param array|\Zend_Config $options + * @param EventDispatcher $eventDispatcher + */ + public function __construct($options = null, $eventDispatcher = null) + { + $this->eventDispatcher = $eventDispatcher; + parent::__construct($options); + } + + /** + * Create a endpoint instance. + * + * If you supply a string as the first arguments ($options) it will be used as the key for the endpoint + * and it will be registered. + * If you supply an options array/object that contains a key the endpoint will also be registered. + * + * When no key is supplied the endpoint cannot be registered, in that case you will need to do this manually + * after setting the key, by using the addEndpoint method. + * + * @param mixed $options + * @param bool $setAsDefault + * + * @return Endpoint + */ + public function createEndpoint($options = null, $setAsDefault = false) + { + if (is_string($options)) { + $endpoint = new Endpoint(); + $endpoint->setKey($options); + } else { + $endpoint = new Endpoint($options); + } + + if (null !== $endpoint->getKey()) { + $this->addEndpoint($endpoint); + if (true === $setAsDefault) { + $this->setDefaultEndpoint($endpoint); + } + } + + return $endpoint; + } + + /** + * Add an endpoint. + * + * Supports a endpoint instance or a config array as input. + * In case of options a new endpoint instance wil be created based on the options. + * + * + * @param Endpoint|array $endpoint + * + * @throws InvalidArgumentException + * + * @return self Provides fluent interface + */ + public function addEndpoint($endpoint) + { + if (is_array($endpoint)) { + $endpoint = new Endpoint($endpoint); + } + + $key = $endpoint->getKey(); + + if (0 === strlen($key)) { + throw new InvalidArgumentException('An endpoint must have a key value'); + } + + //double add calls for the same endpoint are ignored, but non-unique keys cause an exception + if (array_key_exists($key, $this->endpoints) && $this->endpoints[$key] !== $endpoint) { + throw new InvalidArgumentException('An endpoint must have a unique key'); + } + + $this->endpoints[$key] = $endpoint; + + // if no default endpoint is set do so now + if (null === $this->defaultEndpoint) { + $this->defaultEndpoint = $key; + } + + return $this; + } + + /** + * Add multiple endpoints. + * + * @param array $endpoints + * + * @return self Provides fluent interface + */ + public function addEndpoints(array $endpoints) + { + foreach ($endpoints as $key => $endpoint) { + // in case of a config array: add key to config + if (is_array($endpoint) && !isset($endpoint['key'])) { + $endpoint['key'] = $key; + } + + $this->addEndpoint($endpoint); + } + + return $this; + } + + /** + * Get an endpoint by key. + * + * + * @param string $key + * + * @throws OutOfBoundsException + * + * @return Endpoint + */ + public function getEndpoint($key = null) + { + if (null === $key) { + $key = $this->defaultEndpoint; + } + + if (!isset($this->endpoints[$key])) { + throw new OutOfBoundsException('Endpoint '.$key.' not available'); + } + + return $this->endpoints[$key]; + } + + /** + * Get all endpoints. + * + * @return Endpoint[] + */ + public function getEndpoints() + { + return $this->endpoints; + } + + /** + * Remove a single endpoint. + * + * You can remove a endpoint by passing it's key, or by passing the endpoint instance + * + * @param string|Endpoint $endpoint + * + * @return self Provides fluent interface + */ + public function removeEndpoint($endpoint) + { + if (is_object($endpoint)) { + $endpoint = $endpoint->getKey(); + } + + if (isset($this->endpoints[$endpoint])) { + unset($this->endpoints[$endpoint]); + } + + return $this; + } + + /** + * Remove all endpoints. + * + * @return self Provides fluent interface + */ + public function clearEndpoints() + { + $this->endpoints = []; + $this->defaultEndpoint = null; + + return $this; + } + + /** + * Set multiple endpoints. + * + * This overwrites any existing endpoints + * + * @param array $endpoints + */ + public function setEndpoints($endpoints) + { + $this->clearEndpoints(); + $this->addEndpoints($endpoints); + } + + /** + * Set a default endpoint. + * + * All queries executed without a specific endpoint will use this default endpoint. + * + * @param string|Endpoint $endpoint + * + * @throws OutOfBoundsException + * + * @return self Provides fluent interface + */ + public function setDefaultEndpoint($endpoint) + { + if (is_object($endpoint)) { + $endpoint = $endpoint->getKey(); + } + + if (!isset($this->endpoints[$endpoint])) { + throw new OutOfBoundsException('Unknown endpoint '.$endpoint.' cannot be set as default'); + } + + $this->defaultEndpoint = $endpoint; + + return $this; + } + + /** + * Set the adapter. + * + * The adapter has to be a class that implements the AdapterInterface + * + * If a string is passed it is assumed to be the classname and it will be + * instantiated on first use. This requires the availability of the class + * through autoloading or a manual require before calling this method. + * Any existing adapter instance will be removed by this method, this way an + * instance of the new adapter type will be created upon the next usage of + * the adapter (lazy-loading) + * + * If an adapter instance is passed it will replace the current adapter + * immediately, bypassing the lazy loading. + * + * + * @param string|Adapter\AdapterInterface $adapter + * + * @throws InvalidArgumentException + * + * @return self Provides fluent interface + */ + public function setAdapter($adapter) + { + if (is_string($adapter)) { + $this->adapter = null; + + return $this->setOption('adapter', $adapter); + } elseif ($adapter instanceof AdapterInterface) { + // forward options + $adapter->setOptions($this->getOption('adapteroptions')); + // overwrite existing adapter + $this->adapter = $adapter; + + return $this; + } + + throw new InvalidArgumentException('Invalid adapter input for setAdapter'); + } + + /** + * Get the adapter instance. + * + * If {@see $adapter} doesn't hold an instance a new one will be created by + * calling {@see createAdapter()} + * + * @param bool $autoload + * + * @return AdapterInterface + */ + public function getAdapter($autoload = true) + { + if (null === $this->adapter && $autoload) { + $this->createAdapter(); + } + + return $this->adapter; + } + + /** + * Register a querytype. + * + * You can also use this method to override any existing querytype with a new mapping. + * This requires the availability of the classes through autoloading or a manual + * require before calling this method. + * + * @param string $type + * @param string $queryClass + * + * @return self Provides fluent interface + */ + public function registerQueryType($type, $queryClass) + { + $this->queryTypes[$type] = $queryClass; + + return $this; + } + + /** + * Register multiple querytypes. + * + * @param array $queryTypes + * + * @return self Provides fluent interface + */ + public function registerQueryTypes($queryTypes) + { + foreach ($queryTypes as $type => $class) { + // support both "key=>value" and "(no-key) => array(key=>x,query=>y)" formats + if (is_array($class)) { + if (isset($class['type'])) { + $type = $class['type']; + } + $class = $class['query']; + } + + $this->registerQueryType($type, $class); + } + } + + /** + * Get all registered querytypes. + * + * @return array + */ + public function getQueryTypes() + { + return $this->queryTypes; + } + + /** + * Gets the event dispatcher. + * + * @return EventDispatcherInterface + */ + public function getEventDispatcher() + { + return $this->eventDispatcher; + } + + /** + * Sets the event dispatcher. + * + * @param EventDispatcherInterface $eventDispatcher + * + * @return $this + */ + public function setEventDispatcher(EventDispatcherInterface $eventDispatcher) + { + $this->eventDispatcher = $eventDispatcher; + + return $this; + } + + /** + * Register a plugin. + * + * You can supply a plugin instance or a plugin classname as string. + * This requires the availability of the class through autoloading + * or a manual require. + * + * + * @param string $key + * @param string|PluginInterface $plugin + * @param array $options + * + * @throws InvalidArgumentException + * + * @return self Provides fluent interface + */ + public function registerPlugin($key, $plugin, $options = []) + { + if (is_string($plugin)) { + $plugin = class_exists($plugin) ? $plugin : $plugin.strrchr($plugin, '\\'); + $plugin = new $plugin(); + } + + if (!($plugin instanceof PluginInterface)) { + throw new InvalidArgumentException('All plugins must implement the PluginInterface'); + } + + $plugin->initPlugin($this, $options); + + $this->pluginInstances[$key] = $plugin; + + return $this; + } + + /** + * Register multiple plugins. + * + * @param array $plugins + * + * @return self Provides fluent interface + */ + public function registerPlugins($plugins) + { + foreach ($plugins as $key => $plugin) { + if (!isset($plugin['key'])) { + $plugin['key'] = $key; + } + + $this->registerPlugin( + $plugin['key'], + $plugin['plugin'], + $plugin['options'] + ); + } + + return $this; + } + + /** + * Get all registered plugins. + * + * @return PluginInterface[] + */ + public function getPlugins() + { + return $this->pluginInstances; + } + + /** + * Get a plugin instance. + * + * + * @param string $key + * @param bool $autocreate + * + * @throws OutOfBoundsException + * + * @return PluginInterface|null + */ + public function getPlugin($key, $autocreate = true) + { + if (isset($this->pluginInstances[$key])) { + return $this->pluginInstances[$key]; + } elseif ($autocreate) { + if (array_key_exists($key, $this->pluginTypes)) { + $this->registerPlugin($key, $this->pluginTypes[$key]); + + return $this->pluginInstances[$key]; + } + + throw new OutOfBoundsException('Cannot autoload plugin of unknown type: '.$key); + } + } + + /** + * Remove a plugin instance. + * + * You can remove a plugin by passing the plugin key, or the plugin instance + * + * @param string|PluginInterface $plugin + * + * @return self Provides fluent interface + */ + public function removePlugin($plugin) + { + if (is_object($plugin)) { + foreach ($this->pluginInstances as $key => $instance) { + if ($instance === $plugin) { + unset($this->pluginInstances[$key]); + break; + } + } + } else { + if (isset($this->pluginInstances[$plugin])) { + unset($this->pluginInstances[$plugin]); + } + } + + return $this; + } + + /** + * Creates a request based on a query instance. + * + * + * @param QueryInterface $query + * + * @throws UnexpectedValueException + * + * @return Request + */ + public function createRequest(QueryInterface $query) + { + $event = new PreCreateRequestEvent($query); + $this->eventDispatcher->dispatch(Events::PRE_CREATE_REQUEST, $event); + if (null !== $event->getRequest()) { + return $event->getRequest(); + } + + $requestBuilder = $query->getRequestBuilder(); + if (!$requestBuilder || !($requestBuilder instanceof RequestBuilderInterface)) { + throw new UnexpectedValueException('No requestbuilder returned by querytype: '.$query->getType()); + } + + $request = $requestBuilder->build($query); + + $this->eventDispatcher->dispatch( + Events::POST_CREATE_REQUEST, + new PostCreateRequestEvent($query, $request) + ); + + return $request; + } + + /** + * Creates a result object. + * + * + * @param QueryInterface $query + * @param array Response $response + * + * @throws UnexpectedValueException; + * + * @return ResultInterface + */ + public function createResult(QueryInterface $query, $response) + { + $event = new PreCreateResultEvent($query, $response); + $this->eventDispatcher->dispatch(Events::PRE_CREATE_RESULT, $event); + if (null !== $event->getResult()) { + return $event->getResult(); + } + + $resultClass = $query->getResultClass(); + $result = new $resultClass($query, $response); + + if (!($result instanceof ResultInterface)) { + throw new UnexpectedValueException('Result class must implement the ResultInterface'); + } + + $this->eventDispatcher->dispatch( + Events::POST_CREATE_RESULT, + new PostCreateResultEvent($query, $response, $result) + ); + + return $result; + } + + /** + * Execute a query. + * + * @param QueryInterface $query + * @param Endpoint|string|null $endpoint + * + * @return ResultInterface + */ + public function execute(QueryInterface $query, $endpoint = null) + { + $event = new PreExecuteEvent($query); + $this->eventDispatcher->dispatch(Events::PRE_EXECUTE, $event); + if (null !== $event->getResult()) { + return $event->getResult(); + } + + $request = $this->createRequest($query); + $response = $this->executeRequest($request, $endpoint); + $result = $this->createResult($query, $response); + + $this->eventDispatcher->dispatch( + Events::POST_EXECUTE, + new PostExecuteEvent($query, $result) + ); + + return $result; + } + + /** + * Execute a request and return the response. + * + * @param Request $request + * @param Endpoint|string|null $endpoint + * + * @return Response + */ + public function executeRequest($request, $endpoint = null) + { + // load endpoint by string or by using the default one in case of a null value + if (!($endpoint instanceof Endpoint)) { + $endpoint = $this->getEndpoint($endpoint); + } + + $event = new PreExecuteRequestEvent($request, $endpoint); + $this->eventDispatcher->dispatch(Events::PRE_EXECUTE_REQUEST, $event); + if (null !== $event->getResponse()) { + $response = $event->getResponse(); //a plugin result overrules the standard execution result + } else { + $response = $this->getAdapter()->execute($request, $endpoint); + } + + $this->eventDispatcher->dispatch( + Events::POST_EXECUTE_REQUEST, + new PostExecuteRequestEvent($request, $endpoint, $response) + ); + + return $response; + } + + /** + * Execute a ping query. + * + * This is a convenience method that forwards the query to the + * execute method, thus allowing for an easy to use and clean API. + * + * Example usage: + * + * $client = new Solarium\Client; + * $query = $client->createPing(); + * $result = $client->ping($query); + * + * + * @param QueryInterface|\Solarium\QueryType\Ping\Query $query + * @param Endpoint|string|null $endpoint + * + * @return \Solarium\QueryType\Ping\Result + */ + public function ping(QueryInterface $query, $endpoint = null) + { + return $this->execute($query, $endpoint); + } + + /** + * Execute an update query. + * + * This is a convenience method that forwards the query to the + * execute method, thus allowing for an easy to use and clean API. + * + * Example usage: + * + * $client = new Solarium\Client; + * $query = $client->createUpdate(); + * $update->addOptimize(); + * $result = $client->update($update); + * + * + * @param QueryInterface|\Solarium\QueryType\Update\Query\Query $query + * @param Endpoint|string|null $endpoint + * + * @return \Solarium\QueryType\Update\Result + */ + public function update(QueryInterface $query, $endpoint = null) + { + return $this->execute($query, $endpoint); + } + + /** + * Execute a select query. + * + * This is a convenience method that forwards the query to the + * execute method, thus allowing for an easy to use and clean API. + * + * Example usage: + * + * $client = new Solarium\Client; + * $query = $client->createSelect(); + * $result = $client->select($query); + * + * + * @param QueryInterface|\Solarium\QueryType\Select\Query\Query $query + * @param Endpoint|string|null $endpoint + * + * @return \Solarium\QueryType\Select\Result\Result + */ + public function select(QueryInterface $query, $endpoint = null) + { + return $this->execute($query, $endpoint); + } + + /** + * Execute a MoreLikeThis query. + * + * This is a convenience method that forwards the query to the + * execute method, thus allowing for an easy to use and clean API. + * + * Example usage: + * + * $client = new Solarium\Client; + * $query = $client->createMoreLikeThis(); + * $result = $client->moreLikeThis($query); + * + * + * @param QueryInterface|\Solarium\QueryType\MoreLikeThis\Query $query + * @param Endpoint|string|null $endpoint + * + * @return \Solarium\QueryType\MoreLikeThis\Result + */ + public function moreLikeThis(QueryInterface $query, $endpoint = null) + { + return $this->execute($query, $endpoint); + } + + /** + * Execute an analysis query. + * + * This is a convenience method that forwards the query to the + * execute method, thus allowing for an easy to use and clean API. + * + * @param QueryInterface|\Solarium\QueryType\Analysis\Query\Document|\Solarium\QueryType\Analysis\Query\Field $query + * @param Endpoint|string|null $endpoint + * + * @return \Solarium\QueryType\Analysis\Result\Document|\Solarium\QueryType\Analysis\Result\Field + */ + public function analyze(QueryInterface $query, $endpoint = null) + { + return $this->execute($query, $endpoint); + } + + /** + * Execute a terms query. + * + * This is a convenience method that forwards the query to the + * execute method, thus allowing for an easy to use and clean API. + * + * @param QueryInterface|\Solarium\QueryType\Terms\Query $query + * @param Endpoint|string|null $endpoint + * + * @return \Solarium\QueryType\Terms\Result + */ + public function terms(QueryInterface $query, $endpoint = null) + { + return $this->execute($query, $endpoint); + } + + /** + * Execute a spellcheck query. + * + * This is a convenience method that forwards the query to the + * execute method, thus allowing for an easy to use and clean API. + * + * @param QueryInterface|\Solarium\QueryType\Spellcheck\Query $query + * @param Endpoint|string|null $endpoint + * + * @return \Solarium\QueryType\Spellcheck\Result\Result + */ + public function spellcheck(QueryInterface $query, $endpoint = null) + { + return $this->execute($query, $endpoint); + } + + /** + * Execute a suggester query. + * + * This is a convenience method that forwards the query to the + * execute method, thus allowing for an easy to use and clean API. + * + * @param QueryInterface|\Solarium\QueryType\Suggester\Query $query + * @param Endpoint|string|null $endpoint + * + * @return \Solarium\QueryType\Suggester\Result\Result + */ + public function suggester(QueryInterface $query, $endpoint = null) + { + return $this->execute($query, $endpoint); + } + + /** + * Execute an extract query. + * + * This is a convenience method that forwards the query to the + * execute method, thus allowing for an easy to use and clean API. + * + * @param QueryInterface|\Solarium\QueryType\Extract\Query $query + * @param Endpoint|string|null $endpoint + * + * @return \Solarium\QueryType\Extract\Result + */ + public function extract(QueryInterface $query, $endpoint = null) + { + return $this->execute($query, $endpoint); + } + + /** + * Execute a RealtimeGet query. + * + * This is a convenience method that forwards the query to the + * execute method, thus allowing for an easy to use and clean API. + * + * @param QueryInterface|\Solarium\QueryType\RealtimeGet\Query $query + * @param Endpoint|string|null $endpoint + * + * @return \Solarium\QueryType\RealtimeGet\Result + */ + public function realtimeGet(QueryInterface $query, $endpoint = null) + { + return $this->execute($query, $endpoint); + } + + /** + * Execute a CoreAdmin query. + * + * This is a convenience method that forwards the query to the + * execute method, thus allowing for an easy to use and clean API. + * + * @param QueryInterface|\Solarium\QueryType\Server\CoreAdmin\Query\Query $query + * @param Endpoint|string|null $endpoint + * + * @return \Solarium\QueryType\Server\CoreAdmin\Result\Result + */ + public function coreAdmin(QueryInterface $query, $endpoint = null) + { + return $this->execute($query, $endpoint); + } + + /** + * Create a query instance. + * + * + * @param string $type + * @param array $options + * + * @throws InvalidArgumentException|UnexpectedValueException + * + * @return \Solarium\Core\Query\AbstractQuery + */ + public function createQuery($type, $options = null) + { + $type = strtolower($type); + + $event = new PreCreateQueryEvent($type, $options); + $this->eventDispatcher->dispatch(Events::PRE_CREATE_QUERY, $event); + if (null !== $event->getQuery()) { + return $event->getQuery(); + } + + if (!isset($this->queryTypes[$type])) { + throw new InvalidArgumentException('Unknown querytype: '.$type); + } + + $class = $this->queryTypes[$type]; + $query = new $class($options); + + if (!($query instanceof QueryInterface)) { + throw new UnexpectedValueException('All query classes must implement the QueryInterface'); + } + + $this->eventDispatcher->dispatch( + Events::POST_CREATE_QUERY, + new PostCreateQueryEvent($type, $options, $query) + ); + + return $query; + } + + /** + * Create a select query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\Select\Query\Query + */ + public function createSelect($options = null) + { + return $this->createQuery(self::QUERY_SELECT, $options); + } + + /** + * Create a MoreLikeThis query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\MorelikeThis\Query + */ + public function createMoreLikeThis($options = null) + { + return $this->createQuery(self::QUERY_MORELIKETHIS, $options); + } + + /** + * Create an update query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\Update\Query\Query + */ + public function createUpdate($options = null) + { + return $this->createQuery(self::QUERY_UPDATE, $options); + } + + /** + * Create a ping query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\Ping\Query + */ + public function createPing($options = null) + { + return $this->createQuery(self::QUERY_PING, $options); + } + + /** + * Create an analysis field query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\Analysis\Query\Field + */ + public function createAnalysisField($options = null) + { + return $this->createQuery(self::QUERY_ANALYSIS_FIELD, $options); + } + + /** + * Create an analysis document query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\Analysis\Query\Document + */ + public function createAnalysisDocument($options = null) + { + return $this->createQuery(self::QUERY_ANALYSIS_DOCUMENT, $options); + } + + /** + * Create a terms query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\Terms\Query + */ + public function createTerms($options = null) + { + return $this->createQuery(self::QUERY_TERMS, $options); + } + + /** + * Create a specllcheck query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\Spellcheck\Query + */ + public function createSpellcheck($options = null) + { + return $this->createQuery(self::QUERY_SPELLCHECK, $options); + } + + /** + * Create a suggester query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\Suggester\Query + */ + public function createSuggester($options = null) + { + return $this->createQuery(self::QUERY_SUGGESTER, $options); + } + + /** + * Create an extract query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\Extract\Query + */ + public function createExtract($options = null) + { + return $this->createQuery(self::QUERY_EXTRACT, $options); + } + + /** + * Create a stream query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\Stream\Query + */ + public function createStream($options = null) + { + // Streaming expressions tend to be very long. Therfore we use the 'postbigrequest' plugin. The plugin needs to + // be loaded before the request is created. + $this->getPlugin('postbigrequest'); + + return $this->createQuery(self::QUERY_STREAM, $options); + } + + /** + * Create a graph query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\Graph\Query + */ + public function createGraph($options = null) + { + // Streaming expressions tend to be very long. Therfore we use the 'postbigrequest' plugin. The plugin needs to + // be loaded before the request is created. + $this->getPlugin('postbigrequest'); + + return $this->createQuery(self::QUERY_GRAPH, $options); + } + + /** + * Create a RealtimeGet query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\RealtimeGet\Query + */ + public function createRealtimeGet($options = null) + { + return $this->createQuery(self::QUERY_REALTIME_GET, $options); + } + + /** + * Create a CoreAdmin query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\Server\CoreAdmin\Query\Query + */ + public function createCoreAdmin($options = null) + { + return $this->createQuery(self::QUERY_CORE_ADMIN, $options); + } + + /** + * Create a managed resources query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\ManagedResources\Query\Resources + */ + public function createManagedResources($options = null) + { + return $this->createQuery(self::QUERY_MANAGED_RESOURCES, $options); + } + + /** + * Create a managed resources query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\ManagedResources\Query\Stopwords + */ + public function createManagedStopwords($options = null) + { + return $this->createQuery(self::QUERY_MANAGED_STOPWORDS, $options); + } + + /** + * Create a managed resources query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\ManagedResources\Query\Synonyms + */ + public function createManagedSynonyms($options = null) + { + return $this->createQuery(self::QUERY_MANAGED_SYNONYMS, $options); + } + + /** + * Initialization hook. + */ + protected function init() + { + if (null === $this->eventDispatcher) { + $this->eventDispatcher = new EventDispatcher(); + } + + foreach ($this->options as $name => $value) { + switch ($name) { + case 'endpoint': + $this->setEndpoints($value); + break; + case 'querytype': + $this->registerQueryTypes($value); + break; + case 'plugin': + $this->registerPlugins($value); + break; + } + } + } + + /** + * Create an adapter instance. + * + * The 'adapter' entry in {@link $options} will be used to create an + * adapter instance. This entry can be the default value of + * {@link $options}, a value passed to the constructor or a value set by + * using {@link setAdapter()} + * + * This method is used for lazy-loading the adapter upon first use in + * {@link getAdapter()} + * + * @throws InvalidArgumentException + */ + protected function createAdapter() + { + $adapterClass = $this->getOption('adapter'); + $adapter = new $adapterClass(); + + // check interface + if (!($adapter instanceof AdapterInterface)) { + throw new InvalidArgumentException('An adapter must implement the AdapterInterface'); + } + + $adapter->setOptions($this->getOption('adapteroptions')); + $this->adapter = $adapter; + } +} diff --git a/vendor/solarium/solarium/src/Core/Client/ClientInterface.php b/vendor/solarium/solarium/src/Core/Client/ClientInterface.php new file mode 100644 index 000000000..af788a07f --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Client/ClientInterface.php @@ -0,0 +1,615 @@ + + * $client = new Solarium\Client; + * $query = $client->createSelect(); + * $result = $client->select($query); + * + */ +interface ClientInterface +{ + /** + * Create a endpoint instance. + * + * If you supply a string as the first arguments ($options) it will be used as the key for the endpoint + * and it will be registered. + * If you supply an options array/object that contains a key the endpoint will also be registered. + * + * When no key is supplied the endpoint cannot be registered, in that case you will need to do this manually + * after setting the key, by using the addEndpoint method. + * + * @param mixed $options + * @param bool $setAsDefault + * + * @return Endpoint + */ + public function createEndpoint($options = null, $setAsDefault = false); + + /** + * Add an endpoint. + * + * Supports a endpoint instance or a config array as input. + * In case of options a new endpoint instance wil be created based on the options. + * + * @param Endpoint|array $endpoint + * + * @throws InvalidArgumentException + * + * @return self Provides fluent interface + */ + public function addEndpoint($endpoint); + + /** + * Add multiple endpoints. + * + * @param array $endpoints + * + * @return self Provides fluent interface + */ + public function addEndpoints(array $endpoints); + + /** + * Get an endpoint by key. + * + * @param string $key + * + * @throws OutOfBoundsException + * + * @return Endpoint + */ + public function getEndpoint($key = null); + + /** + * Get all endpoints. + * + * @return Endpoint[] + */ + public function getEndpoints(); + + /** + * Remove a single endpoint. + * + * You can remove a endpoint by passing it's key, or by passing the endpoint instance + * + * @param string|Endpoint $endpoint + * + * @return self Provides fluent interface + */ + public function removeEndpoint($endpoint); + + /** + * Remove all endpoints. + * + * @return self Provides fluent interface + */ + public function clearEndpoints(); + + /** + * Set multiple endpoints. + * + * This overwrites any existing endpoints + * + * @param array $endpoints + */ + public function setEndpoints($endpoints); + + /** + * Set a default endpoint. + * + * All queries executed without a specific endpoint will use this default endpoint. + * + * @param string|Endpoint $endpoint + * + * @throws OutOfBoundsException + * + * @return self Provides fluent interface + */ + public function setDefaultEndpoint($endpoint); + + /** + * Set the adapter. + * + * The adapter has to be a class that implements the AdapterInterface + * + * If a string is passed it is assumed to be the classname and it will be + * instantiated on first use. This requires the availability of the class + * through autoloading or a manual require before calling this method. + * Any existing adapter instance will be removed by this method, this way an + * instance of the new adapter type will be created upon the next usage of + * the adapter (lazy-loading) + * + * If an adapter instance is passed it will replace the current adapter + * immediately, bypassing the lazy loading. + * + * @param string|Adapter\AdapterInterface $adapter + * + * @throws InvalidArgumentException + * + * @return self Provides fluent interface + */ + public function setAdapter($adapter); + + /** + * Get the adapter instance. + * + * If {@see $adapter} doesn't hold an instance a new one will be created by + * calling {@see createAdapter()} + * + * @param bool $autoload + * + * @return AdapterInterface + */ + public function getAdapter($autoload = true); + + /** + * Register a querytype. + * + * You can also use this method to override any existing querytype with a new mapping. + * This requires the availability of the classes through autoloading or a manual + * require before calling this method. + * + * @param string $type + * @param string $queryClass + * + * @return self Provides fluent interface + */ + public function registerQueryType($type, $queryClass); + + /** + * Register multiple querytypes. + * + * @param array $queryTypes + * + * @return self Provides fluent interface + */ + public function registerQueryTypes($queryTypes); + + /** + * Get all registered querytypes. + * + * @return array + */ + public function getQueryTypes(); + + /** + * Gets the event dispatcher. + * + * @return EventDispatcherInterface + */ + public function getEventDispatcher(); + + /** + * Sets the event dispatcher. + * + * @param EventDispatcherInterface $eventDispatcher + * + * @return self Provides fluent interface + */ + public function setEventDispatcher(EventDispatcherInterface $eventDispatcher); + + /** + * Register a plugin. + * + * You can supply a plugin instance or a plugin classname as string. + * This requires the availability of the class through autoloading + * or a manual require. + * + * @param string $key + * @param string|PluginInterface $plugin + * @param array $options + * + * @throws InvalidArgumentException + * + * @return self Provides fluent interface + */ + public function registerPlugin($key, $plugin, $options = []); + + /** + * Register multiple plugins. + * + * @param array $plugins + * + * @return self Provides fluent interface + */ + public function registerPlugins($plugins); + + /** + * Get all registered plugins. + * + * @return PluginInterface[] + */ + public function getPlugins(); + + /** + * Get a plugin instance. + * + * @param string $key + * @param bool $autocreate + * + * @throws OutOfBoundsException + * + * @return PluginInterface|null + */ + public function getPlugin($key, $autocreate = true); + + /** + * Remove a plugin instance. + * + * You can remove a plugin by passing the plugin key, or the plugin instance + * + * @param string|PluginInterface $plugin + * + * @return self Provides fluent interface + */ + public function removePlugin($plugin); + + /** + * Creates a request based on a query instance. + * + * @param QueryInterface $query + * + * @throws UnexpectedValueException + * + * @return Request + */ + public function createRequest(QueryInterface $query); + + /** + * Creates a result object. + * + * @param QueryInterface $query + * @param array Response $response + * + * @throws UnexpectedValueException; + * + * @return ResultInterface + */ + public function createResult(QueryInterface $query, $response); + + /** + * Execute a query. + * + * @param QueryInterface $query + * @param Endpoint|string|null $endpoint + * + * @return ResultInterface + */ + public function execute(QueryInterface $query, $endpoint = null); + + /** + * Execute a request and return the response. + * + * @param Request + * @param Endpoint|string|null + * @param mixed $request + * @param null|mixed $endpoint + * + * @return Response + */ + public function executeRequest($request, $endpoint = null); + + /** + * Execute a ping query. + * + * Example usage: + * + * $client = new Solarium\Client; + * $query = $client->createPing(); + * $result = $client->ping($query); + * + * + * @see \Solarium\QueryType\Ping\Query + * + * @internal this is a convenience method that forwards the query to the + * execute method, thus allowing for an easy to use and clean API + * + * @param QueryInterface|\Solarium\QueryType\Ping\Query $query + * @param Endpoint|string|null $endpoint + * + * @return \Solarium\QueryType\Ping\Result + */ + public function ping(QueryInterface $query, $endpoint = null); + + /** + * Execute an update query. + * + * Example usage: + * + * $client = new Solarium\Client; + * $query = $client->createUpdate(); + * $update->addOptimize(); + * $result = $client->update($update); + * + * + * @see \Solarium\QueryType\Update\Query\Query + * @see \Solarium\QueryType\Update\Result + * + * @internal this is a convenience method that forwards the query to the + * execute method, thus allowing for an easy to use and clean API + * + * @param QueryInterface|\Solarium\QueryType\Update\Query\Query $query + * @param Endpoint|string|null $endpoint + * + * @return \Solarium\QueryType\Update\Result + */ + public function update(QueryInterface $query, $endpoint = null); + + /** + * Execute a select query. + * + * Example usage: + * + * $client = new Solarium\Client; + * $query = $client->createSelect(); + * $result = $client->select($query); + * + * + * @see \Solarium\QueryType\Select\Query\Query + * @see \Solarium\QueryType\Select\Result\Result + * + * @internal this is a convenience method that forwards the query to the + * execute method, thus allowing for an easy to use and clean API + * + * @param QueryInterface|\Solarium\QueryType\Select\Query\Query $query + * @param Endpoint|string|null $endpoint + * + * @return \Solarium\QueryType\Select\Result\Result + */ + public function select(QueryInterface $query, $endpoint = null); + + /** + * Execute a MoreLikeThis query. + * + * Example usage: + * + * $client = new Solarium\Client; + * $query = $client->createMoreLikeThis(); + * $result = $client->moreLikeThis($query); + * + * + * @see \Solarium\QueryType\MoreLikeThis\Query + * @see \Solarium\QueryType\MoreLikeThis\Result + * + * @internal this is a convenience method that forwards the query to the + * execute method, thus allowing for an easy to use and clean API + * + * @param QueryInterface|\Solarium\QueryType\MoreLikeThis\Query $query + * @param Endpoint|string|null $endpoint + * + * @return \Solarium\QueryType\MoreLikeThis\Result + */ + public function moreLikeThis(QueryInterface $query, $endpoint = null); + + /** + * Execute an analysis query. + * + * @internal this is a convenience method that forwards the query to the + * execute method, thus allowing for an easy to use and clean API + * + * @param QueryInterface|AnalysisQueryDocument|AnalysisQueryField $query + * @param Endpoint|string|null $endpoint + * + * @return AnalysisResultDocument|AnalysisResultField + */ + public function analyze(QueryInterface $query, $endpoint = null); + + /** + * Execute a terms query. + * + * @internal this is a convenience method that forwards the query to the + * execute method, thus allowing for an easy to use and clean API + * + * @param QueryInterface|\Solarium\QueryType\Terms\Query $query + * @param Endpoint|string|null $endpoint + * + * @return \Solarium\QueryType\Terms\Result + */ + public function terms(QueryInterface $query, $endpoint = null); + + /** + * Execute a spellcheck query. + * + * @internal this is a convenience method that forwards the query to the + * execute method, thus allowing for an easy to use and clean API + * + * @param QueryInterface|\Solarium\QueryType\Spellcheck\Query $query + * @param Endpoint|string|null $endpoint + * + * @return \Solarium\QueryType\Spellcheck\Result\Result + */ + public function spellcheck(QueryInterface $query, $endpoint = null); + + /** + * Execute a suggester query. + * + * @internal this is a convenience method that forwards the query to the + * execute method, thus allowing for an easy to use and clean API + * + * @param QueryInterface|\Solarium\QueryType\Suggester\Query $query + * @param Endpoint|string|null $endpoint + * + * @return \Solarium\QueryType\Suggester\Result\Result + */ + public function suggester(QueryInterface $query, $endpoint = null); + + /** + * Execute an extract query. + * + * @internal this is a convenience method that forwards the query to the + * execute method, thus allowing for an easy to use and clean API + * + * @param QueryInterface|\Solarium\QueryType\Extract\Query $query + * @param Endpoint|string|null $endpoint + * + * @return \Solarium\QueryType\Extract\Result + */ + public function extract(QueryInterface $query, $endpoint = null); + + /** + * Execute a RealtimeGet query. + * + * @internal this is a convenience method that forwards the query to the + * execute method, thus allowing for an easy to use and clean API + * + * @param QueryInterface|\Solarium\QueryType\RealtimeGet\Query $query + * @param Endpoint|string|null $endpoint + * + * @return \Solarium\QueryType\RealtimeGet\Result + */ + public function realtimeGet(QueryInterface $query, $endpoint = null); + + /** + * Execute a CoreAdmin query. + * + * @internal this is a convenience method that forwards the query to the + * execute method, thus allowing for an easy to use and clean API + * + * @param QueryInterface|\Solarium\QueryType\Server\CoreAdmin\Query\Query $query + * @param Endpoint|string|null $endpoint + * + * @return \Solarium\QueryType\Server\CoreAdmin\Result\Result + */ + public function coreAdmin(QueryInterface $query, $endpoint = null); + + /** + * Create a query instance. + * + * @param string $type + * @param array $options + * + * @throws InvalidArgumentException|UnexpectedValueException + * + * @return \Solarium\Core\Query\Query + */ + public function createQuery($type, $options = null); + + /** + * Create a select query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\Select\Query\Query + */ + public function createSelect($options = null); + + /** + * Create a MoreLikeThis query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\MorelikeThis\Query + */ + public function createMoreLikeThis($options = null); + + /** + * Create an update query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\Update\Query\Query + */ + public function createUpdate($options = null); + + /** + * Create a ping query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\Ping\Query + */ + public function createPing($options = null); + + /** + * Create an analysis field query instance. + * + * @param mixed $options + * + * @return AnalysisQueryField + */ + public function createAnalysisField($options = null); + + /** + * Create an analysis document query instance. + * + * @param mixed $options + * + * @return AnalysisQueryDocument + */ + public function createAnalysisDocument($options = null); + + /** + * Create a terms query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\Terms\Query + */ + public function createTerms($options = null); + + /** + * Create a spellcheck query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\Spellcheck\Query + */ + public function createSpellcheck($options = null); + + /** + * Create a suggester query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\Suggester\Query + */ + public function createSuggester($options = null); + + /** + * Create an extract query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\Extract\Query + */ + public function createExtract($options = null); + + /** + * Create a RealtimeGet query instance. + * + * @param mixed $options + * + * @return \Solarium\QueryType\RealtimeGet\Query + */ + public function createRealtimeGet($options = null); + + /** + * @param mixed $options + * + * @return \Solarium\QueryType\Server\CoreAdmin\Query\Query + */ + public function createCoreAdmin($options = null); +} diff --git a/vendor/solarium/solarium/src/Core/Client/Endpoint.php b/vendor/solarium/solarium/src/Core/Client/Endpoint.php new file mode 100644 index 000000000..6a147a900 --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Client/Endpoint.php @@ -0,0 +1,299 @@ + 'http', + 'host' => '127.0.0.1', + 'port' => 8983, + 'path' => '/solr', + 'core' => null, + 'timeout' => 5, + ]; + + /** + * Magic method enables a object to be transformed to a string. + * + * Get a summary showing significant variables in the object + * note: uri resource is decoded for readability + * + * @return string + */ + public function __toString() + { + $output = __CLASS__.'::__toString'."\n".'base uri: '.$this->getCoreBaseUri()."\n".'host: '.$this->getHost()."\n".'port: '.$this->getPort()."\n".'path: '.$this->getPath()."\n".'core: '.$this->getCore()."\n".'timeout: '.$this->getTimeout()."\n".'authentication: '.print_r($this->getAuthentication(), 1); + + return $output; + } + + /** + * Get key value. + * + * @return string + */ + public function getKey() + { + return $this->getOption('key'); + } + + /** + * Set key value. + * + * @param string $value + * + * @return self Provides fluent interface + */ + public function setKey($value) + { + return $this->setOption('key', $value); + } + + /** + * Set host option. + * + * @param string $host This can be a hostname or an IP address + * + * @return self Provides fluent interface + */ + public function setHost($host) + { + return $this->setOption('host', $host); + } + + /** + * Get host option. + * + * @return string + */ + public function getHost() + { + return $this->getOption('host'); + } + + /** + * Set port option. + * + * @param int $port Common values are 80, 8080 and 8983 + * + * @return self Provides fluent interface + */ + public function setPort($port) + { + return $this->setOption('port', $port); + } + + /** + * Get port option. + * + * @return int + */ + public function getPort() + { + return $this->getOption('port'); + } + + /** + * Set path option. + * + * If the path has a trailing slash it will be removed. + * + * @param string $path + * + * @return self Provides fluent interface + */ + public function setPath($path) + { + if ('/' == substr($path, -1)) { + $path = substr($path, 0, -1); + } + + return $this->setOption('path', $path); + } + + /** + * Get path option. + * + * @return string + */ + public function getPath() + { + return $this->getOption('path'); + } + + /** + * Set core option. + * + * @param string $core + * + * @return self Provides fluent interface + */ + public function setCore($core) + { + return $this->setOption('core', $core); + } + + /** + * Get core option. + * + * @return string + */ + public function getCore() + { + return $this->getOption('core'); + } + + /** + * Set timeout option. + * + * @param int $timeout + * + * @return self Provides fluent interface + */ + public function setTimeout($timeout) + { + return $this->setOption('timeout', $timeout); + } + + /** + * Get timeout option. + * + * @return string + */ + public function getTimeout() + { + return $this->getOption('timeout'); + } + + /** + * Set scheme option. + * + * @param string $scheme + * + * @return self Provides fluent interface + */ + public function setScheme($scheme) + { + return $this->setOption('scheme', $scheme); + } + + /** + * Get scheme option. + * + * @return string + */ + public function getScheme() + { + return $this->getOption('scheme'); + } + + /** + * Get the base url for all requests. + * + * Based on host, path, port and core options. + * + * @return string + */ + public function getCoreBaseUri() + { + $uri = $this->getServerUri(); + $core = $this->getCore(); + + if (!empty($core)) { + $uri .= $core.'/'; + } + + return $uri; + } + + /** + * Get the base url for all requests. + * + * Based on host, path, port and core options. + * + * @deprecated Please use getCoreBaseUri or getServerUri now, will be removed in Solarium 5 + * + * @return string + */ + public function getBaseUri() + { + $message = 'Endpoint::getBaseUri is deprecated since Solarium 4.2, will be removed in Solarium 5.'. + 'please use getServerUri or getCoreBaseUri now.'; + @trigger_error($message, E_USER_DEPRECATED); + + return $this->getCoreBaseUri(); + } + + /** + * Get the server uri, required for non core/collection specific requests. + * + * @return string + */ + public function getServerUri() + { + return $this->getScheme().'://'.$this->getHost().':'.$this->getPort().$this->getPath().'/'; + } + + /** + * Set HTTP basic auth settings. + * + * If one or both values are NULL authentication will be disabled + * + * @param string $username + * @param string $password + * + * @return self Provides fluent interface + */ + public function setAuthentication($username, $password) + { + $this->setOption('username', $username); + $this->setOption('password', $password); + + return $this; + } + + /** + * Get HTTP basic auth settings. + * + * @return array + */ + public function getAuthentication() + { + return [ + 'username' => $this->getOption('username'), + 'password' => $this->getOption('password'), + ]; + } + + /** + * Initialization hook. + * + * In this case the path needs to be cleaned of trailing slashes. + * + * @see setPath() + */ + protected function init() + { + foreach ($this->options as $name => $value) { + switch ($name) { + case 'path': + $this->setPath($value); + break; + } + } + } +} diff --git a/vendor/solarium/solarium/src/Core/Client/Request.php b/vendor/solarium/solarium/src/Core/Client/Request.php new file mode 100644 index 000000000..fd4b69666 --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Client/Request.php @@ -0,0 +1,348 @@ + self::METHOD_GET, + ]; + + /** + * Request headers. + */ + protected $headers = []; + + /** + * Raw POST data. + * + * @var string + */ + protected $rawData; + + /** + * Magic method enables a object to be transformed to a string. + * + * Get a summary showing significant variables in the object + * note: uri resource is decoded for readability + * + * @return string + */ + public function __toString() + { + $output = __CLASS__.'::__toString'."\n".'method: '.$this->getMethod()."\n".'header: '.print_r($this->getHeaders(), 1).'authentication: '.print_r($this->getAuthentication(), 1).'resource: '.$this->getUri()."\n".'resource urldecoded: '.urldecode($this->getUri())."\n".'raw data: '.$this->getRawData()."\n".'file upload: '.$this->getFileUpload()."\n"; + + return $output; + } + + /** + * Set request handler. + * + * @param string $handler + * + * @return self Provides fluent interface + */ + public function setHandler($handler) + { + $this->setOption('handler', $handler); + + return $this; + } + + /** + * Get request handler. + * + * @return string + */ + public function getHandler() + { + return $this->getOption('handler'); + } + + /** + * Set request method. + * + * Use one of the constants as value + * + * @param string $method + * + * @return self Provides fluent interface + */ + public function setMethod($method) + { + $this->setOption('method', $method); + + return $this; + } + + /** + * Get request method. + * + * @return string + */ + public function getMethod() + { + return $this->getOption('method'); + } + + /** + * Get raw POST data. + * + * @return string + */ + public function getRawData() + { + return $this->rawData; + } + + /** + * Set raw POST data. + * + * This string must be safely encoded. + * + * @param string $data + * + * @return self Provides fluent interface + */ + public function setRawData($data) + { + $this->rawData = $data; + + return $this; + } + + /** + * Get the file to upload via "multipart/form-data" POST request. + * + * @return string|null + */ + public function getFileUpload() + { + return $this->getOption('file'); + } + + /** + * Set the file to upload via "multipart/form-data" POST request. + * + * + * @param string $filename Name of file to upload + * + * @throws RuntimeException + * + * @return self + */ + public function setFileUpload($filename) + { + if (!is_file($filename) || !is_readable($filename)) { + throw new RuntimeException("Unable to read file '{$filename}' for upload"); + } + + $this->setOption('file', $filename); + + return $this; + } + + /** + * Get all request headers. + * + * @return array + */ + public function getHeaders() + { + return $this->headers; + } + + /** + * Set request headers. + * + * @param array $headers + * + * @return self Provides fluent interface + */ + public function setHeaders($headers) + { + $this->clearHeaders(); + $this->addHeaders($headers); + + return $this; + } + + /** + * Add a request header. + * + * @param string|array $value + * + * @return self Provides fluent interface + */ + public function addHeader($value) + { + $this->headers[] = $value; + + return $this; + } + + /** + * Add multiple headers to the request. + * + * @param array $headers + * + * @return self Provides fluent interface + */ + public function addHeaders($headers) + { + foreach ($headers as $header) { + $this->addHeader($header); + } + + return $this; + } + + /** + * Clear all request headers. + * + * @return self Provides fluent interface + */ + public function clearHeaders() + { + $this->headers = []; + + return $this; + } + + /** + * Get an URI for this request. + * + * @return string + */ + public function getUri() + { + return $this->getHandler().'?'.$this->getQueryString(); + } + + /** + * Set HTTP basic auth settings. + * + * If one or both values are NULL authentication will be disabled + * + * @param string $username + * @param string $password + * + * @return self Provides fluent interface + */ + public function setAuthentication($username, $password) + { + $this->setOption('username', $username); + $this->setOption('password', $password); + + return $this; + } + + /** + * Get HTTP basic auth settings. + * + * @return array + */ + public function getAuthentication() + { + return [ + 'username' => $this->getOption('username'), + 'password' => $this->getOption('password'), + ]; + } + + /** + * Execute a request outside of the core context in the global solr context. + * + * @param bool $isServerRequest + */ + public function setIsServerRequest($isServerRequest = false) + { + $this->setOption('isserverrequest', $isServerRequest); + } + + /** + * Indicates if a request is core independent and could be executed outside a core context. + * By default a Request is not core independent and must be executed in the context of a core. + * + * @return bool + */ + public function getIsServerRequest(): bool + { + return $this->getOption('isserverrequest') ?? false; + } + + /** + * Initialization hook. + */ + protected function init() + { + foreach ($this->options as $name => $value) { + switch ($name) { + case 'rawdata': + $this->setRawData($value); + break; + case 'file': + $this->setFileUpload($value); + break; + case 'param': + $this->setParams($value); + break; + case 'header': + $this->setHeaders($value); + break; + case 'authentication': + if (isset($value['username']) && isset($value['password'])) { + $this->setAuthentication($value['username'], $value['password']); + } + } + } + } + + /** + * @return string + */ + public function getHash() + { + return spl_object_hash($this); + } +} diff --git a/vendor/solarium/solarium/src/Core/Client/Response.php b/vendor/solarium/solarium/src/Core/Client/Response.php new file mode 100644 index 000000000..c1230f0b2 --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Client/Response.php @@ -0,0 +1,126 @@ +body = $body; + $this->headers = $headers; + + $this->setHeaders($headers); + } + + /** + * Get body data. + * + * @return string + */ + public function getBody() + { + return $this->body; + } + + /** + * Get response headers. + * + * @return array + */ + public function getHeaders() + { + return $this->headers; + } + + /** + * Get status code. + * + * @return int + */ + public function getStatusCode() + { + return $this->statusCode; + } + + /** + * Get status message. + * + * @return string + */ + public function getStatusMessage() + { + return $this->statusMessage; + } + + /** + * Set headers. + * + * + * @param array $headers + * + * @throws HttpException + */ + public function setHeaders($headers) + { + $this->headers = $headers; + + // get the status header + $statusHeader = null; + foreach ($headers as $header) { + if ('HTTP' == substr($header, 0, 4)) { + $statusHeader = $header; + break; + } + } + + if (null === $statusHeader) { + throw new HttpException('No HTTP status found'); + } + + // parse header like "$statusInfo[1]" into code and message + // $statusInfo[1] = the HTTP response code + // $statusInfo[2] = the response message + $statusInfo = explode(' ', $statusHeader, 3); + $this->statusCode = (int) $statusInfo[1]; + $this->statusMessage = $statusInfo[2]; + } +} diff --git a/vendor/solarium/solarium/src/Core/Configurable.php b/vendor/solarium/solarium/src/Core/Configurable.php new file mode 100644 index 000000000..077d609e4 --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Configurable.php @@ -0,0 +1,171 @@ +setOptions($options); + } else { + $this->init(); + } + } + + /** + * Set options. + * + * If $options is an object, it will be converted into an array by calling + * its toArray method. This is compatible with the Zend_Config classes in + * Zend Framework, but can also easily be implemented in any other object. + * If $options does not have the toArray method, the internal method will + * be used instead. + * + * + * @param array|\Zend_Config $options + * @param bool $overwrite True for overwriting existing options, false + * for merging (new values overwrite old ones if needed) + * + * @throws InvalidArgumentException + */ + public function setOptions($options, $overwrite = false) + { + if (null !== $options) { + // first convert to array if needed + if (!is_array($options)) { + if (is_object($options)) { + $options = (!method_exists($options, 'toArray') ? $this->toArray($options) : $options->toArray()); + } else { + throw new InvalidArgumentException( + 'Options value given to the setOptions() method must be an array or a Zend_Config object' + ); + } + } + + if (true === $overwrite) { + $this->options = $options; + } else { + $this->options = array_merge($this->options, $options); + } + + // re-init for new options + $this->init(); + } + } + + /** + * Get an option value by name. + * + * If the option is empty or not set a NULL value will be returned. + * + * @param string $name + * + * @return mixed + */ + public function getOption($name) + { + if (isset($this->options[$name])) { + return $this->options[$name]; + } + } + + /** + * Get all options. + * + * @return array + */ + public function getOptions() + { + return $this->options; + } + + /** + * Initialization hook. + * + * Can be used by classes for special behaviour. For instance some options + * have extra setup work in their 'set' method that also need to be called + * when the option is passed as a constructor argument. + * + * This hook is called by the constructor after saving the constructor + * arguments in {@link $options} + * + * This empty implementation can optionally be implemented in + * descending classes. It's not an abstract method on purpose, there are + * many cases where no initialization is needed. + */ + protected function init() + { + } + + /** + * Set an option. + * + * @param string $name + * @param mixed $value + * + * @return self Provides fluent interface + */ + protected function setOption($name, $value) + { + $this->options[$name] = $value; + + return $this; + } + + /** + * Turns an object array into an associative multidimensional array. + * + * @param $object + * + * @return array|object + */ + protected function toArray($object) + { + if (is_object($object)) { + // get_object_vars() does not handle recursive objects well, + // so use set-type without scope operator instead + settype($object, 'array'); + } + + /* + * Return array converted to object + * Using __METHOD__ (Magic constant) + * for recursive call + */ + if (is_array($object)) { + return array_map(__METHOD__, $object); + } + + return $object; + } +} diff --git a/vendor/solarium/solarium/src/Core/ConfigurableInterface.php b/vendor/solarium/solarium/src/Core/ConfigurableInterface.php new file mode 100644 index 000000000..dd1b4b827 --- /dev/null +++ b/vendor/solarium/solarium/src/Core/ConfigurableInterface.php @@ -0,0 +1,49 @@ +type = $type; + $this->options = $options; + $this->query = $query; + } + + /** + * Get the query object for this event. + * + * @return QueryInterface + */ + public function getQuery() + { + return $this->query; + } + + /** + * Get the querytype for this event. + * + * @return string + */ + public function getQueryType() + { + return $this->type; + } + + /** + * Get the options for this event. + * + * @return string + */ + public function getOptions() + { + return $this->options; + } +} diff --git a/vendor/solarium/solarium/src/Core/Event/PostCreateRequest.php b/vendor/solarium/solarium/src/Core/Event/PostCreateRequest.php new file mode 100644 index 000000000..9239a8450 --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Event/PostCreateRequest.php @@ -0,0 +1,55 @@ +query = $query; + $this->request = $request; + } + + /** + * Get the query object for this event. + * + * @return QueryInterface + */ + public function getQuery() + { + return $this->query; + } + + /** + * Get the request object for this event. + * + * @return Request + */ + public function getRequest() + { + return $this->request; + } +} diff --git a/vendor/solarium/solarium/src/Core/Event/PostCreateResult.php b/vendor/solarium/solarium/src/Core/Event/PostCreateResult.php new file mode 100644 index 000000000..f066163eb --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Event/PostCreateResult.php @@ -0,0 +1,73 @@ +query = $query; + $this->response = $response; + $this->result = $result; + } + + /** + * Get the query object for this event. + * + * @return QueryInterface + */ + public function getQuery() + { + return $this->query; + } + + /** + * Get the response object for this event. + * + * @return Response + */ + public function getResponse() + { + return $this->response; + } + + /** + * Get the result object for this event. + * + * @return ResultInterface + */ + public function getResult() + { + return $this->result; + } +} diff --git a/vendor/solarium/solarium/src/Core/Event/PostExecute.php b/vendor/solarium/solarium/src/Core/Event/PostExecute.php new file mode 100644 index 000000000..66a06ff17 --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Event/PostExecute.php @@ -0,0 +1,55 @@ +query = $query; + $this->result = $result; + } + + /** + * Get the query object for this event. + * + * @return QueryInterface + */ + public function getQuery() + { + return $this->query; + } + + /** + * Get the result object for this event. + * + * @return ResultInterface + */ + public function getResult() + { + return $this->result; + } +} diff --git a/vendor/solarium/solarium/src/Core/Event/PostExecuteRequest.php b/vendor/solarium/solarium/src/Core/Event/PostExecuteRequest.php new file mode 100644 index 000000000..3facaf0e5 --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Event/PostExecuteRequest.php @@ -0,0 +1,73 @@ +request = $request; + $this->endpoint = $endpoint; + $this->response = $response; + } + + /** + * Get the endpoint object for this event. + * + * @return Endpoint + */ + public function getEndpoint() + { + return $this->endpoint; + } + + /** + * Get the response object for this event. + * + * @return Response + */ + public function getResponse() + { + return $this->response; + } + + /** + * Get the request object for this event. + * + * @return Request + */ + public function getRequest() + { + return $this->request; + } +} diff --git a/vendor/solarium/solarium/src/Core/Event/PreCreateQuery.php b/vendor/solarium/solarium/src/Core/Event/PreCreateQuery.php new file mode 100644 index 000000000..e6c3250a4 --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Event/PreCreateQuery.php @@ -0,0 +1,79 @@ +type = $type; + $this->options = $options; + } + + /** + * Get the query object for this event. + * + * @return QueryInterface + */ + public function getQuery() + { + return $this->query; + } + + /** + * Set the query object for this event, this overrides default execution. + * + * @param QueryInterface $query + */ + public function setQuery($query) + { + $this->query = $query; + } + + /** + * Get the querytype for this event. + * + * @return string + */ + public function getQueryType() + { + return $this->type; + } + + /** + * Get the options for this event. + * + * @return array|null + */ + public function getOptions() + { + return $this->options; + } +} diff --git a/vendor/solarium/solarium/src/Core/Event/PreCreateRequest.php b/vendor/solarium/solarium/src/Core/Event/PreCreateRequest.php new file mode 100644 index 000000000..d03da5ec3 --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Event/PreCreateRequest.php @@ -0,0 +1,65 @@ +query = $query; + } + + /** + * Get the query object for this event. + * + * @return QueryInterface + */ + public function getQuery() + { + return $this->query; + } + + /** + * Set request. + * + * If you set this request value the default execution is skipped and this request is directly returned + * + * @param Request $request + */ + public function setRequest(Request $request) + { + $this->request = $request; + } + + /** + * Get the result. + * + * @return null|Request + */ + public function getRequest() + { + return $this->request; + } +} diff --git a/vendor/solarium/solarium/src/Core/Event/PreCreateResult.php b/vendor/solarium/solarium/src/Core/Event/PreCreateResult.php new file mode 100644 index 000000000..e9cb2c80e --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Event/PreCreateResult.php @@ -0,0 +1,81 @@ +query = $query; + $this->response = $response; + } + + /** + * Get the query object for this event. + * + * @return QueryInterface + */ + public function getQuery() + { + return $this->query; + } + + /** + * Get the response object for this event. + * + * @return Response + */ + public function getResponse() + { + return $this->response; + } + + /** + * Get the result object for this event. + * + * @return ResultInterface + */ + public function getResult() + { + return $this->result; + } + + /** + * Set the result object for this event, overrides default execution. + * + * @param ResultInterface $result + */ + public function setResult($result) + { + $this->result = $result; + } +} diff --git a/vendor/solarium/solarium/src/Core/Event/PreExecute.php b/vendor/solarium/solarium/src/Core/Event/PreExecute.php new file mode 100644 index 000000000..41def3752 --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Event/PreExecute.php @@ -0,0 +1,63 @@ +query = $query; + } + + /** + * Get the query object for this event. + * + * @return QueryInterface + */ + public function getQuery() + { + return $this->query; + } + + /** + * Get the result object for this event. + * + * @return ResultInterface + */ + public function getResult() + { + return $this->result; + } + + /** + * Set the result object for this event, overrides default execution. + * + * @param ResultInterface $result + */ + public function setResult($result) + { + $this->result = $result; + } +} diff --git a/vendor/solarium/solarium/src/Core/Event/PreExecuteRequest.php b/vendor/solarium/solarium/src/Core/Event/PreExecuteRequest.php new file mode 100644 index 000000000..5f65cb830 --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Event/PreExecuteRequest.php @@ -0,0 +1,91 @@ +request = $request; + $this->endpoint = $endpoint; + } + + /** + * Get the endpoint object for this event. + * + * @return Endpoint + */ + public function getEndpoint() + { + return $this->endpoint; + } + + /** + * Get the request object for this event. + * + * @return Request + */ + public function getRequest() + { + return $this->request; + } + + /** + * Get the request object for this event. + * + * @param Request $request + */ + public function setRequest($request) + { + $this->request = $request; + } + + /** + * Get the response object for this event. + * + * @return Response + */ + public function getResponse() + { + return $this->response; + } + + /** + * Set the response object for this event, overrides default execution. + * + * @param Response $response + */ + public function setResponse($response) + { + $this->response = $response; + } +} diff --git a/vendor/solarium/solarium/src/Core/Plugin/AbstractPlugin.php b/vendor/solarium/solarium/src/Core/Plugin/AbstractPlugin.php new file mode 100644 index 000000000..159c0fd1d --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Plugin/AbstractPlugin.php @@ -0,0 +1,45 @@ +client = $client; + parent::__construct($options); + + $this->initPluginType(); + } + + /** + * Plugin init function. + * + * This is an extension point for plugin implementations. + * Will be called as soon as $this->client and options have been set. + */ + protected function initPluginType() + { + } +} diff --git a/vendor/solarium/solarium/src/Core/Plugin/PluginInterface.php b/vendor/solarium/solarium/src/Core/Plugin/PluginInterface.php new file mode 100644 index 000000000..c2f84defc --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Plugin/PluginInterface.php @@ -0,0 +1,22 @@ +setOption('handler', $handler); + } + + /** + * Get handler option. + * + * @return string + */ + public function getHandler() + { + return $this->getOption('handler'); + } + + /** + * Set resultclass option. + * + * If you set a custom result class it must be available through autoloading + * or a manual require before calling this method. This is your + * responsibility. + * + * Also you need to make sure it extends the orginal result class of the + * query or has an identical API. + * + * @param string $classname + * + * @return self Provides fluent interface + */ + public function setResultClass($classname) + { + return $this->setOption('resultclass', $classname); + } + + /** + * Get resultclass option. + * + * @return string + */ + public function getResultClass() + { + return $this->getOption('resultclass'); + } + + /** + * Set timeAllowed option. + * + * @param int $value + * + * @return self Provides fluent interface + */ + public function setTimeAllowed($value) + { + return $this->setOption('timeallowed', $value); + } + + /** + * Get timeAllowed option. + * + * @return int|null + */ + public function getTimeAllowed() + { + return $this->getOption('timeallowed'); + } + + /** + * Set omitHeader option. + * + * @param bool $value + * + * @return self Provides fluent interface + */ + public function setOmitHeader($value) + { + return $this->setOption('omitheader', $value); + } + + /** + * Get omitHeader option. + * + * @return bool + */ + public function getOmitHeader() + { + return $this->getOption('omitheader'); + } + + /** + * Get a helper instance. + * + * Uses lazy loading: the helper is instantiated on first use + * + * @return Helper + */ + public function getHelper() + { + if (null === $this->helper) { + $this->helper = new Helper($this); + } + + return $this->helper; + } + + /** + * Add extra params to the request. + * + * Only intended for internal use, for instance with dereferenced params. + * Therefore the params are limited in functionality. Only add and get + * + * @param string $name + * @param string $value + * + * @return self Provides fluent interface + */ + public function addParam($name, $value) + { + $this->params[$name] = $value; + + return $this; + } + + /** + * Removes a param that was previously added by addParam. + * + * Note: This can not be used to remove known default parameters of the solarium api. + * + * @param string $name + * + * @return self Provides fluent interface + */ + public function removeParam($name) + { + if (isset($this->params[$name])) { + unset($this->params[$name]); + } + + return $this; + } + + /** + * Get extra params. + * + * @return array + */ + public function getParams() + { + return $this->params; + } + + /** + * Set responsewriter option. + * + * @param string $value + * + * @return self Provides fluent interface + */ + public function setResponseWriter($value) + { + return $this->setOption('responsewriter', $value); + } + + /** + * Get responsewriter option. + * + * Defaults to json for backwards compatibility and security. + * + * If you can fully trust the Solr responses (phps has a security risk from untrusted sources) you might consider + * setting the responsewriter to 'phps' (serialized php). This can give a performance advantage, + * especially with big resultsets. + * + * @return string + */ + public function getResponseWriter() + { + $responseWriter = $this->getOption('responsewriter'); + if (null === $responseWriter) { + $responseWriter = self::WT_JSON; + } + + return $responseWriter; + } + + /** + * Set now option. + * + * Instructs Solr to use an arbitrary moment in time (past or future) to override NOW for date math expressions. + * + * Make sure to pass a string instead of an int if the code has to run on a 32-bit PHP installation. + * + * @param string $timestamp Milliseconds since epoch + * + * @return self Provides fluent interface + */ + public function setNow($timestamp) + { + return $this->setOption('now', $timestamp); + } + + /** + * Get now option. + * + * @return string Milliseconds since epoch + */ + public function getNow() + { + return $this->getOption('now'); + } + + /** + * Set timezone option. + * + * Forces all date based addition and rounding to be relative to the specified time zone instead of UTC. + * + * @param string $timezone Java TimeZone ID + * + * @return self Provides fluent interface + */ + public function setTimeZone($timezone) + { + return $this->setOption('timezone', $timezone); + } + + /** + * Get timezone option. + * + * @return string Java TimeZone ID + */ + public function getTimeZone() + { + return $this->getOption('timezone'); + } +} diff --git a/vendor/solarium/solarium/src/Core/Query/AbstractRequestBuilder.php b/vendor/solarium/solarium/src/Core/Query/AbstractRequestBuilder.php new file mode 100644 index 000000000..a7a91119e --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Query/AbstractRequestBuilder.php @@ -0,0 +1,115 @@ +setHandler($query->getHandler()); + $request->addParam('omitHeader', $query->getOmitHeader()); + $request->addParam('timeAllowed', $query->getTimeAllowed()); + $request->addParam('NOW', $query->getNow()); + $request->addParam('TZ', $query->getTimeZone()); + $request->addParams($query->getParams()); + + $request->addParam('wt', $query->getResponseWriter()); + if ($query->getResponseWriter() == $query::WT_JSON) { + // only one JSON format is supported + $request->addParam('json.nl', 'flat'); + } + + $isServerQuery = ($query instanceof AbstractServerQuery); + $request->setIsServerRequest($isServerQuery); + + return $request; + } + + /** + * Render a param with localParams. + * + * LocalParams can be use in various Solr GET params. + * + * @see http://wiki.apache.org/solr/LocalParams + * + * @param string $value + * @param array $localParams in key => value format + * + * @return string with Solr localparams syntax + */ + public function renderLocalParams($value, $localParams = []) + { + $params = ''; + foreach ($localParams as $paramName => $paramValue) { + if (empty($paramValue)) { + continue; + } + + if (is_array($paramValue)) { + $paramValue = implode($paramValue, ','); + } + + $params .= $paramName.'='.$paramValue.' '; + } + + if ('' !== $params) { + $value = '{!'.trim($params).'}'.$value; + } + + return $value; + } + + /** + * Render a boolean attribute. + * + * For use in building XML messages + * + * @param string $name + * @param bool $value + * + * @return string + */ + public function boolAttrib($name, $value) + { + if (null !== $value) { + $value = (true === (bool) $value) ? 'true' : 'false'; + + return $this->attrib($name, $value); + } + + return ''; + } + + /** + * Render an attribute. + * + * For use in building XML messages + * + * @param string $name + * @param string $value + * + * @return string + */ + public function attrib($name, $value) + { + if (null !== $value) { + return ' '.$name.'="'.$value.'"'; + } + + return ''; + } +} diff --git a/vendor/solarium/solarium/src/Core/Query/AbstractResponseParser.php b/vendor/solarium/solarium/src/Core/Query/AbstractResponseParser.php new file mode 100644 index 000000000..0a438363e --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Query/AbstractResponseParser.php @@ -0,0 +1,67 @@ +query = $query; + } + + /** + * Escape a term. + * + * A term is a single word. + * All characters that have a special meaning in a Solr query are escaped. + * + * If you want to use the input as a phrase please use the {@link phrase()} + * method, because a phrase requires much less escaping.\ + * + * @see https://lucene.apache.org/core/7_5_0/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#package.description + * + * @param string $input + * + * @return string + */ + public function escapeTerm($input) + { + $pattern = '/( |\+|-|&&|\|\||!|\(|\)|\{|}|\[|]|\^|"|~|\*|\?|:|\/|\\\)/'; + + return preg_replace($pattern, '\\\$1', $input); + } + + /** + * Escape a phrase. + * + * A phrase is a group of words. + * Special characters will be escaped and the phrase will be surrounded by + * double quotes to group the input into a single phrase. So don't put + * quotes around the input. + * + * Do mind that you cannot build a complete query first and then pass it to + * this method, the whole query will be escaped. You need to escape only the + * 'content' of your query. + * + * @param string $input + * + * @return string + */ + public function escapePhrase($input) + { + return '"'.preg_replace('/("|\\\)/', '\\\$1', $input).'"'; + } + + /** + * Format a date to the expected formatting used in SOLR. + * + * This format was derived to be standards compliant (ISO 8601) + * A date field shall be of the form 1995-12-31T23:59:59Z The trailing "Z" designates UTC time and is mandatory + * + * @see http://lucene.apache.org/solr/api/org/apache/solr/schema/DateField.html + * + * @param int|string|\DateTimeInterface $input accepted formats: timestamp, date string or DateTime / DateTimeImmutable + * + * @return string|bool false is returned in case of invalid input + */ + public function formatDate($input) + { + switch (true) { + // input of datetime object + case $input instanceof \DateTimeInterface: + $input = clone $input; + break; + // input of timestamp or date/time string + case is_string($input) || is_numeric($input): + + // if date/time string: convert to timestamp first + if (is_string($input)) { + $input = strtotime($input); + } + + // now try converting the timestamp to a datetime instance, on failure return false + try { + $input = new \DateTime('@'.$input); + } catch (\Exception $e) { + $input = false; + } + break; + // any other input formats can be added in additional cases here... + // case $input instanceof Zend_Date: + + // unsupported input format + default: + $input = false; + break; + } + + // handle the filtered input + if ($input) { + // when we get here the input is always a datetime object + $input = $input->setTimezone(new \DateTimeZone('UTC')); + $iso8601 = $input->format(\DateTime::ISO8601); + $iso8601 = strstr($iso8601, '+', true); //strip timezone + $iso8601 .= 'Z'; + + return $iso8601; + } + + // unsupported input + return false; + } + + /** + * Render a range query. + * + * From and to can be any type of data. For instance int, string or point. + * If they are null, then '*' will be used. + * + * Example: rangeQuery('store', '45,-94', '46,-93') + * Returns: store:[45,-94 TO 46,-93] + * + * Example: rangeQuery('store', '5', '*', false) + * Returns: store:{5 TO *} + * + * @param string $field + * @param string $from + * @param string $to + * @param bool $inclusive + * + * @return string + */ + public function rangeQuery($field, $from, $to, $inclusive = true) + { + if (null === $from) { + $from = '*'; + } else { + $from = $this->escapePhrase($from); + } + + if (null === $to) { + $to = '*'; + } else { + $to = $this->escapePhrase($to); + } + + if ($inclusive) { + return $field.':['.$from.' TO '.$to.']'; + } + + if ($inclusive) { + return $field.':['.$from.' TO '.$to.']'; + } + + return $field.':{'.$from.' TO '.$to.'}'; + } + + /** + * Render a geofilt (distance) filter. + * + * Find all entries within the distance of a certain point. + * + * @param string $field + * @param string $pointX + * @param string $pointY + * @param string $distance + * @param bool $dereferenced + * + * @return string + */ + public function geofilt($field, $pointX, $pointY, $distance, $dereferenced = false) + { + return $this->qparser( + 'geofilt', + [ + 'pt' => $pointX.','.$pointY, + 'sfield' => $field, + 'd' => $distance, + ], + $dereferenced + ); + } + + /** + * Render a bbox (boundingbox) filter. + * + * Exact distance calculations can be somewhat expensive and it can often + * make sense to use a quick approximation instead. The bbox filter is + * guaranteed to encompass all of the points of interest, but it may also + * include other points that are slightly outside of the required distance. + * + * @param string $field + * @param string $pointX + * @param string $pointY + * @param string $distance + * @param bool $dereferenced + * + * @return string + */ + public function bbox($field, $pointX, $pointY, $distance, $dereferenced = false) + { + return $this->qparser( + 'bbox', + [ + 'pt' => $pointX.','.$pointY, + 'sfield' => $field, + 'd' => $distance, + ], + $dereferenced + ); + } + + /** + * Render a geodist function call. + * + * geodist is a function query that yields the calculated distance. + * This gives the flexibility to do a number of interesting things, + * such as sorting by the distance (Solr can sort by any function query), + * or combining the distance with the relevancy score, + * such as boosting by the inverse of the distance. + * + * @param string $field + * @param string $pointX + * @param string $pointY + * @param bool $dereferenced + * + * @return string + */ + public function geodist($field, $pointX, $pointY, $dereferenced = false) + { + return $this->functionCall( + 'geodist', + ['sfield' => $field, 'pt' => $pointX.','.$pointY], + $dereferenced + ); + } + + /** + * Render a qparser plugin call. + * + * + * @param string $name + * @param array $params + * @param bool $dereferenced + * @param bool $forceKeys + * + * @throws InvalidArgumentException + * + * @return string + */ + public function qparser($name, $params = [], $dereferenced = false, $forceKeys = false) + { + if ($dereferenced) { + if (!$this->query) { + throw new InvalidArgumentException( + 'Dereferenced params can only be used in a Solarium query helper instance retrieved from the query '.'by using the getHelper() method, this instance was manually created' + ); + } + + foreach ($params as $paramKey => $paramValue) { + if (is_int($paramKey) || $forceKeys) { + ++$this->derefencedParamsLastKey; + $derefKey = 'deref_'.$this->derefencedParamsLastKey; + } else { + $derefKey = $paramKey; + } + $this->query->addParam($derefKey, $paramValue); + $params[$paramKey] = '$'.$derefKey; + } + } + + $output = '{!'.$name; + foreach ($params as $key => $value) { + if (!$dereferenced || $forceKeys || is_int($key)) { + $output .= ' '.$key.'='.$value; + } + } + $output .= '}'; + + return $output; + } + + /** + * Render a functionCall. + * + * @param string $name + * @param array $params + * @param bool $dereferenced + * + * @return string + */ + public function functionCall($name, $params = [], $dereferenced = false) + { + if ($dereferenced) { + foreach ($params as $key => $value) { + $this->query->addParam($key, $value); + } + + return $name.'()'; + } + + return $name.'('.implode($params, ',').')'; + } + + /** + * Assemble a querystring with placeholders. + * + * These placeholder modes are supported: + * %1% = no mode, will default to literal + * %L2% = literal + * %P3% = phrase-escaped + * %T4% = term-escaped + * + * Numbering starts at 1, so number 1 refers to the first entry + * of $parts (which has array key 0) + * You can use the same part multiple times, even in multiple modes. + * The mode letters are not case sensitive. + * + * The mode matching pattern can be customized by overriding the + * value of $this->placeHolderPattern + * + * @since 2.1.0 + * + * @param string $query + * @param array $parts Array of strings + * + * @return string + */ + public function assemble($query, $parts) + { + $this->assembleParts = $parts; + + return preg_replace_callback( + $this->placeHolderPattern, + [$this, 'renderPlaceHolder'], + $query + ); + } + + /** + * Render join localparams syntax. + * + * @see http://wiki.apache.org/solr/Join + * @since 2.4.0 + * + * @param string $from + * @param string $to + * @param bool $dereferenced + * + * @return string + */ + public function join($from, $to, $dereferenced = false) + { + return $this->qparser('join', ['from' => $from, 'to' => $to], $dereferenced, $dereferenced); + } + + /** + * Render term query. + * + * Useful for avoiding query parser escaping madness when drilling into facets via fq parameters, example: + * {!term f=weight}1.5 + * + * This is a Solr 3.2+ feature. + * + * @see http://wiki.apache.org/solr/SolrQuerySyntax#Other_built-in_useful_query_parsers + * + * @param string $field + * @param float $weight + * + * @return string + */ + public function qparserTerm($field, $weight) + { + return $this->qparser('term', ['f' => $field]).$weight; + } + + /** + * Render cache control param for use in filterquery. + * + * This is a Solr 3.4+ feature. + * + * @see http://wiki.apache.org/solr/CommonQueryParameters#Caching_of_filters + * + * @param bool $useCache + * @param float|null $cost + * + * @return string + */ + public function cacheControl($useCache, $cost = null) + { + $cache = 'false'; + + if (true === $useCache) { + $cache = 'true'; + } + + $result = '{!cache='.$cache; + if (null !== $cost) { + $result .= ' cost='.$cost; + } + $result .= '}'; + + return $result; + } + + /** + * Filters control characters that cause issues with servlet containers. + * + * Mainly useful to filter data before adding it to a document for the update query. + * + * @param string $data + * + * @return mixed + */ + public function filterControlCharacters($data) + { + return preg_replace('@[\x00-\x08\x0B\x0C\x0E-\x1F]@', ' ', $data); + } + + /** + * Render placeholders in a querystring. + * + * + * @param array $matches + * + * @throws InvalidArgumentException + * + * @return string + */ + protected function renderPlaceHolder($matches) + { + $partNumber = $matches[2]; + $partMode = strtoupper($matches[1]); + + if (isset($this->assembleParts[$partNumber - 1])) { + $value = $this->assembleParts[$partNumber - 1]; + } else { + throw new InvalidArgumentException('No value supplied for part #'.$partNumber.' in query assembler'); + } + + switch ($partMode) { + case 'P': + $value = $this->escapePhrase($value); + break; + case 'T': + $value = $this->escapeTerm($value); + break; + } + + return $value; + } +} diff --git a/vendor/solarium/solarium/src/Core/Query/QueryInterface.php b/vendor/solarium/solarium/src/Core/Query/QueryInterface.php new file mode 100644 index 000000000..7492b2ac6 --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Query/QueryInterface.php @@ -0,0 +1,97 @@ +parsed) { + $responseParser = $this->query->getResponseParser(); + if (!$responseParser || !($responseParser instanceof ResponseParserInterface)) { + throw new UnexpectedValueException( + 'No responseparser returned by querytype: '.$this->query->getType() + ); + } + + $this->mapData($responseParser->parse($this)); + + $this->parsed = true; + } + } + + /** + * Map parser data into properties. + * + * @param array $mapData + */ + protected function mapData($mapData) + { + foreach ($mapData as $key => $data) { + $this->$key = $data; + } + } +} diff --git a/vendor/solarium/solarium/src/Core/Query/Result/Result.php b/vendor/solarium/solarium/src/Core/Query/Result/Result.php new file mode 100644 index 000000000..bb0472d09 --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Query/Result/Result.php @@ -0,0 +1,122 @@ +query = $query; + $this->response = $response; + + // check status for error (range of 400 and 500) + $statusNum = floor($response->getStatusCode() / 100); + if (4 == $statusNum || 5 == $statusNum) { + throw new HttpException( + $response->getStatusMessage(), + $response->getStatusCode(), + $response->getBody() + ); + } + } + + /** + * Get response object. + * + * This is the raw HTTP response object, not the parsed data! + * + * @return Response + */ + public function getResponse() + { + return $this->response; + } + + /** + * Get query instance. + * + * @return AbstractQuery + */ + public function getQuery() + { + return $this->query; + } + + /** + * Get Solr response data. + * + * Includes a lazy loading mechanism: JSON body data is decoded on first use and then saved for reuse. + * + * @throws UnexpectedValueException + * @throws RuntimeException + * + * @return array + */ + public function getData() + { + if (null === $this->data) { + switch ($this->query->getResponseWriter()) { + case AbstractQuery::WT_PHPS: + $this->data = unserialize($this->response->getBody()); + break; + case AbstractQuery::WT_JSON: + $this->data = json_decode($this->response->getBody(), true); + break; + default: + throw new RuntimeException('Responseparser cannot handle '.$this->query->getResponseWriter()); + } + + if (null === $this->data) { + throw new UnexpectedValueException( + 'Solr JSON response could not be decoded' + ); + } + } + + return $this->data; + } +} diff --git a/vendor/solarium/solarium/src/Core/Query/Result/ResultInterface.php b/vendor/solarium/solarium/src/Core/Query/Result/ResultInterface.php new file mode 100644 index 000000000..c877248bf --- /dev/null +++ b/vendor/solarium/solarium/src/Core/Query/Result/ResultInterface.php @@ -0,0 +1,37 @@ +statusMessage = $statusMessage; + $this->body = $body; + + $message = 'Solr HTTP error: '.$statusMessage; + if (null !== $code) { + $message .= ' ('.$code.')'; + } + if ($body) { + $message .= "\n".$body; + } + + parent::__construct($message, $code); + } + + /** + * Get the HTTP status message. + * + * @return string + */ + public function getStatusMessage() + { + return $this->statusMessage; + } + + /** + * Get body. + * + * @return string + */ + public function getBody() + { + return $this->body; + } +} diff --git a/vendor/solarium/solarium/src/Exception/InvalidArgumentException.php b/vendor/solarium/solarium/src/Exception/InvalidArgumentException.php new file mode 100644 index 000000000..56361a5ff --- /dev/null +++ b/vendor/solarium/solarium/src/Exception/InvalidArgumentException.php @@ -0,0 +1,10 @@ +expression = $expression; + } + + /** + * Get the streaming expression that caused the exception. + * + * @return string + */ + public function getExpression() + { + return $this->expression; + } +} diff --git a/vendor/solarium/solarium/src/Exception/UnexpectedValueException.php b/vendor/solarium/solarium/src/Exception/UnexpectedValueException.php new file mode 100644 index 000000000..22f4d5cf7 --- /dev/null +++ b/vendor/solarium/solarium/src/Exception/UnexpectedValueException.php @@ -0,0 +1,10 @@ + 100, + ]; + + /** + * Update query instance. + * + * @var UpdateQuery + */ + protected $updateQuery; + + /** + * Buffered documents. + * + * @var DocumentInterface[] + */ + protected $buffer = []; + + /** + * Set the endpoint for the documents. + * + * @param string $endpoint The endpoint to set + * + * @return self + */ + public function setEndpoint($endpoint) + { + return $this->setOption('endpoint', $endpoint); + } + + /** + * Return the endpoint. + * + * @return string + */ + public function getEndpoint() + { + return $this->getOption('endpoint'); + } + + /** + * Set buffer size option. + * + * @param int $size + * + * @return self + */ + public function setBufferSize($size) + { + return $this->setOption('buffersize', $size); + } + + /** + * Get buffer size option value. + * + * @return int + */ + public function getBufferSize() + { + return $this->getOption('buffersize'); + } + + /** + * Set commitWithin time option. + * + * @param int $time + * + * @return self + */ + public function setCommitWithin($time) + { + return $this->setOption('commitwithin', $time); + } + + /** + * Get commitWithin time option value. + * + * @return int + */ + public function getCommitWithin() + { + return $this->getOption('commitwithin'); + } + + /** + * Set overwrite boolean option. + * + * @param bool $value + * + * @return self + */ + public function setOverwrite($value) + { + return $this->setOption('overwrite', $value); + } + + /** + * Get overwrite boolean option value. + * + * @return bool + */ + public function getOverwrite() + { + return $this->getOption('overwrite'); + } + + /** + * Create a document object instance and add it to the buffer. + * + * @param array $fields + * @param array $boosts + * + * @return self Provides fluent interface + */ + public function createDocument($fields, $boosts = []) + { + $doc = $this->updateQuery->createDocument($fields, $boosts); + $this->addDocument($doc); + + return $this; + } + + /** + * Add a document. + * + * @param DocumentInterface $document + * + * @return self Provides fluent interface + */ + public function addDocument($document) + { + $this->buffer[] = $document; + + $event = new AddDocumentEvent($document); + $this->client->getEventDispatcher()->dispatch(Events::ADD_DOCUMENT, $event); + + if (count($this->buffer) == $this->options['buffersize']) { + $this->flush(); + } + + return $this; + } + + /** + * Add multiple documents. + * + * @param array $documents + * + * @return self Provides fluent interface + */ + public function addDocuments($documents) + { + foreach ($documents as $document) { + $this->addDocument($document); + } + + return $this; + } + + /** + * Get all documents currently in the buffer. + * + * Any previously flushed documents will not be included! + * + * @return DocumentInterface[] + */ + public function getDocuments() + { + return $this->buffer; + } + + /** + * Clear any buffered documents. + * + * @return self Provides fluent interface + */ + public function clear() + { + $this->updateQuery = $this->client->createUpdate(); + $this->buffer = []; + + return $this; + } + + /** + * Flush any buffered documents to Solr. + * + * @param bool $overwrite + * @param int $commitWithin + * + * @return bool|UpdateResult + */ + public function flush($overwrite = null, $commitWithin = null) + { + if (0 == count($this->buffer)) { + // nothing to do + return false; + } + + $overwrite = is_null($overwrite) ? $this->getOverwrite() : $overwrite; + $commitWithin = is_null($commitWithin) ? $this->getCommitWithin() : $commitWithin; + + $event = new PreFlushEvent($this->buffer, $overwrite, $commitWithin); + $this->client->getEventDispatcher()->dispatch(Events::PRE_FLUSH, $event); + + $this->updateQuery->addDocuments($event->getBuffer(), $event->getOverwrite(), $event->getCommitWithin()); + $result = $this->client->update($this->updateQuery, $this->getEndpoint()); + $this->clear(); + + $event = new PostFlushEvent($result); + $this->client->getEventDispatcher()->dispatch(Events::POST_FLUSH, $event); + + return $result; + } + + /** + * Commit changes. + * + * Any remaining documents in the buffer will also be flushed + * + * @param bool $overwrite + * @param bool $softCommit + * @param bool $waitSearcher + * @param bool $expungeDeletes + * + * @return UpdateResult + */ + public function commit($overwrite = null, $softCommit = null, $waitSearcher = null, $expungeDeletes = null) + { + $event = new PreCommitEvent($this->buffer, $overwrite, $softCommit, $waitSearcher, $expungeDeletes); + $this->client->getEventDispatcher()->dispatch(Events::PRE_COMMIT, $event); + + $this->updateQuery->addDocuments($this->buffer, $event->getOverwrite()); + $this->updateQuery->addCommit($event->getSoftCommit(), $event->getWaitSearcher(), $event->getExpungeDeletes()); + $result = $this->client->update($this->updateQuery, $this->getEndpoint()); + $this->clear(); + + $event = new PostCommitEvent($result); + $this->client->getEventDispatcher()->dispatch(Events::POST_COMMIT, $event); + + return $result; + } + + /** + * Plugin init function. + * + * This is an extension point for plugin implementations. + * Will be called as soon as $this->client and options have been set. + */ + protected function initPluginType() + { + $this->updateQuery = $this->client->createUpdate(); + } +} diff --git a/vendor/solarium/solarium/src/Plugin/BufferedAdd/Event/AddDocument.php b/vendor/solarium/solarium/src/Plugin/BufferedAdd/Event/AddDocument.php new file mode 100644 index 000000000..600649996 --- /dev/null +++ b/vendor/solarium/solarium/src/Plugin/BufferedAdd/Event/AddDocument.php @@ -0,0 +1,37 @@ +document = $document; + } + + /** + * Get the result for this event. + * + * @return DocumentInterface + */ + public function getDocument() + { + return $this->document; + } +} diff --git a/vendor/solarium/solarium/src/Plugin/BufferedAdd/Event/Events.php b/vendor/solarium/solarium/src/Plugin/BufferedAdd/Event/Events.php new file mode 100644 index 000000000..c853b68db --- /dev/null +++ b/vendor/solarium/solarium/src/Plugin/BufferedAdd/Event/Events.php @@ -0,0 +1,54 @@ +result = $result; + } + + /** + * Get the result for this event. + * + * @return DocumentInterface[] + */ + public function getResult() + { + return $this->result; + } +} diff --git a/vendor/solarium/solarium/src/Plugin/BufferedAdd/Event/PostFlush.php b/vendor/solarium/solarium/src/Plugin/BufferedAdd/Event/PostFlush.php new file mode 100644 index 000000000..b4bce6599 --- /dev/null +++ b/vendor/solarium/solarium/src/Plugin/BufferedAdd/Event/PostFlush.php @@ -0,0 +1,38 @@ +result = $result; + } + + /** + * Get the result for this event. + * + * @return DocumentInterface[] + */ + public function getResult() + { + return $this->result; + } +} diff --git a/vendor/solarium/solarium/src/Plugin/BufferedAdd/Event/PreCommit.php b/vendor/solarium/solarium/src/Plugin/BufferedAdd/Event/PreCommit.php new file mode 100644 index 000000000..9ab544658 --- /dev/null +++ b/vendor/solarium/solarium/src/Plugin/BufferedAdd/Event/PreCommit.php @@ -0,0 +1,147 @@ +buffer = $buffer; + $this->overwrite = $overwrite; + $this->softCommit = $softCommit; + $this->waitSearcher = $waitSearcher; + $this->expungeDeletes = $expungeDeletes; + } + + /** + * Get the buffer for this event. + * + * @return DocumentInterface[] + */ + public function getBuffer() + { + return $this->buffer; + } + + /** + * Set the buffer for this event, this way you can alter the buffer before it is committed to Solr. + * + * @param array $buffer + */ + public function setBuffer($buffer) + { + $this->buffer = $buffer; + } + + /** + * Optionally override the value. + * + * @param bool $expungeDeletes + */ + public function setExpungeDeletes($expungeDeletes) + { + $this->expungeDeletes = $expungeDeletes; + } + + /** + * @return bool + */ + public function getExpungeDeletes() + { + return $this->expungeDeletes; + } + + /** + * Optionally override the value. + * + * @param bool $overwrite + */ + public function setOverwrite($overwrite) + { + $this->overwrite = $overwrite; + } + + /** + * @return bool + */ + public function getOverwrite() + { + return $this->overwrite; + } + + /** + * Optionally override the value. + * + * @param bool $softCommit + */ + public function setSoftCommit($softCommit) + { + $this->softCommit = $softCommit; + } + + /** + * @return bool + */ + public function getSoftCommit() + { + return $this->softCommit; + } + + /** + * Optionally override the value. + * + * @param bool $waitSearcher + */ + public function setWaitSearcher($waitSearcher) + { + $this->waitSearcher = $waitSearcher; + } + + /** + * @return bool + */ + public function getWaitSearcher() + { + return $this->waitSearcher; + } +} diff --git a/vendor/solarium/solarium/src/Plugin/BufferedAdd/Event/PreFlush.php b/vendor/solarium/solarium/src/Plugin/BufferedAdd/Event/PreFlush.php new file mode 100644 index 000000000..3e9ff0eca --- /dev/null +++ b/vendor/solarium/solarium/src/Plugin/BufferedAdd/Event/PreFlush.php @@ -0,0 +1,97 @@ +buffer = $buffer; + $this->overwrite = $overwrite; + $this->commitWithin = $commitWithin; + } + + /** + * Get the buffer for this event. + * + * @return DocumentInterface[] + */ + public function getBuffer() + { + return $this->buffer; + } + + /** + * Set the buffer for this event, this way you can alter the buffer before it is committed to Solr. + * + * @param array $buffer + */ + public function setBuffer($buffer) + { + $this->buffer = $buffer; + } + + /** + * Optionally override the value. + * + * @param int $commitWithin + */ + public function setCommitWithin($commitWithin) + { + $this->commitWithin = $commitWithin; + } + + /** + * @return int + */ + public function getCommitWithin() + { + return $this->commitWithin; + } + + /** + * Optionally override the value. + * + * @param bool $overwrite + */ + public function setOverwrite($overwrite) + { + $this->overwrite = $overwrite; + } + + /** + * @return bool + */ + public function getOverwrite() + { + return $this->overwrite; + } +} diff --git a/vendor/solarium/solarium/src/Plugin/CustomizeRequest/Customization.php b/vendor/solarium/solarium/src/Plugin/CustomizeRequest/Customization.php new file mode 100644 index 000000000..c6f9e4f62 --- /dev/null +++ b/vendor/solarium/solarium/src/Plugin/CustomizeRequest/Customization.php @@ -0,0 +1,198 @@ + null, + 'type' => null, + 'name' => null, + 'value' => null, + 'persistent' => false, + 'overwrite' => true, + ]; + + /** + * Set key value. + * + * @param string $value + * + * @return self Provides fluent interface + */ + public function setKey($value) + { + $this->setOption('key', $value); + + return $this; + } + + /** + * Get key value. + * + * @return string + */ + public function getKey() + { + return $this->getOption('key'); + } + + /** + * Set type value. + * + * @param string $value + * + * @return Customization + */ + public function setType($value) + { + $this->setOption('type', $value); + + return $this; + } + + /** + * Get type value. + * + * @return string + */ + public function getType() + { + return $this->getOption('type'); + } + + /** + * Set name value. + * + * @param string $value + * + * @return Customization + */ + public function setName($value) + { + $this->setOption('name', $value); + + return $this; + } + + /** + * Get name value. + * + * @return string + */ + public function getName() + { + return $this->getOption('name'); + } + + /** + * Set value. + * + * @param string $value + * + * @return Customization + */ + public function setValue($value) + { + $this->setOption('value', $value); + + return $this; + } + + /** + * Get value. + * + * @return string + */ + public function getValue() + { + return $this->getOption('value'); + } + + /** + * Set persistent on/off. + * + * @param bool $value + * + * @return Customization + */ + public function setPersistent($value) + { + $this->setOption('persistent', $value); + + return $this; + } + + /** + * Get persistent setting. + * + * @return bool + */ + public function getPersistent() + { + return $this->getOption('persistent'); + } + + /** + * Set overwrite option on/off. + * + * @param bool $value + * + * @return Customization + */ + public function setOverwrite($value) + { + $this->setOption('overwrite', $value); + + return $this; + } + + /** + * Get overwrite option value. + * + * @return bool + */ + public function getOverwrite() + { + return $this->getOption('overwrite'); + } + + /** + * Check for all mandatory settings. + * + * @return bool + */ + public function isValid() + { + $type = $this->getType(); + if (self::TYPE_PARAM !== $type && self::TYPE_HEADER !== $type) { + return false; + } + + if (null === $this->getKey() || null === $this->getName() || null === $this->getValue()) { + return false; + } + + return true; + } +} diff --git a/vendor/solarium/solarium/src/Plugin/CustomizeRequest/CustomizeRequest.php b/vendor/solarium/solarium/src/Plugin/CustomizeRequest/CustomizeRequest.php new file mode 100644 index 000000000..7fe21dc5a --- /dev/null +++ b/vendor/solarium/solarium/src/Plugin/CustomizeRequest/CustomizeRequest.php @@ -0,0 +1,251 @@ +setKey($options); + } else { + $fq = new Customization($options); + } + + if (null !== $fq->getKey()) { + $this->addCustomization($fq); + } + + return $fq; + } + + /** + * Add a customization. + * + * Supports a Customization instance or a config array, in that case a new + * Customization instance wil be created based on the options. + * + * + * @param Customization|array $customization + * + * @throws InvalidArgumentException + * + * @return self Provides fluent interface + */ + public function addCustomization($customization) + { + if (is_array($customization)) { + $customization = new Customization($customization); + } + + $key = $customization->getKey(); + + // check for non-empty key + if (0 === strlen($key)) { + throw new InvalidArgumentException('A Customization must have a key value'); + } + + // check for a unique key + if (array_key_exists($key, $this->customizations)) { + //double add calls for the same customization are ignored, others cause an exception + if ($this->customizations[$key] !== $customization) { + throw new InvalidArgumentException('A Customization must have a unique key value'); + } + } + + $this->customizations[$key] = $customization; + + return $this; + } + + /** + * Add multiple Customizations. + * + * @param array $customizations + * + * @return CustomizeRequest Provides fluent interface + */ + public function addCustomizations(array $customizations) + { + foreach ($customizations as $key => $customization) { + // in case of a config array: add key to config + if (is_array($customization) && !isset($customization['key'])) { + $customization['key'] = $key; + } + + $this->addCustomization($customization); + } + + return $this; + } + + /** + * Get a Customization. + * + * @param string $key + * + * @return string + */ + public function getCustomization($key) + { + if (isset($this->customizations[$key])) { + return $this->customizations[$key]; + } + } + + /** + * Get all Customizations. + * + * @return Customization[] + */ + public function getCustomizations() + { + return $this->customizations; + } + + /** + * Remove a single Customization. + * + * You can remove a Customization by passing its key, or by passing the Customization instance. + * + * @param string|Customization $customization + * + * @return CustomizeRequest Provides fluent interface + */ + public function removeCustomization($customization) + { + if (is_object($customization)) { + $customization = $customization->getKey(); + } + + if (isset($this->customizations[$customization])) { + unset($this->customizations[$customization]); + } + + return $this; + } + + /** + * Remove all Customizations. + * + * @return CustomizeRequest Provides fluent interface + */ + public function clearCustomizations() + { + $this->customizations = []; + + return $this; + } + + /** + * Set multiple Customizations. + * + * This overwrites any existing Customizations + * + * @param array $customizations + */ + public function setCustomizations($customizations) + { + $this->clearCustomizations(); + $this->addCustomizations($customizations); + } + + /** + * Event hook to customize the request object. + * + * + * @param preExecuteRequestEvent $event + * + * @throws RuntimeException + */ + public function preExecuteRequest(preExecuteRequestEvent $event) + { + $request = $event->getRequest(); + foreach ($this->getCustomizations() as $key => $customization) { + // first validate + if (!$customization->isValid()) { + throw new RuntimeException('Request customization with key "'.$key.'" is invalid'); + } + + // apply to request, depending on type + switch ($customization->getType()) { + case Customization::TYPE_PARAM: + $request->addParam( + $customization->getName(), + $customization->getValue(), + $customization->getOverwrite() + ); + break; + case Customization::TYPE_HEADER: + $request->addHeader($customization->getName().': '.$customization->getValue()); + break; + } + + // remove single-use customizations after use + if (!$customization->getPersistent()) { + $this->removeCustomization($key); + } + } + + $event->setRequest($request); + } + + /** + * Initialize options. + */ + protected function init() + { + foreach ($this->options as $name => $value) { + switch ($name) { + case 'customization': + $this->addCustomizations($value); + break; + } + } + } + + /** + * Plugin init function. + * + * Register event listeners + */ + protected function initPluginType() + { + $dispatcher = $this->client->getEventDispatcher(); + $dispatcher->addListener(Events::PRE_EXECUTE_REQUEST, [$this, 'preExecuteRequest']); + } +} diff --git a/vendor/solarium/solarium/src/Plugin/Loadbalancer/Event/EndpointFailure.php b/vendor/solarium/solarium/src/Plugin/Loadbalancer/Event/EndpointFailure.php new file mode 100644 index 000000000..e4d767d16 --- /dev/null +++ b/vendor/solarium/solarium/src/Plugin/Loadbalancer/Event/EndpointFailure.php @@ -0,0 +1,51 @@ +endpoint = $endpoint; + $this->exception = $exception; + } + + /** + * @return Endpoint + */ + public function getEndpoint() + { + return $this->endpoint; + } + + /** + * @return HttpException + */ + public function getException() + { + return $this->exception; + } +} diff --git a/vendor/solarium/solarium/src/Plugin/Loadbalancer/Event/Events.php b/vendor/solarium/solarium/src/Plugin/Loadbalancer/Event/Events.php new file mode 100644 index 000000000..24efa6f06 --- /dev/null +++ b/vendor/solarium/solarium/src/Plugin/Loadbalancer/Event/Events.php @@ -0,0 +1,18 @@ + false, + 'failovermaxretries' => 1, + ]; + + /** + * Registered endpoints. + * + * @var Endpoint[] + */ + protected $endpoints = []; + + /** + * Query types that are blocked from loadbalancing. + * + * @var array + */ + protected $blockedQueryTypes = [ + Client::QUERY_UPDATE => true, + ]; + + /** + * Last used endpoint key. + * + * The value can be null if no queries have been executed, or if the last executed query didn't use loadbalancing. + * + * @var null|string + */ + protected $lastEndpoint; + + /** + * Endpoint key to use for next query (overrules randomizer). + * + * @var string + */ + protected $nextEndpoint; + + /** + * Default endpoint key. + * + * This endpoint is used for queries that cannot be loadbalanced + * (for instance update queries that need to go to the master) + * + * @var string + */ + protected $defaultEndpoint; + + /** + * Pool of endpoint keys to use for requests. + * + * @var WeightedRandomChoice + */ + protected $randomizer; + + /** + * Query type. + * + * @var string + */ + protected $queryType; + + /** + * Used for failover mechanism. + * + * @var array + */ + protected $endpointExcludes; + + /** + * Set failover enabled option. + * + * @param bool $value + * + * @return self Provides fluent interface + */ + public function setFailoverEnabled($value) + { + return $this->setOption('failoverenabled', $value); + } + + /** + * Get failoverenabled option. + * + * @return bool + */ + public function getFailoverEnabled() + { + return $this->getOption('failoverenabled'); + } + + /** + * Set failover max retries. + * + * @param int $value + * + * @return self Provides fluent interface + */ + public function setFailoverMaxRetries($value) + { + return $this->setOption('failovermaxretries', $value); + } + + /** + * Get failovermaxretries option. + * + * @return int + */ + public function getFailoverMaxRetries() + { + return $this->getOption('failovermaxretries'); + } + + /** + * Add an endpoint to the loadbalacing 'pool'. + * + * + * @param Endpoint|string $endpoint + * @param int $weight Must be a positive number + * + * @throws InvalidArgumentException + * + * @return self Provides fluent interface + */ + public function addEndpoint($endpoint, $weight = 1) + { + if (!is_string($endpoint)) { + $endpoint = $endpoint->getKey(); + } + + if (array_key_exists($endpoint, $this->endpoints)) { + throw new InvalidArgumentException('An endpoint for the loadbalancer plugin must have a unique key'); + } + + $this->endpoints[$endpoint] = $weight; + + // reset the randomizer as soon as a new endpoint is added + $this->randomizer = null; + + return $this; + } + + /** + * Add multiple endpoints. + * + * @param array $endpoints + * + * @return self Provides fluent interface + */ + public function addEndpoints(array $endpoints) + { + foreach ($endpoints as $endpoint => $weight) { + $this->addEndpoint($endpoint, $weight); + } + + return $this; + } + + /** + * Get the endpoints in the loadbalancing pool. + * + * @return Endpoint[] + */ + public function getEndpoints() + { + return $this->endpoints; + } + + /** + * Clear all endpoint entries. + * + * @return self Provides fluent interface + */ + public function clearEndpoints() + { + $this->endpoints = []; + } + + /** + * Remove an endpoint by key. + * + * @param Endpoint|string $endpoint + * + * @return self Provides fluent interface + */ + public function removeEndpoint($endpoint) + { + if (!is_string($endpoint)) { + $endpoint = $endpoint->getKey(); + } + + if (isset($this->endpoints[$endpoint])) { + unset($this->endpoints[$endpoint]); + } + + return $this; + } + + /** + * Set multiple endpoints. + * + * This overwrites any existing endpoints + * + * @param array $endpoints + */ + public function setEndpoints($endpoints) + { + $this->clearEndpoints(); + $this->addEndpoints($endpoints); + } + + /** + * Set a forced endpoints (by key) for the next request. + * + * As soon as one query has used the forced endpoint this setting is reset. If you want to remove this setting + * pass NULL as the key value. + * + * If the next query cannot be loadbalanced (for instance based on the querytype) this setting is ignored + * but will still be reset. + * + * + * @param string|null|Endpoint $endpoint + * + * @throws OutOfBoundsException + * + * @return self Provides fluent interface + */ + public function setForcedEndpointForNextQuery($endpoint) + { + if (!is_string($endpoint)) { + $endpoint = $endpoint->getKey(); + } + + if (null !== $endpoint && !array_key_exists($endpoint, $this->endpoints)) { + throw new OutOfBoundsException('Unknown endpoint forced for next query'); + } + + $this->nextEndpoint = $endpoint; + + return $this; + } + + /** + * Get the ForcedEndpointForNextQuery value. + * + * @return string|null + */ + public function getForcedEndpointForNextQuery() + { + return $this->nextEndpoint; + } + + /** + * Get an array of blocked querytypes. + * + * @return array + */ + public function getBlockedQueryTypes() + { + return array_keys($this->blockedQueryTypes); + } + + /** + * Set querytypes to block from loadbalancing. + * + * Overwrites any existing types + * + * @param array $types Use an array with the constants defined in Solarium\Client as values + * + * @return self Provides fluent interface + */ + public function setBlockedQueryTypes($types) + { + $this->clearBlockedQueryTypes(); + $this->addBlockedQueryTypes($types); + + return $this; + } + + /** + * Add a querytype to block from loadbalancing. + * + * @param string $type Use one of the constants defined in Solarium\Client + * + * @return self Provides fluent interface + */ + public function addBlockedQueryType($type) + { + if (!array_key_exists($type, $this->blockedQueryTypes)) { + $this->blockedQueryTypes[$type] = true; + } + + return $this; + } + + /** + * Add querytypes to block from loadbalancing. + * + * Appended to any existing types + * + * @param array $types Use an array with the constants defined in Solarium\Client as values + * + * @return self Provides fluent interface + */ + public function addBlockedQueryTypes($types) + { + foreach ($types as $type) { + $this->addBlockedQueryType($type); + } + } + + /** + * Remove a single querytype from the block list. + * + * @param string $type + */ + public function removeBlockedQueryType($type) + { + if (array_key_exists($type, $this->blockedQueryTypes)) { + unset($this->blockedQueryTypes[$type]); + } + } + + /** + * Clear all blocked querytypes. + * + * @return self Provides fluent interface + */ + public function clearBlockedQueryTypes() + { + $this->blockedQueryTypes = []; + } + + /** + * Get the key of the endpoint that was used for the last query. + * + * May return a null value if no query has been executed yet, or the last query could not be loadbalanced. + * + * @return null|string + */ + public function getLastEndpoint() + { + return $this->lastEndpoint; + } + + /** + * Event hook to capture querytype. + * + * @param PreCreateRequestEvent $event + */ + public function preCreateRequest(PreCreateRequestEvent $event) + { + $this->queryType = $event->getQuery()->getType(); + } + + /** + * Event hook to adjust client settings just before query execution. + * + * @param PreExecuteRequestEvent $event + */ + public function preExecuteRequest(PreExecuteRequestEvent $event) + { + $adapter = $this->client->getAdapter(); + + // save adapter presets (once) to allow the settings to be restored later + if (null === $this->defaultEndpoint) { + $this->defaultEndpoint = $this->client->getEndpoint()->getKey(); + } + + // check querytype: is loadbalancing allowed? + if (!array_key_exists($this->queryType, $this->blockedQueryTypes)) { + $response = $this->getLoadbalancedResponse($event->getRequest()); + } else { + $endpoint = $this->client->getEndpoint($this->defaultEndpoint); + $this->lastEndpoint = null; + + // execute request and return result + $response = $adapter->execute($event->getRequest(), $endpoint); + } + + $event->setResponse($response); + } + + /** + * Execute a request using the adapter. + * + * + * @param Request $request + * + * @throws RuntimeException + * + * @return Response $response + */ + protected function getLoadbalancedResponse($request) + { + $this->endpointExcludes = []; // reset for each query + $adapter = $this->client->getAdapter(); + + if (true === $this->getFailoverEnabled()) { + $maxRetries = $this->getFailoverMaxRetries(); + for ($i = 0; $i <= $maxRetries; ++$i) { + $endpoint = $this->getRandomEndpoint(); + try { + return $adapter->execute($request, $endpoint); + } catch (HttpException $e) { + // ignore HTTP errors and try again + // but do issue an event for things like logging + $this->client->getEventDispatcher()->dispatch( + Events::ENDPOINT_FAILURE, + new EndpointFailureEvent($endpoint, $e) + ); + } + } + + // if we get here no more retries available, throw exception + throw new RuntimeException('Maximum number of loadbalancer retries reached'); + } + + // no failover retries, just execute and let an exception bubble upwards + $endpoint = $this->getRandomEndpoint(); + + return $adapter->execute($request, $endpoint); + } + + /** + * Get a random endpoint. + * + * @return Endpoint + */ + protected function getRandomEndpoint() + { + // determine the endpoint to use + if (null !== $this->nextEndpoint) { + $key = $this->nextEndpoint; + // reset forced endpoint directly after use + $this->nextEndpoint = null; + } else { + $key = $this->getRandomizer()->getRandom($this->endpointExcludes); + } + + $this->endpointExcludes[] = $key; + $this->lastEndpoint = $key; + + return $this->client->getEndpoint($key); + } + + /** + * Get randomizer instance. + * + * @return WeightedRandomChoice + */ + protected function getRandomizer() + { + if (null === $this->randomizer) { + $this->randomizer = new WeightedRandomChoice($this->endpoints); + } + + return $this->randomizer; + } + + /** + * Initialize options. + * + * Several options need some extra checks or setup work, for these options + * the setters are called. + */ + protected function init() + { + foreach ($this->options as $name => $value) { + switch ($name) { + case 'endpoint': + $this->setEndpoints($value); + break; + case 'blockedquerytype': + $this->setBlockedQueryTypes($value); + break; + } + } + } + + /** + * Plugin init function. + * + * Register event listeners + */ + protected function initPluginType() + { + $dispatcher = $this->client->getEventDispatcher(); + $dispatcher->addListener(CoreEvents::PRE_EXECUTE_REQUEST, [$this, 'preExecuteRequest']); + $dispatcher->addListener(CoreEvents::PRE_CREATE_REQUEST, [$this, 'preCreateRequest']); + } +} diff --git a/vendor/solarium/solarium/src/Plugin/Loadbalancer/WeightedRandomChoice.php b/vendor/solarium/solarium/src/Plugin/Loadbalancer/WeightedRandomChoice.php new file mode 100644 index 000000000..222c48efb --- /dev/null +++ b/vendor/solarium/solarium/src/Plugin/Loadbalancer/WeightedRandomChoice.php @@ -0,0 +1,116 @@ + $weight) { + if ($weight <= 0) { + throw new InvalidArgumentException('Weight must be greater than zero'); + } + + $this->totalWeight += $weight; + $this->lookup[$i] = $this->totalWeight; + $this->values[$i] = $key; + + ++$i; + } + } + + /** + * Get a (weighted) random entry. + * + * + * @param array $excludes Keys to exclude + * + * @throws RuntimeException + * + * @return string + */ + public function getRandom($excludes = []) + { + if (count($excludes) == count($this->values)) { + throw new RuntimeException('No more server entries available'); + } + + // continue until a non-excluded value is found + $result = null; + while (1) { + $result = $this->values[$this->getKey()]; + if (!in_array($result, $excludes, true)) { + break; + } + } + + return $result; + } + + /** + * Get a (weighted) random entry key. + * + * @return int + */ + protected function getKey() + { + $random = mt_rand(1, $this->totalWeight); + $high = count($this->lookup) - 1; + $low = 0; + + while ($low < $high) { + $probe = (int) (($high + $low) / 2); + if ($this->lookup[$probe] < $random) { + $low = $probe + 1; + } elseif ($this->lookup[$probe] > $random) { + $high = $probe - 1; + } else { + return $probe; + } + } + + if ($this->lookup[$low] >= $random) { + return $low; + } + + return $low + 1; + } +} diff --git a/vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/Document.php b/vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/Document.php new file mode 100644 index 000000000..671ef3570 --- /dev/null +++ b/vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/Document.php @@ -0,0 +1,169 @@ +document = $document; + $this->marked = $threshold > $document->score; + } + + /** + * Forward all other calls to the original document. + * + * @param string $name + * @param array $arguments + * + * @return mixed + */ + public function __call($name, $arguments) + { + return $this->document->$name($arguments); + } + + /** + * Forward all other calls to the original document. + * + * @param string $name + * + * @return mixed + */ + public function __get($name) + { + return $this->document->__get($name); + } + + /** + * Forward isset call to the original document. + * + * @param string $name + * + * @return bool + */ + public function __isset($name) + { + return $this->document->__isset($name); + } + + /** + * Set field value. + * + * Magic method for setting a field as property of this object. Since this + * is a readonly document an exception will be thrown to prevent this. + * + * + * @param string $name + * @param string $value + * + * @throws RuntimeException + */ + public function __set($name, $value) + { + throw new RuntimeException('A readonly document cannot be altered'); + } + + /** + * Get markedAsLowScore status. + * + * @return bool + */ + public function markedAsLowScore() + { + return $this->marked; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return $this->document->getIterator(); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return $this->document->count(); + } + + /** + * ArrayAccess implementation. + * + * @param mixed $offset + * + * @return bool + */ + public function offsetExists($offset) + { + return $this->document->offsetExists($offset); + } + + /** + * ArrayAccess implementation. + * + * @param mixed $offset + */ + public function offsetUnset($offset) + { + $this->document->offsetUnset($offset); + } + + /** + * ArrayAccess implementation. + * + * @param mixed $offset + * + * @return mixed|null + */ + public function offsetGet($offset) + { + return $this->document->offsetGet($offset); + } + + /** + * ArrayAccess implementation. + * + * @param mixed $offset + * @param mixed $value + */ + public function offsetSet($offset, $value) + { + $this->__set($offset, $value); + } +} diff --git a/vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/Filter.php b/vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/Filter.php new file mode 100644 index 000000000..dcc325588 --- /dev/null +++ b/vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/Filter.php @@ -0,0 +1,46 @@ + $document) { + if ($document->score < $threshold) { + unset($documents[$key]); + } + } + break; + case Query::FILTER_MODE_MARK: + foreach ($documents as $key => $document) { + $documents[$key] = new Document($document, $threshold); + } + break; + default: + throw new OutOfBoundsException('Unknown filter mode in query: '.$mode); + break; + } + + return $documents; + } +} diff --git a/vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/MinimumScoreFilter.php b/vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/MinimumScoreFilter.php new file mode 100644 index 000000000..beb94594f --- /dev/null +++ b/vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/MinimumScoreFilter.php @@ -0,0 +1,28 @@ +client->registerQueryType(self::QUERY_TYPE, 'Solarium\Plugin\MinimumScoreFilter\Query'); + } +} diff --git a/vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/Query.php b/vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/Query.php new file mode 100644 index 000000000..9d572228c --- /dev/null +++ b/vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/Query.php @@ -0,0 +1,127 @@ + 'select', + 'resultclass' => 'Solarium\QueryType\Select\Result\Result', + 'documentclass' => 'Solarium\QueryType\Select\Result\Document', + 'query' => '*:*', + 'start' => 0, + 'rows' => 10, + 'fields' => '*,score', + 'omitheader' => true, + 'filterratio' => 0.1, + 'filter_mode' => self::FILTER_MODE_REMOVE, + ]; + + /** + * Set filter mode. + * + * @param string $mode + * + * @return self Provides fluent interface + */ + public function setFilterMode($mode) + { + return $this->setOption('filter_mode', $mode); + } + + /** + * Get filter mode. + * + * @return string + */ + public function getFilterMode() + { + return $this->getOption('filter_mode'); + } + + /** + * Set filterratio option. + * + * This should be a ratio between 0 and 1, the minimum score is calculated by multiplying maxscore with this ratio. + * + * @param float $value + * + * @return self Provides fluent interface + */ + public function setFilterRatio($value) + { + return $this->setOption('filterratio', $value); + } + + /** + * Get filterratio option. + * + * @return float + */ + public function getFilterRatio() + { + return $this->getOption('filterratio'); + } + + /** + * Make sure the score field is always enabled. + * + * @return array + */ + public function getFields() + { + $fields = parent::getFields(); + if (!in_array('score', $fields, true)) { + $fields[] = 'score'; + } + + return $fields; + } + + /** + * Make sure the filtering result class is always used. + * + * @return string + */ + public function getResultClass() + { + return 'Solarium\Plugin\MinimumScoreFilter\Result'; + } + + /** + * Get all registered components. + * + * @return AbstractComponent[] + */ + public function getComponents() + { + if (isset($this->components[self::COMPONENT_GROUPING])) { + $this->components[self::COMPONENT_GROUPING]->setOption('resultquerygroupclass', 'Solarium\Plugin\MinimumScoreFilter\QueryGroupResult'); + $this->components[self::COMPONENT_GROUPING]->setOption('resultvaluegroupclass', 'Solarium\Plugin\MinimumScoreFilter\ValueGroupResult'); + } + + return parent::getComponents(); + } +} diff --git a/vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/QueryGroupResult.php b/vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/QueryGroupResult.php new file mode 100644 index 000000000..0334e366b --- /dev/null +++ b/vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/QueryGroupResult.php @@ -0,0 +1,70 @@ +filterMode = $query->getFilterMode(); + $this->filterRatio = $query->getFilterRatio(); + + // Use the maximumScore of the first group as maximum for all groups + if (null === self::$overallMaximumScore) { + self::$overallMaximumScore = $maximumScore; + } + + parent::__construct($matches, $numFound, $start, $maximumScore, $documents, $query); + } + + /** + * Get all documents, apply filter at first use. + * + * @return array + */ + public function getDocuments() + { + if (!$this->filtered) { + $filter = new Filter(); + $this->documents = $filter->filterDocuments($this->documents, self::$overallMaximumScore, $this->filterRatio, $this->filterMode); + $this->filtered = true; + } + + return $this->documents; + } +} diff --git a/vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/Result.php b/vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/Result.php new file mode 100644 index 000000000..ca267ba75 --- /dev/null +++ b/vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/Result.php @@ -0,0 +1,31 @@ + $data) { + if ('documents' == $key) { + $filter = new Filter(); + $mode = $this->getQuery()->getFilterMode(); + $ratio = $this->getQuery()->getFilterRatio(); + $data = $filter->filterDocuments($data, $mapData['maxscore'], $ratio, $mode); + } + $this->$key = $data; + } + } +} diff --git a/vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/ValueGroupResult.php b/vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/ValueGroupResult.php new file mode 100644 index 000000000..9d07b9b8c --- /dev/null +++ b/vendor/solarium/solarium/src/Plugin/MinimumScoreFilter/ValueGroupResult.php @@ -0,0 +1,70 @@ +filterMode = $query->getFilterMode(); + $this->filterRatio = $query->getFilterRatio(); + + // Use the maximumScore of the first group as maximum for all groups + if ($maximumScore > self::$overallMaximumScore) { + self::$overallMaximumScore = $maximumScore; + } + + parent::__construct($value, $numFound, $start, $documents); + } + + /** + * Get all documents, apply filter at first use. + * + * @return array + */ + public function getDocuments() + { + if (!$this->filtered) { + $filter = new Filter(); + $this->documents = $filter->filterDocuments($this->documents, self::$overallMaximumScore, $this->filterRatio, $this->filterMode); + $this->filtered = true; + } + + return $this->documents; + } +} diff --git a/vendor/solarium/solarium/src/Plugin/ParallelExecution/Event/Events.php b/vendor/solarium/solarium/src/Plugin/ParallelExecution/Event/Events.php new file mode 100644 index 000000000..691cc4436 --- /dev/null +++ b/vendor/solarium/solarium/src/Plugin/ParallelExecution/Event/Events.php @@ -0,0 +1,27 @@ + 0.1, + ]; + + /** + * Queries (and optionally clients) to execute. + * + * @var AbstractQuery[] + */ + protected $queries = []; + + /** + * Add a query to execute. + * + * @param string $key + * @param AbstractQuery $query + * @param null|string|Endpoint $endpoint + * + * @return self Provides fluent interface + */ + public function addQuery($key, $query, $endpoint = null) + { + if (is_object($endpoint)) { + $endpoint = $endpoint->getKey(); + } + + if (null === $endpoint) { + $endpoint = $this->client->getEndpoint()->getKey(); + } + + $this->queries[$key] = [ + 'query' => $query, + 'endpoint' => $endpoint, + ]; + + return $this; + } + + /** + * Get queries (and coupled client instances). + * + * @return AbstractQuery[] + */ + public function getQueries() + { + return $this->queries; + } + + /** + * Clear all queries. + * + * @return self Provides fluent interface + */ + public function clearQueries() + { + $this->queries = []; + + return $this; + } + + // @codeCoverageIgnoreStart + + /** + * Execute queries parallel. + * + * @return \Solarium\Core\Query\Result\Result[] + */ + public function execute() + { + // create handles and add all handles to the multihandle + $adapter = $this->client->getAdapter(); + $multiHandle = curl_multi_init(); + $handles = []; + foreach ($this->queries as $key => $data) { + $request = $this->client->createRequest($data['query']); + $endpoint = $this->client->getEndpoint($data['endpoint']); + $handle = $adapter->createHandle($request, $endpoint); + curl_multi_add_handle($multiHandle, $handle); + $handles[$key] = $handle; + } + + // executing multihandle (all requests) + $this->client->getEventDispatcher()->dispatch(Events::EXECUTE_START, new ExecuteStartEvent()); + + do { + $mrc = curl_multi_exec($multiHandle, $active); + } while (CURLM_CALL_MULTI_PERFORM == $mrc); + + $timeout = $this->getOption('curlmultiselecttimeout'); + while ($active && CURLM_OK == $mrc) { + if (curl_multi_select($multiHandle, $timeout) == -1) { + usleep(100); + } + + do { + $mrc = curl_multi_exec($multiHandle, $active); + } while (CURLM_CALL_MULTI_PERFORM == $mrc); + } + + $this->client->getEventDispatcher()->dispatch(Events::EXECUTE_END, new ExecuteEndEvent()); + + // get the results + $results = []; + foreach ($handles as $key => $handle) { + try { + curl_multi_remove_handle($multiHandle, $handle); + $response = $adapter->getResponse($handle, curl_multi_getcontent($handle)); + $results[$key] = $this->client->createResult($this->queries[$key]['query'], $response); + } catch (HttpException $e) { + $results[$key] = $e; + } + } + + curl_multi_close($multiHandle); + + return $results; + } + + /* + * @codeCoverageIgnoreEnd + */ + + /** + * Set curl adapter (the only type that supports parallelexecution). + */ + protected function initPluginType() + { + $this->client->setAdapter('Solarium\Core\Client\Adapter\Curl'); + } +} diff --git a/vendor/solarium/solarium/src/Plugin/PostBigRequest.php b/vendor/solarium/solarium/src/Plugin/PostBigRequest.php new file mode 100644 index 000000000..c8f132e8b --- /dev/null +++ b/vendor/solarium/solarium/src/Plugin/PostBigRequest.php @@ -0,0 +1,81 @@ + 1024, + ]; + + /** + * Set maxquerystringlength enabled option. + * + * @param int $value + * + * @return self Provides fluent interface + */ + public function setMaxQueryStringLength($value) + { + return $this->setOption('maxquerystringlength', $value); + } + + /** + * Get maxquerystringlength option. + * + * @return int + */ + public function getMaxQueryStringLength() + { + return $this->getOption('maxquerystringlength'); + } + + /** + * Event hook to adjust client settings just before query execution. + * + * @param PostCreateRequestEvent $event + */ + public function postCreateRequest($event) + { + $request = $event->getRequest(); + $queryString = $request->getQueryString(); + if (Request::METHOD_GET == $request->getMethod() && + strlen($queryString) > $this->getMaxQueryStringLength()) { + $request->setMethod(Request::METHOD_POST); + $request->setRawData($queryString); + $request->clearParams(); + $request->addHeader('Content-Type: application/x-www-form-urlencoded'); + } + } + + /** + * Plugin init function. + * + * Register event listeners + */ + protected function initPluginType() + { + $dispatcher = $this->client->getEventDispatcher(); + $dispatcher->addListener(Events::POST_CREATE_REQUEST, [$this, 'postCreateRequest']); + } +} diff --git a/vendor/solarium/solarium/src/Plugin/PrefetchIterator.php b/vendor/solarium/solarium/src/Plugin/PrefetchIterator.php new file mode 100644 index 000000000..a681111a5 --- /dev/null +++ b/vendor/solarium/solarium/src/Plugin/PrefetchIterator.php @@ -0,0 +1,254 @@ + 100, + ]; + + /** + * Query instance to execute. + * + * @var SelectQuery + */ + protected $query; + + /** + * Start position (offset). + * + * @var int + */ + protected $start = 0; + + /** + * Last resultset from the query instance. + * + * @var SelectResult + */ + protected $result; + + /** + * Iterator position. + * + * @var int + */ + protected $position; + + /** + * Cursor mark. + * + * @var string + */ + protected $cursormark; + + /** + * Documents from the last resultset. + * + * @var DocumentInterface[] + */ + protected $documents; + + /** + * Set prefetch option. + * + * @param int $value + * + * @return self Provides fluent interface + */ + public function setPrefetch($value) + { + $this->resetData(); + + return $this->setOption('prefetch', $value); + } + + /** + * Get prefetch option. + * + * @return int + */ + public function getPrefetch() + { + return $this->getOption('prefetch'); + } + + /** + * Set query to use for prefetching. + * + * @param SelectQuery $query + * + * @return self Provides fluent interface + */ + public function setQuery($query) + { + $this->query = $query; + $this->resetData(); + + return $this; + } + + /** + * Get the query object used. + * + * @return SelectQuery + */ + public function getQuery() + { + return $this->query; + } + + /** + * Set endpoint to use. + * + * This overwrites any existing endpoint + * + * @param string|Endpoint $endpoint + * + * @return self Provides fluent interface + */ + public function setEndpoint($endpoint) + { + return $this->setOption('endpoint', $endpoint); + } + + /** + * Get endpoint setting. + * + * @return string|Endpoint|null + */ + public function getEndpoint() + { + return $this->getOption('endpoint'); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + // if no results are available yet, get them now + if (null === $this->result) { + $this->fetchNext(); + } + + return $this->result->getNumFound(); + } + + /** + * Iterator implementation. + */ + public function rewind() + { + $this->position = 0; + + // this condition prevent useless re-fetching of data if a count is done before the iterator is used + if ($this->start !== $this->options['prefetch']) { + $this->start = 0; + + if (null !== $this->cursormark) { + $this->cursormark = '*'; + } + } + } + + /** + * Iterator implementation. + * + * @return DocumentInterface + */ + public function current() + { + $adjustedIndex = $this->position % $this->options['prefetch']; + + return $this->documents[$adjustedIndex]; + } + + /** + * Iterator implementation. + * + * @return int + */ + public function key() + { + return $this->position; + } + + /** + * Iterator implementation. + */ + public function next() + { + ++$this->position; + } + + /** + * Iterator implementation. + * + * @return bool + */ + public function valid() + { + $adjustedIndex = $this->position % $this->options['prefetch']; + + // this condition prevent useless re-fetching of data if a count is done before the iterator is used + if (0 === $adjustedIndex && (0 !== $this->position || null === $this->result)) { + $this->fetchNext(); + } + + return isset($this->documents[$adjustedIndex]); + } + + /** + * Fetch the next set of results. + */ + protected function fetchNext() + { + if (null === $this->cursormark && null !== $this->query->getCursormark()) { + $this->cursormark = '*'; + } + + if (null === $this->cursormark) { + $this->query->setStart($this->start)->setRows($this->getPrefetch()); + } else { + $this->query->setCursormark($this->cursormark)->setRows($this->getPrefetch()); + } + + $this->result = $this->client->execute($this->query, $this->getOption('endpoint')); + $this->cursormark = $this->result->getNextCursorMark(); + $this->documents = $this->result->getDocuments(); + $this->start += $this->getPrefetch(); + } + + /** + * Reset any cached data / position. + */ + protected function resetData() + { + $this->position = null; + $this->result = null; + $this->documents = null; + $this->start = 0; + $this->cursormark = null; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Analysis/Query/AbstractQuery.php b/vendor/solarium/solarium/src/QueryType/Analysis/Query/AbstractQuery.php new file mode 100644 index 000000000..6967fa928 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Analysis/Query/AbstractQuery.php @@ -0,0 +1,37 @@ +setOption('showmatch', $show); + } + + /** + * Get the showmatch option. + * + * @return mixed + */ + public function getShowMatch() + { + return $this->getOption('showmatch'); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Analysis/Query/Document.php b/vendor/solarium/solarium/src/QueryType/Analysis/Query/Document.php new file mode 100644 index 000000000..9e72785a2 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Analysis/Query/Document.php @@ -0,0 +1,120 @@ + 'analysis/document', + 'resultclass' => 'Solarium\QueryType\Analysis\Result\Document', + 'omitheader' => true, + ]; + + /** + * Get type for this query. + * + * @return string + */ + public function getType() + { + return Client::QUERY_ANALYSIS_DOCUMENT; + } + + /** + * Get a requestbuilder for this query. + * + * @return RequestBuilder + */ + public function getRequestBuilder() + { + return new RequestBuilder(); + } + + /** + * Get a response parser for this query. + * + * @return ResponseParser + */ + public function getResponseParser() + { + return new ResponseParser(); + } + + /** + * Add a single document. + * + * @param ReadOnlyDocumentInterface|DocumentInterface $document + * + * @throws RuntimeException If the given document doesn't have the right interface + * + * @return self Provides fluent interface + */ + public function addDocument($document) + { + if (!($document instanceof ReadOnlyDocumentInterface) && !($document instanceof DocumentInterface)) { + throw new RuntimeException(sprintf(static::DOCUMENT_TYPE_HINT_EXCEPTION_MESSAGE, get_class($document))); + } + + $this->documents[] = $document; + + return $this; + } + + /** + * Add multiple documents. + * + * @param ReadOnlyDocumentInterface[]|DocumentInterface[] $documents + * + * @throws RuntimeException If the given documents doesn't have the right interface + * + * @return self Provides fluent interface + */ + public function addDocuments($documents) + { + foreach ($documents as $document) { + if (!($document instanceof ReadOnlyDocumentInterface) && !($document instanceof DocumentInterface)) { + throw new RuntimeException(sprintf(static::DOCUMENT_TYPE_HINT_EXCEPTION_MESSAGE, get_class($document))); + } + } + + $this->documents = array_merge($this->documents, $documents); + + return $this; + } + + /** + * Get all documents. + * + * @return ReadOnlyDocumentInterface[]|DocumentInterface[] + */ + public function getDocuments() + { + return $this->documents; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Analysis/Query/Field.php b/vendor/solarium/solarium/src/QueryType/Analysis/Query/Field.php new file mode 100644 index 000000000..0ead813f4 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Analysis/Query/Field.php @@ -0,0 +1,126 @@ + 'analysis/field', + 'resultclass' => 'Solarium\QueryType\Analysis\Result\Field', + 'omitheader' => true, + ]; + + /** + * Get type for this query. + * + * @return string + */ + public function getType() + { + return Client::QUERY_ANALYSIS_FIELD; + } + + /** + * Get a requestbuilder for this query. + * + * @return RequestBuilder + */ + public function getRequestBuilder() + { + return new RequestBuilder(); + } + + /** + * Get a response parser for this query. + * + * @return ResponseParser + */ + public function getResponseParser() + { + return new ResponseParser(); + } + + /** + * Set the field value option. + * + * The text that will be analyzed. The analysis will mimic the index-time analysis. + * + * @param string $value + * + * @return self Provides fluent interface + */ + public function setFieldValue($value) + { + return $this->setOption('fieldvalue', $value); + } + + /** + * Get the field value option. + * + * @return string + */ + public function getFieldValue() + { + return $this->getOption('fieldvalue'); + } + + /** + * Set the field type option. + * + * When present, the text will be analyzed based on the specified type + * + * @param string $type + * + * @return self Provides fluent interface + */ + public function setFieldType($type) + { + return $this->setOption('fieldtype', $type); + } + + /** + * Get the fieldtype option. + * + * @return string + */ + public function getFieldType() + { + return $this->getOption('fieldtype'); + } + + /** + * Set the field name option. + * + * When present, the text will be analyzed based on the type of this field name + * + * @param string $name + * + * @return self Provides fluent interface + */ + public function setFieldName($name) + { + return $this->setOption('fieldname', $name); + } + + /** + * Get the fieldname option. + * + * @return string + */ + public function getFieldName() + { + return $this->getOption('fieldname'); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Analysis/RequestBuilder/Document.php b/vendor/solarium/solarium/src/QueryType/Analysis/RequestBuilder/Document.php new file mode 100644 index 000000000..aca14da1f --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Analysis/RequestBuilder/Document.php @@ -0,0 +1,75 @@ +setRawData($this->getRawData($query)); + $request->setMethod(Request::METHOD_POST); + + return $request; + } + + /** + * Create the raw post data (xml). + * + * @param QueryDocument $query + * + * @return string + */ + public function getRawData($query) + { + $xml = ''; + + foreach ($query->getDocuments() as $doc) { + $xml .= ''; + + foreach ($doc->getFields() as $name => $value) { + if (is_array($value)) { + foreach ($value as $multival) { + $xml .= $this->buildFieldXml($name, $multival); + } + } else { + $xml .= $this->buildFieldXml($name, $value); + } + } + + $xml .= ''; + } + + $xml .= ''; + + return $xml; + } + + /** + * Build XML for a field. + * + * @param string $name + * @param mixed $value + * + * @return string + */ + protected function buildFieldXml($name, $value) + { + return ''.htmlspecialchars($value, ENT_NOQUOTES, 'UTF-8').''; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Analysis/RequestBuilder/Field.php b/vendor/solarium/solarium/src/QueryType/Analysis/RequestBuilder/Field.php new file mode 100644 index 000000000..32bb2542e --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Analysis/RequestBuilder/Field.php @@ -0,0 +1,31 @@ +addParam('analysis.fieldvalue', $query->getFieldValue()); + $request->addParam('analysis.fieldname', $query->getFieldName()); + $request->addParam('analysis.fieldtype', $query->getFieldType()); + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Analysis/RequestBuilder/RequestBuilder.php b/vendor/solarium/solarium/src/QueryType/Analysis/RequestBuilder/RequestBuilder.php new file mode 100644 index 000000000..06a6f7431 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Analysis/RequestBuilder/RequestBuilder.php @@ -0,0 +1,29 @@ +addParam('analysis.query', $query->getQuery()); + $request->addParam('analysis.showmatch', $query->getShowMatch()); + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Analysis/ResponseParser/Document.php b/vendor/solarium/solarium/src/QueryType/Analysis/ResponseParser/Document.php new file mode 100644 index 000000000..fef1e5db7 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Analysis/ResponseParser/Document.php @@ -0,0 +1,30 @@ + $documentData) { + $fields = $this->parseTypes($result, $documentData); + $documents[] = new ResultList($documentKey, $fields); + } + + return $documents; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Analysis/ResponseParser/Field.php b/vendor/solarium/solarium/src/QueryType/Analysis/ResponseParser/Field.php new file mode 100644 index 000000000..5193be1f2 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Analysis/ResponseParser/Field.php @@ -0,0 +1,114 @@ +getData(); + + $items = []; + + if (isset($data['analysis'])) { + $items = $this->parseAnalysis($result, $data['analysis']); + } + + return $this->addHeaderInfo($data, ['items' => $items]); + } + + /** + * Parser. + * + * @param Result $result + * @param array $data + * + * @return Types[] + */ + protected function parseAnalysis($result, $data) + { + $types = []; + foreach ($data as $documentKey => $documentData) { + $fields = $this->parseTypes($result, $documentData); + $types[] = new AnalysisResult\ResultList($documentKey, $fields); + } + + return $types; + } + + /** + * Parse analysis types and items. + * + * @param Result $result + * @param array $typeData + * + * @return Types[] + */ + protected function parseTypes($result, $typeData) + { + $query = $result->getQuery(); + + $results = []; + foreach ($typeData as $fieldKey => $fieldData) { + $types = []; + foreach ($fieldData as $typeKey => $typeData) { + if ($query->getResponseWriter() == $query::WT_JSON) { + // fix for extra level for key fields + if (1 == count($typeData)) { + $typeData = current($typeData); + } + $typeData = $this->convertToKeyValueArray($typeData); + } + + $classes = []; + foreach ($typeData as $class => $analysis) { + if (is_string($analysis)) { + $item = new Item( + [ + 'text' => $analysis, + 'start' => null, + 'end' => null, + 'position' => null, + 'positionHistory' => null, + 'type' => null, + ] + ); + + $classes[] = new ResultList($class, [$item]); + } else { + $items = []; + foreach ($analysis as $itemData) { + $items[] = new Item($itemData); + } + + $classes[] = new ResultList($class, $items); + } + } + + $types[] = new ResultList($typeKey, $classes); + } + + $results[] = new Types($fieldKey, $types); + } + + return $results; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Analysis/Result/Document.php b/vendor/solarium/solarium/src/QueryType/Analysis/Result/Document.php new file mode 100644 index 000000000..7a6b21aeb --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Analysis/Result/Document.php @@ -0,0 +1,116 @@ +parseResponse(); + + return $this->status; + } + + /** + * Get Solr query time. + * + * This doesn't include things like the HTTP responsetime. Purely the Solr + * query execution time. + * + * @return int + */ + public function getQueryTime() + { + $this->parseResponse(); + + return $this->queryTime; + } + + /** + * Get all documents. + * + * @return ResultList[] + */ + public function getDocuments() + { + $this->parseResponse(); + + return $this->items; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + $this->parseResponse(); + + return new \ArrayIterator($this->items); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + $this->parseResponse(); + + return count($this->items); + } + + /** + * Get a document by uniquekey value. + * + * @param string $key + * + * @return ResultList|null + */ + public function getDocument($key) + { + $this->parseResponse(); + + if (isset($this->items[$key])) { + return $this->items[$key]; + } + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Analysis/Result/Field.php b/vendor/solarium/solarium/src/QueryType/Analysis/Result/Field.php new file mode 100644 index 000000000..05fd504b6 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Analysis/Result/Field.php @@ -0,0 +1,100 @@ +parseResponse(); + + return $this->status; + } + + /** + * Get Solr query time. + * + * This doesn't include things like the HTTP responsetime. Purely the Solr + * query execution time. + * + * @return int + */ + public function getQueryTime() + { + $this->parseResponse(); + + return $this->queryTime; + } + + /** + * Get all lists. + * + * @return array + */ + public function getLists() + { + $this->parseResponse(); + + return $this->items; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + $this->parseResponse(); + + return new \ArrayIterator($this->items); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + $this->parseResponse(); + + return count($this->items); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Analysis/Result/Item.php b/vendor/solarium/solarium/src/QueryType/Analysis/Result/Item.php new file mode 100644 index 000000000..23d45d791 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Analysis/Result/Item.php @@ -0,0 +1,174 @@ +text = $analysis['text']; + $this->start = $analysis['start']; + $this->end = $analysis['end']; + $this->position = $analysis['position']; + $this->positionHistory = $analysis['positionHistory']; + $this->type = $analysis['type']; + + if (isset($analysis['raw_text'])) { + $this->rawText = $analysis['raw_text']; + } + + if (isset($analysis['match'])) { + $this->match = $analysis['match']; + } + } + + /** + * Get text value. + * + * @return string + */ + public function getText() + { + return $this->text; + } + + /** + * Get raw text value. + * + * This values is not available in all cases + * + * @return string + */ + public function getRawText() + { + return $this->rawText; + } + + /** + * Get start value. + * + * @return int + */ + public function getStart() + { + return $this->start; + } + + /** + * Get end value. + * + * @return int + */ + public function getEnd() + { + return $this->end; + } + + /** + * Get postion value. + * + * @return int + */ + public function getPosition() + { + return $this->position; + } + + /** + * Get position history value. + * + * @return array + */ + public function getPositionHistory() + { + if (is_array($this->positionHistory)) { + return $this->positionHistory; + } + + return []; + } + + /** + * Get type value. + * + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * Get match value. + * + * @return bool + */ + public function getMatch() + { + return $this->match; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Analysis/Result/ResultList.php b/vendor/solarium/solarium/src/QueryType/Analysis/Result/ResultList.php new file mode 100644 index 000000000..176243a90 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Analysis/Result/ResultList.php @@ -0,0 +1,75 @@ +name = $name; + $this->items = $items; + } + + /** + * Get type value. + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Get all items. + * + * @return array + */ + public function getItems() + { + return $this->items; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->items); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->items); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Analysis/Result/Types.php b/vendor/solarium/solarium/src/QueryType/Analysis/Result/Types.php new file mode 100644 index 000000000..9d276da39 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Analysis/Result/Types.php @@ -0,0 +1,44 @@ +items as $item) { + if ('index' == $item->getName()) { + return $item; + } + } + } + + /** + * Get query analysis list. + * + * @return ResultList|null + */ + public function getQueryAnalysis() + { + foreach ($this->items as $item) { + if ('query' == $item->getName()) { + return $item; + } + } + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Extract/Query.php b/vendor/solarium/solarium/src/QueryType/Extract/Query.php new file mode 100644 index 000000000..c20df2c41 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Extract/Query.php @@ -0,0 +1,396 @@ + 'update/extract', + 'resultclass' => 'Solarium\QueryType\Extract\Result', + 'documentclass' => 'Solarium\QueryType\Update\Query\Document\Document', + 'omitheader' => true, + 'extractonly' => false, + ]; + + /** + * Field name mappings. + * + * @var array + */ + protected $fieldMappings = []; + + /** + * Get type for this query. + * + * @return string + */ + public function getType() + { + return Client::QUERY_EXTRACT; + } + + /** + * Get a requestbuilder for this query. + * + * @return RequestBuilder + */ + public function getRequestBuilder() + { + return new RequestBuilder(); + } + + /** + * Get a response parser for this query. + * + * @return UpdateResponseParser + */ + public function getResponseParser() + { + return new UpdateResponseParser(); + } + + /** + * Set the document with literal fields and boost settings. + * + * The fields in the document are indexed together with the generated + * fields that Solr extracts from the file. + * + * @param DocumentInterface $document + * + * @return self + */ + public function setDocument(DocumentInterface $document) + { + return $this->setOption('document', $document); + } + + /** + * Get the document with literal fields and boost settings. + * + * @return DocumentInterface|null + */ + public function getDocument() + { + return $this->getOption('document'); + } + + /** + * Set the file to upload and index. + * + * @param string $filename + * + * @return self + */ + public function setFile($filename) + { + return $this->setOption('file', $filename); + } + + /** + * Get the file to upload and index. + * + * @return string|null + */ + public function getFile() + { + return $this->getOption('file'); + } + + /** + * Set the prefix for fields that are not defined in the schema. + * + * @param string $uprefix + * + * @return self + */ + public function setUprefix($uprefix) + { + return $this->setOption('uprefix', $uprefix); + } + + /** + * Get the prefix for fields that are not defined in the schema. + * + * @return string|null + */ + public function getUprefix() + { + return $this->getOption('uprefix'); + } + + /** + * Set the field to use if uprefix is not specified and a field cannot be + * determined. + * + * @param string $defaultField + * + * @return self + */ + public function setDefaultField($defaultField) + { + return $this->setOption('defaultField', $defaultField); + } + + /** + * Get the field to use if uprefix is not specified and a field cannot be + * determined. + * + * @return string|null + */ + public function getDefaultField() + { + return $this->getOption('defaultField'); + } + + /** + * Set if all field names should be mapped to lowercase with underscores. + * For example, Content-Type would be mapped to content_type. + * + * @param bool $lowerNames + * + * @return self + */ + public function setLowernames($lowerNames) + { + return $this->setOption('lowernames', (bool) $lowerNames); + } + + /** + * Get if all field names should be mapped to lowercase with underscores. + * + * @return bool + */ + public function getLowernames() + { + return $this->getOption('lowernames'); + } + + /** + * Set if the extract should be committed immediately. + * + * @param bool $commit + * + * @return self Provides fluent interface + */ + public function setCommit($commit) + { + return $this->setOption('commit', (bool) $commit); + } + + /** + * Get if the extract should be committed immediately. + * + * @return bool + */ + public function getCommit() + { + return $this->getOption('commit'); + } + + /** + * Set milliseconds until extract update is committed. Since Solr 3.4. + * + * @param int $commitWithin + * + * @return self Provides fluent interface + */ + public function setCommitWithin($commitWithin) + { + return $this->setOption('commitWithin', $commitWithin); + } + + /** + * Get milliseconds until extract update is committed. Since Solr 3.4. + * + * @return int + */ + public function getCommitWithin() + { + return $this->getOption('commitWithin'); + } + + /** + * Add a name mapping from one field to another. + * + * Example: fmap.content=text will cause the content field normally + * generated by Tika to be moved to the "text" field. + * + * @param string $fromField Original field name + * @param mixed|array $toField New field name + * + * @return self Provides fluent interface + */ + public function addFieldMapping($fromField, $toField) + { + $this->fieldMappings[$fromField] = $toField; + + return $this; + } + + /** + * Add multiple field name mappings. + * + * @param array $mappings Name mapping in the form [$fromField => $toField, ...] + * + * @return self Provides fluent interface + */ + public function addFieldMappings($mappings) + { + foreach ($mappings as $fromField => $toField) { + $this->addFieldMapping($fromField, $toField); + } + + return $this; + } + + /** + * Remove a field name mapping. + * + * @param string $fromField + * + * @return self Provides fluent interface + */ + public function removeFieldMapping($fromField) + { + if (isset($this->fieldMappings[$fromField])) { + unset($this->fieldMappings[$fromField]); + } + + return $this; + } + + /** + * Remove all field name mappings. + * + * @return self Provides fluent interface + */ + public function clearFieldMappings() + { + $this->fieldMappings = []; + + return $this; + } + + /** + * Get all field name mappings. + * + * @return array + */ + public function getFieldMappings() + { + return $this->fieldMappings; + } + + /** + * Set many field name mappings. This overwrites any existing fields. + * + * @param array $mappings Name mapping in the form [$fromField => $toField, ...] + * + * @return self Provides fluent interface + */ + public function setFieldMappings($mappings) + { + $this->clearFieldMappings(); + $this->addFieldMappings($mappings); + + return $this; + } + + /** + * Set a custom document class for use in the createDocument method. + * + * This class should implement the document interface + * + * @param string $value classname + * + * @return self Provides fluent interface + */ + public function setDocumentClass($value) + { + return $this->setOption('documentclass', $value); + } + + /** + * Get the current documentclass option. + * + * The value is a classname, not an instance + * + * @return string + */ + public function getDocumentClass() + { + return $this->getOption('documentclass'); + } + + /** + * Set the ExtractOnly parameter of SOLR Extraction Handler. + * + * @param bool $value + * + * @return self Provides fluent interface + */ + public function setExtractOnly($value) + { + return $this->setOption('extractonly', (bool) $value); + } + + /** + * Get the ExtractOnly parameter of SOLR Extraction Handler. + * + * @return bool + */ + public function getExtractOnly() + { + return $this->getOption('extractonly'); + } + + /** + * Create a document object instance. + * + * You can optionally directly supply the fields and boosts + * to get a ready-made document instance for direct use in an add command + * + * @param array $fields + * @param array $boosts + * + * @return DocumentInterface + */ + public function createDocument($fields = [], $boosts = []) + { + $class = $this->getDocumentClass(); + + return new $class($fields, $boosts); + } + + /** + * Initialize options. + * + * Several options need some extra checks or setup work, for these options + * the setters are called. + */ + protected function init() + { + if (isset($this->options['fmap'])) { + $this->setFieldMappings($this->options['fmap']); + } + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Extract/RequestBuilder.php b/vendor/solarium/solarium/src/QueryType/Extract/RequestBuilder.php new file mode 100644 index 000000000..61f00ba58 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Extract/RequestBuilder.php @@ -0,0 +1,81 @@ +setMethod(Request::METHOD_POST); + + // add common options to request + $request->addParam('commit', $query->getCommit()); + $request->addParam('commitWithin', $query->getCommitWithin()); + + $request->addParam('uprefix', $query->getUprefix()); + $request->addParam('lowernames', $query->getLowernames()); + $request->addParam('defaultField', $query->getDefaultField()); + $request->addParam('extractOnly', $query->getExtractOnly()); + + foreach ($query->getFieldMappings() as $fromField => $toField) { + $request->addParam('fmap.'.$fromField, $toField); + } + + // add document settings to request + if (null !== ($doc = $query->getDocument())) { + if (null !== $doc->getBoost()) { + throw new RuntimeException('Extract does not support document-level boosts, use field boosts instead.'); + } + + // literal.* + foreach ($doc->getFields() as $name => $value) { + if ($value instanceof \DateTime) { + $value = $query->getHelper()->formatDate($value); + } + $value = (array) $value; + foreach ($value as $multival) { + $request->addParam('literal.'.$name, $multival); + } + } + + // boost.* + foreach ($doc->getFieldBoosts() as $name => $value) { + $request->addParam('boost.'.$name, $value); + } + } + + // add file to request + $file = $query->getFile(); + if (preg_match('/^(http|https):\/\/(.+)/i', $file)) { + $request->addParam('stream.url', $file); + $request->setMethod(Request::METHOD_GET); + } elseif (is_readable($file)) { + $request->setFileUpload($file); + $request->addParam('resource.name', basename($query->getFile())); + $request->addHeader('Content-Type: multipart/form-data; boundary='.$request->getHash()); + } else { + throw new RuntimeException('Extract query file path/url invalid or not available'); + } + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Extract/Result.php b/vendor/solarium/solarium/src/QueryType/Extract/Result.php new file mode 100644 index 000000000..b1e645e71 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Extract/Result.php @@ -0,0 +1,13 @@ + 'graph', + 'resultclass' => 'Solarium\QueryType\Graph\Result', + ]; + + /** + * Get type for this query. + * + * @return string + */ + public function getType() + { + return Client::QUERY_GRAPH; + } + + /** + * Get a requestbuilder for this query. + * + * @return RequestBuilder + */ + public function getRequestBuilder() + { + return new RequestBuilder(); + } + + /** + * No response parser required since we pass through GraphML. + */ + public function getResponseParser() + { + } + + /** + * Set the expression. + * + * @param string $expr + * + * @return self Provides fluent interface + */ + public function setExpression($expr) + { + return $this->setOption('expr', $expr); + } + + /** + * Get the expression. + * + * @return string + */ + public function getExpression() + { + return $this->getOption('expr'); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Graph/Result.php b/vendor/solarium/solarium/src/QueryType/Graph/Result.php new file mode 100644 index 000000000..c210325e0 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Graph/Result.php @@ -0,0 +1,43 @@ +response->getStatusCode(); + } + + /** + * Get Solr response body. + * + * @return string The response body + */ + public function getData() + { + return $this->response->getBody(); + } + + /** + * Get Solr response data in GraphML format. + * + * More expressive convenience method that just call getData(). + * + * @return string GraphML XML document + */ + public function getGraphML() + { + return $this->getData(); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Resources.php b/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Resources.php new file mode 100644 index 000000000..f75bf642e --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Resources.php @@ -0,0 +1,69 @@ + 'schema/managed', + 'resultclass' => 'Solarium\QueryType\ManagedResources\Result\Resources\ResourceList', + 'omitheader' => true, + ]; + + /** + * Get the name of resources. + * + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * Get query type. + * + * @return string + */ + public function getType(): string + { + return Client::QUERY_MANAGED_RESOURCES; + } + + /** + * Get the request builder class for this query. + * + * @return RequestBuilder + */ + public function getRequestBuilder(): RequestBuilder + { + return new RequestBuilder(); + } + + /** + * Get the response parser class for this query. + * + * @return ResponseParser + */ + public function getResponseParser(): ResponseParser + { + return new ResponseParser(); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Stopwords.php b/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Stopwords.php new file mode 100644 index 000000000..807b974ca --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Stopwords.php @@ -0,0 +1,173 @@ + 'Solarium\QueryType\ManagedResources\Query\Stopwords\Command\Add', + self::COMMAND_DELETE => 'Solarium\QueryType\ManagedResources\Query\Stopwords\Command\Delete', + self::COMMAND_EXISTS => 'Solarium\QueryType\ManagedResources\Query\Stopwords\Command\Exists', + ]; + + /** + * Default options. + * + * @var array + */ + protected $options = [ + 'handler' => 'schema/analysis/stopwords/', + 'resultclass' => 'Solarium\QueryType\ManagedResources\Result\Stopwords\WordSet', + 'omitheader' => true, + ]; + + /** + * Get query type. + * + * @return string + */ + public function getType(): string + { + return Client::QUERY_MANAGED_STOPWORDS; + } + + /** + * Get the request builder class for this query. + * + * @return RequestBuilder + */ + public function getRequestBuilder(): RequestBuilder + { + return new RequestBuilder(); + } + + /** + * Get the response parser class for this query. + * + * @return ResponseParser + */ + public function getResponseParser(): ResponseParser + { + return new ResponseParser(); + } + + /** + * Get the name of the stopwords resource. + * + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * Set the name of the stopwords resource. + * + * @param string $name + */ + public function setName(string $name) + { + $this->name = $name; + } + + /** + * Create a command instance. + * + * @param string $type + * @param mixed $options + * + * @throws InvalidArgumentException + * + * @return AbstractCommand + */ + public function createCommand($type, $options = null): AbstractCommand + { + $type = strtolower($type); + + if (!isset($this->commandTypes[$type])) { + throw new InvalidArgumentException('Stopwords commandtype unknown: '.$type); + } + + $class = $this->commandTypes[$type]; + + return new $class($options); + } + + /** + * Get command for this stopwords query. + * + * @return AbstractCommand|null + */ + public function getCommand() + { + return $this->command; + } + + /** + * Set a command to the stopwords query. + * + * @param AbstractCommand $command + * + * @return self Provides fluent interface + */ + public function setCommand(AbstractCommand $command): self + { + $this->command = $command; + + return $this; + } + + /** + * Remove command. + * + * @return self Provides fluent interface + */ + public function removeCommand(): self + { + $this->command = null; + + return $this; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Stopwords/Command/AbstractCommand.php b/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Stopwords/Command/AbstractCommand.php new file mode 100644 index 000000000..42a6ff25c --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Stopwords/Command/AbstractCommand.php @@ -0,0 +1,39 @@ +stopwords; + } + + /** + * Set stopwords. + * + * @param array $synonyms + */ + public function setStopwords(array $stopwords) + { + $this->stopwords = $stopwords; + } + + /** + * Returns the data to be send to Solr. + * + * @return string + */ + public function getRawData(): string + { + return json_encode($this->stopwords); + } + + /** + * Returns the term to be send to Solr. + * + * @return string + */ + public function getTerm(): string + { + return ''; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Stopwords/Command/Delete.php b/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Stopwords/Command/Delete.php new file mode 100644 index 000000000..adbb8672a --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Stopwords/Command/Delete.php @@ -0,0 +1,66 @@ +term; + } + + /** + * Set the term to be deleted. + * + * @param string $term + */ + public function setTerm(string $term) + { + $this->term = $term; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Stopwords/Command/Exists.php b/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Stopwords/Command/Exists.php new file mode 100644 index 000000000..ba3d3fab9 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Stopwords/Command/Exists.php @@ -0,0 +1,66 @@ +term; + } + + /** + * Set the term to be checked if exists. + * + * @param string $term + */ + public function setTerm(string $term) + { + $this->term = $term; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Stopwords/Stopword.php b/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Stopwords/Stopword.php new file mode 100644 index 000000000..d74d3edec --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Stopwords/Stopword.php @@ -0,0 +1,27 @@ +term; + } + + /** + * @param string $term + */ + public function setTerm(string $term) + { + $this->term = $term; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Synonyms.php b/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Synonyms.php new file mode 100644 index 000000000..6c2f0d0e2 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Synonyms.php @@ -0,0 +1,197 @@ + 'Solarium\QueryType\ManagedResources\Query\Synonyms\Command\Add', + self::COMMAND_DELETE => 'Solarium\QueryType\ManagedResources\Query\Synonyms\Command\Delete', + self::COMMAND_EXISTS => 'Solarium\QueryType\ManagedResources\Query\Synonyms\Command\Exists', + ]; + + /** + * Default options. + * + * @var array + */ + protected $options = [ + 'handler' => 'schema/analysis/synonyms/', + 'resultclass' => 'Solarium\QueryType\ManagedResources\Result\Synonyms\SynonymMappings', + 'omitheader' => true, + ]; + + /** + * Get query type. + * + * @return string + */ + public function getType() + { + return Client::QUERY_MANAGED_SYNONYMS; + } + + /** + * Get the request builder class for this query. + * + * @return RequestBuilder + */ + public function getRequestBuilder(): RequestBuilder + { + return new RequestBuilder(); + } + + /** + * Get the response parser class for this query. + * + * @return ResponseParser + */ + public function getResponseParser(): ResponseParser + { + return new ResponseParser(); + } + + /** + * Get the name of the synonym resource. + * + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * Set the name of the synonym resource. + * + * @param string $name + */ + public function setName(string $name) + { + $this->name = $name; + } + + /** + * Create a command instance. + * + * @param string $type + * @param mixed $options + * + * @throws InvalidArgumentException + * + * @return AbstractCommand + */ + public function createCommand($type, $options = null): AbstractCommand + { + $type = strtolower($type); + + if (!isset($this->commandTypes[$type])) { + throw new InvalidArgumentException('Synonyms commandtype unknown: '.$type); + } + + $class = $this->commandTypes[$type]; + + return new $class($options); + } + + /** + * Get command for this synonyms query. + * + * @return AbstractCommand|null + */ + public function getCommand() + { + return $this->command; + } + + /** + * Set a command for the synonyms query. + * + * @param AbstractCommand $command + * + * @return self Provides fluent interface + */ + public function setCommand(AbstractCommand $command): self + { + $this->command = $command; + + return $this; + } + + /** + * Remove command. + * + * @return self Provides fluent interface + */ + public function removeCommand(): self + { + $this->command = null; + + return $this; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Synonyms/Command/AbstractCommand.php b/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Synonyms/Command/AbstractCommand.php new file mode 100644 index 000000000..54d7e229e --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Synonyms/Command/AbstractCommand.php @@ -0,0 +1,39 @@ +synonyms; + } + + /** + * Set synonyms. + * + * @param SynonymsData $synonyms + */ + public function setSynonyms(SynonymsData $synonyms) + { + $this->synonyms = $synonyms; + } + + /** + * Returns the raw data to be sent to Solr. + */ + public function getRawData(): string + { + if (null !== $this->getSynonyms() && !empty($this->getSynonyms()->getSynonyms())) { + if (0 != strlen(trim($this->getSynonyms()->getTerm()))) { + return json_encode([$this->getSynonyms()->getTerm() => $this->getSynonyms()->getSynonyms()]); + } + + return json_encode($this->getSynonyms()->getSynonyms()); + } + + return ''; + } + + /** + * Empty. + * + * @return string + */ + public function getTerm(): string + { + return ''; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Synonyms/Command/Delete.php b/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Synonyms/Command/Delete.php new file mode 100644 index 000000000..2b3c2ab59 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Synonyms/Command/Delete.php @@ -0,0 +1,66 @@ +term; + } + + /** + * Set the term to be deleted. + * + * @param string $term + */ + public function setTerm(string $term) + { + $this->term = $term; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Synonyms/Command/Exists.php b/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Synonyms/Command/Exists.php new file mode 100644 index 000000000..c1cb91e54 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Synonyms/Command/Exists.php @@ -0,0 +1,66 @@ +term; + } + + /** + * Set the term to be checked if exists. + * + * @param string $term + */ + public function setTerm(string $term) + { + $this->term = $term; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Synonyms/Synonyms.php b/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Synonyms/Synonyms.php new file mode 100644 index 000000000..6fd421e85 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/ManagedResources/Query/Synonyms/Synonyms.php @@ -0,0 +1,55 @@ +term; + } + + /** + * @param string $term + */ + public function setTerm(string $term) + { + $this->term = $term; + } + + /** + * @return array + */ + public function getSynonyms(): array + { + return $this->synonyms; + } + + /** + * Sets the synonyms. To set a list of symmetric synonyms leave the term empty. + * + * @param array $synonyms + */ + public function setSynonyms(array $synonyms) + { + $this->synonyms = $synonyms; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/ManagedResources/RequestBuilder/Resources.php b/vendor/solarium/solarium/src/QueryType/ManagedResources/RequestBuilder/Resources.php new file mode 100644 index 000000000..634bd8db3 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/ManagedResources/RequestBuilder/Resources.php @@ -0,0 +1,9 @@ +getName())) { + throw new \Solarium\Exception\RuntimeException('Name of the stopwords resource is not set in the query.'); + } + + $request = parent::build($query); + $request->setHandler($query->getHandler().$query->getName()); + if (null !== $query->getCommand()) { + $request->addHeader('Content-Type: application/json; charset=utf-8'); + $this->buildCommand($request, $query->getCommand()); + } else { + // Lists all stopwords. + $request->setMethod(Request::METHOD_GET); + } + + return $request; + } + + /** + * @param Request $request + * @param AbstractCommand $command + */ + protected function buildCommand(Request $request, AbstractCommand $command) + { + $request->setMethod($command->getRequestMethod()); + + switch ($command->getType()) { + case StopwordsQuery::COMMAND_ADD: + $request->setRawData($command->getRawData()); + break; + case StopwordsQuery::COMMAND_DELETE: + $request->setHandler($request->getHandler().'/'.$command->getTerm()); + break; + case StopwordsQuery::COMMAND_EXISTS: + $request->setHandler($request->getHandler().'/'.$command->getTerm()); + break; + default: + throw new RuntimeException('Unsupported command type'); + break; + } + + $request->setMethod($command->getRequestMethod()); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/ManagedResources/RequestBuilder/Synonyms.php b/vendor/solarium/solarium/src/QueryType/ManagedResources/RequestBuilder/Synonyms.php new file mode 100644 index 000000000..4f28e26e0 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/ManagedResources/RequestBuilder/Synonyms.php @@ -0,0 +1,65 @@ +getName())) { + throw new \Solarium\Exception\RuntimeException('Name of the synonym resource is not set in the query.'); + } + + $request = parent::build($query); + $request->setHandler($query->getHandler().$query->getName()); + if (null !== $query->getCommand()) { + $request->addHeader('Content-Type: application/json; charset=utf-8'); + $this->buildCommand($request, $query->getCommand()); + } else { + // Lists all synonyms. + $request->setMethod(Request::METHOD_GET); + } + + return $request; + } + + /** + * @param Request $request + * @param AbstractCommand $command + */ + protected function buildCommand(Request $request, AbstractCommand $command) + { + $request->setMethod($command->getRequestMethod()); + + switch ($command->getType()) { + case SynonymsQuery::COMMAND_ADD: + $request->setRawData($command->getRawData()); + break; + case SynonymsQuery::COMMAND_DELETE: + $request->setHandler($request->getHandler().'/'.$command->getTerm()); + break; + case SynonymsQuery::COMMAND_EXISTS: + $request->setHandler($request->getHandler().'/'.$command->getTerm()); + break; + default: + throw new RuntimeException('Unsupported command type'); + break; + } + + $request->setMethod($command->getRequestMethod()); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/ManagedResources/ResponseParser/Resources.php b/vendor/solarium/solarium/src/QueryType/ManagedResources/ResponseParser/Resources.php new file mode 100644 index 000000000..b80e44051 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/ManagedResources/ResponseParser/Resources.php @@ -0,0 +1,33 @@ +getData(); + + $items = []; + + if (isset($data['managedResources']) && !empty($data['managedResources'])) { + foreach ($data['managedResources'] as $resource) { + $items[] = new Resource($resource); + } + } + + return $this->addHeaderInfo($data, ['items' => $items]); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/ManagedResources/ResponseParser/Stopwords.php b/vendor/solarium/solarium/src/QueryType/ManagedResources/ResponseParser/Stopwords.php new file mode 100644 index 000000000..4a46c1a02 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/ManagedResources/ResponseParser/Stopwords.php @@ -0,0 +1,38 @@ +getData(); + $wordSet = null; + if (isset($data['wordSet'])) { + $wordSet = $data['wordSet']; + } + + $parsed = []; + + if (null !== $wordSet && !empty($wordSet)) { + $parsed['items'] = $wordSet['managedList']; + $parsed['ignoreCase'] = $wordSet['initArgs']['ignoreCase']; + $parsed['initializedOn'] = $wordSet['initializedOn']; + } + + $this->addHeaderInfo($data, $parsed); + + return $parsed; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/ManagedResources/ResponseParser/Synonyms.php b/vendor/solarium/solarium/src/QueryType/ManagedResources/ResponseParser/Synonyms.php new file mode 100644 index 000000000..0be9b0a3f --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/ManagedResources/ResponseParser/Synonyms.php @@ -0,0 +1,47 @@ +getData(); + $synonymMappings = null; + if (isset($data['synonymMappings'])) { + $synonymMappings = $data['synonymMappings']; + } + + $parsed = []; + $items = []; + + if (null !== $synonymMappings && !empty($synonymMappings)) { + foreach ($synonymMappings['managedMap'] as $term => $synonyms) { + $items[] = new \Solarium\QueryType\ManagedResources\Result\Synonyms\Synonyms($term, $synonyms); + } + + $parsed['items'] = $items; + $parsed['ignoreCase'] = $synonymMappings['initArgs']['ignoreCase']; + $parsed['initializedOn'] = $synonymMappings['initializedOn']; + } + + $this->addHeaderInfo($data, $parsed); + + return $parsed; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/ManagedResources/Result/Resources/Resource.php b/vendor/solarium/solarium/src/QueryType/ManagedResources/Result/Resources/Resource.php new file mode 100644 index 000000000..09ec8bdfa --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/ManagedResources/Result/Resources/Resource.php @@ -0,0 +1,107 @@ +resourceId = $resource['resourceId']; + $this->numObservers = $resource['numObservers']; + $this->class = $resource['class']; + } + + /** + * @return string + */ + public function getResourceId(): string + { + return $this->resourceId; + } + + /** + * @param string $resourceId + */ + public function setResourceId(string $resourceId) + { + $this->resourceId = $resourceId; + } + + /** + * @return int + */ + public function getNumObservers(): int + { + return $this->numObservers; + } + + /** + * @param int $numObservers + */ + public function setNumObservers(int $numObservers) + { + $this->numObservers = $numObservers; + } + + /** + * @return string + */ + public function getClass(): string + { + return $this->class; + } + + /** + * @param string $class + */ + public function setClass(string $class) + { + $this->class = $class; + } + + /* + * Returns the type: 'stopwords', 'synonyms' or '' if unknown. + * + * @return string + */ + public function getType(): string + { + if (0 === strncmp($this->resourceId, '/schema/analysis/stopwords', strlen('/schema/analysis/stopwords'))) { + return self::TYPE_STOPWORDS; + } elseif (0 === strncmp($this->resourceId, '/schema/analysis/synonyms', strlen('/schema/analysis/synonyms'))) { + return self::TYPE_SYNONYMS; + } + + return ''; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/ManagedResources/Result/Resources/ResourceList.php b/vendor/solarium/solarium/src/QueryType/ManagedResources/Result/Resources/ResourceList.php new file mode 100644 index 000000000..5cb3657ea --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/ManagedResources/Result/Resources/ResourceList.php @@ -0,0 +1,79 @@ +name; + } + + /** + * Get all items. + * + * @return resource[] + */ + public function getItems(): array + { + $this->parseResponse(); + return $this->items; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator(): \ArrayIterator + { + $this->parseResponse(); + return new \ArrayIterator($this->items); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count(): int + { + $this->parseResponse(); + return \count($this->items); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/ManagedResources/Result/Stopwords/WordSet.php b/vendor/solarium/solarium/src/QueryType/ManagedResources/Result/Stopwords/WordSet.php new file mode 100644 index 000000000..f875d16dd --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/ManagedResources/Result/Stopwords/WordSet.php @@ -0,0 +1,117 @@ +parseResponse(); + } + + /** + * Get type value. + * + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * Get all items. + * + * @return array + */ + public function getItems(): array + { + $this->parseResponse(); + return $this->items; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator(): \ArrayIterator + { + $this->parseResponse(); + return new \ArrayIterator($this->items); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count(): int + { + $this->parseResponse(); + return count($this->items); + } + + /** + * @return bool + */ + public function isIgnoreCase(): bool + { + $this->parseResponse(); + return $this->ignoreCase; + } + + /** + * @return string + */ + public function getInitializedOn(): string + { + $this->parseResponse(); + return $this->initializedOn; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/ManagedResources/Result/Synonyms/SynonymMappings.php b/vendor/solarium/solarium/src/QueryType/ManagedResources/Result/Synonyms/SynonymMappings.php new file mode 100644 index 000000000..047b0dd78 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/ManagedResources/Result/Synonyms/SynonymMappings.php @@ -0,0 +1,132 @@ +name; + } + + /** + * Get all items. + * + * @return Synonyms[] + */ + public function getItems(): array + { + $this->parseResponse(); + return $this->items; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator(): \ArrayIterator + { + $this->parseResponse(); + return new \ArrayIterator($this->items); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count(): int + { + $this->parseResponse(); + return \count($this->items); + } + + /** + * @return string + */ + public function getResourceId(): string + { + $this->parseResponse(); + return $this->resourceId; + } + + /** + * @return bool + */ + public function isIgnoreCase(): bool + { + $this->parseResponse(); + return $this->ignoreCase; + } + + /** + * @return string + */ + public function getInitializedOn(): string + { + $this->parseResponse(); + return $this->initializedOn; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/ManagedResources/Result/Synonyms/Synonyms.php b/vendor/solarium/solarium/src/QueryType/ManagedResources/Result/Synonyms/Synonyms.php new file mode 100644 index 000000000..2b98d4341 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/ManagedResources/Result/Synonyms/Synonyms.php @@ -0,0 +1,67 @@ +term = $term; + $this->synonyms = $synonyms; + } + + /** + * Set the term. + * + * @return string + */ + public function getTerm(): string + { + return $this->term; + } + + /** + * @param string $term + */ + public function setTerm(string $term) + { + $this->term = $term; + } + + /** + * @return array + */ + public function getSynonyms(): array + { + return $this->synonyms; + } + + /** + * Sets the synonyms. To set a list of symmetric synonyms leave the term empty. + * + * @param array $synonyms + */ + public function setSynonyms(array $synonyms) + { + $this->synonyms = $synonyms; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/MoreLikeThis/Query.php b/vendor/solarium/solarium/src/QueryType/MoreLikeThis/Query.php new file mode 100644 index 000000000..06e60728c --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/MoreLikeThis/Query.php @@ -0,0 +1,411 @@ + 'mlt', + 'resultclass' => 'Solarium\QueryType\MoreLikeThis\Result', + 'documentclass' => 'Solarium\QueryType\Select\Result\Document', + 'query' => '*:*', + 'start' => 0, + 'rows' => 10, + 'fields' => '*,score', + 'interestingTerms' => 'none', + 'matchinclude' => false, + 'matchoffset' => 0, + 'stream' => false, + 'omitheader' => true, + ]; + + /** + * Get type for this query. + * + * @return string + */ + public function getType() + { + return Client::QUERY_MORELIKETHIS; + } + + /** + * Get a requestbuilder for this query. + * + * @return RequestBuilder + */ + public function getRequestBuilder() + { + return new RequestBuilder(); + } + + /** + * Get a response parser for this query. + * + * @return ResponseParser + */ + public function getResponseParser() + { + return new ResponseParser(); + } + + /** + * Set query stream option. + * + * Set to true to post query content instead of using the URL param + * + * @see http://wiki.apache.org/solr/ContentStream ContentStream + * + * @param bool $stream + * + * @return self Provides fluent interface + */ + public function setQueryStream($stream) + { + return $this->setOption('stream', $stream); + } + + /** + * Get stream option. + * + * @return bool + */ + public function getQueryStream() + { + return $this->getOption('stream'); + } + + /** + * Set the interestingTerms parameter. Must be one of: none, list, details. + * + * @see http://wiki.apache.org/solr/MoreLikeThisHandler#Params + * + * @param string $term + * + * @return self Provides fluent interface + */ + public function setInterestingTerms($term) + { + return $this->setOption('interestingTerms', $term); + } + + /** + * Get the interestingTerm parameter. + * + * @return string + */ + public function getInterestingTerms() + { + return $this->getOption('interestingTerms'); + } + + /** + * Set the match.include parameter, which is either 'true' or 'false'. + * + * @see http://wiki.apache.org/solr/MoreLikeThisHandler#Params + * + * @param bool $include + * + * @return self Provides fluent interface + */ + public function setMatchInclude($include) + { + return $this->setOption('matchinclude', $include); + } + + /** + * Get the match.include parameter. + * + * @return string + */ + public function getMatchInclude() + { + return $this->getOption('matchinclude'); + } + + /** + * Set the mlt.match.offset parameter, which determines the which result from the query should be used for MLT + * For paging of MLT use setStart / setRows. + * + * @see http://wiki.apache.org/solr/MoreLikeThisHandler#Params + * + * @param int $offset + * + * @return self Provides fluent interface + */ + public function setMatchOffset($offset) + { + return $this->setOption('matchoffset', $offset); + } + + /** + * Get the mlt.match.offset parameter. + * + * @return int + */ + public function getMatchOffset() + { + return $this->getOption('matchoffset'); + } + + /** + * Set MLT fields option. + * + * The fields to use for similarity. NOTE: if possible, these should have a + * stored TermVector + * + * Separate multiple fields with commas if you use string input. + * + * @param string|array $fields + * + * @return self Provides fluent interface + */ + public function setMltFields($fields) + { + if (is_string($fields)) { + $fields = explode(',', $fields); + $fields = array_map('trim', $fields); + } + + return $this->setOption('mltfields', $fields); + } + + /** + * Get MLT fields option. + * + * @return array + */ + public function getMltFields() + { + $value = $this->getOption('mltfields'); + if (null === $value) { + $value = []; + } + + return $value; + } + + /** + * Set minimumtermfrequency option. + * + * Minimum Term Frequency - the frequency below which terms will be ignored + * in the source doc. + * + * @param int $minimum + * + * @return self Provides fluent interface + */ + public function setMinimumTermFrequency($minimum) + { + return $this->setOption('minimumtermfrequency', $minimum); + } + + /** + * Get minimumtermfrequency option. + * + * @return int|null + */ + public function getMinimumTermFrequency() + { + return $this->getOption('minimumtermfrequency'); + } + + /** + * Set minimumdocumentfrequency option. + * + * Minimum Document Frequency - the frequency at which words will be + * ignored which do not occur in at least this many docs. + * + * @param int $minimum + * + * @return self Provides fluent interface + */ + public function setMinimumDocumentFrequency($minimum) + { + return $this->setOption('minimumdocumentfrequency', $minimum); + } + + /** + * Get minimumdocumentfrequency option. + * + * @return int|null + */ + public function getMinimumDocumentFrequency() + { + return $this->getOption('minimumdocumentfrequency'); + } + + /** + * Set minimumwordlength option. + * + * Minimum word length below which words will be ignored. + * + * @param int $minimum + * + * @return self Provides fluent interface + */ + public function setMinimumWordLength($minimum) + { + return $this->setOption('minimumwordlength', $minimum); + } + + /** + * Get minimumwordlength option. + * + * @return int|null + */ + public function getMinimumWordLength() + { + return $this->getOption('minimumwordlength'); + } + + /** + * Set maximumwordlength option. + * + * Maximum word length above which words will be ignored. + * + * @param int $maximum + * + * @return self Provides fluent interface + */ + public function setMaximumWordLength($maximum) + { + return $this->setOption('maximumwordlength', $maximum); + } + + /** + * Get maximumwordlength option. + * + * @return int|null + */ + public function getMaximumWordLength() + { + return $this->getOption('maximumwordlength'); + } + + /** + * Set maximumqueryterms option. + * + * Maximum number of query terms that will be included in any generated + * query. + * + * @param int $maximum + * + * @return self Provides fluent interface + */ + public function setMaximumQueryTerms($maximum) + { + return $this->setOption('maximumqueryterms', $maximum); + } + + /** + * Get maximumqueryterms option. + * + * @return int|null + */ + public function getMaximumQueryTerms() + { + return $this->getOption('maximumqueryterms'); + } + + /** + * Set maximumnumberoftokens option. + * + * Maximum number of tokens to parse in each example doc field that is not + * stored with TermVector support. + * + * @param int $maximum + * + * @return self Provides fluent interface + */ + public function setMaximumNumberOfTokens($maximum) + { + return $this->setOption('maximumnumberoftokens', $maximum); + } + + /** + * Get maximumnumberoftokens option. + * + * @return int|null + */ + public function getMaximumNumberOfTokens() + { + return $this->getOption('maximumnumberoftokens'); + } + + /** + * Set boost option. + * + * If true the query will be boosted by the interesting term relevance. + * + * @param bool $boost + * + * @return self Provides fluent interface + */ + public function setBoost($boost) + { + return $this->setOption('boost', $boost); + } + + /** + * Get boost option. + * + * @return bool|null + */ + public function getBoost() + { + return $this->getOption('boost'); + } + + /** + * Set queryfields option. + * + * Query fields and their boosts using the same format as that used in + * DisMaxQParserPlugin. These fields must also be specified in fields. + * + * Separate multiple fields with commas if you use string input. + * + * @param string|array $queryFields + * + * @return self Provides fluent interface + */ + public function setQueryFields($queryFields) + { + if (is_string($queryFields)) { + $queryFields = explode(',', $queryFields); + $queryFields = array_map('trim', $queryFields); + } + + return $this->setOption('queryfields', $queryFields); + } + + /** + * Get queryfields option. + * + * @return array + */ + public function getQueryFields() + { + $value = $this->getOption('queryfields'); + if (null === $value) { + $value = []; + } + + return $value; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/MoreLikeThis/RequestBuilder.php b/vendor/solarium/solarium/src/QueryType/MoreLikeThis/RequestBuilder.php new file mode 100644 index 000000000..201b6d235 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/MoreLikeThis/RequestBuilder.php @@ -0,0 +1,49 @@ +addParam('mlt.interestingTerms', $query->getInterestingTerms()); + $request->addParam('mlt.match.include', $query->getMatchInclude()); + $request->addParam('mlt.match.offset', $query->getMatchOffset()); + $request->addParam('mlt.fl', implode(',', $query->getMltFields())); + $request->addParam('mlt.mintf', $query->getMinimumTermFrequency()); + $request->addParam('mlt.mindf', $query->getMinimumDocumentFrequency()); + $request->addParam('mlt.minwl', $query->getMinimumWordLength()); + $request->addParam('mlt.maxwl', $query->getMaximumWordLength()); + $request->addParam('mlt.maxqt', $query->getMaximumQueryTerms()); + $request->addParam('mlt.maxntp', $query->getMaximumNumberOfTokens()); + $request->addParam('mlt.boost', $query->getBoost()); + $request->addParam('mlt.qf', $query->getQueryFields()); + + // convert query to stream if necessary + if (true === $query->getQueryStream()) { + $request->removeParam('q'); + $request->setRawData($query->getQuery()); + $request->setMethod(Request::METHOD_POST); + $request->addHeader('Content-Type: text/plain; charset=utf-8'); + } + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/MoreLikeThis/ResponseParser.php b/vendor/solarium/solarium/src/QueryType/MoreLikeThis/ResponseParser.php new file mode 100644 index 000000000..ffa056e53 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/MoreLikeThis/ResponseParser.php @@ -0,0 +1,45 @@ +getData(); + $query = $result->getQuery(); + + $parseResult = parent::parse($result); + if (isset($data['interestingTerms']) && 'none' != $query->getInterestingTerms()) { + $terms = $data['interestingTerms']; + if ('details' == $query->getInterestingTerms()) { + if ($query->getResponseWriter() == $query::WT_JSON) { + $terms = $this->convertToKeyValueArray($terms); + } + } + $parseResult['interestingTerms'] = $terms; + } + + if (isset($data['match']['docs'][0]) && true === $query->getMatchInclude()) { + $matchData = $data['match']['docs'][0]; + + $documentClass = $query->getOption('documentclass'); + $fields = (array) $matchData; + $parseResult['match'] = new $documentClass($fields); + } + + return $parseResult; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/MoreLikeThis/Result.php b/vendor/solarium/solarium/src/QueryType/MoreLikeThis/Result.php new file mode 100644 index 000000000..ca9d65ee9 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/MoreLikeThis/Result.php @@ -0,0 +1,90 @@ + + * // total solr mlt results + * $result->getNumFound(); + * + * // results fetched + * count($result); + * + * // iterate over fetched mlt docs + * foreach ($result as $doc) { + * .... + * } + * + */ +class Result extends SelectResult +{ + /** + * MLT interesting terms. + */ + protected $interestingTerms; + + /** + * MLT match document. + */ + protected $match; + + /** + * Get query instance. + * + * @return Query + */ + public function getQuery() + { + return $this->query; + } + + /** + * Get MLT interesting terms. + * + * this will show what "interesting" terms are used for the MoreLikeThis + * query. These are the top tf/idf terms. NOTE: if you select 'details', + * this shows you the term and boost used for each term. Unless + * mlt.boost=true all terms will have boost=1.0 + * + * @throws UnexpectedValueException + * + * @return array + */ + public function getInterestingTerms() + { + $query = $this->getQuery(); + if ('none' == $query->getInterestingTerms()) { + throw new UnexpectedValueException('interestingterms is none'); + } + $this->parseResponse(); + + return $this->interestingTerms; + } + + /** + * Get matched document. + * + * Only available if matchinclude was set to true in the query. + * + * @throws UnexpectedValueException + * + * @return ReadOnlyDocument + */ + public function getMatch() + { + $query = $this->getQuery(); + if (true !== $query->getMatchInclude()) { + throw new UnexpectedValueException('matchinclude was disabled in the MLT query'); + } + $this->parseResponse(); + + return $this->match; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Ping/Query.php b/vendor/solarium/solarium/src/QueryType/Ping/Query.php new file mode 100644 index 000000000..ebc75e7a8 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Ping/Query.php @@ -0,0 +1,54 @@ + 'Solarium\QueryType\Ping\Result', + 'handler' => 'admin/ping', + 'omitheader' => true, + ]; + + /** + * Get type for this query. + * + * @return string + */ + public function getType() + { + return Client::QUERY_PING; + } + + /** + * Get a requestbuilder for this query. + * + * @return RequestBuilder + */ + public function getRequestBuilder() + { + return new RequestBuilder(); + } + + /** + * The ping query has no response parser so we return a null value. + */ + public function getResponseParser() + { + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Ping/RequestBuilder.php b/vendor/solarium/solarium/src/QueryType/Ping/RequestBuilder.php new file mode 100644 index 000000000..27f63290f --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Ping/RequestBuilder.php @@ -0,0 +1,28 @@ +setMethod(Request::METHOD_GET); + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Ping/Result.php b/vendor/solarium/solarium/src/QueryType/Ping/Result.php new file mode 100644 index 000000000..eb659c0e6 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Ping/Result.php @@ -0,0 +1,27 @@ + 'Solarium\QueryType\RealtimeGet\Result', + 'documentclass' => 'Solarium\QueryType\Select\Result\Document', + 'handler' => 'get', + 'omitheader' => true, + ]; + + /** + * Document IDs. + * + * @var array + */ + protected $ids = []; + + /** + * Get type for this query. + * + * @return string + */ + public function getType() + { + return Client::QUERY_REALTIME_GET; + } + + /** + * Get a requestbuilder for this query. + * + * @return RequestBuilder + */ + public function getRequestBuilder() + { + return new RequestBuilder(); + } + + /** + * The ping query has no response parser so we return a null value. + * + * @return ResponseParser + */ + public function getResponseParser() + { + return new ResponseParser(); + } + + /** + * Add an id. + * + * @param string $id + * + * @return self Provides fluent interface + */ + public function addId($id) + { + $this->ids[$id] = true; + + return $this; + } + + /** + * Add multiple ids. + * + * @param string|array $ids can be an array or string with comma separated ids + * + * @return self Provides fluent interface + */ + public function addIds($ids) + { + if (is_string($ids)) { + $ids = explode(',', $ids); + $ids = array_map('trim', $ids); + } + + foreach ($ids as $id) { + $this->addId($id); + } + + return $this; + } + + /** + * Remove an id. + * + * @param string $id + * + * @return self Provides fluent interface + */ + public function removeId($id) + { + if (isset($this->ids[$id])) { + unset($this->ids[$id]); + } + + return $this; + } + + /** + * Remove all IDs. + * + * @return self Provides fluent interface + */ + public function clearIds() + { + $this->ids = []; + + return $this; + } + + /** + * Get the list of ids. + * + * @return array + */ + public function getIds() + { + return array_keys($this->ids); + } + + /** + * Set multiple ids. + * + * This overwrites any existing ids + * + * @param array $ids + * + * @return self Provides fluent interface + */ + public function setIds($ids) + { + $this->clearIds(); + $this->addIds($ids); + + return $this; + } + + /** + * Set a custom document class. + * + * This class should implement the document interface + * + * @param string $value classname + * + * @return self Provides fluent interface + */ + public function setDocumentClass($value) + { + return $this->setOption('documentclass', $value); + } + + /** + * Get the current documentclass option. + * + * The value is a classname, not an instance + * + * @return string + */ + public function getDocumentClass() + { + return $this->getOption('documentclass'); + } + + /** + * No components for this querytype. + * + * @return array + */ + public function getComponents() + { + return []; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/RealtimeGet/RequestBuilder.php b/vendor/solarium/solarium/src/QueryType/RealtimeGet/RequestBuilder.php new file mode 100644 index 000000000..e9129bb44 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/RealtimeGet/RequestBuilder.php @@ -0,0 +1,29 @@ +setMethod(Request::METHOD_GET); + $request->addParam('ids', implode(',', $query->getIds())); + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/RealtimeGet/Result.php b/vendor/solarium/solarium/src/QueryType/RealtimeGet/Result.php new file mode 100644 index 000000000..5bb5975d2 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/RealtimeGet/Result.php @@ -0,0 +1,26 @@ +getDocuments(); + + return reset($docs); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Select/Query/FilterQuery.php b/vendor/solarium/solarium/src/QueryType/Select/Query/FilterQuery.php new file mode 100644 index 000000000..10fa1b9e2 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Select/Query/FilterQuery.php @@ -0,0 +1,171 @@ +getOption('key'); + } + + /** + * Set key value. + * + * @param string $value + * + * @return self Provides fluent interface + */ + public function setKey($value) + { + return $this->setOption('key', $value); + } + + /** + * Add a tag. + * + * @param string $tag + * + * @return self Provides fluent interface + */ + public function addTag($tag) + { + $this->tags[$tag] = true; + + return $this; + } + + /** + * Add tags. + * + * @param array $tags + * + * @return self Provides fluent interface + */ + public function addTags($tags) + { + foreach ($tags as $tag) { + $this->addTag($tag); + } + + return $this; + } + + /** + * Get all tagss. + * + * @return array + */ + public function getTags() + { + return array_keys($this->tags); + } + + /** + * Remove a tag. + * + * @param string $tag + * + * @return self Provides fluent interface + */ + public function removeTag($tag) + { + if (isset($this->tags[$tag])) { + unset($this->tags[$tag]); + } + + return $this; + } + + /** + * Remove all tags. + * + * @return self Provides fluent interface + */ + public function clearTags() + { + $this->tags = []; + + return $this; + } + + /** + * Set multiple tags. + * + * This overwrites any existing tags + * + * @param array $tags + * + * @return self Provides fluent interface + */ + public function setTags($tags) + { + $this->clearTags(); + + return $this->addTags($tags); + } + + /** + * Returns a query helper. + * + * @return \Solarium\Core\Query\Helper + */ + public function getHelper() + { + return new Helper(); + } + + /** + * Initialize options. + */ + protected function init() + { + foreach ($this->options as $name => $value) { + switch ($name) { + case 'tag': + if (!is_array($value)) { + $value = [$value]; + } + $this->addTags($value); + break; + case 'key': + $this->setKey($value); + break; + case 'query': + $this->setQuery($value); + break; + } + } + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Select/Query/Query.php b/vendor/solarium/solarium/src/QueryType/Select/Query/Query.php new file mode 100644 index 000000000..46af4f38f --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Select/Query/Query.php @@ -0,0 +1,813 @@ + 'select', + 'resultclass' => 'Solarium\QueryType\Select\Result\Result', + 'documentclass' => 'Solarium\QueryType\Select\Result\Document', + 'query' => '*:*', + 'start' => 0, + 'rows' => 10, + 'fields' => '*,score', + 'omitheader' => true, + ]; + + /** + * Tags for this query. + * + * @var array + */ + protected $tags = []; + + /** + * Fields to fetch. + * + * @var array + */ + protected $fields = []; + + /** + * Items to sort on. + * + * @var array + */ + protected $sorts = []; + + /** + * Filterqueries. + * + * @var FilterQuery[] + */ + protected $filterQueries = []; + + public function __construct($options = null) + { + $this->componentTypes = [ + ComponentAwareQueryInterface::COMPONENT_MORELIKETHIS => 'Solarium\Component\MoreLikeThis', + ComponentAwareQueryInterface::COMPONENT_SPELLCHECK => 'Solarium\Component\Spellcheck', + ComponentAwareQueryInterface::COMPONENT_SUGGESTER => 'Solarium\Component\Suggester', + ComponentAwareQueryInterface::COMPONENT_DEBUG => 'Solarium\Component\Debug', + ComponentAwareQueryInterface::COMPONENT_SPATIAL => 'Solarium\Component\Spatial', + ComponentAwareQueryInterface::COMPONENT_FACETSET => 'Solarium\Component\FacetSet', + ComponentAwareQueryInterface::COMPONENT_DISMAX => 'Solarium\Component\DisMax', + ComponentAwareQueryInterface::COMPONENT_EDISMAX => 'Solarium\Component\EdisMax', + ComponentAwareQueryInterface::COMPONENT_HIGHLIGHTING => 'Solarium\Component\Highlighting\Highlighting', + ComponentAwareQueryInterface::COMPONENT_GROUPING => 'Solarium\Component\Grouping', + ComponentAwareQueryInterface::COMPONENT_DISTRIBUTEDSEARCH => 'Solarium\Component\DistributedSearch', + ComponentAwareQueryInterface::COMPONENT_STATS => 'Solarium\Component\Stats\Stats', + ComponentAwareQueryInterface::COMPONENT_QUERYELEVATION => 'Solarium\Component\QueryElevation', + ComponentAwareQueryInterface::COMPONENT_RERANKQUERY => 'Solarium\Component\ReRankQuery', + ]; + + parent::__construct($options); + } + + /** + * Get type for this query. + * + * @return string + */ + public function getType() + { + return Client::QUERY_SELECT; + } + + /** + * Get a requestbuilder for this query. + * + * @return RequestBuilder + */ + public function getRequestBuilder() + { + return new RequestBuilder(); + } + + /** + * Get a response parser for this query. + * + * @return ResponseParser + */ + public function getResponseParser() + { + return new ResponseParser(); + } + + /** + * Set default query operator. + * + * Use one of the constants as value + * + * @param string $operator + * + * @return self Provides fluent interface + */ + public function setQueryDefaultOperator($operator) + { + return $this->setOption('querydefaultoperator', $operator); + } + + /** + * Get the default query operator. + * + * @return null|string + */ + public function getQueryDefaultOperator() + { + return $this->getOption('querydefaultoperator'); + } + + /** + * Set default query field. + * + * @param string $field + * + * @return self Provides fluent interface + */ + public function setQueryDefaultField($field) + { + return $this->setOption('querydefaultfield', $field); + } + + /** + * Get the default query field. + * + * @return null|string + */ + public function getQueryDefaultField() + { + return $this->getOption('querydefaultfield'); + } + + /** + * Set the start offset. + * + * @param int $start + * + * @return self Provides fluent interface + */ + public function setStart($start) + { + return $this->setOption('start', $start); + } + + /** + * Get the start offset. + * + * @return int + */ + public function getStart() + { + return $this->getOption('start'); + } + + /** + * Set a custom document class. + * + * This class should implement the document interface + * + * @param string $value classname + * + * @return self Provides fluent interface + */ + public function setDocumentClass($value) + { + return $this->setOption('documentclass', $value); + } + + /** + * Get the current documentclass option. + * + * The value is a classname, not an instance + * + * @return string + */ + public function getDocumentClass() + { + return $this->getOption('documentclass'); + } + + /** + * Set the number of rows to fetch. + * + * @param int $rows + * + * @return self Provides fluent interface + */ + public function setRows($rows) + { + return $this->setOption('rows', $rows); + } + + /** + * Get the number of rows. + * + * @return int + */ + public function getRows() + { + return $this->getOption('rows'); + } + + /** + * Specify a field to return in the resultset. + * + * @param string $field + * + * @return self Provides fluent interface + */ + public function addField($field) + { + $this->fields[$field] = true; + + return $this; + } + + /** + * Specify multiple fields to return in the resultset. + * + * @param string|array $fields can be an array or string with comma + * separated fieldnames + * + * @return self Provides fluent interface + */ + public function addFields($fields) + { + if (is_string($fields)) { + $fields = explode(',', $fields); + $fields = array_map('trim', $fields); + } + + foreach ($fields as $field) { + $this->addField($field); + } + + return $this; + } + + /** + * Remove a field from the field list. + * + * @param string $field + * + * @return self Provides fluent interface + */ + public function removeField($field) + { + if (isset($this->fields[$field])) { + unset($this->fields[$field]); + } + + return $this; + } + + /** + * Remove all fields from the field list. + * + * @return self Provides fluent interface + */ + public function clearFields() + { + $this->fields = []; + + return $this; + } + + /** + * Get the list of fields. + * + * @return array + */ + public function getFields() + { + return array_keys($this->fields); + } + + /** + * Set multiple fields. + * + * This overwrites any existing fields + * + * @param array $fields + * + * @return self Provides fluent interface + */ + public function setFields($fields) + { + $this->clearFields(); + $this->addFields($fields); + + return $this; + } + + /** + * Add a sort. + * + * @param string $sort + * @param string $order + * + * @return self Provides fluent interface + */ + public function addSort($sort, $order) + { + $this->sorts[$sort] = $order; + + return $this; + } + + /** + * Add multiple sorts. + * + * The input array must contain sort items as keys and the order as values. + * + * @param array $sorts + * + * @return self Provides fluent interface + */ + public function addSorts(array $sorts) + { + foreach ($sorts as $sort => $order) { + $this->addSort($sort, $order); + } + + return $this; + } + + /** + * Remove a sort. + * + * @param string $sort + * + * @return self Provides fluent interface + */ + public function removeSort($sort) + { + if (isset($this->sorts[$sort])) { + unset($this->sorts[$sort]); + } + + return $this; + } + + /** + * Remove all sorts. + * + * @return self Provides fluent interface + */ + public function clearSorts() + { + $this->sorts = []; + + return $this; + } + + /** + * Get a list of the sorts. + * + * @return array + */ + public function getSorts() + { + return $this->sorts; + } + + /** + * Set multiple sorts. + * + * This overwrites any existing sorts + * + * @param array $sorts + * + * @return self Provides fluent interface + */ + public function setSorts($sorts) + { + $this->clearSorts(); + $this->addSorts($sorts); + + return $this; + } + + /** + * Create a filterquery instance. + * + * If you supply a string as the first arguments ($options) it will be used as the key for the filterquery + * and it will be added to this query. + * If you supply an options array/object that contains a key the filterquery will also be added to the query. + * + * When no key is supplied the filterquery cannot be added, in that case you will need to add it manually + * after setting the key, by using the addFilterQuery method. + * + * @param mixed $options + * + * @return FilterQuery + */ + public function createFilterQuery($options = null) + { + if (is_string($options)) { + $fq = new FilterQuery(); + $fq->setKey($options); + } else { + $fq = new FilterQuery($options); + } + + if (null !== $fq->getKey()) { + $this->addFilterQuery($fq); + } + + return $fq; + } + + /** + * Add a filter query. + * + * Supports a filterquery instance or a config array, in that case a new + * filterquery instance wil be created based on the options. + * + * + * @param FilterQuery|array $filterQuery + * + * @throws InvalidArgumentException + * + * @return self Provides fluent interface + */ + public function addFilterQuery($filterQuery) + { + if (is_array($filterQuery)) { + $filterQuery = new FilterQuery($filterQuery); + } + + $key = $filterQuery->getKey(); + + if (0 === strlen($key)) { + throw new InvalidArgumentException('A filterquery must have a key value'); + } + + //double add calls for the same FQ are ignored, but non-unique keys cause an exception + if (array_key_exists($key, $this->filterQueries) && $this->filterQueries[$key] !== $filterQuery) { + throw new InvalidArgumentException('A filterquery must have a unique key value within a query'); + } + + $this->filterQueries[$key] = $filterQuery; + + return $this; + } + + /** + * Add multiple filterqueries. + * + * @param array $filterQueries + * + * @return self Provides fluent interface + */ + public function addFilterQueries(array $filterQueries) + { + foreach ($filterQueries as $key => $filterQuery) { + // in case of a config array: add key to config + if (is_array($filterQuery) && !isset($filterQuery['key'])) { + $filterQuery['key'] = $key; + } + + $this->addFilterQuery($filterQuery); + } + + return $this; + } + + /** + * Get a filterquery. + * + * @param string $key + * + * @return string + */ + public function getFilterQuery($key) + { + if (isset($this->filterQueries[$key])) { + return $this->filterQueries[$key]; + } + } + + /** + * Get all filterqueries. + * + * @return FilterQuery[] + */ + public function getFilterQueries() + { + return $this->filterQueries; + } + + /** + * Remove a single filterquery. + * + * You can remove a filterquery by passing its key, or by passing the filterquery instance + * + * @param string|FilterQuery $filterQuery + * + * @return self Provides fluent interface + */ + public function removeFilterQuery($filterQuery) + { + if (is_object($filterQuery)) { + $filterQuery = $filterQuery->getKey(); + } + + if (isset($this->filterQueries[$filterQuery])) { + unset($this->filterQueries[$filterQuery]); + } + + return $this; + } + + /** + * Remove all filterqueries. + * + * @return self Provides fluent interface + */ + public function clearFilterQueries() + { + $this->filterQueries = []; + + return $this; + } + + /** + * Set multiple filterqueries. + * + * This overwrites any existing filterqueries + * + * @param array $filterQueries + */ + public function setFilterQueries($filterQueries) + { + $this->clearFilterQueries(); + $this->addFilterQueries($filterQueries); + } + + /** + * Add a tag. + * + * @param string $tag + * + * @return self Provides fluent interface + */ + public function addTag($tag) + { + $this->tags[$tag] = true; + + return $this; + } + + /** + * Add tags. + * + * @param array $tags + * + * @return self Provides fluent interface + */ + public function addTags($tags) + { + foreach ($tags as $tag) { + $this->addTag($tag); + } + + return $this; + } + + /** + * Get all tagss. + * + * @return array + */ + public function getTags() + { + return array_keys($this->tags); + } + + /** + * Remove a tag. + * + * @param string $tag + * + * @return self Provides fluent interface + */ + public function removeTag($tag) + { + if (isset($this->tags[$tag])) { + unset($this->tags[$tag]); + } + + return $this; + } + + /** + * Remove all tags. + * + * @return self Provides fluent interface + */ + public function clearTags() + { + $this->tags = []; + + return $this; + } + + /** + * Set multiple tags. + * + * This overwrites any existing tags + * + * @param array $tags + * + * @return self Provides fluent interface + */ + public function setTags($tags) + { + $this->clearTags(); + + return $this->addTags($tags); + } + + /** + * Set the cursor mark to fetch. + * + * Cursor functionality requires a sort containing a uniqueKey field as tie breaker on top of your desired + * sorts for the query. + * Cursor functionality was introduced in Solr 4.7. + * + * @param string $cursormark + * + * @return self Provides fluent interface + */ + public function setCursormark($cursormark) + { + return $this->setOption('cursormark', $cursormark); + } + + /** + * Get the cursor mark. + * + * @return string|null + */ + public function getCursormark() + { + return $this->getOption('cursormark'); + } + + /** + * Remove the cursor mark. + * + * @return self Provides fluent interface + */ + public function clearCursormark() + { + return $this->setOption('cursormark', null); + } + + /** + * Set SplitOnWhitespace option. + * + * Specifies whether the query parser splits the query text on whitespace before it's sent to be analyzed. + * + * The default is to split on whitespace, equivalent to &sow=true. + * The sow parameter was introduced in Solr 6.5. + * + * @param bool $splitOnWhitespace + * + * @return self Provides fluent interface + */ + public function setSplitOnWhitespace($splitOnWhitespace) + { + return $this->setOption('splitonwhitespace', $splitOnWhitespace); + } + + /** + * Get SplitOnWhitespace option. + * + * @return bool|null + */ + public function getSplitOnWhitespace() + { + return $this->getOption('splitonwhitespace'); + } + + /** + * Initialize options. + * + * Several options need some extra checks or setup work, for these options + * the setters are called. + */ + protected function init() + { + foreach ($this->options as $name => $value) { + switch ($name) { + case 'query': + $this->setQuery($value); + break; + case 'filterquery': + $this->addFilterQueries($value); + break; + case 'sort': + $this->addSorts($value); + break; + case 'fields': + $this->addFields($value); + break; + case 'rows': + $this->setRows((int) $value); + break; + case 'start': + $this->setStart((int) $value); + break; + case 'component': + $this->createComponents($value); + break; + case 'tag': + if (!is_array($value)) { + $value = explode(',', $value); + } + $this->addTags($value); + break; + case 'cursormark': + $this->setCursormark($value); + break; + } + } + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Select/RequestBuilder.php b/vendor/solarium/solarium/src/QueryType/Select/RequestBuilder.php new file mode 100644 index 000000000..0607b9935 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Select/RequestBuilder.php @@ -0,0 +1,73 @@ +addParam( + 'q', + $this->renderLocalParams( + $query->getQuery(), + ['tag' => $query->getTags()] + ) + ); + $request->addParam('start', $query->getStart()); + $request->addParam('rows', $query->getRows()); + $request->addParam('fl', implode(',', $query->getFields())); + $request->addParam('q.op', $query->getQueryDefaultOperator()); + $request->addParam('df', $query->getQueryDefaultField()); + $request->addParam('cursorMark', $query->getCursormark()); + $request->addParam('sow', $query->getSplitOnWhitespace()); + + // add sort fields to request + $sort = []; + foreach ($query->getSorts() as $field => $order) { + $sort[] = $field.' '.$order; + } + if (0 !== count($sort)) { + $request->addParam('sort', implode(',', $sort)); + } + + // add filterqueries to request + $filterQueries = $query->getFilterQueries(); + if (0 !== count($filterQueries)) { + foreach ($filterQueries as $filterQuery) { + $fq = $this->renderLocalParams( + $filterQuery->getQuery(), + ['tag' => $filterQuery->getTags()] + ); + $request->addParam('fq', $fq); + } + } + + // add components to request + foreach ($query->getComponents() as $component) { + $componentBuilder = $component->getRequestBuilder(); + if ($componentBuilder) { + $request = $componentBuilder->buildComponent($component, $request); + } + } + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Select/ResponseParser.php b/vendor/solarium/solarium/src/QueryType/Select/ResponseParser.php new file mode 100644 index 000000000..eb8bbe42b --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Select/ResponseParser.php @@ -0,0 +1,88 @@ +getData(); + + /* + * @var Query + */ + $query = $result->getQuery(); + + // create document instances + $documentClass = $query->getOption('documentclass'); + $classes = class_implements($documentClass); + if (!in_array('Solarium\QueryType\Select\Result\DocumentInterface', $classes, true) && + !in_array('Solarium\QueryType\Update\Query\Document\DocumentInterface', $classes, true) + ) { + throw new RuntimeException('The result document class must implement a document interface'); + } + + $documents = []; + if (isset($data['response']['docs'])) { + foreach ($data['response']['docs'] as $doc) { + $fields = (array) $doc; + $documents[] = new $documentClass($fields); + } + } + + // component results + $components = []; + foreach ($query->getComponents() as $component) { + $componentParser = $component->getResponseParser(); + if ($componentParser) { + $components[$component->getType()] = $componentParser->parse($query, $component, $data); + } + } + + $numFound = null; + + if (isset($data['response']['numFound'])) { + $numFound = $data['response']['numFound']; + } + + $maxScore = null; + + if (isset($data['response']['maxScore'])) { + $maxScore = $data['response']['maxScore']; + } + + if (isset($data['nextCursorMark'])) { + $nextCursorMark = $data['nextCursorMark']; + } else { + $nextCursorMark = null; + } + + return $this->addHeaderInfo( + $data, + [ + 'numfound' => $numFound, + 'maxscore' => $maxScore, + 'documents' => $documents, + 'components' => $components, + 'nextcursormark' => $nextCursorMark, + ] + ); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Select/Result/AbstractDocument.php b/vendor/solarium/solarium/src/QueryType/Select/Result/AbstractDocument.php new file mode 100644 index 000000000..2f2cb55ee --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Select/Result/AbstractDocument.php @@ -0,0 +1,125 @@ +fields[$name])) { + return; + } + + return $this->fields[$name]; + } + + /** + * Check if field is set by name. + * + * Magic method for checking if fields are set as properties of this document + * object, by field name. Also used by empty(). + * + * @param string $name + * + * @return bool + */ + public function __isset($name) + { + return isset($this->fields[$name]); + } + + /** + * Get all fields. + * + * @return array + */ + public function getFields() + { + return $this->fields; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->fields); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->fields); + } + + /** + * ArrayAccess implementation. + * + * @param mixed $offset + * @param mixed $value + */ + public function offsetSet($offset, $value) + { + $this->__set($offset, $value); + } + + /** + * ArrayAccess implementation. + * + * @param mixed $offset + * + * @return bool + */ + public function offsetExists($offset) + { + return null !== $this->__get($offset); + } + + /** + * ArrayAccess implementation. + * + * @param mixed $offset + */ + public function offsetUnset($offset) + { + $this->__set($offset, null); + } + + /** + * ArrayAccess implementation. + * + * @param mixed $offset + * + * @return mixed|null + */ + public function offsetGet($offset) + { + return $this->__get($offset); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Select/Result/Document.php b/vendor/solarium/solarium/src/QueryType/Select/Result/Document.php new file mode 100644 index 000000000..53437c494 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Select/Result/Document.php @@ -0,0 +1,48 @@ +fields = $fields; + } + + /** + * Set field value. + * + * Magic method for setting a field as property of this object. Since this + * is a readonly document an exception will be thrown to prevent this. + * + * + * @param string $name + * @param string $value + * + * @throws RuntimeException + */ + public function __set($name, $value) + { + throw new RuntimeException('A readonly document cannot be altered'); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Select/Result/DocumentInterface.php b/vendor/solarium/solarium/src/QueryType/Select/Result/DocumentInterface.php new file mode 100644 index 000000000..c663e003b --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Select/Result/DocumentInterface.php @@ -0,0 +1,16 @@ + + * // total solr results + * $result->getNumFound(); + * + * // results fetched + * count($result); + * + * // get a single facet by key + * $result->getFacet('category'); + * + * // iterate over fetched docs + * foreach ($result as $doc) { + * .... + * } + * + */ +class Result extends BaseResult implements \IteratorAggregate, \Countable +{ + /** + * Solr numFound. + * + * This is NOT the number of document fetched from Solr! + * + * @var int + */ + protected $numfound; + + /** + * Solr maxscore. + * + * Will only be available if 'score' was one of the requested fields in your query + * + * @var float + */ + protected $maxscore; + + /** + * Solr nextcursormark. + * + * Will only be available if 'cursormark' was set for your query + * + * @var string + */ + protected $nextcursormark; + + /** + * Document instances array. + * + * @var array + */ + protected $documents; + + /** + * Component results. + */ + protected $components; + + /** + * Status code returned by Solr. + * + * @var int + */ + protected $status; + + /** + * Solr index queryTime. + * + * This doesn't include things like the HTTP responsetime. Purely the Solr + * query execution time. + * + * @var int + */ + protected $queryTime; + + /** + * Get Solr status code. + * + * This is not the HTTP status code! The normal value for success is 0. + * + * @return int + */ + public function getStatus() + { + $this->parseResponse(); + + return $this->status; + } + + /** + * Get Solr query time. + * + * This doesn't include things like the HTTP responsetime. Purely the Solr + * query execution time. + * + * @return int + */ + public function getQueryTime() + { + $this->parseResponse(); + + return $this->queryTime; + } + + /** + * get Solr numFound. + * + * Returns the total number of documents found by Solr (this is NOT the + * number of document fetched from Solr!) + * + * @return int + */ + public function getNumFound() + { + $this->parseResponse(); + + return $this->numfound; + } + + /** + * get Solr maxscore. + * + * Returns the highest score of the documents in the total result for your current query (ignoring paging) + * Will only be available if 'score' was one of the requested fields in your query + * + * @return float + */ + public function getMaxScore() + { + $this->parseResponse(); + + return $this->maxscore; + } + + /** + * get Solr nextcursormark. + * + * Returns the next cursor mark for deep paging + * Will only be available if 'cursormark' was set for your query against Solr 4.7+ + * + * @return string + */ + public function getNextCursorMark() + { + $this->parseResponse(); + + return $this->nextcursormark; + } + + /** + * Get all documents. + * + * @return DocumentInterface[] + */ + public function getDocuments() + { + $this->parseResponse(); + + return $this->documents; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + $this->parseResponse(); + + return new \ArrayIterator($this->documents); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + $this->parseResponse(); + + return count($this->documents); + } + + /** + * Get all component results. + * + * @return array + */ + public function getComponents() + { + $this->parseResponse(); + + return $this->components; + } + + /** + * Get a component result by key. + * + * @param string $key + * + * @return mixed + */ + public function getComponent($key) + { + $this->parseResponse(); + + if (isset($this->components[$key])) { + return $this->components[$key]; + } + + return null; + } + + /** + * Get morelikethis component result. + * + * This is a convenience method that maps presets to getComponent + * + * @return MoreLikeThisResult|null + */ + public function getMoreLikeThis() + { + return $this->getComponent(ComponentAwareQueryInterface::COMPONENT_MORELIKETHIS); + } + + /** + * Get highlighting component result. + * + * This is a convenience method that maps presets to getComponent + * + * @return Highlighting|null + */ + public function getHighlighting() + { + return $this->getComponent(ComponentAwareQueryInterface::COMPONENT_HIGHLIGHTING); + } + + /** + * Get grouping component result. + * + * This is a convenience method that maps presets to getComponent + * + * @return GroupingResult|null + */ + public function getGrouping() + { + return $this->getComponent(ComponentAwareQueryInterface::COMPONENT_GROUPING); + } + + /** + * Get facetset component result. + * + * This is a convenience method that maps presets to getComponent + * + * @return FacetSetResult|null + */ + public function getFacetSet() + { + return $this->getComponent(ComponentAwareQueryInterface::COMPONENT_FACETSET); + } + + /** + * Get spellcheck component result. + * + * This is a convenience method that maps presets to getComponent + * + * @return SpellcheckResult|null + */ + public function getSpellcheck() + { + return $this->getComponent(ComponentAwareQueryInterface::COMPONENT_SPELLCHECK); + } + + /** + * Get suggester component result. + * + * This is a convenience method that maps presets to getComponent + * + * @return SuggesterResult|null + */ + public function getSuggester() + { + return $this->getComponent(ComponentAwareQueryInterface::COMPONENT_SUGGESTER); + } + + /** + * Get stats component result. + * + * This is a convenience method that maps presets to getComponent + * + * @return StatsResult|null + */ + public function getStats() + { + return $this->getComponent(ComponentAwareQueryInterface::COMPONENT_STATS); + } + + /** + * Get debug component result. + * + * This is a convenience method that maps presets to getComponent + * + * @return DebugResult|null + */ + public function getDebug() + { + return $this->getComponent(ComponentAwareQueryInterface::COMPONENT_DEBUG); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Server/AbstractServerQuery.php b/vendor/solarium/solarium/src/QueryType/Server/AbstractServerQuery.php new file mode 100644 index 000000000..df00ddedc --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Server/AbstractServerQuery.php @@ -0,0 +1,12 @@ +setOption('async', $async); + } + + /** + * Get the passed handle for asynchronous processing. + * + * @return string + */ + public function getAsync(): string + { + return (string) $this->getOption('async'); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/AbstractCoreAction.php b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/AbstractCoreAction.php new file mode 100644 index 000000000..020d6552a --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/AbstractCoreAction.php @@ -0,0 +1,26 @@ +setOption('core', $core); + } + + /** + * Get the related core name. + * + * @return string + */ + public function getCore(): string + { + return (string) $this->getOption('core'); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Create.php b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Create.php new file mode 100644 index 000000000..322178deb --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Create.php @@ -0,0 +1,224 @@ +setOption('name', $core); + } + + /** + * Get the related core name. + * + * @return string + */ + public function getCore(): string + { + // for some reason the core is called "name" in the create action + return $this->getOption('name'); + } + + /** + * Set the instanceDir. + * + * @param string $instanceDir + * + * @return self Provides fluent interface + */ + public function setInstanceDir(string $instanceDir) + { + return $this->setOption('instanceDir', $instanceDir); + } + + /** + * Get the instanceDir. + * + * @return string + */ + public function getInstanceDir(): string + { + return (string) $this->getOption('instanceDir'); + } + + /** + * Set the config. + * + * @param string $config + * + * @return self Provides fluent interface + */ + public function setConfig(string $config) + { + return $this->setOption('config', $config); + } + + /** + * Get the config. + * + * @return string + */ + public function getConfig(): string + { + return $this->getOption('config'); + } + + /** + * Set the schema. + * + * @param string $schema + * + * @return self Provides fluent interface + */ + public function setSchema(string $schema) + { + return $this->setOption('schema', $schema); + } + + /** + * Get the schema. + * + * @return string + */ + public function getSchema(): string + { + return (string) $this->getOption('schema'); + } + + /** + * Set the dataDir. + * + * @param string $dataDir + * + * @return self Provides fluent interface + */ + public function setDataDir(string $dataDir) + { + return $this->setOption('dataDir', $dataDir); + } + + /** + * Get the schema. + * + * @return string + */ + public function getDataDir(): string + { + return (string) $this->getOption('dataDir'); + } + + /** + * Set the configSet. + * + * @param string $configSet + * + * @return self Provides fluent interface + */ + public function setConfigSet(string $configSet) + { + return $this->setOption('configSet', $configSet); + } + + /** + * Get the configSet. + * + * @return string + */ + public function getConfigSet(): string + { + return (string) $this->getOption('configSet'); + } + + /** + * Set the collection. + * + * @param string $collection + * + * @return self Provides fluent interface + */ + public function setCollection(string $collection) + { + return $this->setOption('collection', $collection); + } + + /** + * Get the collection. + * + * @return string + */ + public function getCollection(): string + { + return (string) $this->getOption('collection'); + } + + /** + * Set the shard. + * + * @param string $shard + * + * @return self Provides fluent interface + */ + public function setShard($shard) + { + return $this->setOption('shard', $shard); + } + + /** + * Get the collection. + * + * @return string + */ + public function getShard(): string + { + return (string) $this->getOption('shard'); + } + + /** + * Set the a property in the core.properties file. + * + * @param string $name + * @param string $value + * + * @return self Provides fluent interface + */ + public function setCoreProperty(string $name, string $value) + { + $option = 'property.'.$name; + return $this->setOption($option, $value); + } + + /** + * Get a previously added core property. + * + * @return string + */ + public function getCoreProperty($name): string + { + $option = 'property.'.$name; + return (string) $this->getOption($option); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/MergeIndexes.php b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/MergeIndexes.php new file mode 100644 index 000000000..c58cfe399 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/MergeIndexes.php @@ -0,0 +1,62 @@ +setOption('indexDir', $indexDir); + } + + /** + * Get the other core that should be the new name. + * + * @return string[] + */ + public function getIndexDir(): array + { + return (array) $this->getOption('indexDir'); + } + + /** + * Directories that should be merged. + * + * @param string[] $srcCore + * + * @return self Provides fluent interface + */ + public function setSrcCore(array $srcCore) + { + return $this->setOption('srcCore', $srcCore); + } + + /** + * Get the other core that should be the new name. + * + * @return string[] + */ + public function getSrcCore(): array + { + return (array) $this->getOption('srcCore'); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Reload.php b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Reload.php new file mode 100644 index 000000000..11dcac714 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Reload.php @@ -0,0 +1,18 @@ +setOption('other', $other); + } + + /** + * Get the other core that should be the new name. + * + * @return string + */ + public function getOther(): string + { + return (string) $this->getOption('other'); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/RequestRecovery.php b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/RequestRecovery.php new file mode 100644 index 000000000..b2147ed57 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/RequestRecovery.php @@ -0,0 +1,18 @@ +setOption('requestid', $requestId); + } + + /** + * Get the requestId where that status should be retrieved for. + * + * @return string + */ + public function getRequestId(): string + { + return (string) $this->getOption('requestid'); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Split.php b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Split.php new file mode 100644 index 000000000..ff9579b30 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Split.php @@ -0,0 +1,109 @@ +setOption('path', $path); + } + + /** + * Get the pathes that should be used to split into. + * + * @return array + */ + public function getPath(): array + { + return (array) $this->getOption('path'); + } + + /** + * The target core names to split into. + * + * @param string[] $targetCore + * + * @return self Provides fluent interface + */ + public function setTargetCore(array $targetCore) + { + return $this->setOption('targetCore', $targetCore); + } + + /** + * Get the pathes that should be used to split into. + * + * @return array + */ + public function getTargetCore(): array + { + return (array) $this->getOption('targetCore'); + } + + /** + * Set a comma-separated list of hash ranges in a hexadecimal format. + * + * @param string $ranges + * + * @return self Provides fluent interface + */ + public function setRanges(string $ranges) + { + return $this->setOption('ranges', $ranges); + } + + /** + * Get the pathes that should be used to split into. + * + * @return string + */ + public function getRanges(): string + { + return (string) $this->getOption('ranges'); + } + + /** + * Set a key that should be used for splitting. + * + * @param string $splitKey + * + * @return self Provides fluent interface + */ + public function setSplitKey(string $splitKey) + { + return $this->setOption('split.key', $splitKey); + } + + /** + * Returns the key that should be used for splitting. + * + * @return string + */ + public function getSplitKey(): string + { + return (string) $this->getOption('split.key'); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Status.php b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Status.php new file mode 100644 index 000000000..f91498d9f --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Status.php @@ -0,0 +1,41 @@ +setOption('indexInfo', $indexInfo); + } + + /** + * Get if information about the index should be retrieved. + * + * @return bool + */ + public function getIndexInfo(): bool + { + return (string) $this->getOption('indexInfo'); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Swap.php b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Swap.php new file mode 100644 index 000000000..bea3d9c3e --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Swap.php @@ -0,0 +1,40 @@ +setOption('other', $other); + } + + /** + * Get the other core that should ne used for swapping. + * + * @return string + */ + public function getOther(): string + { + return (string) $this->getOption('other'); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Unload.php b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Unload.php new file mode 100644 index 000000000..faa16a908 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Action/Unload.php @@ -0,0 +1,87 @@ +setOption('deleteIndex', $deleteIndex); + } + + /** + * Indicates if a deletion was forced. + * + * @return bool + */ + public function getDeleteIndex(): bool + { + return (string) $this->getOption('deleteIndex'); + } + + /** + * If set to true the data dir will be removed when unloading. + * + * @param bool $deleteDataDir + * + * @return self Provides fluent interface + */ + public function setDeleteDataDir(bool $deleteDataDir) + { + return $this->setOption('deleteDataDir', $deleteDataDir); + } + + /** + * Indicates if a deletion of the dataDir was forced. + * + * @return bool + */ + public function getDeleteDataDir(): bool + { + return (string) $this->getOption('deleteDataDir'); + } + + /** + * If set to true the instance dir will be removed when unloading. + * + * @param bool $deleteInstanceDir + * + * @return self Provides fluent interface + */ + public function setDeleteInstanceDir(bool $deleteInstanceDir) + { + return $this->setOption('deleteInstanceDir', $deleteInstanceDir); + } + + /** + * Indicates if a deletion of the instanceDir was forced. + * + * @return bool + */ + public function getDeleteInstanceDir(): bool + { + return (string) $this->getOption('deleteInstanceDir'); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Query.php b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Query.php new file mode 100644 index 000000000..396374caa --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Query/Query.php @@ -0,0 +1,282 @@ + 'Solarium\QueryType\Server\CoreAdmin\Query\Action\Create', + self::ACTION_MERGE_INDEXES => 'Solarium\QueryType\Server\CoreAdmin\Query\Action\MergeIndexes', + self::ACTION_RELOAD => 'Solarium\QueryType\Server\CoreAdmin\Query\Action\Reload', + self::ACTION_RENAME => 'Solarium\QueryType\Server\CoreAdmin\Query\Action\Rename', + self::ACTION_REQUEST_RECOVERY => 'Solarium\QueryType\Server\CoreAdmin\Query\Action\RequestRecovery', + self::ACTION_REQUEST_STATUS => 'Solarium\QueryType\Server\CoreAdmin\Query\Action\RequestStatus', + self::ACTION_SPLIT => 'Solarium\QueryType\Server\CoreAdmin\Query\Action\Split', + self::ACTION_STATUS => 'Solarium\QueryType\Server\CoreAdmin\Query\Action\Status', + self::ACTION_SWAP => 'Solarium\QueryType\Server\CoreAdmin\Query\Action\Swap', + self::ACTION_UNLOAD => 'Solarium\QueryType\Server\CoreAdmin\Query\Action\Unload', + ]; + + /** + * Default options. + * + * @var array + */ + protected $options = [ + 'handler' => 'admin/cores', + 'resultclass' => 'Solarium\QueryType\Server\CoreAdmin\Result\Result', + ]; + + /** + * Action that should be performed on the core admin api. + * + * @var AbstractAction + */ + protected $action = null; + + /** + * Get type for this query. + * + * @return string + */ + public function getType() + { + return Client::QUERY_CORE_ADMIN; + } + + /** + * Get a requestbuilder for this query. + * + * @return RequestBuilder + */ + public function getRequestBuilder() + { + return new RequestBuilder(); + } + + /** + * Get a response parser for this query. + * + * @return ResponseParser + */ + public function getResponseParser() + { + return new ResponseParser(); + } + + /** + * @param array $options + * + * @return Create + */ + public function createCreate($options = []) + { + return $this->createAction(self::ACTION_CREATE, $options); + } + + /** + * @param array $options + * + * @return MergeIndexes + */ + public function createMergeIndexes($options = []) + { + return $this->createAction(self::ACTION_MERGE_INDEXES, $options); + } + + /** + * @param array $options + * + * @return Reload + */ + public function createReload($options = []) + { + return $this->createAction(self::ACTION_RELOAD, $options); + } + + /** + * @param array $options + * + * @return Rename + */ + public function createRename($options = []) + { + return $this->createAction(self::ACTION_RENAME, $options); + } + + /** + * @param array $options + * + * @return RequestRecovery + */ + public function createRequestRecovery($options = []) + { + return $this->createAction(self::ACTION_REQUEST_RECOVERY, $options); + } + + /** + * @param array $options + * + * @return RequestStatus + */ + public function createRequestStatus($options = []) + { + return $this->createAction(self::ACTION_REQUEST_STATUS, $options); + } + + /** + * @param array $options + * + * @return Split + */ + public function createSplit($options = []) + { + return $this->createAction(self::ACTION_SPLIT, $options); + } + + /** + * @param array $options + * + * @return Status + */ + public function createStatus($options = []) + { + return $this->createAction(self::ACTION_STATUS, $options); + } + + /** + * @param array $options + * + * @return Swap + */ + public function createSwap($options = []) + { + return $this->createAction(self::ACTION_SWAP, $options); + } + + /** + * @param array $options + * + * @return Unload + */ + public function createUnload($options = []) + { + return $this->createAction(self::ACTION_UNLOAD, $options); + } + + /** + * Create a command instance. + * + * @param string $type + * @param mixed $options + * + * @throws InvalidArgumentException + * + * @return AbstractAction + */ + public function createAction($type, $options = null) + { + if (!isset($this->actionTypes[$type])) { + throw new InvalidArgumentException('CoreAdmin action unknown: '.$type); + } + + $class = $this->actionTypes[$type]; + + return new $class($options); + } + + /** + * @param AbstractAction $action + */ + public function setAction(AbstractAction $action) + { + $this->action = $action; + } + + /** + * Get the active action. + * + * @return AbstractAction + */ + public function getAction() + { + return $this->action; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/RequestBuilder.php b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/RequestBuilder.php new file mode 100644 index 000000000..5e396376c --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/RequestBuilder.php @@ -0,0 +1,38 @@ +setMethod(Request::METHOD_GET); + $request = $this->addOptionsFromAction($query->getAction(), $request); + return $request; + } + + protected function addOptionsFromAction(AbstractAction $action, Request $request) + { + $options = ['action' => $action->getType()]; + $options += $action->getOptions(); + $request->addParams($options); + return $request; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/ResponseParser.php b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/ResponseParser.php new file mode 100644 index 000000000..c6d89bdba --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/ResponseParser.php @@ -0,0 +1,81 @@ +getData(); + $data = $this->parseStatus($data, $result); + $data = $this->addHeaderInfo($data, $data); + return $data; + } + + /** + * @param array $data + * @param Result $result + * + * @return array + */ + protected function parseStatus(array $data, Result $result) + { + $action = $result->getQuery()->getAction(); + $type = $action->getType(); + + $data['wasSuccessful'] = 200 === $result->getResponse()->getStatusCode(); + $data['statusMessage'] = $result->getResponse()->getStatusMessage(); + + if (Query::ACTION_STATUS !== $type) { + return $data; + } + + if (!is_array($data['status'])) { + return $data; + } + + $coreStatusResults = []; + $coreStatusResult = null; + + foreach ($data['status'] as $coreName => $coreStatusData) { + $status = new StatusResult(); + $status->setCoreName($coreName); + $status->setNumberOfDocuments($coreStatusData['index']['numDocs'] ?? 0); + $status->setVersion($coreStatusData['index']['version'] ?? 0); + $status->setUptime($coreStatusData['uptime'] ?? 0); + + $startTimeDate = isset($coreStatusData['startTime']) ? new \DateTime($coreStatusData['startTime']) : null; + $status->setStartTime($startTimeDate); + + $lastModifiedDate = isset($coreStatusData['index']['lastModified']) ? new \DateTime($coreStatusData['index']['lastModified']) : null; + $status->setLastModified($lastModifiedDate); + $coreStatusResults[] = $status; + + // when a core name was set in the action and we have a response we remember it to set a single statusResult + if ($coreName === $action->getCore()) { + $coreStatusResult = $status; + } + } + + $data['statusResults'] = $coreStatusResults; + $data['statusResult'] = $coreStatusResult; + + return $data; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Result/Result.php b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Result/Result.php new file mode 100644 index 000000000..e8ce01dd8 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Result/Result.php @@ -0,0 +1,85 @@ +parseResponse(); + return $this->wasSuccessful; + } + + /** + * @return string + */ + public function getStatusMessage(): string + { + $this->parseResponse(); + return $this->statusMessage; + } + + /** + * Returns the status result objects for all requested core statuses. + * + * @return StatusResult[]|null + */ + public function getStatusResults() + { + $this->parseResponse(); + return $this->statusResults; + } + + /** + * Retrives the status of the core, only available when the core was filtered to a core in the status action. + * + * @return StatusResult|null + */ + public function getStatusResult() + { + $this->parseResponse(); + return $this->statusResult; + } + + /** + * @param string $coreName + * + * @return null|StatusResult + */ + public function getStatusResultByCoreName($coreName) + { + return $this->statusResults[$coreName] ?? null; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Result/StatusResult.php b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Result/StatusResult.php new file mode 100644 index 000000000..3d73d472d --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Server/CoreAdmin/Result/StatusResult.php @@ -0,0 +1,135 @@ +coreName; + } + + /** + * @param string $coreName + */ + public function setCoreName(string $coreName) + { + $this->coreName = $coreName; + } + + /** + * @return int + */ + public function getNumberOfDocuments(): int + { + return $this->numberOfDocuments; + } + + /** + * @param int $numberOfDocuments + */ + public function setNumberOfDocuments(int $numberOfDocuments) + { + $this->numberOfDocuments = $numberOfDocuments; + } + + /** + * @return int + */ + public function getUptime(): int + { + return $this->uptime; + } + + /** + * @param int $uptime + */ + public function setUptime(int $uptime) + { + $this->uptime = $uptime; + } + + /** + * @return int + */ + public function getVersion(): int + { + return $this->version; + } + + /** + * @param int $version + */ + public function setVersion(int $version) + { + $this->version = $version; + } + + /** + * @return \DateTime|null + */ + public function getStartTime() + { + return $this->startTime; + } + + /** + * @param \DateTime|null $startTime + */ + public function setStartTime($startTime) + { + $this->startTime = $startTime; + } + + /** + * @return \DateTime|null + */ + public function getLastModified() + { + return $this->lastModified; + } + + /** + * @param \DateTime|null $lastModified + */ + public function setLastModified($lastModified) + { + $this->lastModified = $lastModified; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Spellcheck/Query.php b/vendor/solarium/solarium/src/QueryType/Spellcheck/Query.php new file mode 100644 index 000000000..1112ce568 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Spellcheck/Query.php @@ -0,0 +1,64 @@ + 'spell', + 'resultclass' => 'Solarium\QueryType\Spellcheck\Result\Result', + 'termclass' => 'Solarium\QueryType\Spellcheck\Result\Term', + 'omitheader' => true, + 'build' => false, + ]; + + /** + * Get type for this query. + * + * @return string + */ + public function getType() + { + return Client::QUERY_SPELLCHECK; + } + + /** + * Get a requestbuilder for this query. + * + * @return RequestBuilder + */ + public function getRequestBuilder() + { + return new RequestBuilder(); + } + + /** + * Get a response parser for this query. + * + * @return ResponseParser + */ + public function getResponseParser() + { + return new ResponseParser(); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Spellcheck/RequestBuilder.php b/vendor/solarium/solarium/src/QueryType/Spellcheck/RequestBuilder.php new file mode 100644 index 000000000..cf8787f7b --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Spellcheck/RequestBuilder.php @@ -0,0 +1,31 @@ +buildComponent($query, $request); + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Spellcheck/ResponseParser.php b/vendor/solarium/solarium/src/QueryType/Spellcheck/ResponseParser.php new file mode 100644 index 000000000..e73e545f9 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Spellcheck/ResponseParser.php @@ -0,0 +1,76 @@ +getData(); + $query = $result->getQuery(); + + $suggestions = []; + $allSuggestions = []; + $collation = null; + + if (isset($data['spellcheck']['suggestions']) && is_array($data['spellcheck']['suggestions'])) { + $suggestResults = $data['spellcheck']['suggestions']; + $termClass = $query->getOption('termclass'); + + if ($query->getResponseWriter() == $query::WT_JSON) { + $suggestResults = $this->convertToKeyValueArray($suggestResults); + } + + foreach ($suggestResults as $term => $termData) { + if ('collation' == $term) { + $collation = $termData; + } else { + if (!array_key_exists(0, $termData)) { + $termData = [$termData]; + } + + foreach ($termData as $currentTermData) { + $allSuggestions[] = $this->createTerm($termClass, $currentTermData); + + if (!array_key_exists($term, $suggestions)) { + $suggestions[$term] = $this->createTerm($termClass, $currentTermData); + } + } + } + } + } + + return $this->addHeaderInfo( + $data, + [ + 'results' => $suggestions, + 'all' => $allSuggestions, + 'collation' => $collation, + ] + ); + } + + private function createTerm($termClass, array $termData) + { + return new $termClass( + $termData['numFound'], + $termData['startOffset'], + $termData['endOffset'], + $termData['suggestion'] + ); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Spellcheck/Result/Result.php b/vendor/solarium/solarium/src/QueryType/Spellcheck/Result/Result.php new file mode 100644 index 000000000..d12dc5866 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Spellcheck/Result/Result.php @@ -0,0 +1,158 @@ +parseResponse(); + + return $this->status; + } + + /** + * Get Solr query time. + * + * This doesn't include things like the HTTP responsetime. Purely the Solr + * query execution time. + * + * @return int + */ + public function getQueryTime() + { + $this->parseResponse(); + + return $this->queryTime; + } + + /** + * Get all results. + * + * @return array + */ + public function getResults() + { + $this->parseResponse(); + + return $this->results; + } + + /** + * Get flat results. + * + * @return array + */ + public function getAll() + { + $this->parseResponse(); + + return $this->all; + } + + /** + * Get results for a specific term. + * + * @param string $term + * + * @return array + */ + public function getTerm($term) + { + $this->parseResponse(); + + if (isset($this->results[$term])) { + return $this->results[$term]; + } + + return []; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + $this->parseResponse(); + + return new \ArrayIterator($this->results); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + $this->parseResponse(); + + return count($this->results); + } + + /** + * Get collation. + * + * @return null|string + */ + public function getCollation() + { + $this->parseResponse(); + + return $this->collation; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Spellcheck/Result/Term.php b/vendor/solarium/solarium/src/QueryType/Spellcheck/Result/Term.php new file mode 100644 index 000000000..21aff4874 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Spellcheck/Result/Term.php @@ -0,0 +1,113 @@ +numFound = $numFound; + $this->startOffset = $startOffset; + $this->endOffset = $endOffset; + $this->suggestions = $suggestions; + } + + /** + * Get NumFound. + * + * @return int + */ + public function getNumFound() + { + return $this->numFound; + } + + /** + * Get StartOffset. + * + * @return int + */ + public function getStartOffset() + { + return $this->startOffset; + } + + /** + * Get EndOffset. + * + * @return int + */ + public function getEndOffset() + { + return $this->endOffset; + } + + /** + * Get suggestions. + * + * @return array + */ + public function getSuggestions() + { + return $this->suggestions; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->suggestions); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->suggestions); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Stream/Expression.php b/vendor/solarium/solarium/src/QueryType/Stream/Expression.php new file mode 100644 index 000000000..9364e5fe6 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Stream/Expression.php @@ -0,0 +1,67 @@ + 'stream', + 'resultclass' => 'Solarium\QueryType\Stream\Result', + 'documentclass' => 'Solarium\QueryType\Select\Result\Document', + ]; + + /** + * Get type for this query. + * + * @return string + */ + public function getType() + { + return Client::QUERY_STREAM; + } + + /** + * Get a requestbuilder for this query. + * + * @return RequestBuilder + */ + public function getRequestBuilder() + { + return new RequestBuilder(); + } + + /** + * Get a response parser for this query. + * + * @return ResponseParser + */ + public function getResponseParser() + { + return new ResponseParser(); + } + + /** + * Set the expression. + * + * @param string $expr + * + * @return self Provides fluent interface + */ + public function setExpression($expr) + { + return $this->setOption('expr', $expr); + } + + /** + * Get the expression. + * + * @return string + */ + public function getExpression() + { + return $this->getOption('expr'); + } + + /** + * Set a custom document class. + * + * This class should implement the document interface + * + * @param string $value classname + * + * @return self Provides fluent interface + */ + public function setDocumentClass($value) + { + return $this->setOption('documentclass', $value); + } + + /** + * Get the current documentclass option. + * + * The value is a classname, not an instance + * + * @return string + */ + public function getDocumentClass() + { + return $this->getOption('documentclass'); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Stream/RequestBuilder.php b/vendor/solarium/solarium/src/QueryType/Stream/RequestBuilder.php new file mode 100644 index 000000000..70d75de27 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Stream/RequestBuilder.php @@ -0,0 +1,31 @@ +setHandler($query->getHandler()); + $request->addParam('expr', $query->getExpression()); + $request->addParams($query->getParams()); + $request->addHeader('Content-Type: text/plain; charset=utf-8'); + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Stream/ResponseParser.php b/vendor/solarium/solarium/src/QueryType/Stream/ResponseParser.php new file mode 100644 index 000000000..63ba572fa --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Stream/ResponseParser.php @@ -0,0 +1,78 @@ +getData(); + + /* + * @var Query + */ + $query = $result->getQuery(); + + // create document instances + $documentClass = $query->getOption('documentclass'); + $classes = class_implements($documentClass); + if (!in_array('Solarium\QueryType\Select\Result\DocumentInterface', $classes, true)) { + throw new RuntimeException('The result document class must implement a document interface'); + } + + $documents = []; + if (isset($data['result-set']['docs'])) { + foreach ($data['result-set']['docs'] as $doc) { + $fields = (array) $doc; + if (isset($fields['EXCEPTION'])) { + // Use Solr's exception as message. + $e = new StreamException($fields['EXCEPTION']); + $e->setExpression($query->getExpression()); + throw $e; + } + if (isset($fields['EOF'])) { + // End of stream. + break; + } + $documents[] = new $documentClass($fields); + } + if (!isset($fields['EOF'])) { + $e = new StreamException('Streaming expression returned an incomplete result-set.'); + $e->setExpression($query->getExpression()); + throw $e; + } + $data['responseHeader']['QTime'] = $fields['RESPONSE_TIME']; + $data['responseHeader']['status'] = 0; + } else { + $e = new StreamException('Streaming expression did not return a result-set.'); + $e->setExpression($query->getExpression()); + throw $e; + } + + return $this->addHeaderInfo( + $data, + [ + 'numfound' => count($documents), + 'documents' => $documents, + ] + ); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Stream/Result.php b/vendor/solarium/solarium/src/QueryType/Stream/Result.php new file mode 100644 index 000000000..864452c05 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Stream/Result.php @@ -0,0 +1,173 @@ +parseResponse(); + + return $this->status; + } + + /** + * Get Solr query time. + * + * This doesn't include things like the HTTP responsetime. Purely the Solr + * query execution time. + * + * @return int + */ + public function getQueryTime() + { + $this->parseResponse(); + + return $this->queryTime; + } + + /** + * get Solr numFound. + * + * Returns the total number of documents found by Solr (this is NOT the + * number of document fetched from Solr!) + * + * @return int + */ + public function getNumFound() + { + $this->parseResponse(); + + return $this->numfound; + } + + /** + * Get Solr status code. + * + * @return int + */ + public function getStatusCode() + { + return $this->response->getStatusCode(); + } + + /** + * Get all documents. + * + * @return DocumentInterface[] + */ + public function getDocuments() + { + $this->parseResponse(); + + return $this->documents; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + $this->parseResponse(); + + return new \ArrayIterator($this->documents); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + $this->parseResponse(); + + return count($this->documents); + } + + /** + * Get Solr response body. + * + * @return string A JSON encoded string + */ + public function getBody() + { + return $this->response->getBody(); + } + + /** + * Get Solr response body in JSON format. + * + * More expressive convenience method that just call getBody(). + * + * @return string JSON + */ + public function getJson() + { + return $this->getBody(); + } + + /** + * Get Solr response data. + * + * Includes a lazy loading mechanism: JSON body data is decoded on first use and then saved for reuse. + * + * @return array + */ + public function getData() + { + if (null === $this->data) { + $this->data = json_decode($this->response->getBody(), true); + } + + return $this->data; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Suggester/Query.php b/vendor/solarium/solarium/src/QueryType/Suggester/Query.php new file mode 100644 index 000000000..9fc15fcbc --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Suggester/Query.php @@ -0,0 +1,66 @@ + 'suggest', + 'resultclass' => 'Solarium\QueryType\Suggester\Result\Result', + 'dictionaryclass' => 'Solarium\QueryType\Suggester\Result\Dictionary', + 'termclass' => 'Solarium\QueryType\Suggester\Result\Term', + 'omitheader' => true, + 'build' => false, + 'reload' => false, + ]; + + /** + * Get type for this query. + * + * @return string + */ + public function getType() + { + return Client::QUERY_SUGGESTER; + } + + /** + * Get a requestbuilder for this query. + * + * @return RequestBuilder + */ + public function getRequestBuilder() + { + return new RequestBuilder(); + } + + /** + * Get a response parser for this query. + * + * @return ResponseParser + */ + public function getResponseParser() + { + return new ResponseParser(); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Suggester/RequestBuilder.php b/vendor/solarium/solarium/src/QueryType/Suggester/RequestBuilder.php new file mode 100644 index 000000000..3fcd1c6f7 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Suggester/RequestBuilder.php @@ -0,0 +1,31 @@ +buildComponent($query, $request); + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Suggester/ResponseParser.php b/vendor/solarium/solarium/src/QueryType/Suggester/ResponseParser.php new file mode 100644 index 000000000..fc1b8f10d --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Suggester/ResponseParser.php @@ -0,0 +1,66 @@ +getData(); + $query = $result->getQuery(); + + $dictionaries = []; + $allSuggestions = []; + + if (isset($data['suggest']) && is_array($data['suggest'])) { + $dictionaryClass = $query->getOption('dictionaryclass'); + $termClass = $query->getOption('termclass'); + + foreach ($data['suggest'] as $dictionary => $dictionaryResults) { + $terms = []; + foreach ($dictionaryResults as $term => $termData) { + $allSuggestions[] = $this->createTerm($termClass, $termData); + $terms[$term] = $this->createTerm($termClass, $termData); + } + $dictionaries[$dictionary] = $this->createDictionary($dictionaryClass, $terms); + } + } + + return $this->addHeaderInfo( + $data, + [ + 'results' => $dictionaries, + 'all' => $allSuggestions, + ] + ); + } + + private function createDictionary($dictionaryClass, array $terms) + { + return new $dictionaryClass( + $terms + ); + } + + private function createTerm($termClass, array $termData) + { + return new $termClass( + $termData['numFound'], + $termData['suggestions'] + ); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Suggester/Result/Dictionary.php b/vendor/solarium/solarium/src/QueryType/Suggester/Result/Dictionary.php new file mode 100644 index 000000000..7b7a8e667 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Suggester/Result/Dictionary.php @@ -0,0 +1,72 @@ +terms = $terms; + } + + /** + * Get Terms. + * + * @return Term[] + */ + public function getTerms() + { + return $this->terms; + } + + /** + * Get results for a specific term. + * + * @param string $term + * + * @return Term|null + */ + public function getTerm($term) + { + if (isset($this->terms[$term])) { + return $this->terms[$term]; + } + + return null; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->terms); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->terms); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Suggester/Result/Result.php b/vendor/solarium/solarium/src/QueryType/Suggester/Result/Result.php new file mode 100644 index 000000000..7c173e38a --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Suggester/Result/Result.php @@ -0,0 +1,137 @@ +parseResponse(); + + return $this->status; + } + + /** + * Get Solr query time. + * + * This doesn't include things like the HTTP responsetime. Purely the Solr + * query execution time. + * + * @return int + */ + public function getQueryTime() + { + $this->parseResponse(); + + return $this->queryTime; + } + + /** + * Get all results. + * + * @return array + */ + public function getResults() + { + $this->parseResponse(); + + return $this->results; + } + + /** + * Get flat results. + * + * @return array + */ + public function getAll() + { + $this->parseResponse(); + + return $this->all; + } + + /** + * Get results for a specific dictionary. + * + * @param string $dictionary + * + * @return Dictionary|null + */ + public function getDictionary($dictionary) + { + $this->parseResponse(); + + if (isset($this->results[$dictionary])) { + return $this->results[$dictionary]; + } + + return null; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + $this->parseResponse(); + + return new \ArrayIterator($this->results); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + $this->parseResponse(); + + return count($this->results); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Suggester/Result/Term.php b/vendor/solarium/solarium/src/QueryType/Suggester/Result/Term.php new file mode 100644 index 000000000..7cec4fa44 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Suggester/Result/Term.php @@ -0,0 +1,75 @@ +numFound = $numFound; + $this->suggestions = $suggestions; + } + + /** + * Get NumFound. + * + * @return int + */ + public function getNumFound() + { + return $this->numFound; + } + + /** + * Get suggestions. + * + * @return array + */ + public function getSuggestions() + { + return $this->suggestions; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->suggestions); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + return count($this->suggestions); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Terms/Query.php b/vendor/solarium/solarium/src/QueryType/Terms/Query.php new file mode 100644 index 000000000..13d192749 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Terms/Query.php @@ -0,0 +1,62 @@ + 'Solarium\QueryType\Terms\Result', + 'handler' => 'terms', + 'omitheader' => true, + ]; + + /** + * Get type for this query. + * + * @return string + */ + public function getType() + { + return Client::QUERY_TERMS; + } + + /** + * Get a requestbuilder for this query. + * + * @return RequestBuilder + */ + public function getRequestBuilder() + { + return new RequestBuilder(); + } + + /** + * Get a response parser for this query. + * + * @return ResponseParser + */ + public function getResponseParser() + { + return new ResponseParser(); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Terms/RequestBuilder.php b/vendor/solarium/solarium/src/QueryType/Terms/RequestBuilder.php new file mode 100644 index 000000000..7912b5286 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Terms/RequestBuilder.php @@ -0,0 +1,31 @@ +buildComponent($query, $request); + + return $request; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Terms/ResponseParser.php b/vendor/solarium/solarium/src/QueryType/Terms/ResponseParser.php new file mode 100644 index 000000000..e8135f064 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Terms/ResponseParser.php @@ -0,0 +1,50 @@ +getData(); + + /* + * @var Query + */ + $query = $result->getQuery(); + + // Special case to handle Solr 1.4 data + if (isset($data['terms']) && count($data['terms']) == count($query->getFields()) * 2) { + $data['terms'] = $this->convertToKeyValueArray($data['terms']); + } + + foreach ($query->getFields() as $field) { + $field = trim($field); + + if (isset($data['terms'][$field])) { + $terms = $data['terms'][$field]; + if ($query->getResponseWriter() == $query::WT_JSON) { + $terms = $this->convertToKeyValueArray($terms); + } + $termResults[$field] = $terms; + } + } + + return $this->addHeaderInfo($data, ['results' => $termResults]); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Terms/Result.php b/vendor/solarium/solarium/src/QueryType/Terms/Result.php new file mode 100644 index 000000000..26db38de3 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Terms/Result.php @@ -0,0 +1,118 @@ +parseResponse(); + + return $this->status; + } + + /** + * Get Solr query time. + * + * This doesn't include things like the HTTP responsetime. Purely the Solr + * query execution time. + * + * @return int + */ + public function getQueryTime() + { + $this->parseResponse(); + + return $this->queryTime; + } + + /** + * Get all term results. + * + * @return array + */ + public function getResults() + { + $this->parseResponse(); + + return $this->results; + } + + /** + * Get term results for a specific field. + * + * @param string $field + * + * @return array + */ + public function getTerms($field) + { + $this->parseResponse(); + + if (isset($this->results[$field])) { + return $this->results[$field]; + } + + return []; + } + + /** + * IteratorAggregate implementation. + * + * @return \ArrayIterator + */ + public function getIterator() + { + $this->parseResponse(); + + return new \ArrayIterator($this->results); + } + + /** + * Countable implementation. + * + * @return int + */ + public function count() + { + $this->parseResponse(); + + return count($this->results); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Update/Query/Command/AbstractCommand.php b/vendor/solarium/solarium/src/QueryType/Update/Query/Command/AbstractCommand.php new file mode 100644 index 000000000..3d40fa512 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Update/Query/Command/AbstractCommand.php @@ -0,0 +1,18 @@ +documents[] = $document; + + return $this; + } + + /** + * Add multiple documents. + * + * @param array|\Traversable $documents + * + * @throws RuntimeException If any of the given documents does not implement DocumentInterface + * + * @return self Provides fluent interface + */ + public function addDocuments($documents) + { + //only check documents for type if in an array (iterating a Traversable may do unnecessary work) + if (is_array($documents)) { + foreach ($documents as $document) { + if (!($document instanceof DocumentInterface)) { + throw new RuntimeException('Documents must implement DocumentInterface.'); + } + } + } + + //if we don't have documents so far, accept arrays or Traversable objects as-is + if (empty($this->documents)) { + $this->documents = $documents; + + return $this; + } + + //if something Traversable is passed in, and there are existing documents, convert all to arrays before merging + if ($documents instanceof \Traversable) { + $documents = iterator_to_array($documents); + } + if ($this->documents instanceof \Traversable) { + $this->documents = array_merge(iterator_to_array($this->documents), $documents); + } else { + $this->documents = array_merge($this->documents, $documents); + } + + return $this; + } + + /** + * Get all documents. + * + * @return DocumentInterface[] + */ + public function getDocuments() + { + return $this->documents; + } + + /** + * Set overwrite option. + * + * @param bool $overwrite + * + * @return self Provides fluent interface + */ + public function setOverwrite($overwrite) + { + return $this->setOption('overwrite', $overwrite); + } + + /** + * Get overwrite option. + * + * @return bool + */ + public function getOverwrite() + { + return $this->getOption('overwrite'); + } + + /** + * Get commitWithin option. + * + * @param bool $commitWithin + * + * @return self Provides fluent interface + */ + public function setCommitWithin($commitWithin) + { + return $this->setOption('commitwithin', $commitWithin); + } + + /** + * Set commitWithin option. + * + * @return bool + */ + public function getCommitWithin() + { + return $this->getOption('commitwithin'); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Update/Query/Command/Commit.php b/vendor/solarium/solarium/src/QueryType/Update/Query/Command/Commit.php new file mode 100644 index 000000000..66a0f1d98 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Update/Query/Command/Commit.php @@ -0,0 +1,89 @@ +getOption('softcommit'); + } + + /** + * Set softCommit option. + * + * @param bool $softCommit + * + * @return self Provides fluent interface + */ + public function setSoftCommit($softCommit) + { + return $this->setOption('softcommit', $softCommit); + } + + /** + * Get waitSearcher option. + * + * @return bool + */ + public function getWaitSearcher() + { + return $this->getOption('waitsearcher'); + } + + /** + * Set waitSearcher option. + * + * @param bool $waitSearcher + * + * @return self Provides fluent interface + */ + public function setWaitSearcher($waitSearcher) + { + return $this->setOption('waitsearcher', $waitSearcher); + } + + /** + * Get expungeDeletes option. + * + * @return bool + */ + public function getExpungeDeletes() + { + return $this->getOption('expungedeletes'); + } + + /** + * Set expungeDeletes option. + * + * @param bool $expungeDeletes + * + * @return self Provides fluent interface + */ + public function setExpungeDeletes($expungeDeletes) + { + return $this->setOption('expungedeletes', $expungeDeletes); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Update/Query/Command/Delete.php b/vendor/solarium/solarium/src/QueryType/Update/Query/Command/Delete.php new file mode 100644 index 000000000..7d63f2371 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Update/Query/Command/Delete.php @@ -0,0 +1,137 @@ +ids[] = $id; + + return $this; + } + + /** + * Add multiple IDs to the delete command. + * + * @param array $ids + * + * @return self Provides fluent interface + */ + public function addIds($ids) + { + $this->ids = array_merge($this->ids, $ids); + + return $this; + } + + /** + * Add a single query to the delete command. + * + * @param string $query + * + * @return self Provides fluent interface + */ + public function addQuery($query) + { + $this->queries[] = $query; + + return $this; + } + + /** + * Add multiple queries to the delete command. + * + * @param array $queries + * + * @return self Provides fluent interface + */ + public function addQueries($queries) + { + $this->queries = array_merge($this->queries, $queries); + + return $this; + } + + /** + * Get all queries of this delete command. + * + * @return array + */ + public function getQueries() + { + return $this->queries; + } + + /** + * Get all qids of this delete command. + * + * @return array + */ + public function getIds() + { + return $this->ids; + } + + /** + * Build ids/queries based on options. + */ + protected function init() + { + $id = $this->getOption('id'); + if (null !== $id) { + if (is_array($id)) { + $this->addIds($id); + } else { + $this->addId($id); + } + } + + $queries = $this->getOption('query'); + if (null !== $queries) { + if (is_array($queries)) { + $this->addQueries($queries); + } else { + $this->addQuery($queries); + } + } + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Update/Query/Command/Optimize.php b/vendor/solarium/solarium/src/QueryType/Update/Query/Command/Optimize.php new file mode 100644 index 000000000..e0ead62e8 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Update/Query/Command/Optimize.php @@ -0,0 +1,89 @@ +getOption('softcommit'); + } + + /** + * Set softCommit option. + * + * @param bool $softCommit + * + * @return self Provides fluent interface + */ + public function setSoftCommit($softCommit) + { + return $this->setOption('softcommit', $softCommit); + } + + /** + * Get waitSearcher option. + * + * @return bool + */ + public function getWaitSearcher() + { + return $this->getOption('waitsearcher'); + } + + /** + * Set waitSearcher option. + * + * @param bool $waitSearcher + * + * @return self Provides fluent interface + */ + public function setWaitSearcher($waitSearcher) + { + return $this->setOption('waitsearcher', $waitSearcher); + } + + /** + * Get maxSegments option. + * + * @return bool + */ + public function getMaxSegments() + { + return $this->getOption('maxsegments'); + } + + /** + * Set maxSegments option. + * + * @param bool $maxSegments + * + * @return self Provides fluent interface + */ + public function setMaxSegments($maxSegments) + { + return $this->setOption('maxsegments', $maxSegments); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Update/Query/Command/Rollback.php b/vendor/solarium/solarium/src/QueryType/Update/Query/Command/Rollback.php new file mode 100644 index 000000000..1c64a1c90 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Update/Query/Command/Rollback.php @@ -0,0 +1,23 @@ +fields = $fields; + $this->fieldBoosts = $boosts; + $this->modifiers = $modifiers; + } + + /** + * Set field value. + * + * Magic method for setting fields as properties of this document + * object, by field name. + * + * If you supply NULL as the value the field will be removed + * If you supply an array a multivalue field will be created. + * In all cases any existing (multi)value will be overwritten. + * + * @param string $name + * @param string|null $value + */ + public function __set($name, $value) + { + $this->setField($name, $value); + } + + /** + * Unset field value. + * + * Magic method for removing fields by unsetting object properties + * + * @param string $name + */ + public function __unset($name) + { + $this->removeField($name); + } + + /** + * Add a field value. + * + * If a field already has a value it will be converted + * to a multivalue field. + * + * @param string $key + * @param mixed $value + * @param float $boost + * @param string $modifier + * + * @return self Provides fluent interface + */ + public function addField($key, $value, $boost = null, $modifier = null) + { + if (!isset($this->fields[$key])) { + $this->setField($key, $value, $boost, $modifier); + } else { + // convert single value to array if needed + if (!is_array($this->fields[$key])) { + $this->fields[$key] = [$this->fields[$key]]; + } + + if ($this->filterControlCharacters && is_string($value)) { + $value = $this->getHelper()->filterControlCharacters($value); + } + + $this->fields[$key][] = $value; + $this->setFieldBoost($key, $boost); + if (null !== $modifier) { + $this->setFieldModifier($key, $modifier); + } + } + + return $this; + } + + /** + * Set a field value. + * + * If a field already has a value it will be overwritten. You cannot use + * this method for a multivalue field. + * If you supply NULL as the value the field will be removed + * + * @param string $key + * @param mixed $value + * @param float $boost + * @param string $modifier + * + * @return self Provides fluent interface + */ + public function setField($key, $value, $boost = null, $modifier = null) + { + if (null === $value && null === $modifier) { + $this->removeField($key); + } else { + if ($this->filterControlCharacters && is_string($value)) { + $value = $this->getHelper()->filterControlCharacters($value); + } + + $this->fields[$key] = $value; + $this->setFieldBoost($key, $boost); + if (null !== $modifier) { + $this->setFieldModifier($key, $modifier); + } + } + + return $this; + } + + /** + * Remove a field. + * + * @param string $key + * + * @return self Provides fluent interface + */ + public function removeField($key) + { + if (isset($this->fields[$key])) { + unset($this->fields[$key]); + } + + if (isset($this->fieldBoosts[$key])) { + unset($this->fieldBoosts[$key]); + } + + return $this; + } + + /** + * Get the boost value for a field. + * + * @param string $key + * + * @return float + */ + public function getFieldBoost($key) + { + if (isset($this->fieldBoosts[$key])) { + return $this->fieldBoosts[$key]; + } + } + + /** + * Set the boost value for a field. + * + * @param string $key + * @param float $boost + * + * @return self Provides fluent interface + */ + public function setFieldBoost($key, $boost) + { + $this->fieldBoosts[$key] = $boost; + + return $this; + } + + /** + * Get boost values for all fields. + * + * @return array + */ + public function getFieldBoosts() + { + return $this->fieldBoosts; + } + + /** + * Set the document boost value. + * + * @param float $boost + * + * @return self Provides fluent interface + */ + public function setBoost($boost) + { + $this->boost = $boost; + + return $this; + } + + /** + * Get the document boost value. + * + * @return float + */ + public function getBoost() + { + return $this->boost; + } + + /** + * Clear all fields. + * + * @return self Provides fluent interface + **/ + public function clear() + { + $this->fields = []; + $this->fieldBoosts = []; + $this->modifiers = []; + + return $this; + } + + /** + * Sets the uniquely identifying key for use in atomic updating. + * + * You can set an existing field as key by supplying that field name as key, or add a new field by also supplying a + * value. + * + * @param string $key + * @param mixed $value + * + * @return self Provides fluent interface + */ + public function setKey($key, $value = null) + { + $this->key = $key; + if (null !== $value) { + $this->addField($key, $value); + } + + return $this; + } + + /** + * Sets the modifier type for the provided field. + * + * @param string $key + * @param string $modifier + * + * @throws RuntimeException + * + * @return self + */ + public function setFieldModifier($key, $modifier = null) + { + if (!in_array($modifier, [self::MODIFIER_ADD, self::MODIFIER_REMOVE, self::MODIFIER_INC, self::MODIFIER_SET], true)) { + throw new RuntimeException('Attempt to set an atomic update modifier that is not supported'); + } + $this->modifiers[$key] = $modifier; + + return $this; + } + + /** + * Returns the appropriate modifier for atomic updates. + * + * @param string $key + * + * @return null|string + */ + public function getFieldModifier($key) + { + return isset($this->modifiers[$key]) ? $this->modifiers[$key] : null; + } + + /** + * Get fields. + * + * Adds validation for atomicUpdates + * + * @throws RuntimeException + * + * @return array + */ + public function getFields() + { + if (count($this->modifiers) > 0 && (null === $this->key || !isset($this->fields[$this->key]))) { + throw new RuntimeException( + 'A document that uses modifiers (atomic updates) must have a key defined before it is used' + ); + } + + return parent::getFields(); + } + + /** + * Set version. + * + * @param int $version + * + * @return self + */ + public function setVersion($version) + { + $this->version = $version; + + return $this; + } + + /** + * Get version. + * + * @return int + */ + public function getVersion() + { + return $this->version; + } + + /** + * Get a helper instance. + * + * Uses lazy loading: the helper is instantiated on first use + * + * @return Helper + */ + public function getHelper() + { + if (null === $this->helper) { + $this->helper = new Helper($this); + } + + return $this->helper; + } + + /** + * Whether values should be filtered for control characters automatically. + * + * @param bool $filterControlCharacters + */ + public function setFilterControlCharacters($filterControlCharacters) + { + $this->filterControlCharacters = $filterControlCharacters; + } + + /** + * Returns whether values should be filtered automatically or control characters. + * + * @return bool + */ + public function getFilterControlCharacters() + { + return $this->filterControlCharacters; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Update/Query/Document/DocumentInterface.php b/vendor/solarium/solarium/src/QueryType/Update/Query/Document/DocumentInterface.php new file mode 100644 index 000000000..f836eaf94 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Update/Query/Document/DocumentInterface.php @@ -0,0 +1,18 @@ + 'Solarium\QueryType\Update\Query\Command\Add', + self::COMMAND_DELETE => 'Solarium\QueryType\Update\Query\Command\Delete', + self::COMMAND_COMMIT => 'Solarium\QueryType\Update\Query\Command\Commit', + self::COMMAND_OPTIMIZE => 'Solarium\QueryType\Update\Query\Command\Optimize', + self::COMMAND_ROLLBACK => 'Solarium\QueryType\Update\Query\Command\Rollback', + ]; + + /** + * Default options. + * + * @var array + */ + protected $options = [ + 'handler' => 'update', + 'resultclass' => 'Solarium\QueryType\Update\Result', + 'documentclass' => 'Solarium\QueryType\Update\Query\Document\Document', + 'omitheader' => false, + ]; + + /** + * Array of commands. + * + * The commands will be executed in the order of this array, this can be + * important in some cases. For instance a rollback. + * + * @var AbstractCommand[] + */ + protected $commands = []; + + /** + * Get type for this query. + * + * @return string + */ + public function getType() + { + return Client::QUERY_UPDATE; + } + + /** + * Get a requestbuilder for this query. + * + * @return RequestBuilder + */ + public function getRequestBuilder() + { + return new RequestBuilder(); + } + + /** + * Get a response parser for this query. + * + * @return ResponseParser + */ + public function getResponseParser() + { + return new ResponseParser(); + } + + /** + * Create a command instance. + * + * + * @param string $type + * @param mixed $options + * + * @throws InvalidArgumentException + * + * @return AbstractCommand + */ + public function createCommand($type, $options = null) + { + $type = strtolower($type); + + if (!isset($this->commandTypes[$type])) { + throw new InvalidArgumentException('Update commandtype unknown: '.$type); + } + + $class = $this->commandTypes[$type]; + + return new $class($options); + } + + /** + * Get all commands for this update query. + * + * @return AbstractCommand[] + */ + public function getCommands() + { + return $this->commands; + } + + /** + * Add a command to this update query. + * + * The command must be an instance of one of the Solarium\QueryType\Update_* + * classes. + * + * @param string $key + * @param object $command + * + * @return self Provides fluent interface + */ + public function add($key, $command) + { + if (0 !== strlen($key)) { + $this->commands[$key] = $command; + } else { + $this->commands[] = $command; + } + + return $this; + } + + /** + * Remove a command. + * + * You can remove a command by passing its key or by passing the command instance. + * + * @param string|\Solarium\QueryType\Update\Query\Command\AbstractCommand $command + * + * @return self Provides fluent interface + */ + public function remove($command) + { + if (is_object($command)) { + foreach ($this->commands as $key => $instance) { + if ($instance === $command) { + unset($this->commands[$key]); + break; + } + } + } else { + if (isset($this->commands[$command])) { + unset($this->commands[$command]); + } + } + + return $this; + } + + /** + * Convenience method for adding a rollback command. + * + * If you need more control, like choosing a key for the command you need to + * create you own command instance and use the add method. + * + * @return self Provides fluent interface + */ + public function addRollback() + { + return $this->add(null, new RollbackCommand()); + } + + /** + * Convenience method for adding a delete query command. + * + * If you need more control, like choosing a key for the command you need to + * create you own command instance and use the add method. + * + * @param string $query + * @param array $bind Bind values for placeholders in the query string + * + * @return self Provides fluent interface + */ + public function addDeleteQuery($query, $bind = null) + { + if (null !== $bind) { + $query = $this->getHelper()->assemble($query, $bind); + } + + $delete = new DeleteCommand(); + $delete->addQuery($query); + + return $this->add(null, $delete); + } + + /** + * Convenience method to add a multi delete query command. + * + * If you need more control, like choosing a key for the command you need to + * create you own command instance and use the add method. + * + * @param array $queries + * + * @return self Provides fluent interface + */ + public function addDeleteQueries($queries) + { + $delete = new DeleteCommand(); + $delete->addQueries($queries); + + return $this->add(null, $delete); + } + + /** + * Convenience method to add a delete by ID command. + * + * If you need more control, like choosing a key for the command you need to + * create you own command instance and use the add method. + * + * @param int|string $id + * + * @return self Provides fluent interface + */ + public function addDeleteById($id) + { + $delete = new DeleteCommand(); + $delete->addId($id); + + return $this->add(null, $delete); + } + + /** + * Convenience method to add a delete by IDs command. + * + * If you need more control, like choosing a key for the command you need to + * create you own command instance and use the add method. + * + * @param array $ids + * + * @return self Provides fluent interface + */ + public function addDeleteByIds($ids) + { + $delete = new DeleteCommand(); + $delete->addIds($ids); + + return $this->add(null, $delete); + } + + /** + * Convenience method to add a 'add document' command. + * + * If you need more control, like choosing a key for the command you need to + * create you own command instance and use the add method. + * + * @param DocumentInterface $document + * @param bool $overwrite + * @param int $commitWithin + * + * @return self Provides fluent interface + */ + public function addDocument(DocumentInterface $document, $overwrite = null, $commitWithin = null) + { + return $this->addDocuments([$document], $overwrite, $commitWithin); + } + + /** + * Convenience method to add a 'add documents' command. + * + * If you need more control, like choosing a key for the command you need to + * create you own command instance and use the add method. + * + * @param array $documents + * @param bool $overwrite + * @param int $commitWithin + * + * @return self Provides fluent interface + */ + public function addDocuments($documents, $overwrite = null, $commitWithin = null) + { + $add = new AddCommand(); + + if (null !== $overwrite) { + $add->setOverwrite($overwrite); + } + + if (null !== $commitWithin) { + $add->setCommitWithin($commitWithin); + } + + $add->addDocuments($documents); + + return $this->add(null, $add); + } + + /** + * Convenience method to add a commit command. + * + * If you need more control, like choosing a key for the command you need to + * create you own command instance and use the add method. + * + * @param bool $softCommit + * @param bool $waitSearcher + * @param bool $expungeDeletes + * + * @return self Provides fluent interface + */ + public function addCommit($softCommit = null, $waitSearcher = null, $expungeDeletes = null) + { + $commit = new CommitCommand(); + + if (null !== $softCommit) { + $commit->setSoftCommit($softCommit); + } + + if (null !== $waitSearcher) { + $commit->setWaitSearcher($waitSearcher); + } + + if (null !== $expungeDeletes) { + $commit->setExpungeDeletes($expungeDeletes); + } + + return $this->add(null, $commit); + } + + /** + * Convenience method to add an optimize command. + * + * If you need more control, like choosing a key for the command you need to + * create you own command instance and use the add method. + * + * @param bool $softCommit + * @param bool $waitSearcher + * @param int $maxSegments + * + * @return self Provides fluent interface + */ + public function addOptimize($softCommit = null, $waitSearcher = null, $maxSegments = null) + { + $optimize = new OptimizeCommand(); + + if (null !== $softCommit) { + $optimize->setSoftCommit($softCommit); + } + + if (null !== $waitSearcher) { + $optimize->setWaitSearcher($waitSearcher); + } + + if (null !== $maxSegments) { + $optimize->setMaxSegments($maxSegments); + } + + return $this->add(null, $optimize); + } + + /** + * Set a custom document class for use in the createDocument method. + * + * This class should implement the document interface + * + * @param string $value classname + * + * @return self Provides fluent interface + */ + public function setDocumentClass($value) + { + return $this->setOption('documentclass', $value); + } + + /** + * Get the current documentclass option. + * + * The value is a classname, not an instance + * + * @return string + */ + public function getDocumentClass() + { + return $this->getOption('documentclass'); + } + + /** + * Create a document object instance. + * + * You can optionally directly supply the fields and boosts + * to get a ready-made document instance for direct use in an add command + * + * @since 2.1.0 + * + * @param array $fields + * @param array $boosts + * @param array $modifiers + * + * @return DocumentInterface + */ + public function createDocument($fields = [], $boosts = [], $modifiers = []) + { + $class = $this->getDocumentClass(); + + return new $class($fields, $boosts, $modifiers); + } + + /** + * Initialize options. + * + * Several options need some extra checks or setup work, for these options + * the setters are called. + * + * @throws RuntimeException + */ + protected function init() + { + if (isset($this->options['command'])) { + foreach ($this->options['command'] as $key => $value) { + $type = $value['type']; + + if (self::COMMAND_ADD == $type) { + throw new RuntimeException( + 'Adding documents is not supported in configuration, use the API for this' + ); + } + + $this->add($key, $this->createCommand($type, $value)); + } + } + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Update/RequestBuilder.php b/vendor/solarium/solarium/src/QueryType/Update/RequestBuilder.php new file mode 100644 index 000000000..697f74e5a --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Update/RequestBuilder.php @@ -0,0 +1,244 @@ +setMethod(Request::METHOD_POST); + $request->setRawData($this->getRawData($query)); + + return $request; + } + + /** + * Generates raw POST data. + * + * Each commandtype is delegated to a separate builder method. + * + * @param UpdateQuery $query + * + * @throws RuntimeException + * + * @return string + */ + public function getRawData($query) + { + $xml = ''; + foreach ($query->getCommands() as $command) { + switch ($command->getType()) { + case UpdateQuery::COMMAND_ADD: + $xml .= $this->buildAddXml($command, $query); + break; + case UpdateQuery::COMMAND_DELETE: + $xml .= $this->buildDeleteXml($command); + break; + case UpdateQuery::COMMAND_OPTIMIZE: + $xml .= $this->buildOptimizeXml($command); + break; + case UpdateQuery::COMMAND_COMMIT: + $xml .= $this->buildCommitXml($command); + break; + case UpdateQuery::COMMAND_ROLLBACK: + $xml .= $this->buildRollbackXml(); + break; + default: + throw new RuntimeException('Unsupported command type'); + break; + } + } + $xml .= ''; + + return $xml; + } + + /** + * Build XML for an add command. + * + * @param \Solarium\QueryType\Update\Query\Command\Add $command + * @param UpdateQuery $query + * + * @return string + */ + public function buildAddXml($command, $query = null) + { + $xml = 'boolAttrib('overwrite', $command->getOverwrite()); + $xml .= $this->attrib('commitWithin', $command->getCommitWithin()); + $xml .= '>'; + + foreach ($command->getDocuments() as $doc) { + $xml .= 'attrib('boost', $doc->getBoost()); + $xml .= '>'; + + foreach ($doc->getFields() as $name => $value) { + $boost = $doc->getFieldBoost($name); + $modifier = $doc->getFieldModifier($name); + $xml .= $this->buildFieldsXml($name, $boost, $value, $modifier, $query); + } + + $version = $doc->getVersion(); + if (null !== $version) { + $xml .= $this->buildFieldXml('_version_', null, $version); + } + + $xml .= ''; + } + + $xml .= ''; + + return $xml; + } + + /** + * Build XML for a delete command. + * + * @param \Solarium\QueryType\Update\Query\Command\Delete $command + * + * @return string + */ + public function buildDeleteXml($command) + { + $xml = ''; + foreach ($command->getIds() as $id) { + $xml .= ''.htmlspecialchars($id, ENT_NOQUOTES, 'UTF-8').''; + } + foreach ($command->getQueries() as $query) { + $xml .= ''.htmlspecialchars($query, ENT_NOQUOTES, 'UTF-8').''; + } + $xml .= ''; + + return $xml; + } + + /** + * Build XML for an update command. + * + * @param \Solarium\QueryType\Update\Query\Command\Optimize $command + * + * @return string + */ + public function buildOptimizeXml($command) + { + $xml = 'boolAttrib('softCommit', $command->getSoftCommit()); + $xml .= $this->boolAttrib('waitSearcher', $command->getWaitSearcher()); + $xml .= $this->attrib('maxSegments', $command->getMaxSegments()); + $xml .= '/>'; + + return $xml; + } + + /** + * Build XML for a commit command. + * + * @param \Solarium\QueryType\Update\Query\Command\Commit $command + * + * @return string + */ + public function buildCommitXml($command) + { + $xml = 'boolAttrib('softCommit', $command->getSoftCommit()); + $xml .= $this->boolAttrib('waitSearcher', $command->getWaitSearcher()); + $xml .= $this->boolAttrib('expungeDeletes', $command->getExpungeDeletes()); + $xml .= '/>'; + + return $xml; + } + + /** + * Build XMl for a rollback command. + * + * @return string + */ + public function buildRollbackXml() + { + return ''; + } + + /** + * Build XML for a field. + * + * Used in the add command + * + * @param string $name + * @param float $boost + * @param mixed $value + * @param string $modifier + * @param UpdateQuery $query + * + * @return string + */ + protected function buildFieldXml($name, $boost, $value, $modifier = null, $query = null) + { + $xml = 'attrib('boost', $boost); + $xml .= $this->attrib('update', $modifier); + if (null === $value) { + $xml .= $this->attrib('null', 'true'); + } elseif (false === $value) { + $value = 'false'; + } elseif (true === $value) { + $value = 'true'; + } elseif ($value instanceof \DateTime) { + $value = $query->getHelper()->formatDate($value); + } else { + $value = htmlspecialchars($value, ENT_NOQUOTES, 'UTF-8'); + } + + $xml .= '>'.$value.''; + + return $xml; + } + + /** + * @param string $key + * @param float $boost + * @param mixed $value + * @param string $modifier + * @param UpdateQuery $query + * + * @return string + */ + private function buildFieldsXml($key, $boost, $value, $modifier, $query) + { + $xml = ''; + if (is_array($value)) { + foreach ($value as $multival) { + if (is_array($multival)) { + $xml .= ''; + foreach ($multival as $k => $v) { + $xml .= $this->buildFieldsXml($k, $boost, $v, $modifier, $query); + } + $xml .= ''; + } else { + $xml .= $this->buildFieldXml($key, $boost, $multival, $modifier, $query); + } + } + } else { + $xml .= $this->buildFieldXml($key, $boost, $value, $modifier, $query); + } + + return $xml; + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Update/ResponseParser.php b/vendor/solarium/solarium/src/QueryType/Update/ResponseParser.php new file mode 100644 index 000000000..d52434e47 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Update/ResponseParser.php @@ -0,0 +1,26 @@ +getData(); + + return $this->addHeaderInfo($data, []); + } +} diff --git a/vendor/solarium/solarium/src/QueryType/Update/Result.php b/vendor/solarium/solarium/src/QueryType/Update/Result.php new file mode 100644 index 000000000..e92860473 --- /dev/null +++ b/vendor/solarium/solarium/src/QueryType/Update/Result.php @@ -0,0 +1,63 @@ +parseResponse(); + + return $this->status; + } + + /** + * Get Solr query time. + * + * This doesn't include things like the HTTP responsetime. Purely the Solr + * query execution time. + * + * @return int + */ + public function getQueryTime() + { + $this->parseResponse(); + + return $this->queryTime; + } +} diff --git a/vendor/solarium/solarium/src/Support/DataFixtures/Executor.php b/vendor/solarium/solarium/src/Support/DataFixtures/Executor.php new file mode 100644 index 000000000..0e7f2fd19 --- /dev/null +++ b/vendor/solarium/solarium/src/Support/DataFixtures/Executor.php @@ -0,0 +1,36 @@ + + */ +class Executor +{ + /** + * @var ClientInterface + */ + private $client; + + /** + * Constructor. + * + * @param ClientInterface $client + */ + public function __construct(ClientInterface $client) + { + $this->client = $client; + } + + /** + * @param FixtureInterface[] $fixtures + */ + public function execute(array $fixtures) + { + foreach ($fixtures as $fixture) { + $fixture->load($this->client); + } + } +} diff --git a/vendor/solarium/solarium/src/Support/DataFixtures/FixtureInterface.php b/vendor/solarium/solarium/src/Support/DataFixtures/FixtureInterface.php new file mode 100644 index 000000000..222bdc3ff --- /dev/null +++ b/vendor/solarium/solarium/src/Support/DataFixtures/FixtureInterface.php @@ -0,0 +1,16 @@ + + */ +interface FixtureInterface +{ + /** + * @param ClientInterface $client + */ + public function load(ClientInterface $client); +} diff --git a/vendor/solarium/solarium/src/Support/DataFixtures/FixtureLoader.php b/vendor/solarium/solarium/src/Support/DataFixtures/FixtureLoader.php new file mode 100644 index 000000000..e21f98afb --- /dev/null +++ b/vendor/solarium/solarium/src/Support/DataFixtures/FixtureLoader.php @@ -0,0 +1,53 @@ + + */ +class FixtureLoader +{ + /** + * @var Loader + */ + private $loader; + + /** + * @var Purger + */ + private $purger; + + /** + * @var Executor + */ + private $executor; + + /** + * @param Loader $loader + * @param Purger $purger + * @param Executor $executor + */ + public function __construct(Loader $loader, Purger $purger, Executor $executor) + { + $this->loader = $loader; + $this->purger = $purger; + $this->executor = $executor; + } + + /** + * @param string $dir + * @param bool $append + */ + public function loadFixturesFromDir($dir, $append = true) + { + if (!$append) { + $this->purger->purge(); + } + + $this->loader->loadFromDirectory($dir); + + $this->executor->execute($this->loader->getFixtures()); + } +} diff --git a/vendor/solarium/solarium/src/Support/DataFixtures/Loader.php b/vendor/solarium/solarium/src/Support/DataFixtures/Loader.php new file mode 100644 index 000000000..0edb1eee6 --- /dev/null +++ b/vendor/solarium/solarium/src/Support/DataFixtures/Loader.php @@ -0,0 +1,87 @@ + + */ +class Loader +{ + /** + * @var FixtureInterface[] + */ + private $fixtures; + + /** + * The file extension of fixture files. + * + * @var string + */ + private $fileExtension = '.php'; + + /** + * constructor. + */ + public function __construct() + { + $this->fixtures = []; + } + + /** + * @param FixtureInterface $fixture + */ + public function addFixture(FixtureInterface $fixture) + { + $this->fixtures[] = $fixture; + } + + /** + * @return FixtureInterface[] + */ + public function getFixtures() + { + return $this->fixtures; + } + + /** + * @param string $dir + * + * @throws \InvalidArgumentException + */ + public function loadFromDirectory($dir) + { + if (!is_dir($dir)) { + throw new \InvalidArgumentException(sprintf('"%s" does not exist', $dir)); + } + + $includedFiles = []; + + $iterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($dir), + \RecursiveIteratorIterator::LEAVES_ONLY + ); + + /** @var $file \DirectoryIterator */ + foreach ($iterator as $file) { + if (($fileName = $file->getBasename($this->fileExtension)) == $file->getBasename()) { + continue; + } + $sourceFile = realpath($file->getPathname()); + /** @noinspection PhpIncludeInspection */ + require_once $sourceFile; + $includedFiles[] = $sourceFile; + } + $declared = get_declared_classes(); + + foreach ($declared as $className) { + $reflClass = new \ReflectionClass($className); + $sourceFile = $reflClass->getFileName(); + + if (in_array($sourceFile, $includedFiles, true)) { + $fixture = new $className(); + + $this->addFixture($fixture); + } + } + } +} diff --git a/vendor/solarium/solarium/src/Support/DataFixtures/Purger.php b/vendor/solarium/solarium/src/Support/DataFixtures/Purger.php new file mode 100644 index 000000000..38fbc446c --- /dev/null +++ b/vendor/solarium/solarium/src/Support/DataFixtures/Purger.php @@ -0,0 +1,44 @@ +client = $client; + } + + /** + * @return bool + */ + public function purge() + { + $update = $this->client->createUpdate(); + + $update->addDeleteQuery($this->deleteQuery); + $update->addCommit(); + + $result = $this->client->update($update); + + return 0 == $result->getStatus(); + } +} diff --git a/vendor/symfony/contracts/.gitignore b/vendor/symfony/contracts/.gitignore new file mode 100644 index 000000000..5414c2c65 --- /dev/null +++ b/vendor/symfony/contracts/.gitignore @@ -0,0 +1,3 @@ +composer.lock +phpunit.xml +vendor/ diff --git a/vendor/symfony/contracts/CHANGELOG.md b/vendor/symfony/contracts/CHANGELOG.md new file mode 100644 index 000000000..fba42d595 --- /dev/null +++ b/vendor/symfony/contracts/CHANGELOG.md @@ -0,0 +1,12 @@ +CHANGELOG +========= + +1.0.0 +----- + + * added `Service\ResetInterface` to provide a way to reset an object to its initial state + * added `Translation\TranslatorInterface` and `Translation\TranslatorTrait` + * added `Cache` contract to extend PSR-6 with tag invalidation, callback-based computation and stampede protection + * added `Service\ServiceSubscriberInterface` to declare the dependencies of a class that consumes a service locator + * added `Service\ServiceSubscriberTrait` to implement `Service\ServiceSubscriberInterface` using methods' return types + * added `Service\ServiceLocatorTrait` to help implement PSR-11 service locators diff --git a/vendor/symfony/contracts/Cache/CacheInterface.php b/vendor/symfony/contracts/Cache/CacheInterface.php new file mode 100644 index 000000000..4b1686b87 --- /dev/null +++ b/vendor/symfony/contracts/Cache/CacheInterface.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Cache; + +use Psr\Cache\CacheItemInterface; +use Psr\Cache\InvalidArgumentException; + +/** + * Covers most simple to advanced caching needs. + * + * @author Nicolas Grekas + */ +interface CacheInterface +{ + /** + * Fetches a value from the pool or computes it if not found. + * + * On cache misses, a callback is called that should return the missing value. + * This callback is given a PSR-6 CacheItemInterface instance corresponding to the + * requested key, that could be used e.g. for expiration control. It could also + * be an ItemInterface instance when its additional features are needed. + * + * @param string $key The key of the item to retrieve from the cache + * @param callable|CallbackInterface $callback Should return the computed value for the given key/item + * @param float|null $beta A float that, as it grows, controls the likeliness of triggering + * early expiration. 0 disables it, INF forces immediate expiration. + * The default (or providing null) is implementation dependent but should + * typically be 1.0, which should provide optimal stampede protection. + * See https://en.wikipedia.org/wiki/Cache_stampede#Probabilistic_early_expiration + * @param array &$metadata The metadata of the cached item {@see ItemInterface::getMetadata()} + * + * @return mixed The value corresponding to the provided key + * + * @throws InvalidArgumentException When $key is not valid or when $beta is negative + */ + public function get(string $key, callable $callback, float $beta = null, array &$metadata = null); + + /** + * Removes an item from the pool. + * + * @param string $key The key to delete + * + * @throws InvalidArgumentException When $key is not valid + * + * @return bool True if the item was successfully removed, false if there was any error + */ + public function delete(string $key): bool; +} diff --git a/vendor/symfony/contracts/Cache/CacheTrait.php b/vendor/symfony/contracts/Cache/CacheTrait.php new file mode 100644 index 000000000..d82d96530 --- /dev/null +++ b/vendor/symfony/contracts/Cache/CacheTrait.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Cache; + +use Psr\Cache\CacheItemPoolInterface; +use Psr\Cache\InvalidArgumentException; + +/** + * An implementation of CacheInterface for PSR-6 CacheItemPoolInterface classes. + * + * @author Nicolas Grekas + */ +trait CacheTrait +{ + /** + * {@inheritdoc} + */ + public function get(string $key, callable $callback, float $beta = null, array &$metadata = null) + { + return $this->doGet($this, $key, $callback, $beta, $metadata); + } + + /** + * {@inheritdoc} + */ + public function delete(string $key): bool + { + return $this->deleteItem($key); + } + + private function doGet(CacheItemPoolInterface $pool, string $key, callable $callback, ?float $beta, array &$metadata = null) + { + if (0 > $beta = $beta ?? 1.0) { + throw new class(sprintf('Argument "$beta" provided to "%s::get()" must be a positive number, %f given.', \get_class($this), $beta)) extends \InvalidArgumentException implements InvalidArgumentException { + }; + } + + $item = $pool->getItem($key); + $recompute = !$item->isHit() || INF === $beta; + $metadata = $item instanceof ItemInterface ? $item->getMetadata() : array(); + + if (!$recompute && $metadata) { + $expiry = $metadata[ItemInterface::METADATA_EXPIRY] ?? false; + $ctime = $metadata[ItemInterface::METADATA_CTIME] ?? false; + + if ($recompute = $ctime && $expiry && $expiry <= microtime(true) - $ctime / 1000 * $beta * log(random_int(1, PHP_INT_MAX) / PHP_INT_MAX)) { + // force applying defaultLifetime to expiry + $item->expiresAt(null); + } + } + + if ($recompute) { + $save = true; + $item->set($callback($item, $save)); + if ($save) { + $pool->save($item); + } + } + + return $item->get(); + } +} diff --git a/vendor/symfony/contracts/Cache/CallbackInterface.php b/vendor/symfony/contracts/Cache/CallbackInterface.php new file mode 100644 index 000000000..7dae2aac3 --- /dev/null +++ b/vendor/symfony/contracts/Cache/CallbackInterface.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Cache; + +use Psr\Cache\CacheItemInterface; + +/** + * Computes and returns the cached value of an item. + * + * @author Nicolas Grekas + */ +interface CallbackInterface +{ + /** + * @param CacheItemInterface|ItemInterface $item The item to compute the value for + * @param bool &$save Should be set to false when the value should not be saved in the pool + * + * @return mixed The computed value for the passed item + */ + public function __invoke(CacheItemInterface $item, bool &$save); +} diff --git a/vendor/symfony/contracts/Cache/ItemInterface.php b/vendor/symfony/contracts/Cache/ItemInterface.php new file mode 100644 index 000000000..4884a2fff --- /dev/null +++ b/vendor/symfony/contracts/Cache/ItemInterface.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Cache; + +use Psr\Cache\CacheException; +use Psr\Cache\CacheItemInterface; +use Psr\Cache\InvalidArgumentException; + +/** + * Augments PSR-6's CacheItemInterface with support for tags and metadata. + * + * @author Nicolas Grekas + */ +interface ItemInterface extends CacheItemInterface +{ + /** + * References the Unix timestamp stating when the item will expire. + */ + const METADATA_EXPIRY = 'expiry'; + + /** + * References the time the item took to be created, in milliseconds. + */ + const METADATA_CTIME = 'ctime'; + + /** + * References the list of tags that were assigned to the item, as string[]. + */ + const METADATA_TAGS = 'tags'; + + /** + * Adds a tag to a cache item. + * + * Tags are strings that follow the same validation rules as keys. + * + * @param string|string[] $tags A tag or array of tags + * + * @return $this + * + * @throws InvalidArgumentException When $tag is not valid + * @throws CacheException When the item comes from a pool that is not tag-aware + */ + public function tag($tags): self; + + /** + * Returns a list of metadata info that were saved alongside with the cached value. + * + * See ItemInterface::METADATA_* consts for keys potentially found in the returned array. + */ + public function getMetadata(): array; +} diff --git a/vendor/symfony/contracts/Cache/TagAwareCacheInterface.php b/vendor/symfony/contracts/Cache/TagAwareCacheInterface.php new file mode 100644 index 000000000..7c4cf1111 --- /dev/null +++ b/vendor/symfony/contracts/Cache/TagAwareCacheInterface.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Cache; + +use Psr\Cache\InvalidArgumentException; + +/** + * Allows invalidating cached items using tags. + * + * @author Nicolas Grekas + */ +interface TagAwareCacheInterface extends CacheInterface +{ + /** + * Invalidates cached items using tags. + * + * When implemented on a PSR-6 pool, invalidation should not apply + * to deferred items. Instead, they should be committed as usual. + * This allows replacing old tagged values by new ones without + * race conditions. + * + * @param string[] $tags An array of tags to invalidate + * + * @return bool True on success + * + * @throws InvalidArgumentException When $tags is not valid + */ + public function invalidateTags(array $tags); +} diff --git a/vendor/symfony/contracts/LICENSE b/vendor/symfony/contracts/LICENSE new file mode 100644 index 000000000..ad399a798 --- /dev/null +++ b/vendor/symfony/contracts/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/contracts/README.md b/vendor/symfony/contracts/README.md new file mode 100644 index 000000000..9cb73af23 --- /dev/null +++ b/vendor/symfony/contracts/README.md @@ -0,0 +1,70 @@ +Symfony Contracts +================= + +A set of abstractions extracted out of the Symfony components. + +Can be used to build on semantics that the Symfony components proved useful - and +that already have battle tested implementations. + +Design Principles +----------------- + + * contracts are split by domain, each into their own sub-namespaces; + * contracts are small and consistent sets of PHP interfaces, traits, normative + docblocks and reference test suites when applicable, etc.; + * all contracts must have a proven implementation to enter this repository; + * they must be backward compatible with existing Symfony components. + +Packages that implement specific contracts should list them in the "provide" +section of their "composer.json" file, using the `symfony/*-contracts-implementation` +convention (e.g. `"provide": { "symfony/cache-contracts-implementation": "1.0" }`). + +FAQ +--- + +### How to use this package? + +The abstractions in this package are useful to achieve loose coupling and +interoperability. By using the provided interfaces as type hints, you are able +to reuse any implementations that match their contracts. It could be a Symfony +component, or another one provided by the PHP community at large. + +Depending on their semantics, some interfaces can be combined with autowiring to +seamlessly inject a service in your classes. + +Others might be useful as labeling interfaces, to hint about a specific behavior +that could be enabled when using autoconfiguration or manual service tagging (or +any other means provided by your framework.) + +### How is this different from PHP-FIG's PSRs? + +When applicable, the provided contracts are built on top of PHP-FIG's PSRs. But +the group has different goals and different processes. Here, we're focusing on +providing abstractions that are useful on their own while still compatible with +implementations provided by Symfony. Although not the main target, we hope that +the declared contracts will directly or indirectly contribute to the PHP-FIG. + +### Why isn't this package split into several packages? + +Putting all interfaces in one package eases discoverability and dependency +management. Instead of dealing with a myriad of small packages and the +corresponding matrix of versions, you just need to deal with one package and one +version. Also when using IDE autocompletion or just reading the source code, it +makes it easier to figure out which contracts are provided. + +There are two downsides to this approach: you may have unused files in your +`vendor/` directory, and in the future, it will be impossible to use two +different sub-namespaces in different major versions of the package. For the +"unused files" downside, it has no practical consequences: their file sizes are +very small, and there is no performance overhead at all since they are never +loaded. For major versions, this package follows the Symfony BC + deprecation +policies, with an additional restriction to never remove deprecated interfaces. + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/contracts.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/vendor/symfony/contracts/Service/ResetInterface.php b/vendor/symfony/contracts/Service/ResetInterface.php new file mode 100644 index 000000000..1af1075ee --- /dev/null +++ b/vendor/symfony/contracts/Service/ResetInterface.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +/** + * Provides a way to reset an object to its initial state. + * + * When calling the "reset()" method on an object, it should be put back to its + * initial state. This usually means clearing any internal buffers and forwarding + * the call to internal dependencies. All properties of the object should be put + * back to the same state it had when it was first ready to use. + * + * This method could be called, for example, to recycle objects that are used as + * services, so that they can be used to handle several requests in the same + * process loop (note that we advise making your services stateless instead of + * implementing this interface when possible.) + */ +interface ResetInterface +{ + public function reset(); +} diff --git a/vendor/symfony/contracts/Service/ServiceLocatorTrait.php b/vendor/symfony/contracts/Service/ServiceLocatorTrait.php new file mode 100644 index 000000000..8ffa2b4f1 --- /dev/null +++ b/vendor/symfony/contracts/Service/ServiceLocatorTrait.php @@ -0,0 +1,97 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; + +/** + * A trait to help implement PSR-11 service locators. + * + * @author Robin Chalas + * @author Nicolas Grekas + */ +trait ServiceLocatorTrait +{ + private $factories; + private $loading = array(); + + /** + * @param callable[] $factories + */ + public function __construct(array $factories) + { + $this->factories = $factories; + } + + /** + * {@inheritdoc} + */ + public function has($id) + { + return isset($this->factories[$id]); + } + + /** + * {@inheritdoc} + */ + public function get($id) + { + if (!isset($this->factories[$id])) { + throw $this->createNotFoundException($id); + } + + if (isset($this->loading[$id])) { + $ids = array_values($this->loading); + $ids = \array_slice($this->loading, array_search($id, $ids)); + $ids[] = $id; + + throw $this->createCircularReferenceException($id, $ids); + } + + $this->loading[$id] = $id; + try { + return $this->factories[$id]($this); + } finally { + unset($this->loading[$id]); + } + } + + private function createNotFoundException(string $id): NotFoundExceptionInterface + { + if (!$alternatives = array_keys($this->factories)) { + $message = 'is empty...'; + } else { + $last = array_pop($alternatives); + if ($alternatives) { + $message = sprintf('only knows about the "%s" and "%s" services.', implode('", "', $alternatives), $last); + } else { + $message = sprintf('only knows about the "%s" service.', $last); + } + } + + if ($this->loading) { + $message = sprintf('The service "%s" has a dependency on a non-existent service "%s". This locator %s', end($this->loading), $id, $message); + } else { + $message = sprintf('Service "%s" not found: the current service locator %s', $id, $message); + } + + return new class($message) extends \InvalidArgumentException implements NotFoundExceptionInterface { + }; + } + + private function createCircularReferenceException(string $id, array $path): ContainerExceptionInterface + { + return new class(sprintf('Circular reference detected for service "%s", path: "%s".', $id, implode(' -> ', $path))) extends \RuntimeException implements ContainerExceptionInterface { + }; + } +} diff --git a/vendor/symfony/contracts/Service/ServiceSubscriberInterface.php b/vendor/symfony/contracts/Service/ServiceSubscriberInterface.php new file mode 100644 index 000000000..cffccadb5 --- /dev/null +++ b/vendor/symfony/contracts/Service/ServiceSubscriberInterface.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +/** + * A ServiceSubscriber exposes its dependencies via the static {@link getSubscribedServices} method. + * + * The getSubscribedServices method returns an array of service types required by such instances, + * optionally keyed by the service names used internally. Service types that start with an interrogation + * mark "?" are optional, while the other ones are mandatory service dependencies. + * + * The injected service locators SHOULD NOT allow access to any other services not specified by the method. + * + * It is expected that ServiceSubscriber instances consume PSR-11-based service locators internally. + * This interface does not dictate any injection method for these service locators, although constructor + * injection is recommended. + * + * @author Nicolas Grekas + */ +interface ServiceSubscriberInterface +{ + /** + * Returns an array of service types required by such instances, optionally keyed by the service names used internally. + * + * For mandatory dependencies: + * + * * array('logger' => 'Psr\Log\LoggerInterface') means the objects use the "logger" name + * internally to fetch a service which must implement Psr\Log\LoggerInterface. + * * array('loggers' => 'Psr\Log\LoggerInterface[]') means the objects use the "loggers" name + * internally to fetch an iterable of Psr\Log\LoggerInterface instances. + * * array('Psr\Log\LoggerInterface') is a shortcut for + * * array('Psr\Log\LoggerInterface' => 'Psr\Log\LoggerInterface') + * + * otherwise: + * + * * array('logger' => '?Psr\Log\LoggerInterface') denotes an optional dependency + * * array('loggers' => '?Psr\Log\LoggerInterface[]') denotes an optional iterable dependency + * * array('?Psr\Log\LoggerInterface') is a shortcut for + * * array('Psr\Log\LoggerInterface' => '?Psr\Log\LoggerInterface') + * + * @return array The required service types, optionally keyed by service names + */ + public static function getSubscribedServices(); +} diff --git a/vendor/symfony/contracts/Service/ServiceSubscriberTrait.php b/vendor/symfony/contracts/Service/ServiceSubscriberTrait.php new file mode 100644 index 000000000..457ffb26b --- /dev/null +++ b/vendor/symfony/contracts/Service/ServiceSubscriberTrait.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +use Psr\Container\ContainerInterface; + +/** + * Implementation of ServiceSubscriberInterface that determines subscribed services from + * private method return types. Service ids are available as "ClassName::methodName". + * + * @author Kevin Bond + */ +trait ServiceSubscriberTrait +{ + /** @var ContainerInterface */ + private $container; + + public static function getSubscribedServices(): array + { + static $services; + + if (null !== $services) { + return $services; + } + + $services = \is_callable(array('parent', __FUNCTION__)) ? parent::getSubscribedServices() : array(); + + foreach ((new \ReflectionClass(self::class))->getMethods() as $method) { + if ($method->isStatic() || $method->isAbstract() || $method->isGenerator() || $method->isInternal() || $method->getNumberOfRequiredParameters()) { + continue; + } + + if (self::class === $method->getDeclaringClass()->name && ($returnType = $method->getReturnType()) && !$returnType->isBuiltin()) { + $services[self::class.'::'.$method->name] = '?'.$returnType->getName(); + } + } + + return $services; + } + + /** + * @required + */ + public function setContainer(ContainerInterface $container) + { + $this->container = $container; + + if (\is_callable(array('parent', __FUNCTION__))) { + return parent::setContainer($container); + } + } +} diff --git a/vendor/symfony/contracts/Tests/Cache/CacheTraitTest.php b/vendor/symfony/contracts/Tests/Cache/CacheTraitTest.php new file mode 100644 index 000000000..5134a9339 --- /dev/null +++ b/vendor/symfony/contracts/Tests/Cache/CacheTraitTest.php @@ -0,0 +1,165 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Tests\Cache; + +use PHPUnit\Framework\TestCase; +use Psr\Cache\CacheItemInterface; +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Contracts\Cache\CacheTrait; + +/** + * @author Tobias Nyholm + */ +class CacheTraitTest extends TestCase +{ + public function testSave() + { + $item = $this->getMockBuilder(CacheItemInterface::class)->getMock(); + $item->method('set') + ->willReturn($item); + $item->method('isHit') + ->willReturn(false); + + $item->expects($this->once()) + ->method('set') + ->with('computed data'); + + $cache = $this->getMockBuilder(TestPool::class) + ->setMethods(array('getItem', 'save')) + ->getMock(); + $cache->expects($this->once()) + ->method('getItem') + ->with('key') + ->willReturn($item); + $cache->expects($this->once()) + ->method('save'); + + $callback = function (CacheItemInterface $item) { + return 'computed data'; + }; + + $cache->get('key', $callback); + } + + public function testNoCallbackCallOnHit() + { + $item = $this->getMockBuilder(CacheItemInterface::class)->getMock(); + $item->method('isHit') + ->willReturn(true); + + $item->expects($this->never()) + ->method('set'); + + $cache = $this->getMockBuilder(TestPool::class) + ->setMethods(array('getItem', 'save')) + ->getMock(); + + $cache->expects($this->once()) + ->method('getItem') + ->with('key') + ->willReturn($item); + $cache->expects($this->never()) + ->method('save'); + + $callback = function (CacheItemInterface $item) { + $this->assertTrue(false, 'This code should never be reached'); + }; + + $cache->get('key', $callback); + } + + public function testRecomputeOnBetaInf() + { + $item = $this->getMockBuilder(CacheItemInterface::class)->getMock(); + $item->method('set') + ->willReturn($item); + $item->method('isHit') + // We want to recompute even if it is a hit + ->willReturn(true); + + $item->expects($this->once()) + ->method('set') + ->with('computed data'); + + $cache = $this->getMockBuilder(TestPool::class) + ->setMethods(array('getItem', 'save')) + ->getMock(); + + $cache->expects($this->once()) + ->method('getItem') + ->with('key') + ->willReturn($item); + $cache->expects($this->once()) + ->method('save'); + + $callback = function (CacheItemInterface $item) { + return 'computed data'; + }; + + $cache->get('key', $callback, INF); + } + + public function testExceptionOnNegativeBeta() + { + $cache = $this->getMockBuilder(TestPool::class) + ->setMethods(array('getItem', 'save')) + ->getMock(); + + $callback = function (CacheItemInterface $item) { + return 'computed data'; + }; + + $this->expectException(\InvalidArgumentException::class); + $cache->get('key', $callback, -2); + } +} + +class TestPool implements CacheItemPoolInterface +{ + use CacheTrait; + + public function hasItem($key) + { + } + + public function deleteItem($key) + { + } + + public function deleteItems(array $keys = array()) + { + } + + public function getItem($key) + { + } + + public function getItems(array $key = array()) + { + } + + public function saveDeferred(CacheItemInterface $item) + { + } + + public function save(CacheItemInterface $item) + { + } + + public function commit() + { + } + + public function clear() + { + } +} diff --git a/vendor/symfony/contracts/Tests/Service/ServiceLocatorTest.php b/vendor/symfony/contracts/Tests/Service/ServiceLocatorTest.php new file mode 100644 index 000000000..265af909d --- /dev/null +++ b/vendor/symfony/contracts/Tests/Service/ServiceLocatorTest.php @@ -0,0 +1,94 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Tests\Service; + +use PHPUnit\Framework\TestCase; +use Psr\Container\ContainerInterface; +use Symfony\Contracts\Service\ServiceLocatorTrait; + +class ServiceLocatorTest extends TestCase +{ + public function getServiceLocator(array $factories) + { + return new class($factories) implements ContainerInterface { + use ServiceLocatorTrait; + }; + } + + public function testHas() + { + $locator = $this->getServiceLocator(array( + 'foo' => function () { return 'bar'; }, + 'bar' => function () { return 'baz'; }, + function () { return 'dummy'; }, + )); + + $this->assertTrue($locator->has('foo')); + $this->assertTrue($locator->has('bar')); + $this->assertFalse($locator->has('dummy')); + } + + public function testGet() + { + $locator = $this->getServiceLocator(array( + 'foo' => function () { return 'bar'; }, + 'bar' => function () { return 'baz'; }, + )); + + $this->assertSame('bar', $locator->get('foo')); + $this->assertSame('baz', $locator->get('bar')); + } + + public function testGetDoesNotMemoize() + { + $i = 0; + $locator = $this->getServiceLocator(array( + 'foo' => function () use (&$i) { + ++$i; + + return 'bar'; + }, + )); + + $this->assertSame('bar', $locator->get('foo')); + $this->assertSame('bar', $locator->get('foo')); + $this->assertSame(2, $i); + } + + /** + * @expectedException \Psr\Container\NotFoundExceptionInterface + * @expectedExceptionMessage The service "foo" has a dependency on a non-existent service "bar". This locator only knows about the "foo" service. + */ + public function testThrowsOnUndefinedInternalService() + { + $locator = $this->getServiceLocator(array( + 'foo' => function () use (&$locator) { return $locator->get('bar'); }, + )); + + $locator->get('foo'); + } + + /** + * @expectedException \Psr\Container\ContainerExceptionInterface + * @expectedExceptionMessage Circular reference detected for service "bar", path: "bar -> baz -> bar". + */ + public function testThrowsOnCircularReference() + { + $locator = $this->getServiceLocator(array( + 'foo' => function () use (&$locator) { return $locator->get('bar'); }, + 'bar' => function () use (&$locator) { return $locator->get('baz'); }, + 'baz' => function () use (&$locator) { return $locator->get('bar'); }, + )); + + $locator->get('foo'); + } +} diff --git a/vendor/symfony/contracts/Tests/Service/ServiceSubscriberTraitTest.php b/vendor/symfony/contracts/Tests/Service/ServiceSubscriberTraitTest.php new file mode 100644 index 000000000..c7742c65d --- /dev/null +++ b/vendor/symfony/contracts/Tests/Service/ServiceSubscriberTraitTest.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Tests\Service; + +use PHPUnit\Framework\TestCase; +use Psr\Container\ContainerInterface; +use Symfony\Contracts\Service\ServiceLocatorTrait; +use Symfony\Contracts\Service\ServiceSubscriberInterface; +use Symfony\Contracts\Service\ServiceSubscriberTrait; + +class ServiceSubscriberTraitTest extends TestCase +{ + public function testMethodsOnParentsAndChildrenAreIgnoredInGetSubscribedServices() + { + $expected = array(TestService::class.'::aService' => '?Symfony\Contracts\Tests\Service\Service2'); + + $this->assertEquals($expected, ChildTestService::getSubscribedServices()); + } + + public function testSetContainerIsCalledOnParent() + { + $container = new class(array()) implements ContainerInterface { + use ServiceLocatorTrait; + }; + + $this->assertSame($container, (new TestService())->setContainer($container)); + } +} + +class ParentTestService +{ + public function aParentService(): Service1 + { + } + + public function setContainer(ContainerInterface $container) + { + return $container; + } +} + +class TestService extends ParentTestService implements ServiceSubscriberInterface +{ + use ServiceSubscriberTrait; + + public function aService(): Service2 + { + } +} + +class ChildTestService extends TestService +{ + public function aChildService(): Service3 + { + } +} diff --git a/vendor/symfony/contracts/Tests/Translation/TranslatorTest.php b/vendor/symfony/contracts/Tests/Translation/TranslatorTest.php new file mode 100644 index 000000000..a3b67dfe5 --- /dev/null +++ b/vendor/symfony/contracts/Tests/Translation/TranslatorTest.php @@ -0,0 +1,353 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Tests\Translation; + +use PHPUnit\Framework\TestCase; +use Symfony\Contracts\Translation\TranslatorInterface; +use Symfony\Contracts\Translation\TranslatorTrait; + +/** + * Test should cover all languages mentioned on http://translate.sourceforge.net/wiki/l10n/pluralforms + * and Plural forms mentioned on http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms. + * + * See also https://developer.mozilla.org/en/Localization_and_Plurals which mentions 15 rules having a maximum of 6 forms. + * The mozilla code is also interesting to check for. + * + * As mentioned by chx http://drupal.org/node/1273968 we can cover all by testing number from 0 to 199 + * + * The goal to cover all languages is to far fetched so this test case is smaller. + * + * @author Clemens Tolboom clemens@build2be.nl + */ +class TranslatorTest extends TestCase +{ + public function getTranslator() + { + return new class() implements TranslatorInterface { + use TranslatorTrait; + }; + } + + /** + * @dataProvider getTransTests + */ + public function testTrans($expected, $id, $parameters) + { + $translator = $this->getTranslator(); + + $this->assertEquals($expected, $translator->trans($id, $parameters)); + } + + /** + * @dataProvider getTransChoiceTests + */ + public function testTransChoiceWithExplicitLocale($expected, $id, $number) + { + $translator = $this->getTranslator(); + $translator->setLocale('en'); + + $this->assertEquals($expected, $translator->trans($id, array('%count%' => $number))); + } + + /** + * @dataProvider getTransChoiceTests + */ + public function testTransChoiceWithDefaultLocale($expected, $id, $number) + { + \Locale::setDefault('en'); + + $translator = $this->getTranslator(); + + $this->assertEquals($expected, $translator->trans($id, array('%count%' => $number))); + } + + public function testGetSetLocale() + { + $translator = $this->getTranslator(); + $translator->setLocale('en'); + + $this->assertEquals('en', $translator->getLocale()); + } + + /** + * @requires extension intl + */ + public function testGetLocaleReturnsDefaultLocaleIfNotSet() + { + $translator = $this->getTranslator(); + + \Locale::setDefault('pt_BR'); + $this->assertEquals('pt_BR', $translator->getLocale()); + + \Locale::setDefault('en'); + $this->assertEquals('en', $translator->getLocale()); + } + + public function getTransTests() + { + return array( + array('Symfony is great!', 'Symfony is great!', array()), + array('Symfony is awesome!', 'Symfony is %what%!', array('%what%' => 'awesome')), + ); + } + + public function getTransChoiceTests() + { + return array( + array('There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0), + array('There is one apple', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 1), + array('There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10), + array('There are 0 apples', 'There is 1 apple|There are %count% apples', 0), + array('There is 1 apple', 'There is 1 apple|There are %count% apples', 1), + array('There are 10 apples', 'There is 1 apple|There are %count% apples', 10), + // custom validation messages may be coded with a fixed value + array('There are 2 apples', 'There are 2 apples', 2), + ); + } + + /** + * @dataProvider getInternal + */ + public function testInterval($expected, $number, $interval) + { + $translator = $this->getTranslator(); + + $this->assertEquals($expected, $translator->trans($interval.' foo|[1,Inf[ bar', array('%count%' => $number))); + } + + public function getInternal() + { + return array( + array('foo', 3, '{1,2, 3 ,4}'), + array('bar', 10, '{1,2, 3 ,4}'), + array('bar', 3, '[1,2]'), + array('foo', 1, '[1,2]'), + array('foo', 2, '[1,2]'), + array('bar', 1, ']1,2['), + array('bar', 2, ']1,2['), + array('foo', log(0), '[-Inf,2['), + array('foo', -log(0), '[-2,+Inf]'), + ); + } + + /** + * @dataProvider getChooseTests + */ + public function testChoose($expected, $id, $number) + { + $translator = $this->getTranslator(); + + $this->assertEquals($expected, $translator->trans($id, array('%count%' => $number))); + } + + public function testReturnMessageIfExactlyOneStandardRuleIsGiven() + { + $translator = $this->getTranslator(); + + $this->assertEquals('There are two apples', $translator->trans('There are two apples', array('%count%' => 2))); + } + + /** + * @dataProvider getNonMatchingMessages + * @expectedException \InvalidArgumentException + */ + public function testThrowExceptionIfMatchingMessageCannotBeFound($id, $number) + { + $translator = $this->getTranslator(); + + $translator->trans($id, array('%count%' => $number)); + } + + public function getNonMatchingMessages() + { + return array( + array('{0} There are no apples|{1} There is one apple', 2), + array('{1} There is one apple|]1,Inf] There are %count% apples', 0), + array('{1} There is one apple|]2,Inf] There are %count% apples', 2), + array('{0} There are no apples|There is one apple', 2), + ); + } + + public function getChooseTests() + { + return array( + array('There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0), + array('There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0), + array('There are no apples', '{0}There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0), + + array('There is one apple', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 1), + + array('There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10), + array('There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf]There are %count% apples', 10), + array('There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10), + + array('There are 0 apples', 'There is one apple|There are %count% apples', 0), + array('There is one apple', 'There is one apple|There are %count% apples', 1), + array('There are 10 apples', 'There is one apple|There are %count% apples', 10), + + array('There are 0 apples', 'one: There is one apple|more: There are %count% apples', 0), + array('There is one apple', 'one: There is one apple|more: There are %count% apples', 1), + array('There are 10 apples', 'one: There is one apple|more: There are %count% apples', 10), + + array('There are no apples', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 0), + array('There is one apple', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 1), + array('There are 10 apples', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 10), + + array('', '{0}|{1} There is one apple|]1,Inf] There are %count% apples', 0), + array('', '{0} There are no apples|{1}|]1,Inf] There are %count% apples', 1), + + // Indexed only tests which are Gettext PoFile* compatible strings. + array('There are 0 apples', 'There is one apple|There are %count% apples', 0), + array('There is one apple', 'There is one apple|There are %count% apples', 1), + array('There are 2 apples', 'There is one apple|There are %count% apples', 2), + + // Tests for float numbers + array('There is almost one apple', '{0} There are no apples|]0,1[ There is almost one apple|{1} There is one apple|[1,Inf] There is more than one apple', 0.7), + array('There is one apple', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 1), + array('There is more than one apple', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 1.7), + array('There are no apples', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0), + array('There are no apples', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0.0), + array('There are no apples', '{0.0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0), + + // Test texts with new-lines + // with double-quotes and \n in id & double-quotes and actual newlines in text + array("This is a text with a\n new-line in it. Selector = 0.", '{0}This is a text with a + new-line in it. Selector = 0.|{1}This is a text with a + new-line in it. Selector = 1.|[1,Inf]This is a text with a + new-line in it. Selector > 1.', 0), + // with double-quotes and \n in id and single-quotes and actual newlines in text + array("This is a text with a\n new-line in it. Selector = 1.", '{0}This is a text with a + new-line in it. Selector = 0.|{1}This is a text with a + new-line in it. Selector = 1.|[1,Inf]This is a text with a + new-line in it. Selector > 1.', 1), + array("This is a text with a\n new-line in it. Selector > 1.", '{0}This is a text with a + new-line in it. Selector = 0.|{1}This is a text with a + new-line in it. Selector = 1.|[1,Inf]This is a text with a + new-line in it. Selector > 1.', 5), + // with double-quotes and id split accros lines + array('This is a text with a + new-line in it. Selector = 1.', '{0}This is a text with a + new-line in it. Selector = 0.|{1}This is a text with a + new-line in it. Selector = 1.|[1,Inf]This is a text with a + new-line in it. Selector > 1.', 1), + // with single-quotes and id split accros lines + array('This is a text with a + new-line in it. Selector > 1.', '{0}This is a text with a + new-line in it. Selector = 0.|{1}This is a text with a + new-line in it. Selector = 1.|[1,Inf]This is a text with a + new-line in it. Selector > 1.', 5), + // with single-quotes and \n in text + array('This is a text with a\nnew-line in it. Selector = 0.', '{0}This is a text with a\nnew-line in it. Selector = 0.|{1}This is a text with a\nnew-line in it. Selector = 1.|[1,Inf]This is a text with a\nnew-line in it. Selector > 1.', 0), + // with double-quotes and id split accros lines + array("This is a text with a\nnew-line in it. Selector = 1.", "{0}This is a text with a\nnew-line in it. Selector = 0.|{1}This is a text with a\nnew-line in it. Selector = 1.|[1,Inf]This is a text with a\nnew-line in it. Selector > 1.", 1), + // esacape pipe + array('This is a text with | in it. Selector = 0.', '{0}This is a text with || in it. Selector = 0.|{1}This is a text with || in it. Selector = 1.', 0), + // Empty plural set (2 plural forms) from a .PO file + array('', '|', 1), + // Empty plural set (3 plural forms) from a .PO file + array('', '||', 1), + ); + } + + /** + * @dataProvider failingLangcodes + */ + public function testFailedLangcodes($nplural, $langCodes) + { + $matrix = $this->generateTestData($langCodes); + $this->validateMatrix($nplural, $matrix, false); + } + + /** + * @dataProvider successLangcodes + */ + public function testLangcodes($nplural, $langCodes) + { + $matrix = $this->generateTestData($langCodes); + $this->validateMatrix($nplural, $matrix); + } + + /** + * This array should contain all currently known langcodes. + * + * As it is impossible to have this ever complete we should try as hard as possible to have it almost complete. + * + * @return array + */ + public function successLangcodes() + { + return array( + array('1', array('ay', 'bo', 'cgg', 'dz', 'id', 'ja', 'jbo', 'ka', 'kk', 'km', 'ko', 'ky')), + array('2', array('nl', 'fr', 'en', 'de', 'de_GE', 'hy', 'hy_AM')), + array('3', array('be', 'bs', 'cs', 'hr')), + array('4', array('cy', 'mt', 'sl')), + array('6', array('ar')), + ); + } + + /** + * This array should be at least empty within the near future. + * + * This both depends on a complete list trying to add above as understanding + * the plural rules of the current failing languages. + * + * @return array with nplural together with langcodes + */ + public function failingLangcodes() + { + return array( + array('1', array('fa')), + array('2', array('jbo')), + array('3', array('cbs')), + array('4', array('gd', 'kw')), + array('5', array('ga')), + ); + } + + /** + * We validate only on the plural coverage. Thus the real rules is not tested. + * + * @param string $nplural Plural expected + * @param array $matrix Containing langcodes and their plural index values + * @param bool $expectSuccess + */ + protected function validateMatrix($nplural, $matrix, $expectSuccess = true) + { + foreach ($matrix as $langCode => $data) { + $indexes = array_flip($data); + if ($expectSuccess) { + $this->assertEquals($nplural, \count($indexes), "Langcode '$langCode' has '$nplural' plural forms."); + } else { + $this->assertNotEquals((int) $nplural, \count($indexes), "Langcode '$langCode' has '$nplural' plural forms."); + } + } + } + + protected function generateTestData($langCodes) + { + $translator = new class() { + use TranslatorTrait { + getPluralizationRule as public; + } + }; + + $matrix = array(); + foreach ($langCodes as $langCode) { + for ($count = 0; $count < 200; ++$count) { + $plural = $translator->getPluralizationRule($count, $langCode); + $matrix[$langCode][$count] = $plural; + } + } + + return $matrix; + } +} diff --git a/vendor/symfony/contracts/Translation/LocaleAwareInterface.php b/vendor/symfony/contracts/Translation/LocaleAwareInterface.php new file mode 100644 index 000000000..dbd8894fe --- /dev/null +++ b/vendor/symfony/contracts/Translation/LocaleAwareInterface.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Translation; + +interface LocaleAwareInterface +{ + /** + * Sets the current locale. + * + * @param string $locale The locale + * + * @throws \InvalidArgumentException If the locale contains invalid characters + */ + public function setLocale($locale); + + /** + * Returns the current locale. + * + * @return string The locale + */ + public function getLocale(); +} diff --git a/vendor/symfony/contracts/Translation/TranslatorInterface.php b/vendor/symfony/contracts/Translation/TranslatorInterface.php new file mode 100644 index 000000000..2bdc415cb --- /dev/null +++ b/vendor/symfony/contracts/Translation/TranslatorInterface.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Translation; + +/** + * @author Fabien Potencier + */ +interface TranslatorInterface +{ + /** + * Translates the given message. + * + * When a number is provided as a parameter named "%count%", the message is parsed for plural + * forms and a translation is chosen according to this number using the following rules: + * + * Given a message with different plural translations separated by a + * pipe (|), this method returns the correct portion of the message based + * on the given number, locale and the pluralization rules in the message + * itself. + * + * The message supports two different types of pluralization rules: + * + * interval: {0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples + * indexed: There is one apple|There are %count% apples + * + * The indexed solution can also contain labels (e.g. one: There is one apple). + * This is purely for making the translations more clear - it does not + * affect the functionality. + * + * The two methods can also be mixed: + * {0} There are no apples|one: There is one apple|more: There are %count% apples + * + * An interval can represent a finite set of numbers: + * {1,2,3,4} + * + * An interval can represent numbers between two numbers: + * [1, +Inf] + * ]-1,2[ + * + * The left delimiter can be [ (inclusive) or ] (exclusive). + * The right delimiter can be [ (exclusive) or ] (inclusive). + * Beside numbers, you can use -Inf and +Inf for the infinite. + * + * @see https://en.wikipedia.org/wiki/ISO_31-11 + * + * @param string $id The message id (may also be an object that can be cast to string) + * @param array $parameters An array of parameters for the message + * @param string|null $domain The domain for the message or null to use the default + * @param string|null $locale The locale or null to use the default + * + * @return string The translated string + * + * @throws \InvalidArgumentException If the locale contains invalid characters + */ + public function trans($id, array $parameters = array(), $domain = null, $locale = null); +} diff --git a/vendor/symfony/contracts/Translation/TranslatorTrait.php b/vendor/symfony/contracts/Translation/TranslatorTrait.php new file mode 100644 index 000000000..4e53fbd42 --- /dev/null +++ b/vendor/symfony/contracts/Translation/TranslatorTrait.php @@ -0,0 +1,255 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Translation; + +use Symfony\Component\Translation\Exception\InvalidArgumentException; + +/** + * A trait to help implement TranslatorInterface and LocaleAwareInterface. + * + * @author Fabien Potencier + */ +trait TranslatorTrait +{ + private $locale; + + /** + * {@inheritdoc} + */ + public function setLocale($locale) + { + $this->locale = (string) $locale; + } + + /** + * {@inheritdoc} + */ + public function getLocale() + { + return $this->locale ?: \Locale::getDefault(); + } + + /** + * {@inheritdoc} + */ + public function trans($id, array $parameters = array(), $domain = null, $locale = null) + { + $id = (string) $id; + + if (!isset($parameters['%count%']) || !is_numeric($parameters['%count%'])) { + return strtr($id, $parameters); + } + + $number = (float) $parameters['%count%']; + $locale = (string) $locale ?: $this->getLocale(); + + $parts = array(); + if (preg_match('/^\|++$/', $id)) { + $parts = explode('|', $id); + } elseif (preg_match_all('/(?:\|\||[^\|])++/', $id, $matches)) { + $parts = $matches[0]; + } + + $intervalRegexp = <<<'EOF' +/^(?P + ({\s* + (\-?\d+(\.\d+)?[\s*,\s*\-?\d+(\.\d+)?]*) + \s*}) + + | + + (?P[\[\]]) + \s* + (?P-Inf|\-?\d+(\.\d+)?) + \s*,\s* + (?P\+?Inf|\-?\d+(\.\d+)?) + \s* + (?P[\[\]]) +)\s*(?P.*?)$/xs +EOF; + + $standardRules = array(); + foreach ($parts as $part) { + $part = trim(str_replace('||', '|', $part)); + + // try to match an explicit rule, then fallback to the standard ones + if (preg_match($intervalRegexp, $part, $matches)) { + if ($matches[2]) { + foreach (explode(',', $matches[3]) as $n) { + if ($number == $n) { + return strtr($matches['message'], $parameters); + } + } + } else { + $leftNumber = '-Inf' === $matches['left'] ? -INF : (float) $matches['left']; + $rightNumber = \is_numeric($matches['right']) ? (float) $matches['right'] : INF; + + if (('[' === $matches['left_delimiter'] ? $number >= $leftNumber : $number > $leftNumber) + && (']' === $matches['right_delimiter'] ? $number <= $rightNumber : $number < $rightNumber) + ) { + return strtr($matches['message'], $parameters); + } + } + } elseif (preg_match('/^\w+\:\s*(.*?)$/', $part, $matches)) { + $standardRules[] = $matches[1]; + } else { + $standardRules[] = $part; + } + } + + $position = $this->getPluralizationRule($number, $locale); + + if (!isset($standardRules[$position])) { + // when there's exactly one rule given, and that rule is a standard + // rule, use this rule + if (1 === \count($parts) && isset($standardRules[0])) { + return strtr($standardRules[0], $parameters); + } + + $message = sprintf('Unable to choose a translation for "%s" with locale "%s" for value "%d". Double check that this translation has the correct plural options (e.g. "There is one apple|There are %%count%% apples").', $id, $locale, $number); + + if (\class_exists(InvalidArgumentException::class)) { + throw new InvalidArgumentException($message); + } + + throw new \InvalidArgumentException($message); + } + + return strtr($standardRules[$position], $parameters); + } + + /** + * Returns the plural position to use for the given locale and number. + * + * The plural rules are derived from code of the Zend Framework (2010-09-25), + * which is subject to the new BSD license (http://framework.zend.com/license/new-bsd). + * Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + */ + private function getPluralizationRule(int $number, string $locale): int + { + switch ('pt_BR' !== $locale && \strlen($locale) > 3 ? substr($locale, 0, strrpos($locale, '_')) : $locale) { + case 'af': + case 'bn': + case 'bg': + case 'ca': + case 'da': + case 'de': + case 'el': + case 'en': + case 'eo': + case 'es': + case 'et': + case 'eu': + case 'fa': + case 'fi': + case 'fo': + case 'fur': + case 'fy': + case 'gl': + case 'gu': + case 'ha': + case 'he': + case 'hu': + case 'is': + case 'it': + case 'ku': + case 'lb': + case 'ml': + case 'mn': + case 'mr': + case 'nah': + case 'nb': + case 'ne': + case 'nl': + case 'nn': + case 'no': + case 'oc': + case 'om': + case 'or': + case 'pa': + case 'pap': + case 'ps': + case 'pt': + case 'so': + case 'sq': + case 'sv': + case 'sw': + case 'ta': + case 'te': + case 'tk': + case 'ur': + case 'zu': + return (1 == $number) ? 0 : 1; + + case 'am': + case 'bh': + case 'fil': + case 'fr': + case 'gun': + case 'hi': + case 'hy': + case 'ln': + case 'mg': + case 'nso': + case 'pt_BR': + case 'ti': + case 'wa': + return ((0 == $number) || (1 == $number)) ? 0 : 1; + + case 'be': + case 'bs': + case 'hr': + case 'ru': + case 'sh': + case 'sr': + case 'uk': + return ((1 == $number % 10) && (11 != $number % 100)) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2); + + case 'cs': + case 'sk': + return (1 == $number) ? 0 : ((($number >= 2) && ($number <= 4)) ? 1 : 2); + + case 'ga': + return (1 == $number) ? 0 : ((2 == $number) ? 1 : 2); + + case 'lt': + return ((1 == $number % 10) && (11 != $number % 100)) ? 0 : ((($number % 10 >= 2) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2); + + case 'sl': + return (1 == $number % 100) ? 0 : ((2 == $number % 100) ? 1 : (((3 == $number % 100) || (4 == $number % 100)) ? 2 : 3)); + + case 'mk': + return (1 == $number % 10) ? 0 : 1; + + case 'mt': + return (1 == $number) ? 0 : (((0 == $number) || (($number % 100 > 1) && ($number % 100 < 11))) ? 1 : ((($number % 100 > 10) && ($number % 100 < 20)) ? 2 : 3)); + + case 'lv': + return (0 == $number) ? 0 : (((1 == $number % 10) && (11 != $number % 100)) ? 1 : 2); + + case 'pl': + return (1 == $number) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 12) || ($number % 100 > 14))) ? 1 : 2); + + case 'cy': + return (1 == $number) ? 0 : ((2 == $number) ? 1 : (((8 == $number) || (11 == $number)) ? 2 : 3)); + + case 'ro': + return (1 == $number) ? 0 : (((0 == $number) || (($number % 100 > 0) && ($number % 100 < 20))) ? 1 : 2); + + case 'ar': + return (0 == $number) ? 0 : ((1 == $number) ? 1 : ((2 == $number) ? 2 : ((($number % 100 >= 3) && ($number % 100 <= 10)) ? 3 : ((($number % 100 >= 11) && ($number % 100 <= 99)) ? 4 : 5)))); + + default: + return 0; + } + } +} diff --git a/vendor/symfony/contracts/composer.json b/vendor/symfony/contracts/composer.json new file mode 100644 index 000000000..2f198a0c3 --- /dev/null +++ b/vendor/symfony/contracts/composer.json @@ -0,0 +1,44 @@ +{ + "name": "symfony/contracts", + "type": "library", + "description": "A set of abstractions extracted out of the Symfony components", + "keywords": ["abstractions", "contracts", "decoupling", "interfaces", "interoperability", "standards"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": "^7.1.3" + }, + "require-dev": { + "psr/cache": "^1.0", + "psr/container": "^1.0" + }, + "suggest": { + "psr/cache": "When using the Cache contracts", + "psr/container": "When using the Service contracts", + "symfony/cache-contracts-implementation": "", + "symfony/service-contracts-implementation": "", + "symfony/translation-contracts-implementation": "" + }, + "autoload": { + "psr-4": { "Symfony\\Contracts\\": "" }, + "exclude-from-classmap": [ + "**/Tests/" + ] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + } +} diff --git a/vendor/symfony/contracts/phpunit.xml.dist b/vendor/symfony/contracts/phpunit.xml.dist new file mode 100644 index 000000000..e222d9f5a --- /dev/null +++ b/vendor/symfony/contracts/phpunit.xml.dist @@ -0,0 +1,31 @@ + + + + + + + + + + ./Tests/ + + + + + + ./ + + ./Tests + ./vendor + + + + + diff --git a/vendor/symfony/event-dispatcher/.gitignore b/vendor/symfony/event-dispatcher/.gitignore new file mode 100644 index 000000000..c49a5d8df --- /dev/null +++ b/vendor/symfony/event-dispatcher/.gitignore @@ -0,0 +1,3 @@ +vendor/ +composer.lock +phpunit.xml diff --git a/vendor/symfony/event-dispatcher/CHANGELOG.md b/vendor/symfony/event-dispatcher/CHANGELOG.md new file mode 100644 index 000000000..b581d3143 --- /dev/null +++ b/vendor/symfony/event-dispatcher/CHANGELOG.md @@ -0,0 +1,55 @@ +CHANGELOG +========= + +4.1.0 +----- + + * added support for invokable event listeners tagged with `kernel.event_listener` by default + * The `TraceableEventDispatcher::getOrphanedEvents()` method has been added. + * The `TraceableEventDispatcherInterface` has been deprecated. + +4.0.0 +----- + + * removed the `ContainerAwareEventDispatcher` class + * added the `reset()` method to the `TraceableEventDispatcherInterface` + +3.4.0 +----- + + * Implementing `TraceableEventDispatcherInterface` without the `reset()` method has been deprecated. + +3.3.0 +----- + + * The ContainerAwareEventDispatcher class has been deprecated. Use EventDispatcher with closure factories instead. + +3.0.0 +----- + + * The method `getListenerPriority($eventName, $listener)` has been added to the + `EventDispatcherInterface`. + * The methods `Event::setDispatcher()`, `Event::getDispatcher()`, `Event::setName()` + and `Event::getName()` have been removed. + The event dispatcher and the event name are passed to the listener call. + +2.5.0 +----- + + * added Debug\TraceableEventDispatcher (originally in HttpKernel) + * changed Debug\TraceableEventDispatcherInterface to extend EventDispatcherInterface + * added RegisterListenersPass (originally in HttpKernel) + +2.1.0 +----- + + * added TraceableEventDispatcherInterface + * added ContainerAwareEventDispatcher + * added a reference to the EventDispatcher on the Event + * added a reference to the Event name on the event + * added fluid interface to the dispatch() method which now returns the Event + object + * added GenericEvent event class + * added the possibility for subscribers to subscribe several times for the + same event + * added ImmutableEventDispatcher diff --git a/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php b/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php new file mode 100644 index 000000000..513d87c7e --- /dev/null +++ b/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php @@ -0,0 +1,353 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Debug; + +use Psr\Log\LoggerInterface; +use Symfony\Component\EventDispatcher\Event; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\Stopwatch\Stopwatch; + +/** + * Collects some data about event listeners. + * + * This event dispatcher delegates the dispatching to another one. + * + * @author Fabien Potencier + */ +class TraceableEventDispatcher implements TraceableEventDispatcherInterface +{ + protected $logger; + protected $stopwatch; + + private $callStack; + private $dispatcher; + private $wrappedListeners; + private $orphanedEvents; + + public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $stopwatch, LoggerInterface $logger = null) + { + $this->dispatcher = $dispatcher; + $this->stopwatch = $stopwatch; + $this->logger = $logger; + $this->wrappedListeners = []; + $this->orphanedEvents = []; + } + + /** + * {@inheritdoc} + */ + public function addListener($eventName, $listener, $priority = 0) + { + $this->dispatcher->addListener($eventName, $listener, $priority); + } + + /** + * {@inheritdoc} + */ + public function addSubscriber(EventSubscriberInterface $subscriber) + { + $this->dispatcher->addSubscriber($subscriber); + } + + /** + * {@inheritdoc} + */ + public function removeListener($eventName, $listener) + { + if (isset($this->wrappedListeners[$eventName])) { + foreach ($this->wrappedListeners[$eventName] as $index => $wrappedListener) { + if ($wrappedListener->getWrappedListener() === $listener) { + $listener = $wrappedListener; + unset($this->wrappedListeners[$eventName][$index]); + break; + } + } + } + + return $this->dispatcher->removeListener($eventName, $listener); + } + + /** + * {@inheritdoc} + */ + public function removeSubscriber(EventSubscriberInterface $subscriber) + { + return $this->dispatcher->removeSubscriber($subscriber); + } + + /** + * {@inheritdoc} + */ + public function getListeners($eventName = null) + { + return $this->dispatcher->getListeners($eventName); + } + + /** + * {@inheritdoc} + */ + public function getListenerPriority($eventName, $listener) + { + // we might have wrapped listeners for the event (if called while dispatching) + // in that case get the priority by wrapper + if (isset($this->wrappedListeners[$eventName])) { + foreach ($this->wrappedListeners[$eventName] as $index => $wrappedListener) { + if ($wrappedListener->getWrappedListener() === $listener) { + return $this->dispatcher->getListenerPriority($eventName, $wrappedListener); + } + } + } + + return $this->dispatcher->getListenerPriority($eventName, $listener); + } + + /** + * {@inheritdoc} + */ + public function hasListeners($eventName = null) + { + return $this->dispatcher->hasListeners($eventName); + } + + /** + * {@inheritdoc} + */ + public function dispatch($eventName, Event $event = null) + { + if (null === $this->callStack) { + $this->callStack = new \SplObjectStorage(); + } + + if (null === $event) { + $event = new Event(); + } + + if (null !== $this->logger && $event->isPropagationStopped()) { + $this->logger->debug(sprintf('The "%s" event is already stopped. No listeners have been called.', $eventName)); + } + + $this->preProcess($eventName); + try { + $this->preDispatch($eventName, $event); + try { + $e = $this->stopwatch->start($eventName, 'section'); + try { + $this->dispatcher->dispatch($eventName, $event); + } finally { + if ($e->isStarted()) { + $e->stop(); + } + } + } finally { + $this->postDispatch($eventName, $event); + } + } finally { + $this->postProcess($eventName); + } + + return $event; + } + + /** + * {@inheritdoc} + */ + public function getCalledListeners() + { + if (null === $this->callStack) { + return []; + } + + $called = []; + foreach ($this->callStack as $listener) { + list($eventName) = $this->callStack->getInfo(); + + $called[] = $listener->getInfo($eventName); + } + + return $called; + } + + /** + * {@inheritdoc} + */ + public function getNotCalledListeners() + { + try { + $allListeners = $this->getListeners(); + } catch (\Exception $e) { + if (null !== $this->logger) { + $this->logger->info('An exception was thrown while getting the uncalled listeners.', ['exception' => $e]); + } + + // unable to retrieve the uncalled listeners + return []; + } + + $notCalled = []; + foreach ($allListeners as $eventName => $listeners) { + foreach ($listeners as $listener) { + $called = false; + if (null !== $this->callStack) { + foreach ($this->callStack as $calledListener) { + if ($calledListener->getWrappedListener() === $listener) { + $called = true; + + break; + } + } + } + + if (!$called) { + if (!$listener instanceof WrappedListener) { + $listener = new WrappedListener($listener, null, $this->stopwatch, $this); + } + $notCalled[] = $listener->getInfo($eventName); + } + } + } + + uasort($notCalled, [$this, 'sortNotCalledListeners']); + + return $notCalled; + } + + public function getOrphanedEvents(): array + { + return $this->orphanedEvents; + } + + public function reset() + { + $this->callStack = null; + $this->orphanedEvents = []; + } + + /** + * Proxies all method calls to the original event dispatcher. + * + * @param string $method The method name + * @param array $arguments The method arguments + * + * @return mixed + */ + public function __call($method, $arguments) + { + return $this->dispatcher->{$method}(...$arguments); + } + + /** + * Called before dispatching the event. + * + * @param string $eventName The event name + * @param Event $event The event + */ + protected function preDispatch($eventName, Event $event) + { + } + + /** + * Called after dispatching the event. + * + * @param string $eventName The event name + * @param Event $event The event + */ + protected function postDispatch($eventName, Event $event) + { + } + + private function preProcess($eventName) + { + if (!$this->dispatcher->hasListeners($eventName)) { + $this->orphanedEvents[] = $eventName; + + return; + } + + foreach ($this->dispatcher->getListeners($eventName) as $listener) { + $priority = $this->getListenerPriority($eventName, $listener); + $wrappedListener = new WrappedListener($listener instanceof WrappedListener ? $listener->getWrappedListener() : $listener, null, $this->stopwatch, $this); + $this->wrappedListeners[$eventName][] = $wrappedListener; + $this->dispatcher->removeListener($eventName, $listener); + $this->dispatcher->addListener($eventName, $wrappedListener, $priority); + $this->callStack->attach($wrappedListener, [$eventName]); + } + } + + private function postProcess($eventName) + { + unset($this->wrappedListeners[$eventName]); + $skipped = false; + foreach ($this->dispatcher->getListeners($eventName) as $listener) { + if (!$listener instanceof WrappedListener) { // #12845: a new listener was added during dispatch. + continue; + } + // Unwrap listener + $priority = $this->getListenerPriority($eventName, $listener); + $this->dispatcher->removeListener($eventName, $listener); + $this->dispatcher->addListener($eventName, $listener->getWrappedListener(), $priority); + + if (null !== $this->logger) { + $context = ['event' => $eventName, 'listener' => $listener->getPretty()]; + } + + if ($listener->wasCalled()) { + if (null !== $this->logger) { + $this->logger->debug('Notified event "{event}" to listener "{listener}".', $context); + } + + if (!isset($this->called[$eventName])) { + $this->called[$eventName] = new \SplObjectStorage(); + } + } else { + $this->callStack->detach($listener); + } + + if (null !== $this->logger && $skipped) { + $this->logger->debug('Listener "{listener}" was not called for event "{event}".', $context); + } + + if ($listener->stoppedPropagation()) { + if (null !== $this->logger) { + $this->logger->debug('Listener "{listener}" stopped propagation of the event "{event}".', $context); + } + + $skipped = true; + } + } + } + + private function sortNotCalledListeners(array $a, array $b) + { + if (0 !== $cmp = strcmp($a['event'], $b['event'])) { + return $cmp; + } + + if (\is_int($a['priority']) && !\is_int($b['priority'])) { + return 1; + } + + if (!\is_int($a['priority']) && \is_int($b['priority'])) { + return -1; + } + + if ($a['priority'] === $b['priority']) { + return 0; + } + + if ($a['priority'] > $b['priority']) { + return -1; + } + + return 1; + } +} diff --git a/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php b/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php new file mode 100644 index 000000000..cd4d7470a --- /dev/null +++ b/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Debug; + +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * @deprecated since Symfony 4.1 + * + * @author Fabien Potencier + */ +interface TraceableEventDispatcherInterface extends EventDispatcherInterface, ResetInterface +{ + /** + * Gets the called listeners. + * + * @return array An array of called listeners + */ + public function getCalledListeners(); + + /** + * Gets the not called listeners. + * + * @return array An array of not called listeners + */ + public function getNotCalledListeners(); +} diff --git a/vendor/symfony/event-dispatcher/Debug/WrappedListener.php b/vendor/symfony/event-dispatcher/Debug/WrappedListener.php new file mode 100644 index 000000000..24e2bb432 --- /dev/null +++ b/vendor/symfony/event-dispatcher/Debug/WrappedListener.php @@ -0,0 +1,125 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Debug; + +use Symfony\Component\EventDispatcher\Event; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\Stopwatch\Stopwatch; +use Symfony\Component\VarDumper\Caster\ClassStub; + +/** + * @author Fabien Potencier + */ +class WrappedListener +{ + private $listener; + private $name; + private $called; + private $stoppedPropagation; + private $stopwatch; + private $dispatcher; + private $pretty; + private $stub; + private $priority; + private static $hasClassStub; + + public function __construct($listener, $name, Stopwatch $stopwatch, EventDispatcherInterface $dispatcher = null) + { + $this->listener = $listener; + $this->stopwatch = $stopwatch; + $this->dispatcher = $dispatcher; + $this->called = false; + $this->stoppedPropagation = false; + + if (\is_array($listener)) { + $this->name = \is_object($listener[0]) ? \get_class($listener[0]) : $listener[0]; + $this->pretty = $this->name.'::'.$listener[1]; + } elseif ($listener instanceof \Closure) { + $r = new \ReflectionFunction($listener); + if (false !== strpos($r->name, '{closure}')) { + $this->pretty = $this->name = 'closure'; + } elseif ($class = $r->getClosureScopeClass()) { + $this->name = $class->name; + $this->pretty = $this->name.'::'.$r->name; + } else { + $this->pretty = $this->name = $r->name; + } + } elseif (\is_string($listener)) { + $this->pretty = $this->name = $listener; + } else { + $this->name = \get_class($listener); + $this->pretty = $this->name.'::__invoke'; + } + + if (null !== $name) { + $this->name = $name; + } + + if (null === self::$hasClassStub) { + self::$hasClassStub = class_exists(ClassStub::class); + } + } + + public function getWrappedListener() + { + return $this->listener; + } + + public function wasCalled() + { + return $this->called; + } + + public function stoppedPropagation() + { + return $this->stoppedPropagation; + } + + public function getPretty() + { + return $this->pretty; + } + + public function getInfo($eventName) + { + if (null === $this->stub) { + $this->stub = self::$hasClassStub ? new ClassStub($this->pretty.'()', $this->listener) : $this->pretty.'()'; + } + + return [ + 'event' => $eventName, + 'priority' => null !== $this->priority ? $this->priority : (null !== $this->dispatcher ? $this->dispatcher->getListenerPriority($eventName, $this->listener) : null), + 'pretty' => $this->pretty, + 'stub' => $this->stub, + ]; + } + + public function __invoke(Event $event, $eventName, EventDispatcherInterface $dispatcher) + { + $dispatcher = $this->dispatcher ?: $dispatcher; + + $this->called = true; + $this->priority = $dispatcher->getListenerPriority($eventName, $this->listener); + + $e = $this->stopwatch->start($this->name, 'event_listener'); + + ($this->listener)($event, $eventName, $dispatcher); + + if ($e->isStarted()) { + $e->stop(); + } + + if ($event->isPropagationStopped()) { + $this->stoppedPropagation = true; + } + } +} diff --git a/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php b/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php new file mode 100644 index 000000000..cf2e93aec --- /dev/null +++ b/vendor/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php @@ -0,0 +1,136 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\DependencyInjection; + +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\EventDispatcher\EventDispatcher; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * Compiler pass to register tagged services for an event dispatcher. + */ +class RegisterListenersPass implements CompilerPassInterface +{ + protected $dispatcherService; + protected $listenerTag; + protected $subscriberTag; + + private $hotPathEvents = []; + private $hotPathTagName; + + public function __construct(string $dispatcherService = 'event_dispatcher', string $listenerTag = 'kernel.event_listener', string $subscriberTag = 'kernel.event_subscriber') + { + $this->dispatcherService = $dispatcherService; + $this->listenerTag = $listenerTag; + $this->subscriberTag = $subscriberTag; + } + + public function setHotPathEvents(array $hotPathEvents, $tagName = 'container.hot_path') + { + $this->hotPathEvents = array_flip($hotPathEvents); + $this->hotPathTagName = $tagName; + + return $this; + } + + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition($this->dispatcherService) && !$container->hasAlias($this->dispatcherService)) { + return; + } + + $definition = $container->findDefinition($this->dispatcherService); + + foreach ($container->findTaggedServiceIds($this->listenerTag, true) as $id => $events) { + foreach ($events as $event) { + $priority = isset($event['priority']) ? $event['priority'] : 0; + + if (!isset($event['event'])) { + throw new InvalidArgumentException(sprintf('Service "%s" must define the "event" attribute on "%s" tags.', $id, $this->listenerTag)); + } + + if (!isset($event['method'])) { + $event['method'] = 'on'.preg_replace_callback([ + '/(?<=\b)[a-z]/i', + '/[^a-z0-9]/i', + ], function ($matches) { return strtoupper($matches[0]); }, $event['event']); + $event['method'] = preg_replace('/[^a-z0-9]/i', '', $event['method']); + + if (null !== ($class = $container->getDefinition($id)->getClass()) && ($r = $container->getReflectionClass($class, false)) && !$r->hasMethod($event['method']) && $r->hasMethod('__invoke')) { + $event['method'] = '__invoke'; + } + } + + $definition->addMethodCall('addListener', [$event['event'], [new ServiceClosureArgument(new Reference($id)), $event['method']], $priority]); + + if (isset($this->hotPathEvents[$event['event']])) { + $container->getDefinition($id)->addTag($this->hotPathTagName); + } + } + } + + $extractingDispatcher = new ExtractingEventDispatcher(); + + foreach ($container->findTaggedServiceIds($this->subscriberTag, true) as $id => $attributes) { + $def = $container->getDefinition($id); + + // We must assume that the class value has been correctly filled, even if the service is created by a factory + $class = $def->getClass(); + + if (!$r = $container->getReflectionClass($class)) { + throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); + } + if (!$r->isSubclassOf(EventSubscriberInterface::class)) { + throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, EventSubscriberInterface::class)); + } + $class = $r->name; + + ExtractingEventDispatcher::$subscriber = $class; + $extractingDispatcher->addSubscriber($extractingDispatcher); + foreach ($extractingDispatcher->listeners as $args) { + $args[1] = [new ServiceClosureArgument(new Reference($id)), $args[1]]; + $definition->addMethodCall('addListener', $args); + + if (isset($this->hotPathEvents[$args[0]])) { + $container->getDefinition($id)->addTag($this->hotPathTagName); + } + } + $extractingDispatcher->listeners = []; + } + } +} + +/** + * @internal + */ +class ExtractingEventDispatcher extends EventDispatcher implements EventSubscriberInterface +{ + public $listeners = []; + + public static $subscriber; + + public function addListener($eventName, $listener, $priority = 0) + { + $this->listeners[] = [$eventName, $listener[1], $priority]; + } + + public static function getSubscribedEvents() + { + $callback = [self::$subscriber, 'getSubscribedEvents']; + + return $callback(); + } +} diff --git a/vendor/symfony/event-dispatcher/Event.php b/vendor/symfony/event-dispatcher/Event.php new file mode 100644 index 000000000..9c56b2f55 --- /dev/null +++ b/vendor/symfony/event-dispatcher/Event.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher; + +/** + * Event is the base class for classes containing event data. + * + * This class contains no event data. It is used by events that do not pass + * state information to an event handler when an event is raised. + * + * You can call the method stopPropagation() to abort the execution of + * further listeners in your event listener. + * + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Bernhard Schussek + */ +class Event +{ + /** + * @var bool Whether no further event listeners should be triggered + */ + private $propagationStopped = false; + + /** + * Returns whether further event listeners should be triggered. + * + * @see Event::stopPropagation() + * + * @return bool Whether propagation was already stopped for this event + */ + public function isPropagationStopped() + { + return $this->propagationStopped; + } + + /** + * Stops the propagation of the event to further event listeners. + * + * If multiple event listeners are connected to the same event, no + * further event listener will be triggered once any trigger calls + * stopPropagation(). + */ + public function stopPropagation() + { + $this->propagationStopped = true; + } +} diff --git a/vendor/symfony/event-dispatcher/EventDispatcher.php b/vendor/symfony/event-dispatcher/EventDispatcher.php new file mode 100644 index 000000000..afc443b28 --- /dev/null +++ b/vendor/symfony/event-dispatcher/EventDispatcher.php @@ -0,0 +1,236 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher; + +/** + * The EventDispatcherInterface is the central point of Symfony's event listener system. + * + * Listeners are registered on the manager and events are dispatched through the + * manager. + * + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Bernhard Schussek + * @author Fabien Potencier + * @author Jordi Boggiano + * @author Jordan Alliot + * @author Nicolas Grekas + */ +class EventDispatcher implements EventDispatcherInterface +{ + private $listeners = []; + private $sorted = []; + + /** + * {@inheritdoc} + */ + public function dispatch($eventName, Event $event = null) + { + if (null === $event) { + $event = new Event(); + } + + if ($listeners = $this->getListeners($eventName)) { + $this->doDispatch($listeners, $eventName, $event); + } + + return $event; + } + + /** + * {@inheritdoc} + */ + public function getListeners($eventName = null) + { + if (null !== $eventName) { + if (empty($this->listeners[$eventName])) { + return []; + } + + if (!isset($this->sorted[$eventName])) { + $this->sortListeners($eventName); + } + + return $this->sorted[$eventName]; + } + + foreach ($this->listeners as $eventName => $eventListeners) { + if (!isset($this->sorted[$eventName])) { + $this->sortListeners($eventName); + } + } + + return array_filter($this->sorted); + } + + /** + * {@inheritdoc} + */ + public function getListenerPriority($eventName, $listener) + { + if (empty($this->listeners[$eventName])) { + return; + } + + if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) { + $listener[0] = $listener[0](); + } + + foreach ($this->listeners[$eventName] as $priority => $listeners) { + foreach ($listeners as $k => $v) { + if ($v !== $listener && \is_array($v) && isset($v[0]) && $v[0] instanceof \Closure) { + $v[0] = $v[0](); + $this->listeners[$eventName][$priority][$k] = $v; + } + if ($v === $listener) { + return $priority; + } + } + } + } + + /** + * {@inheritdoc} + */ + public function hasListeners($eventName = null) + { + if (null !== $eventName) { + return !empty($this->listeners[$eventName]); + } + + foreach ($this->listeners as $eventListeners) { + if ($eventListeners) { + return true; + } + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function addListener($eventName, $listener, $priority = 0) + { + $this->listeners[$eventName][$priority][] = $listener; + unset($this->sorted[$eventName]); + } + + /** + * {@inheritdoc} + */ + public function removeListener($eventName, $listener) + { + if (empty($this->listeners[$eventName])) { + return; + } + + if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) { + $listener[0] = $listener[0](); + } + + foreach ($this->listeners[$eventName] as $priority => $listeners) { + foreach ($listeners as $k => $v) { + if ($v !== $listener && \is_array($v) && isset($v[0]) && $v[0] instanceof \Closure) { + $v[0] = $v[0](); + } + if ($v === $listener) { + unset($listeners[$k], $this->sorted[$eventName]); + } else { + $listeners[$k] = $v; + } + } + + if ($listeners) { + $this->listeners[$eventName][$priority] = $listeners; + } else { + unset($this->listeners[$eventName][$priority]); + } + } + } + + /** + * {@inheritdoc} + */ + public function addSubscriber(EventSubscriberInterface $subscriber) + { + foreach ($subscriber->getSubscribedEvents() as $eventName => $params) { + if (\is_string($params)) { + $this->addListener($eventName, [$subscriber, $params]); + } elseif (\is_string($params[0])) { + $this->addListener($eventName, [$subscriber, $params[0]], isset($params[1]) ? $params[1] : 0); + } else { + foreach ($params as $listener) { + $this->addListener($eventName, [$subscriber, $listener[0]], isset($listener[1]) ? $listener[1] : 0); + } + } + } + } + + /** + * {@inheritdoc} + */ + public function removeSubscriber(EventSubscriberInterface $subscriber) + { + foreach ($subscriber->getSubscribedEvents() as $eventName => $params) { + if (\is_array($params) && \is_array($params[0])) { + foreach ($params as $listener) { + $this->removeListener($eventName, [$subscriber, $listener[0]]); + } + } else { + $this->removeListener($eventName, [$subscriber, \is_string($params) ? $params : $params[0]]); + } + } + } + + /** + * Triggers the listeners of an event. + * + * This method can be overridden to add functionality that is executed + * for each listener. + * + * @param callable[] $listeners The event listeners + * @param string $eventName The name of the event to dispatch + * @param Event $event The event object to pass to the event handlers/listeners + */ + protected function doDispatch($listeners, $eventName, Event $event) + { + foreach ($listeners as $listener) { + if ($event->isPropagationStopped()) { + break; + } + $listener($event, $eventName, $this); + } + } + + /** + * Sorts the internal list of listeners for the given event by priority. + * + * @param string $eventName The name of the event + */ + private function sortListeners($eventName) + { + krsort($this->listeners[$eventName]); + $this->sorted[$eventName] = []; + + foreach ($this->listeners[$eventName] as $priority => $listeners) { + foreach ($listeners as $k => $listener) { + if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) { + $listener[0] = $listener[0](); + $this->listeners[$eventName][$priority][$k] = $listener; + } + $this->sorted[$eventName][] = $listener; + } + } + } +} diff --git a/vendor/symfony/event-dispatcher/EventDispatcherInterface.php b/vendor/symfony/event-dispatcher/EventDispatcherInterface.php new file mode 100644 index 000000000..bde753a12 --- /dev/null +++ b/vendor/symfony/event-dispatcher/EventDispatcherInterface.php @@ -0,0 +1,93 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher; + +/** + * The EventDispatcherInterface is the central point of Symfony's event listener system. + * Listeners are registered on the manager and events are dispatched through the + * manager. + * + * @author Bernhard Schussek + */ +interface EventDispatcherInterface +{ + /** + * Dispatches an event to all registered listeners. + * + * @param string $eventName The name of the event to dispatch. The name of + * the event is the name of the method that is + * invoked on listeners. + * @param Event|null $event The event to pass to the event handlers/listeners + * If not supplied, an empty Event instance is created + * + * @return Event + */ + public function dispatch($eventName, Event $event = null); + + /** + * Adds an event listener that listens on the specified events. + * + * @param string $eventName The event to listen on + * @param callable $listener The listener + * @param int $priority The higher this value, the earlier an event + * listener will be triggered in the chain (defaults to 0) + */ + public function addListener($eventName, $listener, $priority = 0); + + /** + * Adds an event subscriber. + * + * The subscriber is asked for all the events it is + * interested in and added as a listener for these events. + */ + public function addSubscriber(EventSubscriberInterface $subscriber); + + /** + * Removes an event listener from the specified events. + * + * @param string $eventName The event to remove a listener from + * @param callable $listener The listener to remove + */ + public function removeListener($eventName, $listener); + + public function removeSubscriber(EventSubscriberInterface $subscriber); + + /** + * Gets the listeners of a specific event or all listeners sorted by descending priority. + * + * @param string|null $eventName The name of the event + * + * @return array The event listeners for the specified event, or all event listeners by event name + */ + public function getListeners($eventName = null); + + /** + * Gets the listener priority for a specific event. + * + * Returns null if the event or the listener does not exist. + * + * @param string $eventName The name of the event + * @param callable $listener The listener + * + * @return int|null The event listener priority + */ + public function getListenerPriority($eventName, $listener); + + /** + * Checks whether an event has any registered listeners. + * + * @param string|null $eventName The name of the event + * + * @return bool true if the specified event has any listeners, false otherwise + */ + public function hasListeners($eventName = null); +} diff --git a/vendor/symfony/event-dispatcher/EventSubscriberInterface.php b/vendor/symfony/event-dispatcher/EventSubscriberInterface.php new file mode 100644 index 000000000..824f21599 --- /dev/null +++ b/vendor/symfony/event-dispatcher/EventSubscriberInterface.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher; + +/** + * An EventSubscriber knows itself what events it is interested in. + * If an EventSubscriber is added to an EventDispatcherInterface, the manager invokes + * {@link getSubscribedEvents} and registers the subscriber as a listener for all + * returned events. + * + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Bernhard Schussek + */ +interface EventSubscriberInterface +{ + /** + * Returns an array of event names this subscriber wants to listen to. + * + * The array keys are event names and the value can be: + * + * * The method name to call (priority defaults to 0) + * * An array composed of the method name to call and the priority + * * An array of arrays composed of the method names to call and respective + * priorities, or 0 if unset + * + * For instance: + * + * * ['eventName' => 'methodName'] + * * ['eventName' => ['methodName', $priority]] + * * ['eventName' => [['methodName1', $priority], ['methodName2']]] + * + * @return array The event names to listen to + */ + public static function getSubscribedEvents(); +} diff --git a/vendor/symfony/event-dispatcher/GenericEvent.php b/vendor/symfony/event-dispatcher/GenericEvent.php new file mode 100644 index 000000000..f005e3a3d --- /dev/null +++ b/vendor/symfony/event-dispatcher/GenericEvent.php @@ -0,0 +1,175 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher; + +/** + * Event encapsulation class. + * + * Encapsulates events thus decoupling the observer from the subject they encapsulate. + * + * @author Drak + */ +class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate +{ + protected $subject; + protected $arguments; + + /** + * Encapsulate an event with $subject and $args. + * + * @param mixed $subject The subject of the event, usually an object or a callable + * @param array $arguments Arguments to store in the event + */ + public function __construct($subject = null, array $arguments = []) + { + $this->subject = $subject; + $this->arguments = $arguments; + } + + /** + * Getter for subject property. + * + * @return mixed The observer subject + */ + public function getSubject() + { + return $this->subject; + } + + /** + * Get argument by key. + * + * @param string $key Key + * + * @return mixed Contents of array key + * + * @throws \InvalidArgumentException if key is not found + */ + public function getArgument($key) + { + if ($this->hasArgument($key)) { + return $this->arguments[$key]; + } + + throw new \InvalidArgumentException(sprintf('Argument "%s" not found.', $key)); + } + + /** + * Add argument to event. + * + * @param string $key Argument name + * @param mixed $value Value + * + * @return $this + */ + public function setArgument($key, $value) + { + $this->arguments[$key] = $value; + + return $this; + } + + /** + * Getter for all arguments. + * + * @return array + */ + public function getArguments() + { + return $this->arguments; + } + + /** + * Set args property. + * + * @param array $args Arguments + * + * @return $this + */ + public function setArguments(array $args = []) + { + $this->arguments = $args; + + return $this; + } + + /** + * Has argument. + * + * @param string $key Key of arguments array + * + * @return bool + */ + public function hasArgument($key) + { + return \array_key_exists($key, $this->arguments); + } + + /** + * ArrayAccess for argument getter. + * + * @param string $key Array key + * + * @return mixed + * + * @throws \InvalidArgumentException if key does not exist in $this->args + */ + public function offsetGet($key) + { + return $this->getArgument($key); + } + + /** + * ArrayAccess for argument setter. + * + * @param string $key Array key to set + * @param mixed $value Value + */ + public function offsetSet($key, $value) + { + $this->setArgument($key, $value); + } + + /** + * ArrayAccess for unset argument. + * + * @param string $key Array key + */ + public function offsetUnset($key) + { + if ($this->hasArgument($key)) { + unset($this->arguments[$key]); + } + } + + /** + * ArrayAccess has argument. + * + * @param string $key Array key + * + * @return bool + */ + public function offsetExists($key) + { + return $this->hasArgument($key); + } + + /** + * IteratorAggregate for iterating over the object like an array. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->arguments); + } +} diff --git a/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php b/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php new file mode 100644 index 000000000..b3cf56c50 --- /dev/null +++ b/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php @@ -0,0 +1,91 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher; + +/** + * A read-only proxy for an event dispatcher. + * + * @author Bernhard Schussek + */ +class ImmutableEventDispatcher implements EventDispatcherInterface +{ + private $dispatcher; + + public function __construct(EventDispatcherInterface $dispatcher) + { + $this->dispatcher = $dispatcher; + } + + /** + * {@inheritdoc} + */ + public function dispatch($eventName, Event $event = null) + { + return $this->dispatcher->dispatch($eventName, $event); + } + + /** + * {@inheritdoc} + */ + public function addListener($eventName, $listener, $priority = 0) + { + throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.'); + } + + /** + * {@inheritdoc} + */ + public function addSubscriber(EventSubscriberInterface $subscriber) + { + throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.'); + } + + /** + * {@inheritdoc} + */ + public function removeListener($eventName, $listener) + { + throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.'); + } + + /** + * {@inheritdoc} + */ + public function removeSubscriber(EventSubscriberInterface $subscriber) + { + throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.'); + } + + /** + * {@inheritdoc} + */ + public function getListeners($eventName = null) + { + return $this->dispatcher->getListeners($eventName); + } + + /** + * {@inheritdoc} + */ + public function getListenerPriority($eventName, $listener) + { + return $this->dispatcher->getListenerPriority($eventName, $listener); + } + + /** + * {@inheritdoc} + */ + public function hasListeners($eventName = null) + { + return $this->dispatcher->hasListeners($eventName); + } +} diff --git a/vendor/symfony/event-dispatcher/LICENSE b/vendor/symfony/event-dispatcher/LICENSE new file mode 100644 index 000000000..a677f4376 --- /dev/null +++ b/vendor/symfony/event-dispatcher/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2019 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/event-dispatcher/README.md b/vendor/symfony/event-dispatcher/README.md new file mode 100644 index 000000000..185c3fecf --- /dev/null +++ b/vendor/symfony/event-dispatcher/README.md @@ -0,0 +1,15 @@ +EventDispatcher Component +========================= + +The EventDispatcher component provides tools that allow your application +components to communicate with each other by dispatching events and listening to +them. + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/event_dispatcher/index.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/vendor/symfony/event-dispatcher/Tests/AbstractEventDispatcherTest.php b/vendor/symfony/event-dispatcher/Tests/AbstractEventDispatcherTest.php new file mode 100644 index 000000000..b157659dc --- /dev/null +++ b/vendor/symfony/event-dispatcher/Tests/AbstractEventDispatcherTest.php @@ -0,0 +1,442 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\EventDispatcher\Event; +use Symfony\Component\EventDispatcher\EventDispatcher; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +abstract class AbstractEventDispatcherTest extends TestCase +{ + /* Some pseudo events */ + const preFoo = 'pre.foo'; + const postFoo = 'post.foo'; + const preBar = 'pre.bar'; + const postBar = 'post.bar'; + + /** + * @var EventDispatcher + */ + private $dispatcher; + + private $listener; + + protected function setUp() + { + $this->dispatcher = $this->createEventDispatcher(); + $this->listener = new TestEventListener(); + } + + protected function tearDown() + { + $this->dispatcher = null; + $this->listener = null; + } + + abstract protected function createEventDispatcher(); + + public function testInitialState() + { + $this->assertEquals([], $this->dispatcher->getListeners()); + $this->assertFalse($this->dispatcher->hasListeners(self::preFoo)); + $this->assertFalse($this->dispatcher->hasListeners(self::postFoo)); + } + + public function testAddListener() + { + $this->dispatcher->addListener('pre.foo', [$this->listener, 'preFoo']); + $this->dispatcher->addListener('post.foo', [$this->listener, 'postFoo']); + $this->assertTrue($this->dispatcher->hasListeners()); + $this->assertTrue($this->dispatcher->hasListeners(self::preFoo)); + $this->assertTrue($this->dispatcher->hasListeners(self::postFoo)); + $this->assertCount(1, $this->dispatcher->getListeners(self::preFoo)); + $this->assertCount(1, $this->dispatcher->getListeners(self::postFoo)); + $this->assertCount(2, $this->dispatcher->getListeners()); + } + + public function testGetListenersSortsByPriority() + { + $listener1 = new TestEventListener(); + $listener2 = new TestEventListener(); + $listener3 = new TestEventListener(); + $listener1->name = '1'; + $listener2->name = '2'; + $listener3->name = '3'; + + $this->dispatcher->addListener('pre.foo', [$listener1, 'preFoo'], -10); + $this->dispatcher->addListener('pre.foo', [$listener2, 'preFoo'], 10); + $this->dispatcher->addListener('pre.foo', [$listener3, 'preFoo']); + + $expected = [ + [$listener2, 'preFoo'], + [$listener3, 'preFoo'], + [$listener1, 'preFoo'], + ]; + + $this->assertSame($expected, $this->dispatcher->getListeners('pre.foo')); + } + + public function testGetAllListenersSortsByPriority() + { + $listener1 = new TestEventListener(); + $listener2 = new TestEventListener(); + $listener3 = new TestEventListener(); + $listener4 = new TestEventListener(); + $listener5 = new TestEventListener(); + $listener6 = new TestEventListener(); + + $this->dispatcher->addListener('pre.foo', $listener1, -10); + $this->dispatcher->addListener('pre.foo', $listener2); + $this->dispatcher->addListener('pre.foo', $listener3, 10); + $this->dispatcher->addListener('post.foo', $listener4, -10); + $this->dispatcher->addListener('post.foo', $listener5); + $this->dispatcher->addListener('post.foo', $listener6, 10); + + $expected = [ + 'pre.foo' => [$listener3, $listener2, $listener1], + 'post.foo' => [$listener6, $listener5, $listener4], + ]; + + $this->assertSame($expected, $this->dispatcher->getListeners()); + } + + public function testGetListenerPriority() + { + $listener1 = new TestEventListener(); + $listener2 = new TestEventListener(); + + $this->dispatcher->addListener('pre.foo', $listener1, -10); + $this->dispatcher->addListener('pre.foo', $listener2); + + $this->assertSame(-10, $this->dispatcher->getListenerPriority('pre.foo', $listener1)); + $this->assertSame(0, $this->dispatcher->getListenerPriority('pre.foo', $listener2)); + $this->assertNull($this->dispatcher->getListenerPriority('pre.bar', $listener2)); + $this->assertNull($this->dispatcher->getListenerPriority('pre.foo', function () {})); + } + + public function testDispatch() + { + $this->dispatcher->addListener('pre.foo', [$this->listener, 'preFoo']); + $this->dispatcher->addListener('post.foo', [$this->listener, 'postFoo']); + $this->dispatcher->dispatch(self::preFoo); + $this->assertTrue($this->listener->preFooInvoked); + $this->assertFalse($this->listener->postFooInvoked); + $this->assertInstanceOf('Symfony\Component\EventDispatcher\Event', $this->dispatcher->dispatch('noevent')); + $this->assertInstanceOf('Symfony\Component\EventDispatcher\Event', $this->dispatcher->dispatch(self::preFoo)); + $event = new Event(); + $return = $this->dispatcher->dispatch(self::preFoo, $event); + $this->assertSame($event, $return); + } + + public function testDispatchForClosure() + { + $invoked = 0; + $listener = function () use (&$invoked) { + ++$invoked; + }; + $this->dispatcher->addListener('pre.foo', $listener); + $this->dispatcher->addListener('post.foo', $listener); + $this->dispatcher->dispatch(self::preFoo); + $this->assertEquals(1, $invoked); + } + + public function testStopEventPropagation() + { + $otherListener = new TestEventListener(); + + // postFoo() stops the propagation, so only one listener should + // be executed + // Manually set priority to enforce $this->listener to be called first + $this->dispatcher->addListener('post.foo', [$this->listener, 'postFoo'], 10); + $this->dispatcher->addListener('post.foo', [$otherListener, 'postFoo']); + $this->dispatcher->dispatch(self::postFoo); + $this->assertTrue($this->listener->postFooInvoked); + $this->assertFalse($otherListener->postFooInvoked); + } + + public function testDispatchByPriority() + { + $invoked = []; + $listener1 = function () use (&$invoked) { + $invoked[] = '1'; + }; + $listener2 = function () use (&$invoked) { + $invoked[] = '2'; + }; + $listener3 = function () use (&$invoked) { + $invoked[] = '3'; + }; + $this->dispatcher->addListener('pre.foo', $listener1, -10); + $this->dispatcher->addListener('pre.foo', $listener2); + $this->dispatcher->addListener('pre.foo', $listener3, 10); + $this->dispatcher->dispatch(self::preFoo); + $this->assertEquals(['3', '2', '1'], $invoked); + } + + public function testRemoveListener() + { + $this->dispatcher->addListener('pre.bar', $this->listener); + $this->assertTrue($this->dispatcher->hasListeners(self::preBar)); + $this->dispatcher->removeListener('pre.bar', $this->listener); + $this->assertFalse($this->dispatcher->hasListeners(self::preBar)); + $this->dispatcher->removeListener('notExists', $this->listener); + } + + public function testAddSubscriber() + { + $eventSubscriber = new TestEventSubscriber(); + $this->dispatcher->addSubscriber($eventSubscriber); + $this->assertTrue($this->dispatcher->hasListeners(self::preFoo)); + $this->assertTrue($this->dispatcher->hasListeners(self::postFoo)); + } + + public function testAddSubscriberWithPriorities() + { + $eventSubscriber = new TestEventSubscriber(); + $this->dispatcher->addSubscriber($eventSubscriber); + + $eventSubscriber = new TestEventSubscriberWithPriorities(); + $this->dispatcher->addSubscriber($eventSubscriber); + + $listeners = $this->dispatcher->getListeners('pre.foo'); + $this->assertTrue($this->dispatcher->hasListeners(self::preFoo)); + $this->assertCount(2, $listeners); + $this->assertInstanceOf('Symfony\Component\EventDispatcher\Tests\TestEventSubscriberWithPriorities', $listeners[0][0]); + } + + public function testAddSubscriberWithMultipleListeners() + { + $eventSubscriber = new TestEventSubscriberWithMultipleListeners(); + $this->dispatcher->addSubscriber($eventSubscriber); + + $listeners = $this->dispatcher->getListeners('pre.foo'); + $this->assertTrue($this->dispatcher->hasListeners(self::preFoo)); + $this->assertCount(2, $listeners); + $this->assertEquals('preFoo2', $listeners[0][1]); + } + + public function testRemoveSubscriber() + { + $eventSubscriber = new TestEventSubscriber(); + $this->dispatcher->addSubscriber($eventSubscriber); + $this->assertTrue($this->dispatcher->hasListeners(self::preFoo)); + $this->assertTrue($this->dispatcher->hasListeners(self::postFoo)); + $this->dispatcher->removeSubscriber($eventSubscriber); + $this->assertFalse($this->dispatcher->hasListeners(self::preFoo)); + $this->assertFalse($this->dispatcher->hasListeners(self::postFoo)); + } + + public function testRemoveSubscriberWithPriorities() + { + $eventSubscriber = new TestEventSubscriberWithPriorities(); + $this->dispatcher->addSubscriber($eventSubscriber); + $this->assertTrue($this->dispatcher->hasListeners(self::preFoo)); + $this->dispatcher->removeSubscriber($eventSubscriber); + $this->assertFalse($this->dispatcher->hasListeners(self::preFoo)); + } + + public function testRemoveSubscriberWithMultipleListeners() + { + $eventSubscriber = new TestEventSubscriberWithMultipleListeners(); + $this->dispatcher->addSubscriber($eventSubscriber); + $this->assertTrue($this->dispatcher->hasListeners(self::preFoo)); + $this->assertCount(2, $this->dispatcher->getListeners(self::preFoo)); + $this->dispatcher->removeSubscriber($eventSubscriber); + $this->assertFalse($this->dispatcher->hasListeners(self::preFoo)); + } + + public function testEventReceivesTheDispatcherInstanceAsArgument() + { + $listener = new TestWithDispatcher(); + $this->dispatcher->addListener('test', [$listener, 'foo']); + $this->assertNull($listener->name); + $this->assertNull($listener->dispatcher); + $this->dispatcher->dispatch('test'); + $this->assertEquals('test', $listener->name); + $this->assertSame($this->dispatcher, $listener->dispatcher); + } + + /** + * @see https://bugs.php.net/bug.php?id=62976 + * + * This bug affects: + * - The PHP 5.3 branch for versions < 5.3.18 + * - The PHP 5.4 branch for versions < 5.4.8 + * - The PHP 5.5 branch is not affected + */ + public function testWorkaroundForPhpBug62976() + { + $dispatcher = $this->createEventDispatcher(); + $dispatcher->addListener('bug.62976', new CallableClass()); + $dispatcher->removeListener('bug.62976', function () {}); + $this->assertTrue($dispatcher->hasListeners('bug.62976')); + } + + public function testHasListenersWhenAddedCallbackListenerIsRemoved() + { + $listener = function () {}; + $this->dispatcher->addListener('foo', $listener); + $this->dispatcher->removeListener('foo', $listener); + $this->assertFalse($this->dispatcher->hasListeners()); + } + + public function testGetListenersWhenAddedCallbackListenerIsRemoved() + { + $listener = function () {}; + $this->dispatcher->addListener('foo', $listener); + $this->dispatcher->removeListener('foo', $listener); + $this->assertSame([], $this->dispatcher->getListeners()); + } + + public function testHasListenersWithoutEventsReturnsFalseAfterHasListenersWithEventHasBeenCalled() + { + $this->assertFalse($this->dispatcher->hasListeners('foo')); + $this->assertFalse($this->dispatcher->hasListeners()); + } + + public function testHasListenersIsLazy() + { + $called = 0; + $listener = [function () use (&$called) { ++$called; }, 'onFoo']; + $this->dispatcher->addListener('foo', $listener); + $this->assertTrue($this->dispatcher->hasListeners()); + $this->assertTrue($this->dispatcher->hasListeners('foo')); + $this->assertSame(0, $called); + } + + public function testDispatchLazyListener() + { + $called = 0; + $factory = function () use (&$called) { + ++$called; + + return new TestWithDispatcher(); + }; + $this->dispatcher->addListener('foo', [$factory, 'foo']); + $this->assertSame(0, $called); + $this->dispatcher->dispatch('foo', new Event()); + $this->dispatcher->dispatch('foo', new Event()); + $this->assertSame(1, $called); + } + + public function testRemoveFindsLazyListeners() + { + $test = new TestWithDispatcher(); + $factory = function () use ($test) { return $test; }; + + $this->dispatcher->addListener('foo', [$factory, 'foo']); + $this->assertTrue($this->dispatcher->hasListeners('foo')); + $this->dispatcher->removeListener('foo', [$test, 'foo']); + $this->assertFalse($this->dispatcher->hasListeners('foo')); + + $this->dispatcher->addListener('foo', [$test, 'foo']); + $this->assertTrue($this->dispatcher->hasListeners('foo')); + $this->dispatcher->removeListener('foo', [$factory, 'foo']); + $this->assertFalse($this->dispatcher->hasListeners('foo')); + } + + public function testPriorityFindsLazyListeners() + { + $test = new TestWithDispatcher(); + $factory = function () use ($test) { return $test; }; + + $this->dispatcher->addListener('foo', [$factory, 'foo'], 3); + $this->assertSame(3, $this->dispatcher->getListenerPriority('foo', [$test, 'foo'])); + $this->dispatcher->removeListener('foo', [$factory, 'foo']); + + $this->dispatcher->addListener('foo', [$test, 'foo'], 5); + $this->assertSame(5, $this->dispatcher->getListenerPriority('foo', [$factory, 'foo'])); + } + + public function testGetLazyListeners() + { + $test = new TestWithDispatcher(); + $factory = function () use ($test) { return $test; }; + + $this->dispatcher->addListener('foo', [$factory, 'foo'], 3); + $this->assertSame([[$test, 'foo']], $this->dispatcher->getListeners('foo')); + + $this->dispatcher->removeListener('foo', [$test, 'foo']); + $this->dispatcher->addListener('bar', [$factory, 'foo'], 3); + $this->assertSame(['bar' => [[$test, 'foo']]], $this->dispatcher->getListeners()); + } +} + +class CallableClass +{ + public function __invoke() + { + } +} + +class TestEventListener +{ + public $preFooInvoked = false; + public $postFooInvoked = false; + + /* Listener methods */ + + public function preFoo(Event $e) + { + $this->preFooInvoked = true; + } + + public function postFoo(Event $e) + { + $this->postFooInvoked = true; + + $e->stopPropagation(); + } +} + +class TestWithDispatcher +{ + public $name; + public $dispatcher; + + public function foo(Event $e, $name, $dispatcher) + { + $this->name = $name; + $this->dispatcher = $dispatcher; + } +} + +class TestEventSubscriber implements EventSubscriberInterface +{ + public static function getSubscribedEvents() + { + return ['pre.foo' => 'preFoo', 'post.foo' => 'postFoo']; + } +} + +class TestEventSubscriberWithPriorities implements EventSubscriberInterface +{ + public static function getSubscribedEvents() + { + return [ + 'pre.foo' => ['preFoo', 10], + 'post.foo' => ['postFoo'], + ]; + } +} + +class TestEventSubscriberWithMultipleListeners implements EventSubscriberInterface +{ + public static function getSubscribedEvents() + { + return ['pre.foo' => [ + ['preFoo1'], + ['preFoo2', 10], + ]]; + } +} diff --git a/vendor/symfony/event-dispatcher/Tests/Debug/TraceableEventDispatcherTest.php b/vendor/symfony/event-dispatcher/Tests/Debug/TraceableEventDispatcherTest.php new file mode 100644 index 000000000..9a3697a36 --- /dev/null +++ b/vendor/symfony/event-dispatcher/Tests/Debug/TraceableEventDispatcherTest.php @@ -0,0 +1,305 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Tests\Debug; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher; +use Symfony\Component\EventDispatcher\Event; +use Symfony\Component\EventDispatcher\EventDispatcher; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\Stopwatch\Stopwatch; + +class TraceableEventDispatcherTest extends TestCase +{ + public function testAddRemoveListener() + { + $dispatcher = new EventDispatcher(); + $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch()); + + $tdispatcher->addListener('foo', $listener = function () {}); + $listeners = $dispatcher->getListeners('foo'); + $this->assertCount(1, $listeners); + $this->assertSame($listener, $listeners[0]); + + $tdispatcher->removeListener('foo', $listener); + $this->assertCount(0, $dispatcher->getListeners('foo')); + } + + public function testGetListeners() + { + $dispatcher = new EventDispatcher(); + $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch()); + + $tdispatcher->addListener('foo', $listener = function () {}); + $this->assertSame($dispatcher->getListeners('foo'), $tdispatcher->getListeners('foo')); + } + + public function testHasListeners() + { + $dispatcher = new EventDispatcher(); + $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch()); + + $this->assertFalse($dispatcher->hasListeners('foo')); + $this->assertFalse($tdispatcher->hasListeners('foo')); + + $tdispatcher->addListener('foo', $listener = function () {}); + $this->assertTrue($dispatcher->hasListeners('foo')); + $this->assertTrue($tdispatcher->hasListeners('foo')); + } + + public function testGetListenerPriority() + { + $dispatcher = new EventDispatcher(); + $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch()); + + $tdispatcher->addListener('foo', function () {}, 123); + + $listeners = $dispatcher->getListeners('foo'); + $this->assertSame(123, $tdispatcher->getListenerPriority('foo', $listeners[0])); + + // Verify that priority is preserved when listener is removed and re-added + // in preProcess() and postProcess(). + $tdispatcher->dispatch('foo', new Event()); + $listeners = $dispatcher->getListeners('foo'); + $this->assertSame(123, $tdispatcher->getListenerPriority('foo', $listeners[0])); + } + + public function testGetListenerPriorityWhileDispatching() + { + $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $priorityWhileDispatching = null; + + $listener = function () use ($tdispatcher, &$priorityWhileDispatching, &$listener) { + $priorityWhileDispatching = $tdispatcher->getListenerPriority('bar', $listener); + }; + + $tdispatcher->addListener('bar', $listener, 5); + $tdispatcher->dispatch('bar'); + $this->assertSame(5, $priorityWhileDispatching); + } + + public function testAddRemoveSubscriber() + { + $dispatcher = new EventDispatcher(); + $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch()); + + $subscriber = new EventSubscriber(); + + $tdispatcher->addSubscriber($subscriber); + $listeners = $dispatcher->getListeners('foo'); + $this->assertCount(1, $listeners); + $this->assertSame([$subscriber, 'call'], $listeners[0]); + + $tdispatcher->removeSubscriber($subscriber); + $this->assertCount(0, $dispatcher->getListeners('foo')); + } + + public function testGetCalledListeners() + { + $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $tdispatcher->addListener('foo', function () {}, 5); + + $listeners = $tdispatcher->getNotCalledListeners(); + $this->assertArrayHasKey('stub', $listeners[0]); + unset($listeners[0]['stub']); + $this->assertEquals([], $tdispatcher->getCalledListeners()); + $this->assertEquals([['event' => 'foo', 'pretty' => 'closure', 'priority' => 5]], $listeners); + + $tdispatcher->dispatch('foo'); + + $listeners = $tdispatcher->getCalledListeners(); + $this->assertArrayHasKey('stub', $listeners[0]); + unset($listeners[0]['stub']); + $this->assertEquals([['event' => 'foo', 'pretty' => 'closure', 'priority' => 5]], $listeners); + $this->assertEquals([], $tdispatcher->getNotCalledListeners()); + } + + public function testClearCalledListeners() + { + $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $tdispatcher->addListener('foo', function () {}, 5); + + $tdispatcher->dispatch('foo'); + $tdispatcher->reset(); + + $listeners = $tdispatcher->getNotCalledListeners(); + $this->assertArrayHasKey('stub', $listeners[0]); + unset($listeners[0]['stub']); + $this->assertEquals([], $tdispatcher->getCalledListeners()); + $this->assertEquals([['event' => 'foo', 'pretty' => 'closure', 'priority' => 5]], $listeners); + } + + public function testDispatchAfterReset() + { + $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $tdispatcher->addListener('foo', function () {}, 5); + + $tdispatcher->reset(); + $tdispatcher->dispatch('foo'); + + $listeners = $tdispatcher->getCalledListeners(); + $this->assertArrayHasKey('stub', $listeners[0]); + } + + public function testGetCalledListenersNested() + { + $tdispatcher = null; + $dispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $dispatcher->addListener('foo', function (Event $event, $eventName, $dispatcher) use (&$tdispatcher) { + $tdispatcher = $dispatcher; + $dispatcher->dispatch('bar'); + }); + $dispatcher->addListener('bar', function (Event $event) {}); + $dispatcher->dispatch('foo'); + $this->assertSame($dispatcher, $tdispatcher); + $this->assertCount(2, $dispatcher->getCalledListeners()); + } + + public function testItReturnsNoOrphanedEventsWhenCreated() + { + $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $events = $tdispatcher->getOrphanedEvents(); + $this->assertEmpty($events); + } + + public function testItReturnsOrphanedEventsAfterDispatch() + { + $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $tdispatcher->dispatch('foo'); + $events = $tdispatcher->getOrphanedEvents(); + $this->assertCount(1, $events); + $this->assertEquals(['foo'], $events); + } + + public function testItDoesNotReturnHandledEvents() + { + $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $tdispatcher->addListener('foo', function () {}); + $tdispatcher->dispatch('foo'); + $events = $tdispatcher->getOrphanedEvents(); + $this->assertEmpty($events); + } + + public function testLogger() + { + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + + $dispatcher = new EventDispatcher(); + $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch(), $logger); + $tdispatcher->addListener('foo', $listener1 = function () {}); + $tdispatcher->addListener('foo', $listener2 = function () {}); + + $logger->expects($this->at(0))->method('debug')->with('Notified event "{event}" to listener "{listener}".', ['event' => 'foo', 'listener' => 'closure']); + $logger->expects($this->at(1))->method('debug')->with('Notified event "{event}" to listener "{listener}".', ['event' => 'foo', 'listener' => 'closure']); + + $tdispatcher->dispatch('foo'); + } + + public function testLoggerWithStoppedEvent() + { + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + + $dispatcher = new EventDispatcher(); + $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch(), $logger); + $tdispatcher->addListener('foo', $listener1 = function (Event $event) { $event->stopPropagation(); }); + $tdispatcher->addListener('foo', $listener2 = function () {}); + + $logger->expects($this->at(0))->method('debug')->with('Notified event "{event}" to listener "{listener}".', ['event' => 'foo', 'listener' => 'closure']); + $logger->expects($this->at(1))->method('debug')->with('Listener "{listener}" stopped propagation of the event "{event}".', ['event' => 'foo', 'listener' => 'closure']); + $logger->expects($this->at(2))->method('debug')->with('Listener "{listener}" was not called for event "{event}".', ['event' => 'foo', 'listener' => 'closure']); + + $tdispatcher->dispatch('foo'); + } + + public function testDispatchCallListeners() + { + $called = []; + + $dispatcher = new EventDispatcher(); + $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch()); + $tdispatcher->addListener('foo', function () use (&$called) { $called[] = 'foo1'; }, 10); + $tdispatcher->addListener('foo', function () use (&$called) { $called[] = 'foo2'; }, 20); + + $tdispatcher->dispatch('foo'); + + $this->assertSame(['foo2', 'foo1'], $called); + } + + public function testDispatchNested() + { + $dispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $loop = 1; + $dispatchedEvents = 0; + $dispatcher->addListener('foo', $listener1 = function () use ($dispatcher, &$loop) { + ++$loop; + if (2 == $loop) { + $dispatcher->dispatch('foo'); + } + }); + $dispatcher->addListener('foo', function () use (&$dispatchedEvents) { + ++$dispatchedEvents; + }); + + $dispatcher->dispatch('foo'); + + $this->assertSame(2, $dispatchedEvents); + } + + public function testDispatchReusedEventNested() + { + $nestedCall = false; + $dispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $dispatcher->addListener('foo', function (Event $e) use ($dispatcher) { + $dispatcher->dispatch('bar', $e); + }); + $dispatcher->addListener('bar', function (Event $e) use (&$nestedCall) { + $nestedCall = true; + }); + + $this->assertFalse($nestedCall); + $dispatcher->dispatch('foo'); + $this->assertTrue($nestedCall); + } + + public function testListenerCanRemoveItselfWhenExecuted() + { + $eventDispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $listener1 = function ($event, $eventName, EventDispatcherInterface $dispatcher) use (&$listener1) { + $dispatcher->removeListener('foo', $listener1); + }; + $eventDispatcher->addListener('foo', $listener1); + $eventDispatcher->addListener('foo', function () {}); + $eventDispatcher->dispatch('foo'); + + $this->assertCount(1, $eventDispatcher->getListeners('foo'), 'expected listener1 to be removed'); + } + + public function testClearOrphanedEvents() + { + $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $tdispatcher->dispatch('foo'); + $events = $tdispatcher->getOrphanedEvents(); + $this->assertCount(1, $events); + $tdispatcher->reset(); + $events = $tdispatcher->getOrphanedEvents(); + $this->assertCount(0, $events); + } +} + +class EventSubscriber implements EventSubscriberInterface +{ + public static function getSubscribedEvents() + { + return ['foo' => 'call']; + } +} diff --git a/vendor/symfony/event-dispatcher/Tests/Debug/WrappedListenerTest.php b/vendor/symfony/event-dispatcher/Tests/Debug/WrappedListenerTest.php new file mode 100644 index 000000000..56792fe33 --- /dev/null +++ b/vendor/symfony/event-dispatcher/Tests/Debug/WrappedListenerTest.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Tests\Debug; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\EventDispatcher\Debug\WrappedListener; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\Stopwatch\Stopwatch; + +class WrappedListenerTest extends TestCase +{ + /** + * @dataProvider provideListenersToDescribe + */ + public function testListenerDescription(callable $listener, $expected) + { + $wrappedListener = new WrappedListener($listener, null, $this->getMockBuilder(Stopwatch::class)->getMock(), $this->getMockBuilder(EventDispatcherInterface::class)->getMock()); + + $this->assertStringMatchesFormat($expected, $wrappedListener->getPretty()); + } + + public function provideListenersToDescribe() + { + return [ + [new FooListener(), 'Symfony\Component\EventDispatcher\Tests\Debug\FooListener::__invoke'], + [[new FooListener(), 'listen'], 'Symfony\Component\EventDispatcher\Tests\Debug\FooListener::listen'], + [['Symfony\Component\EventDispatcher\Tests\Debug\FooListener', 'listenStatic'], 'Symfony\Component\EventDispatcher\Tests\Debug\FooListener::listenStatic'], + ['var_dump', 'var_dump'], + [function () {}, 'closure'], + [\Closure::fromCallable([new FooListener(), 'listen']), 'Symfony\Component\EventDispatcher\Tests\Debug\FooListener::listen'], + [\Closure::fromCallable(['Symfony\Component\EventDispatcher\Tests\Debug\FooListener', 'listenStatic']), 'Symfony\Component\EventDispatcher\Tests\Debug\FooListener::listenStatic'], + [\Closure::fromCallable(function () {}), 'closure'], + ]; + } +} + +class FooListener +{ + public function listen() + { + } + + public function __invoke() + { + } + + public static function listenStatic() + { + } +} diff --git a/vendor/symfony/event-dispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php b/vendor/symfony/event-dispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php new file mode 100644 index 000000000..d665f426e --- /dev/null +++ b/vendor/symfony/event-dispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php @@ -0,0 +1,206 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Tests\DependencyInjection; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass; + +class RegisterListenersPassTest extends TestCase +{ + /** + * Tests that event subscribers not implementing EventSubscriberInterface + * trigger an exception. + * + * @expectedException \InvalidArgumentException + */ + public function testEventSubscriberWithoutInterface() + { + $builder = new ContainerBuilder(); + $builder->register('event_dispatcher'); + $builder->register('my_event_subscriber', 'stdClass') + ->addTag('kernel.event_subscriber'); + + $registerListenersPass = new RegisterListenersPass(); + $registerListenersPass->process($builder); + } + + public function testValidEventSubscriber() + { + $services = [ + 'my_event_subscriber' => [0 => []], + ]; + + $builder = new ContainerBuilder(); + $eventDispatcherDefinition = $builder->register('event_dispatcher'); + $builder->register('my_event_subscriber', 'Symfony\Component\EventDispatcher\Tests\DependencyInjection\SubscriberService') + ->addTag('kernel.event_subscriber'); + + $registerListenersPass = new RegisterListenersPass(); + $registerListenersPass->process($builder); + + $expectedCalls = [ + [ + 'addListener', + [ + 'event', + [new ServiceClosureArgument(new Reference('my_event_subscriber')), 'onEvent'], + 0, + ], + ], + ]; + $this->assertEquals($expectedCalls, $eventDispatcherDefinition->getMethodCalls()); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The service "foo" tagged "kernel.event_listener" must not be abstract. + */ + public function testAbstractEventListener() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->setAbstract(true)->addTag('kernel.event_listener', []); + $container->register('event_dispatcher', 'stdClass'); + + $registerListenersPass = new RegisterListenersPass(); + $registerListenersPass->process($container); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The service "foo" tagged "kernel.event_subscriber" must not be abstract. + */ + public function testAbstractEventSubscriber() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->setAbstract(true)->addTag('kernel.event_subscriber', []); + $container->register('event_dispatcher', 'stdClass'); + + $registerListenersPass = new RegisterListenersPass(); + $registerListenersPass->process($container); + } + + public function testEventSubscriberResolvableClassName() + { + $container = new ContainerBuilder(); + + $container->setParameter('subscriber.class', 'Symfony\Component\EventDispatcher\Tests\DependencyInjection\SubscriberService'); + $container->register('foo', '%subscriber.class%')->addTag('kernel.event_subscriber', []); + $container->register('event_dispatcher', 'stdClass'); + + $registerListenersPass = new RegisterListenersPass(); + $registerListenersPass->process($container); + + $definition = $container->getDefinition('event_dispatcher'); + $expectedCalls = [ + [ + 'addListener', + [ + 'event', + [new ServiceClosureArgument(new Reference('foo')), 'onEvent'], + 0, + ], + ], + ]; + $this->assertEquals($expectedCalls, $definition->getMethodCalls()); + } + + public function testHotPathEvents() + { + $container = new ContainerBuilder(); + + $container->register('foo', SubscriberService::class)->addTag('kernel.event_subscriber', []); + $container->register('event_dispatcher', 'stdClass'); + + (new RegisterListenersPass())->setHotPathEvents(['event'])->process($container); + + $this->assertTrue($container->getDefinition('foo')->hasTag('container.hot_path')); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage You have requested a non-existent parameter "subscriber.class" + */ + public function testEventSubscriberUnresolvableClassName() + { + $container = new ContainerBuilder(); + $container->register('foo', '%subscriber.class%')->addTag('kernel.event_subscriber', []); + $container->register('event_dispatcher', 'stdClass'); + + $registerListenersPass = new RegisterListenersPass(); + $registerListenersPass->process($container); + } + + public function testInvokableEventListener() + { + $container = new ContainerBuilder(); + $container->register('foo', \stdClass::class)->addTag('kernel.event_listener', ['event' => 'foo.bar']); + $container->register('bar', InvokableListenerService::class)->addTag('kernel.event_listener', ['event' => 'foo.bar']); + $container->register('baz', InvokableListenerService::class)->addTag('kernel.event_listener', ['event' => 'event']); + $container->register('event_dispatcher', \stdClass::class); + + $registerListenersPass = new RegisterListenersPass(); + $registerListenersPass->process($container); + + $definition = $container->getDefinition('event_dispatcher'); + $expectedCalls = [ + [ + 'addListener', + [ + 'foo.bar', + [new ServiceClosureArgument(new Reference('foo')), 'onFooBar'], + 0, + ], + ], + [ + 'addListener', + [ + 'foo.bar', + [new ServiceClosureArgument(new Reference('bar')), '__invoke'], + 0, + ], + ], + [ + 'addListener', + [ + 'event', + [new ServiceClosureArgument(new Reference('baz')), 'onEvent'], + 0, + ], + ], + ]; + $this->assertEquals($expectedCalls, $definition->getMethodCalls()); + } +} + +class SubscriberService implements \Symfony\Component\EventDispatcher\EventSubscriberInterface +{ + public static function getSubscribedEvents() + { + return [ + 'event' => 'onEvent', + ]; + } +} + +class InvokableListenerService +{ + public function __invoke() + { + } + + public function onEvent() + { + } +} diff --git a/vendor/symfony/event-dispatcher/Tests/EventDispatcherTest.php b/vendor/symfony/event-dispatcher/Tests/EventDispatcherTest.php new file mode 100644 index 000000000..5faa5c8be --- /dev/null +++ b/vendor/symfony/event-dispatcher/Tests/EventDispatcherTest.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Tests; + +use Symfony\Component\EventDispatcher\EventDispatcher; + +class EventDispatcherTest extends AbstractEventDispatcherTest +{ + protected function createEventDispatcher() + { + return new EventDispatcher(); + } +} diff --git a/vendor/symfony/event-dispatcher/Tests/EventTest.php b/vendor/symfony/event-dispatcher/Tests/EventTest.php new file mode 100644 index 000000000..5be2ea09f --- /dev/null +++ b/vendor/symfony/event-dispatcher/Tests/EventTest.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\EventDispatcher\Event; + +/** + * Test class for Event. + */ +class EventTest extends TestCase +{ + /** + * @var \Symfony\Component\EventDispatcher\Event + */ + protected $event; + + /** + * Sets up the fixture, for example, opens a network connection. + * This method is called before a test is executed. + */ + protected function setUp() + { + $this->event = new Event(); + } + + /** + * Tears down the fixture, for example, closes a network connection. + * This method is called after a test is executed. + */ + protected function tearDown() + { + $this->event = null; + } + + public function testIsPropagationStopped() + { + $this->assertFalse($this->event->isPropagationStopped()); + } + + public function testStopPropagationAndIsPropagationStopped() + { + $this->event->stopPropagation(); + $this->assertTrue($this->event->isPropagationStopped()); + } +} diff --git a/vendor/symfony/event-dispatcher/Tests/GenericEventTest.php b/vendor/symfony/event-dispatcher/Tests/GenericEventTest.php new file mode 100644 index 000000000..461f86161 --- /dev/null +++ b/vendor/symfony/event-dispatcher/Tests/GenericEventTest.php @@ -0,0 +1,136 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\EventDispatcher\GenericEvent; + +/** + * Test class for Event. + */ +class GenericEventTest extends TestCase +{ + /** + * @var GenericEvent + */ + private $event; + + private $subject; + + /** + * Prepares the environment before running a test. + */ + protected function setUp() + { + $this->subject = new \stdClass(); + $this->event = new GenericEvent($this->subject, ['name' => 'Event']); + } + + /** + * Cleans up the environment after running a test. + */ + protected function tearDown() + { + $this->subject = null; + $this->event = null; + } + + public function testConstruct() + { + $this->assertEquals($this->event, new GenericEvent($this->subject, ['name' => 'Event'])); + } + + /** + * Tests Event->getArgs(). + */ + public function testGetArguments() + { + // test getting all + $this->assertSame(['name' => 'Event'], $this->event->getArguments()); + } + + public function testSetArguments() + { + $result = $this->event->setArguments(['foo' => 'bar']); + $this->assertAttributeSame(['foo' => 'bar'], 'arguments', $this->event); + $this->assertSame($this->event, $result); + } + + public function testSetArgument() + { + $result = $this->event->setArgument('foo2', 'bar2'); + $this->assertAttributeSame(['name' => 'Event', 'foo2' => 'bar2'], 'arguments', $this->event); + $this->assertEquals($this->event, $result); + } + + public function testGetArgument() + { + // test getting key + $this->assertEquals('Event', $this->event->getArgument('name')); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testGetArgException() + { + $this->event->getArgument('nameNotExist'); + } + + public function testOffsetGet() + { + // test getting key + $this->assertEquals('Event', $this->event['name']); + + // test getting invalid arg + $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('InvalidArgumentException'); + $this->assertFalse($this->event['nameNotExist']); + } + + public function testOffsetSet() + { + $this->event['foo2'] = 'bar2'; + $this->assertAttributeSame(['name' => 'Event', 'foo2' => 'bar2'], 'arguments', $this->event); + } + + public function testOffsetUnset() + { + unset($this->event['name']); + $this->assertAttributeSame([], 'arguments', $this->event); + } + + public function testOffsetIsset() + { + $this->assertArrayHasKey('name', $this->event); + $this->assertArrayNotHasKey('nameNotExist', $this->event); + } + + public function testHasArgument() + { + $this->assertTrue($this->event->hasArgument('name')); + $this->assertFalse($this->event->hasArgument('nameNotExist')); + } + + public function testGetSubject() + { + $this->assertSame($this->subject, $this->event->getSubject()); + } + + public function testHasIterator() + { + $data = []; + foreach ($this->event as $key => $value) { + $data[$key] = $value; + } + $this->assertEquals(['name' => 'Event'], $data); + } +} diff --git a/vendor/symfony/event-dispatcher/Tests/ImmutableEventDispatcherTest.php b/vendor/symfony/event-dispatcher/Tests/ImmutableEventDispatcherTest.php new file mode 100644 index 000000000..04f2861e3 --- /dev/null +++ b/vendor/symfony/event-dispatcher/Tests/ImmutableEventDispatcherTest.php @@ -0,0 +1,106 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\EventDispatcher\Event; +use Symfony\Component\EventDispatcher\ImmutableEventDispatcher; + +/** + * @author Bernhard Schussek + */ +class ImmutableEventDispatcherTest extends TestCase +{ + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $innerDispatcher; + + /** + * @var ImmutableEventDispatcher + */ + private $dispatcher; + + protected function setUp() + { + $this->innerDispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock(); + $this->dispatcher = new ImmutableEventDispatcher($this->innerDispatcher); + } + + public function testDispatchDelegates() + { + $event = new Event(); + + $this->innerDispatcher->expects($this->once()) + ->method('dispatch') + ->with('event', $event) + ->will($this->returnValue('result')); + + $this->assertSame('result', $this->dispatcher->dispatch('event', $event)); + } + + public function testGetListenersDelegates() + { + $this->innerDispatcher->expects($this->once()) + ->method('getListeners') + ->with('event') + ->will($this->returnValue('result')); + + $this->assertSame('result', $this->dispatcher->getListeners('event')); + } + + public function testHasListenersDelegates() + { + $this->innerDispatcher->expects($this->once()) + ->method('hasListeners') + ->with('event') + ->will($this->returnValue('result')); + + $this->assertSame('result', $this->dispatcher->hasListeners('event')); + } + + /** + * @expectedException \BadMethodCallException + */ + public function testAddListenerDisallowed() + { + $this->dispatcher->addListener('event', function () { return 'foo'; }); + } + + /** + * @expectedException \BadMethodCallException + */ + public function testAddSubscriberDisallowed() + { + $subscriber = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventSubscriberInterface')->getMock(); + + $this->dispatcher->addSubscriber($subscriber); + } + + /** + * @expectedException \BadMethodCallException + */ + public function testRemoveListenerDisallowed() + { + $this->dispatcher->removeListener('event', function () { return 'foo'; }); + } + + /** + * @expectedException \BadMethodCallException + */ + public function testRemoveSubscriberDisallowed() + { + $subscriber = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventSubscriberInterface')->getMock(); + + $this->dispatcher->removeSubscriber($subscriber); + } +} diff --git a/vendor/symfony/event-dispatcher/composer.json b/vendor/symfony/event-dispatcher/composer.json new file mode 100644 index 000000000..6c75dfbb0 --- /dev/null +++ b/vendor/symfony/event-dispatcher/composer.json @@ -0,0 +1,48 @@ +{ + "name": "symfony/event-dispatcher", + "type": "library", + "description": "Symfony EventDispatcher Component", + "keywords": [], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": "^7.1.3", + "symfony/contracts": "^1.0" + }, + "require-dev": { + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/expression-language": "~3.4|~4.0", + "symfony/config": "~3.4|~4.0", + "symfony/stopwatch": "~3.4|~4.0", + "psr/log": "~1.0" + }, + "conflict": { + "symfony/dependency-injection": "<3.4" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\EventDispatcher\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + } +} diff --git a/vendor/symfony/event-dispatcher/phpunit.xml.dist b/vendor/symfony/event-dispatcher/phpunit.xml.dist new file mode 100644 index 000000000..f2eb1692c --- /dev/null +++ b/vendor/symfony/event-dispatcher/phpunit.xml.dist @@ -0,0 +1,31 @@ + + + + + + + + + + ./Tests/ + + + + + + ./ + + ./Resources + ./Tests + ./vendor + + + + From 8ee5f834f2ec347d59812ff9627fb189fe83f792 Mon Sep 17 00:00:00 2001 From: Mehmood Asghar Date: Wed, 17 Apr 2019 14:42:51 -0400 Subject: [PATCH 003/103] minor changes to SOLR schema --- application/config/solr.php | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/application/config/solr.php b/application/config/solr.php index e5d7c14f7..3d001dce3 100644 --- a/application/config/solr.php +++ b/application/config/solr.php @@ -44,8 +44,33 @@ **/ /* - - + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -67,7 +92,6 @@ - From ffa6381d14eb756db92e640b98de1d871ca73e36 Mon Sep 17 00:00:00 2001 From: Mehmood Asghar Date: Wed, 17 Apr 2019 16:54:36 -0400 Subject: [PATCH 004/103] add chunked reading for variables --- application/libraries/Solr_manager.php | 65 ++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 5 deletions(-) diff --git a/application/libraries/Solr_manager.php b/application/libraries/Solr_manager.php index ee746af65..758578863 100644 --- a/application/libraries/Solr_manager.php +++ b/application/libraries/Solr_manager.php @@ -22,6 +22,9 @@ function __construct($params = array()) log_message('debug', "Solr Class Initialized"); //$this->ci->output->enable_profiler(TRUE); + + ini_set('memory_limit','256M'); // This also needs to be increased in some cases. Can be changed to a higher value as per need) + ini_set('sqlsrv.ClientBufferMaxKBSize','524288'); // Setting to 512M } @@ -719,7 +722,7 @@ function clean_index() * @loop whether to recursively call the function till the end of rows * * */ - public function full_import_variables($start_row=NULL, $limit=100, $loop=TRUE) + public function full_import_variables($start_row=NULL, $limit=100, $loop=FALSE) { $this->ci->load->helper('array'); $this->ci->load->model("Dataset_model"); @@ -752,10 +755,14 @@ public function full_import_variables($start_row=NULL, $limit=100, $loop=TRUE) //echo "memory usage before=".$this->convert(memory_get_usage())."\r\n"; $rows=$this->ci->db->get("variables")->result_array(); + - foreach($rows as $idx=>$row){ - $rows[$idx]['metadata']=array_to_plain_text($this->ci->Dataset_model->decode_metadata($row['metadata'])); - } + /*foreach($rows as $idx=>$row){ + $rows[$idx]['metadata']=''; + if(!empty($row['metadata'])){ + $rows[$idx]['metadata']=array_to_plain_text($this->ci->Dataset_model->decode_metadata($row['metadata'])); + } + }*/ //echo "DB results loaded= ".date("H:i:s")."\r\n"; //echo $this->ci->db->last_query(); @@ -773,12 +780,15 @@ public function full_import_variables($start_row=NULL, $limit=100, $loop=TRUE) //row variable id $last_row_id=$rows[ count($rows)-1]['var_uid']; + + //echo "add docs " .date("H:i:s")."\r\n"; $this->add_documents($rows,$id_prefix='v-'); $row_count=count($rows); unset($rows); + if ($loop){ //recursively call to fetch next batch of rows $this->full_import_variables($last_row_id,$limit,$loop); @@ -922,7 +932,7 @@ function get_survey_repositories($sid) return $output; } - function get_survey_variables($sid) + /*function get_survey_variables($sid) { $this->ci->db->select("uid,name,labl,qstn,catgry"); $this->ci->db->where('sid',$sid); @@ -935,6 +945,51 @@ function get_survey_variables($sid) $output[]=implode(" ", array_values($row)); } return implode(" ",$output); + }*/ + + + function get_survey_variables($sid) + { + //max variables to be indexed + $max_rows=15000; + + $limit=500; + $chunks=ceil($max_rows/$limit); + + $output=array(); + $last_row_id=0; + + for($i=1;$i<=$chunks;$i++){ + + $chunked_variables=$this->get_survey_variables_chunked($sid,$start_row=$last_row_id,$limit=500); + + if(!count($chunked_variables) > 0){ + break; + } + + foreach($chunked_variables as $row){ + $output[]=implode(" ", array_values($row)); + $last_row_id=$row['uid']; + } + unset($chunked_variables); + + if($last_row_id==0){ + break; + } + } + + return implode(" ",$output); + } + + + function get_survey_variables_chunked($sid,$start_row=0,$limit=500) + { + $this->ci->db->select("uid,name,labl,qstn,catgry"); + $this->ci->db->where('sid',$sid); + $this->ci->db->where('uid>',$start_row); + $this->ci->db->limit($limit); + $result= $this->ci->db->get("variables")->result_array(); + return $result; } From 615292bada67afbd16079cfc259bdb54f01e1ab3 Mon Sep 17 00:00:00 2001 From: Mehmood Asghar Date: Thu, 18 Apr 2019 13:55:33 -0400 Subject: [PATCH 005/103] update language translation files --- application/language/base/collection_lang.php | 6 +- application/language/base/ddi_fields_lang.php | 3 +- .../language/base/fields_image_lang.php | 278 +++++++++--------- 3 files changed, 147 insertions(+), 140 deletions(-) diff --git a/application/language/base/collection_lang.php b/application/language/base/collection_lang.php index 21c5a72a6..8612c0987 100644 --- a/application/language/base/collection_lang.php +++ b/application/language/base/collection_lang.php @@ -6,7 +6,6 @@ $lang['repositoryid']="Collection Identification"; $lang['organization']="Organization"; $lang['country']="Country"; -$lang['scan_interval_in_days']="Scan interval (days)"; $lang['published']="Published"; $lang['draft']="Draft"; $lang['status']="Status"; @@ -14,9 +13,6 @@ $lang['thumbnail']="Thumbnail"; $lang['short_description']="Short description"; $lang['long_description']="Long description (this will become the collection about page)"; -$lang['internal']="Internal"; -$lang['external']="External"; -$lang['scan']="Scan"; $lang['manage_repository_users']="Manage collection access"; $lang['manage_users']="Manage users"; $lang['msg_select_active_repo']="Click the collection you like to manage for your current session."; @@ -50,6 +46,8 @@ $lang['none']="None"; $lang['confirm_collection_status_change']="Are you sure you want to continue? This will change the status of all studies beloging to this collection."; $lang['section'] = 'Section'; +$lang['thumbnail_upload_folder_not_set']='Thumbnail upload folder not found or writable'; +$lang['thumbnail_upload_failed']='Thumbnail upload error'; /* End of file collection_lang.php */ /* Location: ./application/language/english/collection_lang.php */ \ No newline at end of file diff --git a/application/language/base/ddi_fields_lang.php b/application/language/base/ddi_fields_lang.php index 861aafdd5..41dc83370 100644 --- a/application/language/base/ddi_fields_lang.php +++ b/application/language/base/ddi_fields_lang.php @@ -287,4 +287,5 @@ $lang['var_qstn_ivulnstr']='Interviewer instructions'; $lang['data_file']='Data file'; -$lang['overview']='Overview'; \ No newline at end of file +$lang['overview']='Overview'; +$lang['contacts']='Contacts'; \ No newline at end of file diff --git a/application/language/base/fields_image_lang.php b/application/language/base/fields_image_lang.php index 91a11329f..954593e0b 100644 --- a/application/language/base/fields_image_lang.php +++ b/application/language/base/fields_image_lang.php @@ -11,148 +11,156 @@ $lang['metadata.metadata_information.production_date']='Date of Production'; $lang['metadata.metadata_information.version']='Document version'; $lang['metadata.image_description']='Image description'; -$lang['metadata.image_description.mediafragment']='Media fragment'; -$lang['metadata.image_description.mediafragment.uri']='URI'; -$lang['metadata.image_description.mediafragment.delimitertype']='Delimiter type'; -$lang['metadata.image_description.mediafragment.description']='Description'; -$lang['metadata.image_description.photoVideoMetadataIPTC']='IPTC metadata'; -$lang['metadata.image_description.photoVideoMetadataIPTC.aboutCvTerms']='CV-Term About Image'; -$lang['metadata.image_description.photoVideoMetadataIPTC.aboutCvTerms.cvId']='ID'; -$lang['metadata.image_description.photoVideoMetadataIPTC.aboutCvTerms.cvTermName']='Term Name'; -$lang['metadata.image_description.photoVideoMetadataIPTC.aboutCvTerms.cvTermId']='Term ID'; -$lang['metadata.image_description.photoVideoMetadataIPTC.aboutCvTerms.cvTermRefinedAbout']='Refined \'about\' Relationship of the CV-Term'; -$lang['metadata.image_description.photoVideoMetadataIPTC.additionalModelInfo']='Additional Model Information'; -$lang['metadata.image_description.photoVideoMetadataIPTC.artworkOrObjects']='Artwork or Object in the Image'; -$lang['metadata.image_description.photoVideoMetadataIPTC.artworkOrObjects.circaDateCreated']='Circa Date Created'; -$lang['metadata.image_description.photoVideoMetadataIPTC.artworkOrObjects.contentDescription']='Content Description'; -$lang['metadata.image_description.photoVideoMetadataIPTC.artworkOrObjects.contributionDescription']='Contribution Description'; -$lang['metadata.image_description.photoVideoMetadataIPTC.artworkOrObjects.copyrightNotice']='Copyright Notice'; -$lang['metadata.image_description.photoVideoMetadataIPTC.artworkOrObjects.creatorIdentifiers']='Creator ID'; -$lang['metadata.image_description.photoVideoMetadataIPTC.artworkOrObjects.creatorNames']='Creator'; -$lang['metadata.image_description.photoVideoMetadataIPTC.artworkOrObjects.currentCopyrightOwnerIdentifier']='Current Copyright Owner ID'; -$lang['metadata.image_description.photoVideoMetadataIPTC.artworkOrObjects.currentCopyrightOwnerName']='Current Copyright Owner Name'; -$lang['metadata.image_description.photoVideoMetadataIPTC.artworkOrObjects.currentLicensorIdentifier']='Current Licensor ID'; -$lang['metadata.image_description.photoVideoMetadataIPTC.artworkOrObjects.currentLicensorName']='Current Licensor Name'; -$lang['metadata.image_description.photoVideoMetadataIPTC.artworkOrObjects.dateCreated']='Date Created'; -$lang['metadata.image_description.photoVideoMetadataIPTC.artworkOrObjects.physicalDescription']='Physical Description'; -$lang['metadata.image_description.photoVideoMetadataIPTC.artworkOrObjects.source']='Source'; -$lang['metadata.image_description.photoVideoMetadataIPTC.artworkOrObjects.sourceInventoryNr']='Source Inventory Number'; -$lang['metadata.image_description.photoVideoMetadataIPTC.artworkOrObjects.sourceInventoryUrl']='Source Inventory URL'; -$lang['metadata.image_description.photoVideoMetadataIPTC.artworkOrObjects.stylePeriod']='Style Period'; -$lang['metadata.image_description.photoVideoMetadataIPTC.artworkOrObjects.title']='Title'; -$lang['metadata.image_description.photoVideoMetadataIPTC.captionWriter']='Description Writer'; -$lang['metadata.image_description.photoVideoMetadataIPTC.cityName']='City (legacy)'; -$lang['metadata.image_description.photoVideoMetadataIPTC.copyrightNotice']='Copyright Notice'; -$lang['metadata.image_description.photoVideoMetadataIPTC.copyrightOwners']='Copyright Owner'; -$lang['metadata.image_description.photoVideoMetadataIPTC.copyrightOwners.name']='Name'; -$lang['metadata.image_description.photoVideoMetadataIPTC.copyrightOwners.role']='Role'; -$lang['metadata.image_description.photoVideoMetadataIPTC.copyrightOwners.identifiers']='Identifier'; -$lang['metadata.image_description.photoVideoMetadataIPTC.countryCode']='Country Code (legacy)'; -$lang['metadata.image_description.photoVideoMetadataIPTC.countryName']='Country (legacy)'; -$lang['metadata.image_description.photoVideoMetadataIPTC.creatorContactInfo']='Creator\'s Contact Info'; -$lang['metadata.image_description.photoVideoMetadataIPTC.creatorContactInfo.country']='Country '; -$lang['metadata.image_description.photoVideoMetadataIPTC.creatorContactInfo.emailwork']='Email address(es) '; -$lang['metadata.image_description.photoVideoMetadataIPTC.creatorContactInfo.region']='State/Province '; -$lang['metadata.image_description.photoVideoMetadataIPTC.creatorContactInfo.phonework']='Phone number(s) '; -$lang['metadata.image_description.photoVideoMetadataIPTC.creatorContactInfo.weburlwork']='Web URL(s) '; -$lang['metadata.image_description.photoVideoMetadataIPTC.creatorContactInfo.address']='Address '; -$lang['metadata.image_description.photoVideoMetadataIPTC.creatorContactInfo.city']='City '; -$lang['metadata.image_description.photoVideoMetadataIPTC.creatorContactInfo.postalCode']='Postal Code '; -$lang['metadata.image_description.photoVideoMetadataIPTC.creatorNames']='Creator'; -$lang['metadata.image_description.photoVideoMetadataIPTC.creditLine']='Credit Line'; -$lang['metadata.image_description.photoVideoMetadataIPTC.dateCreated']='Date Created'; -$lang['metadata.image_description.photoVideoMetadataIPTC.description']='Description'; -$lang['metadata.image_description.photoVideoMetadataIPTC.digitalImageGuid']='Digital Image GUID'; -$lang['metadata.image_description.photoVideoMetadataIPTC.digitalSourceType']='Digital Source Type'; -$lang['metadata.image_description.photoVideoMetadataIPTC.embdEncRightsExpr']='Embedded Encoded Rights Expression'; -$lang['metadata.image_description.photoVideoMetadataIPTC.embdEncRightsExpr.encRightsExpr']='Encoded Rights Expression'; -$lang['metadata.image_description.photoVideoMetadataIPTC.embdEncRightsExpr.rightsExprEncType']='Encoding type'; -$lang['metadata.image_description.photoVideoMetadataIPTC.embdEncRightsExpr.rightsExprLangId']='Rights Expression Language ID'; -$lang['metadata.image_description.photoVideoMetadataIPTC.eventName']='Event'; -$lang['metadata.image_description.photoVideoMetadataIPTC.genres']='Genre'; -$lang['metadata.image_description.photoVideoMetadataIPTC.genres.cvId']='CV-Term CV ID '; -$lang['metadata.image_description.photoVideoMetadataIPTC.genres.cvTermName']='CV-Term name '; -$lang['metadata.image_description.photoVideoMetadataIPTC.genres.cvTermId']='CV-Term ID '; -$lang['metadata.image_description.photoVideoMetadataIPTC.genres.cvTermRefinedAbout']='Refined \'about\' Relationship of the CV-Term '; -$lang['metadata.image_description.photoVideoMetadataIPTC.headline']='Headline'; -$lang['metadata.image_description.photoVideoMetadataIPTC.imageRating']=''; -$lang['metadata.image_description.photoVideoMetadataIPTC.imageSupplierImageId']='Image Supplier Image ID'; -$lang['metadata.image_description.photoVideoMetadataIPTC.instructions']='Instructions'; -$lang['metadata.image_description.photoVideoMetadataIPTC.intellectualGenre']='Intellectual Genre'; -$lang['metadata.image_description.photoVideoMetadataIPTC.jobid']='Job Id'; -$lang['metadata.image_description.photoVideoMetadataIPTC.jobtitle']='Creator\'s jobtitle'; -$lang['metadata.image_description.photoVideoMetadataIPTC.keywords']='Keywords'; -$lang['metadata.image_description.photoVideoMetadataIPTC.linkedEncRightsExpr']='Linked Encoded Rights Expression'; -$lang['metadata.image_description.photoVideoMetadataIPTC.linkedEncRightsExpr.linkedRightsExpr']='Link to Encoded Rights Expression'; -$lang['metadata.image_description.photoVideoMetadataIPTC.linkedEncRightsExpr.rightsExprEncType']='Encoding type'; -$lang['metadata.image_description.photoVideoMetadataIPTC.linkedEncRightsExpr.rightsExprLangId']='Rights Expression Language ID'; -$lang['metadata.image_description.photoVideoMetadataIPTC.locationsShown']='Location created'; -$lang['metadata.image_description.photoVideoMetadataIPTC.locationsShown.city']='City name'; -$lang['metadata.image_description.photoVideoMetadataIPTC.locationsShown.countryCode']='Country ISO code'; -$lang['metadata.image_description.photoVideoMetadataIPTC.locationsShown.countryName']='Country name'; -$lang['metadata.image_description.photoVideoMetadataIPTC.locationsShown.gpsAltitude']='GPS-Altitude'; -$lang['metadata.image_description.photoVideoMetadataIPTC.locationsShown.gpsLatitude']='GPS-Lattitude'; -$lang['metadata.image_description.photoVideoMetadataIPTC.locationsShown.gpsLongitude']='GPS-Longitude'; -$lang['metadata.image_description.photoVideoMetadataIPTC.locationsShown.identifiers']='Identifier'; -$lang['metadata.image_description.photoVideoMetadataIPTC.locationsShown.name']='Name'; -$lang['metadata.image_description.photoVideoMetadataIPTC.locationsShown.provinceState']='State/Province name'; -$lang['metadata.image_description.photoVideoMetadataIPTC.locationsShown.sublocation']='Sublocation name'; -$lang['metadata.image_description.photoVideoMetadataIPTC.locationsShown.worldRegion']='World region name'; -$lang['metadata.image_description.photoVideoMetadataIPTC.maxAvailHeight']='Max Avail Height'; -$lang['metadata.image_description.photoVideoMetadataIPTC.maxAvailWidth']='Max Avail Width'; -$lang['metadata.image_description.photoVideoMetadataIPTC.minorModelAgeDisclosure']='Minor Model Age Disclosure'; -$lang['metadata.image_description.photoVideoMetadataIPTC.modelAges']='Model Age'; -$lang['metadata.image_description.photoVideoMetadataIPTC.modelReleaseDocuments']='Model Release Id'; -$lang['metadata.image_description.photoVideoMetadataIPTC.modelReleaseStatus']='Model Release Status'; -$lang['metadata.image_description.photoVideoMetadataIPTC.modelReleaseStatus.cvId']='CV-Term CV ID '; -$lang['metadata.image_description.photoVideoMetadataIPTC.modelReleaseStatus.cvTermName']='CV-Term name '; -$lang['metadata.image_description.photoVideoMetadataIPTC.modelReleaseStatus.cvTermId']='CV-Term ID '; -$lang['metadata.image_description.photoVideoMetadataIPTC.modelReleaseStatus.cvTermRefinedAbout']='Refined \'about\' Relationship of the CV-Term '; -$lang['metadata.image_description.photoVideoMetadataIPTC.organisationInImageCodes']='Code of Organisation Featured in the Image'; -$lang['metadata.image_description.photoVideoMetadataIPTC.organisationInImageNames']='Name of Organisation Featured in the Image'; -$lang['metadata.image_description.photoVideoMetadataIPTC.personInImageNames']='Person Shown in the Image'; -$lang['metadata.image_description.photoVideoMetadataIPTC.personsShown']='Person Shown in the Image with Details'; -$lang['metadata.image_description.photoVideoMetadataIPTC.personsShown.name']='Name'; -$lang['metadata.image_description.photoVideoMetadataIPTC.personsShown.description']='Description'; -$lang['metadata.image_description.photoVideoMetadataIPTC.personsShown.identifiers']='Identifier'; -$lang['metadata.image_description.photoVideoMetadataIPTC.personsShown.characteristics']='Characteristics'; -$lang['metadata.image_description.photoVideoMetadataIPTC.personsShown.characteristics.cvId']='CV-Term CV ID '; -$lang['metadata.image_description.photoVideoMetadataIPTC.personsShown.characteristics.cvTermName']='CV-Term name '; -$lang['metadata.image_description.photoVideoMetadataIPTC.personsShown.characteristics.cvTermId']='CV-Term ID '; -$lang['metadata.image_description.photoVideoMetadataIPTC.personsShown.characteristics.cvTermRefinedAbout']='Refined \'about\' Relationship of the CV-Term '; -$lang['metadata.image_description.photoVideoMetadataIPTC.productsShown']='Product Shown in the Image'; -$lang['metadata.image_description.photoVideoMetadataIPTC.productsShown.description']='Description '; -$lang['metadata.image_description.photoVideoMetadataIPTC.productsShown.gtin']='GTIN '; -$lang['metadata.image_description.photoVideoMetadataIPTC.productsShown.name']='Name {Product detail}'; -$lang['metadata.image_description.photoVideoMetadataIPTC.propertyReleaseDocuments']='Property Release Id'; -$lang['metadata.image_description.photoVideoMetadataIPTC.propertyReleaseStatus']='Property Release Status'; -$lang['metadata.image_description.photoVideoMetadataIPTC.propertyReleaseStatus.cvId']='CV-Term CV ID '; -$lang['metadata.image_description.photoVideoMetadataIPTC.propertyReleaseStatus.cvTermName']='CV-Term name '; -$lang['metadata.image_description.photoVideoMetadataIPTC.propertyReleaseStatus.cvTermId']='CV-Term ID '; -$lang['metadata.image_description.photoVideoMetadataIPTC.propertyReleaseStatus.cvTermRefinedAbout']='Refined \'about\' Relationship of the CV-Term '; -$lang['metadata.image_description.photoVideoMetadataIPTC.provinceStatePhoto']='Province or State (legacy)'; -$lang['metadata.image_description.photoVideoMetadataIPTC.registryEntries']='Image Registry Entry'; -$lang['metadata.image_description.photoVideoMetadataIPTC.registryEntries.role']='Role'; -$lang['metadata.image_description.photoVideoMetadataIPTC.registryEntries.assetIdentifier']='Asset Identifier'; -$lang['metadata.image_description.photoVideoMetadataIPTC.registryEntries.registryIdentifier']='Registry Identifier'; -$lang['metadata.image_description.photoVideoMetadataIPTC.sceneCodes']='Scene Code'; -$lang['metadata.image_description.photoVideoMetadataIPTC.source']='Source'; -$lang['metadata.image_description.photoVideoMetadataIPTC.subjectCodes']='Subject Code'; -$lang['metadata.image_description.photoVideoMetadataIPTC.sublocationName']='Sublocation (legacy)'; -$lang['metadata.image_description.photoVideoMetadataIPTC.supplier']='Image Supplier'; -$lang['metadata.image_description.photoVideoMetadataIPTC.supplier.name']='Name'; -$lang['metadata.image_description.photoVideoMetadataIPTC.supplier.identifiers']='Identifier'; -$lang['metadata.image_description.photoVideoMetadataIPTC.title']='Title'; -$lang['metadata.image_description.photoVideoMetadataIPTC.usageTerms']='Rights Usage Terms'; -$lang['metadata.image_description.photoVideoMetadataIPTC.webstatementRights']='Web statement rights'; +$lang['metadata.image_description.iptc.mediafragment']='Media fragment'; +$lang['metadata.image_description.iptc.mediafragment.uri']='URI'; +$lang['metadata.image_description.iptc.mediafragment.delimitertype']='Delimiter type'; +$lang['metadata.image_description.iptc.mediafragment.description']='Description'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC']='IPTC metadata'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.aboutCvTerms']='CV-Term About Image'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.aboutCvTerms.cvId']='ID'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.aboutCvTerms.cvTermName']='Term Name'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.aboutCvTerms.cvTermId']='Term ID'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.aboutCvTerms.cvTermRefinedAbout']='Refined \'about\' Relationship of the CV-Term'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.additionalModelInfo']='Additional Model Information'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.artworkOrObjects']='Artwork or Object in the Image'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.artworkOrObjects.circaDateCreated']='Circa Date Created'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.artworkOrObjects.contentDescription']='Content Description'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.artworkOrObjects.contributionDescription']='Contribution Description'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.artworkOrObjects.copyrightNotice']='Copyright Notice'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.artworkOrObjects.creatorIdentifiers']='Creator ID'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.artworkOrObjects.creatorNames']='Creator'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.artworkOrObjects.currentCopyrightOwnerIdentifier']='Current Copyright Owner ID'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.artworkOrObjects.currentCopyrightOwnerName']='Current Copyright Owner Name'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.artworkOrObjects.currentLicensorIdentifier']='Current Licensor ID'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.artworkOrObjects.currentLicensorName']='Current Licensor Name'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.artworkOrObjects.dateCreated']='Date Created'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.artworkOrObjects.physicalDescription']='Physical Description'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.artworkOrObjects.source']='Source'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.artworkOrObjects.sourceInventoryNr']='Source Inventory Number'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.artworkOrObjects.sourceInventoryUrl']='Source Inventory URL'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.artworkOrObjects.stylePeriod']='Style Period'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.artworkOrObjects.title']='Title'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.captionWriter']='Description Writer'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.cityName']='City (legacy)'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.copyrightNotice']='Copyright Notice'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.copyrightOwners']='Copyright Owner'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.copyrightOwners.name']='Name'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.copyrightOwners.role']='Role'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.copyrightOwners.identifiers']='Identifier'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.countryCode']='Country Code (legacy)'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.countryName']='Country (legacy)'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.creatorContactInfo']='Creator\'s Contact Info'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.creatorContactInfo.country']='Country '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.creatorContactInfo.emailwork']='Email address(es) '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.creatorContactInfo.region']='State/Province '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.creatorContactInfo.phonework']='Phone number(s) '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.creatorContactInfo.weburlwork']='Web URL(s) '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.creatorContactInfo.address']='Address '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.creatorContactInfo.city']='City '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.creatorContactInfo.postalCode']='Postal Code '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.creatorNames']='Creator'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.creditLine']='Credit Line'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.dateCreated']='Date Created'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.description']='Description'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.digitalImageGuid']='Digital Image GUID'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.digitalSourceType']='Digital Source Type'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.embdEncRightsExpr']='Embedded Encoded Rights Expression'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.embdEncRightsExpr.encRightsExpr']='Encoded Rights Expression'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.embdEncRightsExpr.rightsExprEncType']='Encoding type'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.embdEncRightsExpr.rightsExprLangId']='Rights Expression Language ID'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.eventName']='Event'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.genres']='Genre'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.genres.cvId']='CV-Term CV ID '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.genres.cvTermName']='CV-Term name '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.genres.cvTermId']='CV-Term ID '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.genres.cvTermRefinedAbout']='Refined \'about\' Relationship of the CV-Term '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.headline']='Headline'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.imageRating']=''; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.imageSupplierImageId']='Image Supplier Image ID'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.instructions']='Instructions'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.intellectualGenre']='Intellectual Genre'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.jobid']='Job Id'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.jobtitle']='Creator\'s jobtitle'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.keywords']='Keywords'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.linkedEncRightsExpr']='Linked Encoded Rights Expression'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.linkedEncRightsExpr.linkedRightsExpr']='Link to Encoded Rights Expression'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.linkedEncRightsExpr.rightsExprEncType']='Encoding type'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.linkedEncRightsExpr.rightsExprLangId']='Rights Expression Language ID'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.locationsShown']='Location created'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.locationsShown.city']='City name'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.locationsShown.countryCode']='Country ISO code'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.locationsShown.countryName']='Country name'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.locationsShown.gpsAltitude']='GPS-Altitude'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.locationsShown.gpsLatitude']='GPS-Lattitude'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.locationsShown.gpsLongitude']='GPS-Longitude'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.locationsShown.identifiers']='Identifier'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.locationsShown.name']='Name'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.locationsShown.provinceState']='State/Province name'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.locationsShown.sublocation']='Sublocation name'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.locationsShown.worldRegion']='World region name'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.maxAvailHeight']='Max Avail Height'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.maxAvailWidth']='Max Avail Width'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.minorModelAgeDisclosure']='Minor Model Age Disclosure'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.modelAges']='Model Age'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.modelReleaseDocuments']='Model Release Id'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.modelReleaseStatus']='Model Release Status'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.modelReleaseStatus.cvId']='CV-Term CV ID '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.modelReleaseStatus.cvTermName']='CV-Term name '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.modelReleaseStatus.cvTermId']='CV-Term ID '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.modelReleaseStatus.cvTermRefinedAbout']='Refined \'about\' Relationship of the CV-Term '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.organisationInImageCodes']='Code of Organisation Featured in the Image'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.organisationInImageNames']='Name of Organisation Featured in the Image'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.personInImageNames']='Person Shown in the Image'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.personsShown']='Person Shown in the Image with Details'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.personsShown.name']='Name'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.personsShown.description']='Description'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.personsShown.identifiers']='Identifier'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.personsShown.characteristics']='Characteristics'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.personsShown.characteristics.cvId']='CV-Term CV ID '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.personsShown.characteristics.cvTermName']='CV-Term name '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.personsShown.characteristics.cvTermId']='CV-Term ID '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.personsShown.characteristics.cvTermRefinedAbout']='Refined \'about\' Relationship of the CV-Term '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.productsShown']='Product Shown in the Image'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.productsShown.description']='Description '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.productsShown.gtin']='GTIN '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.productsShown.name']='Name {Product detail}'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.propertyReleaseDocuments']='Property Release Id'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.propertyReleaseStatus']='Property Release Status'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.propertyReleaseStatus.cvId']='CV-Term CV ID '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.propertyReleaseStatus.cvTermName']='CV-Term name '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.propertyReleaseStatus.cvTermId']='CV-Term ID '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.propertyReleaseStatus.cvTermRefinedAbout']='Refined \'about\' Relationship of the CV-Term '; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.provinceStatePhoto']='Province or State (legacy)'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.registryEntries']='Image Registry Entry'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.registryEntries.role']='Role'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.registryEntries.assetIdentifier']='Asset Identifier'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.registryEntries.registryIdentifier']='Registry Identifier'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.sceneCodes']='Scene Code'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.source']='Source'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.subjectCodes']='Subject Code'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.sublocationName']='Sublocation (legacy)'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.supplier']='Image Supplier'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.supplier.name']='Name'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.supplier.identifiers']='Identifier'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.title']='Title'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.usageTerms']='Rights Usage Terms'; +$lang['metadata.image_description.iptc.photoVideoMetadataIPTC.webstatementRights']='Web statement rights'; $lang['metadata.image_description.files']='Files'; -$lang['metadata.image_description.files.filename']='File name'; $lang['metadata.image_description.files.format']='File format'; $lang['metadata.image_description.files.note']='Notes'; +$lang['metadata.image_description.files.file_uri']='File'; +$lang['metadata.image_description.files.show']='Show'; + +$lang['metadata.image_description.album']='Albums'; +$lang['metadata.image_description.album.name']='Name'; +$lang['metadata.image_description.album.description']='Description'; +$lang['metadata.image_description.album.owner']='Owner'; +$lang['metadata.image_description.album.uri']='URI'; $lang['files']='Files'; +$lang['album']='Albums'; $lang['image_description']='Image description'; $lang['metadata_production']='Metadata production'; $lang['identification']='Identification'; From 29ac999fcdbcc3ad63abc459c2ab4afaf0ee387a Mon Sep 17 00:00:00 2001 From: Mehmood Asghar Date: Thu, 18 Apr 2019 13:58:32 -0400 Subject: [PATCH 006/103] fix import of @vocabURI attribute for DDI's keyword element --- application/libraries/Metadata_parser/classes/DDI2Reader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/libraries/Metadata_parser/classes/DDI2Reader.php b/application/libraries/Metadata_parser/classes/DDI2Reader.php index 4b54b8b34..323f22c0f 100644 --- a/application/libraries/Metadata_parser/classes/DDI2Reader.php +++ b/application/libraries/Metadata_parser/classes/DDI2Reader.php @@ -353,7 +353,7 @@ function __construct($xml_file) 'cols' => array( '.' => 'keyword', '@vocab'=>'vocab', - '@uri' => 'uri' + '@vocabURI' => 'uri' ) ); From d3c631e3a530add425f3c8d037c5a3886a30aacc Mon Sep 17 00:00:00 2001 From: Mehmood Asghar Date: Tue, 23 Apr 2019 11:55:28 -0400 Subject: [PATCH 007/103] solr search study + variables using single box --- application/libraries/Catalog_search_solr.php | 52 +++++++++++++------ 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/application/libraries/Catalog_search_solr.php b/application/libraries/Catalog_search_solr.php index c23b9498e..134aa579d 100644 --- a/application/libraries/Catalog_search_solr.php +++ b/application/libraries/Catalog_search_solr.php @@ -187,11 +187,15 @@ function search($limit=15,$offset=0) /////////////////// variable search /////////////////////////////////////////////////////// if ($variable!==FALSE){ + /* //set keyword search query if (count($search_query)>0){ $query->setQuery(implode(" AND ",$search_query)); } + //set filter - varcount > 0 + $query->createFilterQuery('varcount')->setQuery('!varcount:0'); + $query->setStart($offset)->setRows($limit); $query->setFields(array( 'id:survey_uid', @@ -233,19 +237,6 @@ function search($limit=15,$offset=0) echo '
'; } - /* - ///////// DEBUG RESULTS ////////////////////////////////////////////// - $debugResult = $resultset->getDebug(); - - echo '

Debug data

'; - echo 'Querystring: ' . $debugResult->getQueryString() . '
'; - echo 'Parsed query: ' . $debugResult->getParsedQuery() . '
'; - echo 'Query parser: ' . $debugResult->getQueryParser() . '
'; - echo 'Other query: ' . $debugResult->getOtherQuery() . '
'; - - ////////////// END DEBUG //////////////////////////////////////////// - */ - //get the total number of documents found by solr $this->search_found_rows=$resultset->getNumFound(); @@ -284,7 +275,8 @@ function search($limit=15,$offset=0) $result['offset']=$offset; $result['citations']=$this->get_survey_citation(); - return $result; + return $result;*/ + throw new exception ("VARIABLE_SEARCH_DISABLED"); } else { @@ -318,7 +310,8 @@ function search($limit=15,$offset=0) 'year_start', 'year_end', 'authoring_entity', - 'score' + 'score', + 'varcount' )); //enable debugging @@ -374,6 +367,29 @@ function search($limit=15,$offset=0) $result['offset']=$offset; $result['citations']=$this->get_survey_citation(); + + if ($result['found']>0){ + //search for variables for SURVEY types + $id_list=array_column($this->search_result, "id"); + + if(count($id_list)>0){ + + //search variables and get the counts + $variables_by_study=$this->get_var_count_by_surveys($id_list,$this->study_keywords); + + if(!empty($variables_by_study)){ + foreach($this->search_result as $idx=>$row) + { + if(array_key_exists($row['id'],$variables_by_study)){ + $this->search_result[$idx]['var_found']=$variables_by_study[$row['id']]; + } + } + } + } + + $result['rows']=$this->search_result; + } + return $result; } @@ -390,6 +406,10 @@ function get_var_count_by_surveys($survey_arr,$variable_keywords) ?q=doctype%3A2+AND+text%3Aeducation+AND+sid%3A(590)&wt=json&indent=true&group=true&group.field=sid&group.ngroups=true&group.limit=0 */ + if(empty($variable_keywords)){ + return; + } + //get a select query instance $query = $this->solr_client->createSelect(); @@ -948,7 +968,7 @@ function v_quick_search($surveyid=NULL,$limit=50,$offset=0) )); //set a query (all prices starting from 12) - $query->setQuery(sprintf('doctype:2 AND _text_:%s AND sid:(%s)',$this->variable_keywords, $surveyid ) ); + $query->setQuery(sprintf('doctype:2 AND _text_:%s AND sid:(%s)',$this->study_keywords, $surveyid ) ); $query->setStart(0)->setRows(100); //get 0-100 rows if($this->debug){ From 2fb21fc1501daf39777287a4d2c02c10ebd96ce5 Mon Sep 17 00:00:00 2001 From: Mehmood Asghar Date: Tue, 23 Apr 2019 11:56:12 -0400 Subject: [PATCH 008/103] set variables limit to 5000 for indexing for solr --- application/views/solr/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/views/solr/index.php b/application/views/solr/index.php index 2c5b5f148..3f6075fea 100644 --- a/application/views/solr/index.php +++ b/application/views/solr/index.php @@ -151,7 +151,7 @@ function index_datasets(start_row=0, limit=5, processed=0) } -function index_variables(start_row=0, limit=1000, processed=0) +function index_variables(start_row=0, limit=5000, processed=0) { var jqxhr = $.get( ""+start_row + '/'+limit, function(data) { console.log(data); From 02570e5c05dd189feb83eacfde70161ebc719088 Mon Sep 17 00:00:00 2001 From: Mehmood Asghar Date: Tue, 23 Apr 2019 11:56:58 -0400 Subject: [PATCH 009/103] misc. --- application/controllers/Solr.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/application/controllers/Solr.php b/application/controllers/Solr.php index 3907621b5..b9efaf643 100644 --- a/application/controllers/Solr.php +++ b/application/controllers/Solr.php @@ -15,12 +15,13 @@ public function __construct() { parent::__construct($skip_auth=TRUE); - if(!$this->input->is_cli_request()){ + /*if(!$this->input->is_cli_request()){ die("ERROR_NOT-CLI"); - } + }*/ $this->load->library('solr_manager'); error_reporting(E_ALL); + //$this->output->enable_profiler(TRUE); } @@ -52,7 +53,7 @@ public function ping_test() * @loop whether to recursively call the function till the end of rows * * */ - public function full_import_surveys($start_row=NULL, $limit=10, $loop=TRUE) + public function full_import_surveys($start_row=NULL, $limit=10, $loop=FALSE) { $this->solr_manager->full_import_surveys($start_row, $limit, $loop); } @@ -85,9 +86,12 @@ function get_total_documents_count() * @loop whether to recursively call the function till the end of rows * * */ - public function full_import_variables($start_row=NULL, $limit=100, $loop=TRUE) + public function full_import_variables($start_row=NULL, $limit=100, $loop=FALSE) { - $this->solr_manager->full_import_variables($start_row, $limit, $loop); + $result=$this->solr_manager->full_import_variables($start_row, $limit, $loop); + + echo '
';
+		print_r($result);
 	}
 
 

From 663b23380b00e05f3b76ccaf5082c4a2a349754a Mon Sep 17 00:00:00 2001
From: Mehmood Asghar 
Date: Tue, 23 Apr 2019 14:46:36 -0400
Subject: [PATCH 010/103] remove variables metadata field from index for SOLR

---
 application/libraries/Solr_manager.php | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/application/libraries/Solr_manager.php b/application/libraries/Solr_manager.php
index 758578863..5a55eb609 100644
--- a/application/libraries/Solr_manager.php
+++ b/application/libraries/Solr_manager.php
@@ -740,8 +740,7 @@ public function full_import_variables($start_row=NULL, $limit=100, $loop=FALSE)
 			labl,
 			catgry,
 			qstn,
-			sid,
-			metadata,
+			sid,			
 			uid as var_uid
 			  ",FALSE);
     	$this->ci->db->limit($limit);

From 84c2132365fab5f9f1e2f70dd6b0af2becf5852f Mon Sep 17 00:00:00 2001
From: Mehmood Asghar 
Date: Tue, 23 Apr 2019 15:53:56 -0400
Subject: [PATCH 011/103] fixed multiple keyword seach issue for SOLR

---
 application/libraries/Catalog_search_solr.php | 22 +++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/application/libraries/Catalog_search_solr.php b/application/libraries/Catalog_search_solr.php
index 134aa579d..28fe4fc2a 100644
--- a/application/libraries/Catalog_search_solr.php
+++ b/application/libraries/Catalog_search_solr.php
@@ -410,15 +410,22 @@ function get_var_count_by_surveys($survey_arr,$variable_keywords)
 			return;
 		}
 
+
 		//get a select query instance
 		$query = $this->solr_client->createSelect();
 
 		//set a query (all prices starting from 12)
-		$query->setQuery(sprintf('doctype:2 AND _text_:%s AND sid:(%s)',$variable_keywords, implode(" OR ",$survey_arr)) );
+		$query->setQuery(sprintf('doctype:2 AND _text_:(%s) AND sid:(%s)',$variable_keywords, implode(" OR ",$survey_arr)) );
 
 		//set start and rows param (comparable to SQL limit) using fluent interface
 		$query->setStart(0)->setRows(100);
 
+
+		if ($this->debug){
+			$debug = $query->getDebug();
+		}
+
+	
 		//get grouping component and set a field to group by
 		$groupComponent = $query->getGrouping();
 		$groupComponent->addField('sid'); //group by field
@@ -428,6 +435,17 @@ function get_var_count_by_surveys($survey_arr,$variable_keywords)
 		//execute search
 		$resultset = $this->solr_client->select($query);
 
+	
+		//get raw query
+		if($this->debug){
+			$request = $this->solr_client->createRequest($query);
+			echo "
"; + echo $request->getUri(); + echo "
"; + //var_dump($resultset->getDebug()); + } + + //get groups resultset $groups = $resultset->getGrouping(); @@ -968,7 +986,7 @@ function v_quick_search($surveyid=NULL,$limit=50,$offset=0) )); //set a query (all prices starting from 12) - $query->setQuery(sprintf('doctype:2 AND _text_:%s AND sid:(%s)',$this->study_keywords, $surveyid ) ); + $query->setQuery(sprintf('doctype:2 AND _text_:(%s) AND sid:(%s)',$this->study_keywords, $surveyid ) ); $query->setStart(0)->setRows(100); //get 0-100 rows if($this->debug){ From deef453b9671bf3882068af74bfaf9cc7da22f01 Mon Sep 17 00:00:00 2001 From: Mehmood Asghar Date: Fri, 26 Apr 2019 20:35:34 -0400 Subject: [PATCH 012/103] Fix for issue #6 - for DDI import look for the file ID in both fileDscr and fileDscr/fileTxt/fileName elements --- application/libraries/DDI2_import.php | 9 ++++++++- .../libraries/Metadata_parser/classes/DDI2Reader.php | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/application/libraries/DDI2_import.php b/application/libraries/DDI2_import.php index caa7206ad..0dac18901 100644 --- a/application/libraries/DDI2_import.php +++ b/application/libraries/DDI2_import.php @@ -88,6 +88,10 @@ public function import($params,$sid=null) $idno=$parser->get_id(); + if (trim($idno)==''){ + throw new Exception(t('Required IDNo element is not set in the DDI xml file. Fix the DDI and set the codeBook/@ID and/or stdyDscr/citation/titlStmt/IDNo element.')); + } + //sanitize ID to remove anything except a-Z1-9 characters if ($idno!==$this->sanitize_filename($idno)){ throw new Exception(t('IDNO_INVALID_FORMAT').': '.$idno); @@ -207,8 +211,11 @@ public function import($params,$sid=null) $data_files=array(); foreach($files as $file){ + if(trim($file['id'])=='' && trim($file['file_id'])!='' ){ + $file['id']=$file['file_id']; + } $data_files[$file['id']]=$file; - } + } unset($files); //import data files and update data_files with file db id diff --git a/application/libraries/Metadata_parser/classes/DDI2Reader.php b/application/libraries/Metadata_parser/classes/DDI2Reader.php index 323f22c0f..23dd037ec 100644 --- a/application/libraries/Metadata_parser/classes/DDI2Reader.php +++ b/application/libraries/Metadata_parser/classes/DDI2Reader.php @@ -34,6 +34,7 @@ function __construct($xml_file) '@ID' => 'id', '@URI' => 'uri', 'fileTxt/fileName' => 'filename', + 'fileTxt/fileName/@ID' => 'file_id', 'fileTxt/dimensns/caseQnty' => 'caseQnty', 'fileTxt/dimensns/varQnty' => 'varQnty', 'fileTxt/fileType' => 'filetype', From 50c4a8979c257876469405957de186ead91dca0a Mon Sep 17 00:00:00 2001 From: Mehmood Asghar Date: Fri, 26 Apr 2019 20:37:27 -0400 Subject: [PATCH 013/103] update batch refresh page formatting and show error details - [issue #6] --- application/controllers/admin/Catalog.php | 12 +++++++++++- application/views/catalog/ddi_batch_refresh.php | 11 ++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/application/controllers/admin/Catalog.php b/application/controllers/admin/Catalog.php index 1b6e766c7..434993dd5 100644 --- a/application/controllers/admin/Catalog.php +++ b/application/controllers/admin/Catalog.php @@ -749,11 +749,21 @@ function refresh($id=NULL) 'errors'=>$e->GetValidationErrors() ); - $error_str='Validation Error
'.print_r($e->GetValidationErrors(),true).'
'; + $error_str='Validation Error
'.print_r($e->GetValidationErrors(),true).'
'; + + if ($is_ajax){ + die (json_encode(array('error'=>$error_str) )); + } + $this->session->set_flashdata('error', $error_str); redirect('admin/catalog/edit/'.$id,'refresh');return; } catch(Exception $e){ + + if ($is_ajax){ + die (json_encode(array('error'=>$e->getMessage()) )); + } + $this->session->set_flashdata('error', $e->getMessage()); redirect('admin/catalog/edit/'.$id,'refresh');return; } diff --git a/application/views/catalog/ddi_batch_refresh.php b/application/views/catalog/ddi_batch_refresh.php index c8e272ca6..16aa9b5de 100644 --- a/application/views/catalog/ddi_batch_refresh.php +++ b/application/views/catalog/ddi_batch_refresh.php @@ -4,7 +4,9 @@ '.$error.'' : '';?>

-

+

+ +
@@ -23,10 +25,9 @@
-'form') );?> - +'form'));?> - +
@@ -42,7 +43,7 @@
- + From 38e69631a949a9897c51a8694e835a5943789d44 Mon Sep 17 00:00:00 2001 From: Mehmood Asghar Date: Fri, 26 Apr 2019 20:44:11 -0400 Subject: [PATCH 014/103] clean up old unused files - issue #9 --- javascript/slidesjs/slides.min.jquery.js | 48 ------ javascript/superfish/changelog.txt | 74 -------- javascript/superfish/css/superfish-navbar.css | 93 ---------- .../superfish/css/superfish-vertical.css | 23 --- javascript/superfish/css/superfish.css | 159 ------------------ javascript/superfish/example.html | 123 -------------- .../superfish/images/arrows-ffffff - Copy.png | Bin 244 -> 0 bytes javascript/superfish/images/arrows-ffffff.png | Bin 3645 -> 0 bytes javascript/superfish/images/shadow.png | Bin 1698 -> 0 bytes javascript/superfish/js/hoverIntent.js | 84 --------- javascript/superfish/js/jquery-1.2.6.min.js | 32 ---- .../superfish/js/jquery.bgiframe.min.js | 10 -- javascript/superfish/js/superfish.js | 121 ------------- javascript/superfish/js/supersubs.js | 90 ---------- 14 files changed, 857 deletions(-) delete mode 100644 javascript/slidesjs/slides.min.jquery.js delete mode 100644 javascript/superfish/changelog.txt delete mode 100644 javascript/superfish/css/superfish-navbar.css delete mode 100644 javascript/superfish/css/superfish-vertical.css delete mode 100644 javascript/superfish/css/superfish.css delete mode 100644 javascript/superfish/example.html delete mode 100644 javascript/superfish/images/arrows-ffffff - Copy.png delete mode 100644 javascript/superfish/images/arrows-ffffff.png delete mode 100644 javascript/superfish/images/shadow.png delete mode 100644 javascript/superfish/js/hoverIntent.js delete mode 100644 javascript/superfish/js/jquery-1.2.6.min.js delete mode 100644 javascript/superfish/js/jquery.bgiframe.min.js delete mode 100644 javascript/superfish/js/superfish.js delete mode 100644 javascript/superfish/js/supersubs.js diff --git a/javascript/slidesjs/slides.min.jquery.js b/javascript/slidesjs/slides.min.jquery.js deleted file mode 100644 index 008921f23..000000000 --- a/javascript/slidesjs/slides.min.jquery.js +++ /dev/null @@ -1,48 +0,0 @@ -/* -* Slides, A Slideshow Plugin for jQuery -* Intructions: http://slidesjs.com -* By: Nathan Searles, http://nathansearles.com -* Version: 1.1.3 -* Updated: February 21th, 2011 -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -(function($){$.fn.slides=function(option){option=$.extend({},$.fn.slides.option,option);return this.each(function(){$('.'+option.container,$(this)).children().wrapAll('
');var elem=$(this),control=$('.slides_control',elem),total=control.children().size(),width=control.children().outerWidth(),height=control.children().outerHeight(),start=option.start-1,effect=option.effect.indexOf(',')<0?option.effect:option.effect.replace(' ','').split(',')[0],paginationEffect=option.effect.indexOf(',')<0?effect:option.effect.replace(' ','').split(',')[1],next=0,prev=0,number=0,current=0,loaded,active,clicked,position,direction,imageParent,pauseTimeout,playInterval;function animate(direction,effect,clicked){if(!active&&loaded){active=true;switch(direction){case'next':prev=current;next=current+1;next=total===next?0:next;position=width*2;direction=-width*2;current=next;break;case'prev':prev=current;next=current-1;next=next===-1?total-1:next;position=0;direction=0;current=next;break;case'pagination':next=parseInt(clicked,10);prev=$('.'+option.paginationClass+' li.current a',elem).attr('href').match('[^#/]+$');if(next>prev){position=width*2;direction=-width*2;}else{position=0;direction=0;} -current=next;break;} -if(effect==='fade'){option.animationStart();if(option.crossfade){control.children(':eq('+next+')',elem).css({zIndex:10}).fadeIn(option.fadeSpeed,option.fadeEasing,function(){if(option.autoHeight){control.animate({height:control.children(':eq('+next+')',elem).outerHeight()},option.autoHeightSpeed,function(){control.children(':eq('+prev+')',elem).css({display:'none',zIndex:0});control.children(':eq('+next+')',elem).css({zIndex:0});option.animationComplete(next+1);active=false;});}else{control.children(':eq('+prev+')',elem).css({display:'none',zIndex:0});control.children(':eq('+next+')',elem).css({zIndex:0});option.animationComplete(next+1);active=false;}});}else{option.animationStart();control.children(':eq('+prev+')',elem).fadeOut(option.fadeSpeed,option.fadeEasing,function(){if(option.autoHeight){control.animate({height:control.children(':eq('+next+')',elem).outerHeight()},option.autoHeightSpeed,function(){control.children(':eq('+next+')',elem).fadeIn(option.fadeSpeed,option.fadeEasing);});}else{control.children(':eq('+next+')',elem).fadeIn(option.fadeSpeed,option.fadeEasing,function(){if($.browser.msie){$(this).get(0).style.removeAttribute('filter');}});} -option.animationComplete(next+1);active=false;});}}else{control.children(':eq('+next+')').css({left:position,display:'block'});if(option.autoHeight){option.animationStart();control.animate({left:direction,height:control.children(':eq('+next+')').outerHeight()},option.slideSpeed,option.slideEasing,function(){control.css({left:-width});control.children(':eq('+next+')').css({left:width,zIndex:5});control.children(':eq('+prev+')').css({left:width,display:'none',zIndex:0});option.animationComplete(next+1);active=false;});}else{option.animationStart();control.animate({left:direction},option.slideSpeed,option.slideEasing,function(){control.css({left:-width});control.children(':eq('+next+')').css({left:width,zIndex:5});control.children(':eq('+prev+')').css({left:width,display:'none',zIndex:0});option.animationComplete(next+1);active=false;});}} -if(option.pagination){$('.'+option.paginationClass+' li.current',elem).removeClass('current');$('.'+option.paginationClass+' li:eq('+next+')',elem).addClass('current');}}} -function stop(){clearInterval(elem.data('interval'));} -function pause(){if(option.pause){clearTimeout(elem.data('pause'));clearInterval(elem.data('interval'));pauseTimeout=setTimeout(function(){clearTimeout(elem.data('pause'));playInterval=setInterval(function(){animate("next",effect);},option.play);elem.data('interval',playInterval);},option.pause);elem.data('pause',pauseTimeout);}else{stop();}} -if(total<2){return;} -if(start<0){start=0;} -if(start>total){start=total-1;} -if(option.start){current=start;} -if(option.randomize){control.randomize();} -$('.'+option.container,elem).css({overflow:'hidden',position:'relative'});control.children().css({position:'absolute',top:0,left:control.children().outerWidth(),zIndex:0,display:'none'});control.css({position:'relative',width:(width*3),height:height,left:-width});$('.'+option.container,elem).css({display:'block'});if(option.autoHeight){control.children().css({height:'auto'});control.animate({height:control.children(':eq('+start+')').outerHeight()},option.autoHeightSpeed);} -if(option.preload&&control.find('img').length){$('.'+option.container,elem).css({background:'url('+option.preloadImage+') no-repeat 50% 50%'});var img=control.find('img:eq('+start+')').attr('src')+'?'+(new Date()).getTime();if($('img',elem).parent().attr('class')!='slides_control'){imageParent=control.children(':eq(0)')[0].tagName.toLowerCase();}else{imageParent=control.find('img:eq('+start+')');} -control.find('img:eq('+start+')').attr('src',img).load(function(){control.find(imageParent+':eq('+start+')').fadeIn(option.fadeSpeed,option.fadeEasing,function(){$(this).css({zIndex:5});elem.css({background:''});loaded=true;});});}else{control.children(':eq('+start+')').fadeIn(option.fadeSpeed,option.fadeEasing,function(){loaded=true;});} -if(option.bigTarget){control.children().css({cursor:'pointer'});control.children().click(function(){animate('next',effect);return false;});} -if(option.hoverPause&&option.play){control.bind('mouseover',function(){stop();});control.bind('mouseleave',function(){pause();});} -if(option.generateNextPrev){$('.'+option.container,elem).after('Prev');$('.'+option.prev,elem).after('Next');} -$('.'+option.next,elem).click(function(e){e.preventDefault();if(option.play){pause();} -animate('next',effect);});$('.'+option.prev,elem).click(function(e){e.preventDefault();if(option.play){pause();} -animate('prev',effect);});if(option.generatePagination){elem.append('
    ');control.children().each(function(){$('.'+option.paginationClass,elem).append('
  • '+(number+1)+'
  • ');number++;});}else{$('.'+option.paginationClass+' li a',elem).each(function(){$(this).attr('href','#'+number);number++;});} -$('.'+option.paginationClass+' li:eq('+start+')',elem).addClass('current');$('.'+option.paginationClass+' li a',elem).click(function(){if(option.play){pause();} -clicked=$(this).attr('href').match('[^#/]+$');if(current!=clicked){animate('pagination',paginationEffect,clicked);} -return false;});$('a.link',elem).click(function(){if(option.play){pause();} -clicked=$(this).attr('href').match('[^#/]+$')-1;if(current!=clicked){animate('pagination',paginationEffect,clicked);} -return false;});if(option.play){playInterval=setInterval(function(){animate('next',effect);},option.play);elem.data('interval',playInterval);}});};$.fn.slides.option={preload:false,preloadImage:'',container:'slides_container',generateNextPrev:false,next:'next',prev:'prev',pagination:true,generatePagination:true,paginationClass:'pagination',fadeSpeed:350,fadeEasing:'',slideSpeed:350,slideEasing:'',start:1,effect:'slide',crossfade:false,randomize:false,play:0,pause:0,hoverPause:false,autoHeight:false,autoHeightSpeed:350,bigTarget:false,animationStart:function(){},animationComplete:function(){}};$.fn.randomize=function(callback){function randomizeOrder(){return(Math.round(Math.random())-0.5);} -return($(this).each(function(){var $this=$(this);var $children=$this.children();var childCount=$children.length;if(childCount>1){$children.hide();var indices=[];for(i=0;iul') for smoother animations - Also deleted the iframe removal lines - not necessary it turns out - -v1.2.3: altered jquery 1.1.3.1 broke keyboard access - had to change quite a few things and set display:none on the - .superfish rule in CSS instead of top:-999em - -v1.3: Pretty much a complete overhaul to make all original features work in 1.1.3.1 and above. - .superfish rule reverted back to top:-999em (which is better). - -v1.3.1: altered 'li[ul]' to $('li:has(ul)') to work with jQuery 1.2 - -v1.3.2: added onshow callback option as requested - 'this' keyword refers to revealed ul. - fixed bug whereby multiple menus on a page shared options. Now each menu can have separate options. - fixed IE6 and IE7 bug whereby under certain circumstances => 3rd tier menus appear instantly with text missing when revisited - -v1.3.3: altered event attachment selectors for performance increase on menu setup. - -v1.3.4: fixed pathClass bug as current path was not being restored. Still doesn't if using keyboard nav (will work on that). - -v1.4: store options objects in array $.superfish.o. Also provide public access to $.superfish.defaults - provided backward compat for jQuery versions less than 1.2 via oldJquery option - will use li[ul] or li:has(ul) as needed - added more callbacks, also added option to disable hoverIntent usage if that plugin is detected - -v1.4.1: fixed current path not being restored when using keyboard to tab away from the menu completely - optimised code further - now less code - removed addself() in favour of backward compatible add(this) - also remove new mouseenter/mouseleave events on window.unload (due to paranoia) - -v1.4.2: 3rd July 2008. added semi-colon at start of superfish.js file to avert script concatenation errors - added pathLevels option to limit the depth of submenus that get restored by pathClass - CSS of main example hugely simplified - other example CSS files less-so. - - top level menu items are not fixed width - - only need to set submenu widths in one place. - - various other improvements. - - class names used in all CSS files are changed to be less generic - released optional Supersubs plugin which dynamically adjusts submenu widths - attach everything to jQuery.fn.superfish to clean up jQuery namespace - removed the multi-tier-all-horizontal-example as it was never a great idea and doesn't seem to be in use - Update documentation text and remove certain caveats which were there to support users of much older versions of Superfish - Documentation now show how to apply bgIgrame 2.1 - it's much easier than before - Add all links and their focus and blur events to the onunload unbind - paranoid about memory leaks - -v1.4.3 5th July 2008. documentation completely redone using Mike Alsup's templates. - CSS revised so that all types of menu use superfish.css as a base. Include additional CSS files to acheive alternate styles. - class="sf-menu sf-vertical" creates vertical menu, class="sf-menu sf-navbar" creates nav-bar style menu - -v1.4.4 7th July 2008. arrows feature added. If option 'autoArrows' is true, auto-appends (spans) to anchors that have a ul submenu sibling, - and adds class 'sf-with-ul' to anchor. - CSS added to style new arrows, including an 8-bit alpha (NOT INDEXED!) transparent png of arrow - degrades to solid for IE6. - Manually add arrow mark-up to docs and disable autoArrows (via defaults option) to maintain decent performance (for docs page) - Update docs, including zip download, to suit. - Fix CSS bug that had the third tier of the navbar-style menu visible when JS not available. - -v1.4.5 9 July 2008. decreased code weight - added drop shadows for capable browsers - added css and 8-bit alpha transparent png image for shadow - remove support for jQuery v<1.2 - remove unload clean-up which was there to solve garbage collection problems in early jQuery versions - remove toggling 'visibility' on hide and show which as a fix for an IE bug that is no longer exhibited - removed need for getOpts, rewrote getMenu - use [].join('') instead of string concatenation for performance increase - probably very slight in this case - change selector in 'over' function from '.'+o.hoverClass to 'li.'+o.hoverClass - -v1.4.6 added workaround for IE7 shadows. If animation alters opacity then shadow is hidden during the animation and appears after. - This required some JS and a line of CSS, so created shortcut references to lighten code further. - -v1.4.7 added back in the visibility toggle that was removed in 1.4.5 as the bug is indeed still exhibited by IE6 & 7 - tweaked the look of the shadow slightly and use nicer 32bit png as I now find they behave the same as 8bit png with regard to fades in IE7 - -v1.4.8 fix over-sight: using 32bit png meant that the shadow image did show in IE6. Rather than go back to 8bit, add code to exclude IE6 from getting shadow class. - use new folder structure recommended by Matt from TopicTrack, for easier updates. \ No newline at end of file diff --git a/javascript/superfish/css/superfish-navbar.css b/javascript/superfish/css/superfish-navbar.css deleted file mode 100644 index 68c713584..000000000 --- a/javascript/superfish/css/superfish-navbar.css +++ /dev/null @@ -1,93 +0,0 @@ - -/*** adding the class sf-navbar in addition to sf-menu creates an all-horizontal nav-bar menu ***/ -.sf-navbar { - background: #BDD2FF; - height: 2.5em; - padding-bottom: 2.5em; - position: relative; -} -.sf-navbar li { - background: #AABDE6; - position: static; -} -.sf-navbar a { - border-top: none; -} -.sf-navbar li ul { - width: 44em; /*IE6 soils itself without this*/ -} -.sf-navbar li li { - background: #BDD2FF; - position: relative; -} -.sf-navbar li li ul { - width: 13em; -} -.sf-navbar li li li { - width: 100%; -} -.sf-navbar ul li { - width: auto; - float: left; -} -.sf-navbar a, .sf-navbar a:visited { - border: none; -} -.sf-navbar li.current { - background: #BDD2FF; -} -.sf-navbar li:hover, -.sf-navbar li.sfHover, -.sf-navbar li li.current, -.sf-navbar a:focus, .sf-navbar a:hover, .sf-navbar a:active { - background: #BDD2FF; -} -.sf-navbar ul li:hover, -.sf-navbar ul li.sfHover, -ul.sf-navbar ul li:hover li, -ul.sf-navbar ul li.sfHover li, -.sf-navbar ul a:focus, .sf-navbar ul a:hover, .sf-navbar ul a:active { - background: #D1DFFF; -} -ul.sf-navbar li li li:hover, -ul.sf-navbar li li li.sfHover, -.sf-navbar li li.current li.current, -.sf-navbar ul li li a:focus, .sf-navbar ul li li a:hover, .sf-navbar ul li li a:active { - background: #E6EEFF; -} -ul.sf-navbar .current ul, -ul.sf-navbar ul li:hover ul, -ul.sf-navbar ul li.sfHover ul { - left: 0; - top: 2.5em; /* match top ul list item height */ -} -ul.sf-navbar .current ul ul { - top: -999em; -} - -.sf-navbar li li.current > a { - font-weight: bold; -} - -/*** point all arrows down ***/ -/* point right for anchors in subs */ -.sf-navbar ul .sf-sub-indicator { background-position: -10px -100px; } -.sf-navbar ul a > .sf-sub-indicator { background-position: 0 -100px; } -/* apply hovers to modern browsers */ -.sf-navbar ul a:focus > .sf-sub-indicator, -.sf-navbar ul a:hover > .sf-sub-indicator, -.sf-navbar ul a:active > .sf-sub-indicator, -.sf-navbar ul li:hover > a > .sf-sub-indicator, -.sf-navbar ul li.sfHover > a > .sf-sub-indicator { - background-position: -10px -100px; /* arrow hovers for modern browsers*/ -} - -/*** remove shadow on first submenu ***/ -.sf-navbar > li > ul { - background: transparent; - padding: 0; - -moz-border-radius-bottomleft: 0; - -moz-border-radius-topright: 0; - -webkit-border-top-right-radius: 0; - -webkit-border-bottom-left-radius: 0; -} \ No newline at end of file diff --git a/javascript/superfish/css/superfish-vertical.css b/javascript/superfish/css/superfish-vertical.css deleted file mode 100644 index 8025b7859..000000000 --- a/javascript/superfish/css/superfish-vertical.css +++ /dev/null @@ -1,23 +0,0 @@ -/*** adding sf-vertical in addition to sf-menu creates a vertical menu ***/ -.sf-vertical, .sf-vertical li { - width: 10em; -} -/* this lacks ul at the start of the selector, so the styles from the main CSS file override it where needed */ -.sf-vertical li:hover ul, -.sf-vertical li.sfHover ul { - left: 10em; /* match ul width */ - top: 0; -} - -/*** alter arrow directions ***/ -.sf-vertical .sf-sub-indicator { background-position: -10px 0; } /* IE6 gets solid image only */ -.sf-vertical a > .sf-sub-indicator { background-position: 0 0; } /* use translucent arrow for modern browsers*/ - -/* hover arrow direction for modern browsers*/ -.sf-vertical a:focus > .sf-sub-indicator, -.sf-vertical a:hover > .sf-sub-indicator, -.sf-vertical a:active > .sf-sub-indicator, -.sf-vertical li:hover > a > .sf-sub-indicator, -.sf-vertical li.sfHover > a > .sf-sub-indicator { - background-position: -10px 0; /* arrow hovers for modern browsers*/ -} \ No newline at end of file diff --git a/javascript/superfish/css/superfish.css b/javascript/superfish/css/superfish.css deleted file mode 100644 index 23c379317..000000000 --- a/javascript/superfish/css/superfish.css +++ /dev/null @@ -1,159 +0,0 @@ - -/*** ESSENTIAL STYLES ***/ -.sf-menu, .sf-menu * { - margin: 0; - padding: 0; - list-style: none; - z-index:100; -} -.sf-menu { - line-height: 1.0; -} -.sf-menu ul { - position: absolute; - top: -999em; - width: 10em; /* left offset of submenus need to match (see below) */ -} -.sf-menu ul li { - width:auto -} -.sf-menu li li { - width: 200px; - z-index:2000; -} - -.sf-menu li:hover { - visibility: inherit; /* fixes IE7 'sticky bug' */ - color:white; -} -.sf-menu li { - float: left; - position: relative; - border-right:1px solid gainsboro; -} -.sf-menu a { - display: block; - position: relative; -} -.sf-menu li:hover ul, -.sf-menu li.sfHover ul { - left: 0; - top: 2.5em; /* match top ul list item height */ - z-index: 99; - color:white; -} -ul.sf-menu li:hover li ul, -ul.sf-menu li.sfHover li ul { - top: -999em; - color:white; -} -ul.sf-menu li li:hover ul, -ul.sf-menu li li.sfHover ul { - left: 10em; /* match ul width */ - top: 0; - color:white; -} -ul.sf-menu li li:hover li ul, -ul.sf-menu li li.sfHover li ul { - top: -999em; - color:white; -} -ul.sf-menu li li li:hover ul, -ul.sf-menu li li li.sfHover ul { - left: 10em; /* match ul width */ - top: 0; - color:white; -} - -/*** DEMO SKIN ***/ -.sf-menu { - float: left; - margin-bottom: 1em; -} -.sf-menu a { - border-left: 1px solid #fff; - border-top: 1px solid #CFDEFF; - padding: .75em 1em; - text-decoration:none; -} -.sf-menu a{ /* visited pseudo selector so IE6 applies text colour*/ - color: gray; - font-weight:bold; -} - -.sf-menu li li a{ - color:#CCCCCC; - font-weight:normal; -} - -.sf-menu li { - background: white; -} -.sf-menu li li { - background-color:#333333; -} -.sf-menu li li li { - background:#333333; -} -.sf-menu li:hover, .sf-menu li.sfHover, -.sf-menu a:focus, .sf-menu a:hover, .sf-menu a:active { - background:#333333; - outline: 0; - color:white; -} - -/*** arrows **/ -.sf-menu a.sf-with-ul { - padding-right: 2.25em; - min-width: 1px; /* trigger IE7 hasLayout so spans position accurately */ -} -.sf-sub-indicator { - position: absolute; - display: block; - right: .75em; - top: 1.05em; /* IE6 only */ - width: 10px; - height: 10px; - text-indent: -999em; - overflow: hidden; - background: url('../images/arrows-ffffff.png') no-repeat -10px -100px; /* 8-bit indexed alpha png. IE6 gets solid image only */ -} -a > .sf-sub-indicator { /* give all except IE6 the correct values */ - top: .8em; - background-position: 0 -100px; /* use translucent arrow for modern browsers*/ -} -/* apply hovers to modern browsers */ -a:focus > .sf-sub-indicator, -a:hover > .sf-sub-indicator, -a:active > .sf-sub-indicator, -li:hover > a > .sf-sub-indicator, -li.sfHover > a > .sf-sub-indicator { - background-position: -10px -100px; /* arrow hovers for modern browsers*/ - color:white; -} - -/* point right for anchors in subs */ -.sf-menu ul .sf-sub-indicator { background-position: -10px 0; } -.sf-menu ul a > .sf-sub-indicator { background-position: 0 0; } -/* apply hovers to modern browsers */ -.sf-menu ul a:focus > .sf-sub-indicator, -.sf-menu ul a:hover > .sf-sub-indicator, -.sf-menu ul a:active > .sf-sub-indicator, -.sf-menu ul li:hover > a > .sf-sub-indicator, -.sf-menu ul li.sfHover > a > .sf-sub-indicator { - background-position: -10px 0; /* arrow hovers for modern browsers*/ - color:white; -} - -/*** shadows for all but IE6 ***/ -.sf-shadow ul { - background: url('../images/shadow.png') no-repeat bottom right; - padding: 0 8px 9px 0; - -moz-border-radius-bottomleft: 17px; - -moz-border-radius-topright: 17px; - -webkit-border-top-right-radius: 17px; - -webkit-border-bottom-left-radius: 17px; -} -.sf-shadow ul.sf-shadow-off { - background: transparent; -} diff --git a/javascript/superfish/example.html b/javascript/superfish/example.html deleted file mode 100644 index 582052717..000000000 --- a/javascript/superfish/example.html +++ /dev/null @@ -1,123 +0,0 @@ - - - - A very basic Superfish menu example - - - - - - - - - - - \ No newline at end of file diff --git a/javascript/superfish/images/arrows-ffffff - Copy.png b/javascript/superfish/images/arrows-ffffff - Copy.png deleted file mode 100644 index 995df52065bc250180081f895070ee63de05bfe7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 244 zcmeAS@N?(olHy`uVBq!ia0vp^B0!wS#0(^(;%-|4Ddu7)&kzm{j@u9Y9{{*+s`nvx*DV21Ml+qsS;fz%XuL>4nJa0`JjKLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z00093P)t-s00000000000Q~&?`}_O)`uh3#`S|$w_xJbq_V)Gl_4M@g^Yioa^78TV z@$m5Q@9*#K?(XgF?d+9?4>gws~>FDU_=jZ3<=H}()<>ch#(^($dk<(a_M)&(F`! z&d$xv&CJZq%gf8k%F4;f$;ima$H&LU#>U0P#l*zK!^6YE!otD9!N9=4zrVk}zP`P^ zy}Z1%^r>Cc;rlzH(rKF^!qobpuqN1Upp`f6kpP!$eo}QhZot&JUo12@O znwpuJnV6WEmzS58mX?*3m6Vi}larH@l9G{;k&uv(kB^Uzj*g9ujf{+pi;Ihjii(Me ziHL}ZhlhuThK7ZOg@lBJgM)*Df`Wm8fq;O3e}8{|etvy@eSCa;dwY9&dU|OZ*OmIZf={DJUo?CnqN+CMG2%B_t#yBO@asA|fFn zAs`?iA0Hnc9v&SX9UL4S8yg!M8X6fH85kHC7Z(>678Vs16%-T{6B82>5)u&+5fBg% z4-XFx4h{_s4Gatn3kwSh3JM7c2?z)X2L}fR1_lKM1q1{H0|NsB0s;X60RR91v~Ssb5yv%|q0R^ISzrtRtD*pxMFQ@2 P00000NkvXXu0mjf5n{)b diff --git a/javascript/superfish/images/shadow.png b/javascript/superfish/images/shadow.png deleted file mode 100644 index c04d21b76ecfec013db907302f6bd35afff6cef9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1698 zcmeAS@N?(olHy`uVBq!ia0y~yV4TOmz!by50u)K!%e4$hNtU=qlmzFem6RtIr7}3C zX}uDbwD2HC(*ycgt4t?ty+@+wPUlR;uUiAH4mbx%Td3O?Q*$ zf&zQmF8}g8dC^~1Y@56N`Id%svugXbOJqMzNq%PY>BN*-n!)@W7LRXkPCY$Kvh?pylS=lQEeJmx&}%I_=-`FKFUe^aWI+!LPc+s5;Ys_!vxdGhVg=U0pN)oi@O zH(|f%$AZ)c_dD2+Fh64a*igX$#11wJasvDy3=tjxDF+*z&Y+=G2RoXV5q8l~>f;U; zSXkqU26{?8VjPWfP)eX#Y8W|De&GL-eKmQ98S63@?fZFZo^AD{N4pM&9@*aVN_Vbp z^|qYI$u>urZReRrZ&O^TJg>~`(x&v&vs8m8`Pvvv*_d*2mhSJFey=A#Uy1q3A9|9{K22WQ% Jmvv4FO#s~6iZ1{F diff --git a/javascript/superfish/js/hoverIntent.js b/javascript/superfish/js/hoverIntent.js deleted file mode 100644 index 91da57b24..000000000 --- a/javascript/superfish/js/hoverIntent.js +++ /dev/null @@ -1,84 +0,0 @@ -(function($){ - /* hoverIntent by Brian Cherne */ - $.fn.hoverIntent = function(f,g) { - // default configuration options - var cfg = { - sensitivity: 7, - interval: 100, - timeout: 0 - }; - // override configuration options with user supplied object - cfg = $.extend(cfg, g ? { over: f, out: g } : f ); - - // instantiate variables - // cX, cY = current X and Y position of mouse, updated by mousemove event - // pX, pY = previous X and Y position of mouse, set by mouseover and polling interval - var cX, cY, pX, pY; - - // A private function for getting mouse position - var track = function(ev) { - cX = ev.pageX; - cY = ev.pageY; - }; - - // A private function for comparing current and previous mouse position - var compare = function(ev,ob) { - ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); - // compare mouse positions to see if they've crossed the threshold - if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) { - $(ob).unbind("mousemove",track); - // set hoverIntent state to true (so mouseOut can be called) - ob.hoverIntent_s = 1; - return cfg.over.apply(ob,[ev]); - } else { - // set previous coordinates for next time - pX = cX; pY = cY; - // use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs) - ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval ); - } - }; - - // A private function for delaying the mouseOut function - var delay = function(ev,ob) { - ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); - ob.hoverIntent_s = 0; - return cfg.out.apply(ob,[ev]); - }; - - // A private function for handling mouse 'hovering' - var handleHover = function(e) { - // next three lines copied from jQuery.hover, ignore children onMouseOver/onMouseOut - var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget; - while ( p && p != this ) { try { p = p.parentNode; } catch(e) { p = this; } } - if ( p == this ) { return false; } - - // copy objects to be passed into t (required for event object to be passed in IE) - var ev = jQuery.extend({},e); - var ob = this; - - // cancel hoverIntent timer if it exists - if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); } - - // else e.type == "onmouseover" - if (e.type == "mouseover") { - // set "previous" X and Y position based on initial entry point - pX = ev.pageX; pY = ev.pageY; - // update "current" X and Y position based on mousemove - $(ob).bind("mousemove",track); - // start polling interval (self-calling timeout) to compare mouse coordinates over time - if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );} - - // else e.type == "onmouseout" - } else { - // unbind expensive mousemove event - $(ob).unbind("mousemove",track); - // if hoverIntent state is true, then call the mouseOut function after the specified delay - if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );} - } - }; - - // bind the function to the two event listeners - return this.mouseover(handleHover).mouseout(handleHover); - }; - -})(jQuery); \ No newline at end of file diff --git a/javascript/superfish/js/jquery-1.2.6.min.js b/javascript/superfish/js/jquery-1.2.6.min.js deleted file mode 100644 index 82b98e1d7..000000000 --- a/javascript/superfish/js/jquery-1.2.6.min.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - * jQuery 1.2.6 - New Wave Javascript - * - * Copyright (c) 2008 John Resig (jquery.com) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. - * - * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $ - * $Rev: 5685 $ - */ -(function(){var _jQuery=window.jQuery,_$=window.$;var jQuery=window.jQuery=window.$=function(selector,context){return new jQuery.fn.init(selector,context);};var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,isSimple=/^.[^:#\[\.]*$/,undefined;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;return this;}if(typeof selector=="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1])selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem){if(elem.id!=match[3])return jQuery().find(selector);return jQuery(elem);}selector=[];}}else -return jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(jQuery.makeArray(selector));},jquery:"1.2.6",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(elems){var ret=jQuery(elems);ret.prevObject=this;return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){var ret=-1;return jQuery.inArray(elem&&elem.jquery?elem[0]:elem,this);},attr:function(name,value,type){var options=name;if(name.constructor==String)if(value===undefined)return this[0]&&jQuery[type||"attr"](this[0],name);else{options={};options[name]=value;}return this.each(function(i){for(name in options)jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:function(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0)value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!="object"&&text!=null)return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,false,function(elem){if(this.nodeType==1)this.appendChild(elem);});},prepend:function(){return this.domManip(arguments,true,true,function(elem){if(this.nodeType==1)this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,true,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(selector){var elems=jQuery.map(this,function(elem){return jQuery.find(selector,elem);});return this.pushStack(/[^+>] [^+>]/.test(selector)||selector.indexOf("..")>-1?jQuery.unique(elems):elems);},clone:function(events){var ret=this.map(function(){if(jQuery.browser.msie&&!jQuery.isXMLDoc(this)){var clone=this.cloneNode(true),container=document.createElement("div");container.appendChild(clone);return jQuery.clean([container.innerHTML])[0];}else -return this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){if(this.nodeType==3)return;var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,this));},not:function(selector){if(selector.constructor==String)if(isSimple.test(selector))return this.pushStack(jQuery.multiFilter(selector,this,true));else -selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return this.pushStack(jQuery.unique(jQuery.merge(this.get(),typeof selector=='string'?jQuery(selector):jQuery.makeArray(selector))));},is:function(selector){return!!selector&&jQuery.multiFilter(selector,this).length>0;},hasClass:function(selector){return this.is("."+selector);},val:function(value){if(value==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=jQuery.makeArray(value);jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length)this.selectedIndex=-1;}else -this.value=value;});},html:function(value){return value==undefined?(this[0]?this[0].innerHTML:null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value===undefined){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data===undefined&&this.length)data=jQuery.data(this[0],key);return data===undefined&&parts[1]?this.data(parts[0]):data;}else -return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);if(reverse)elems.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(this.ownerDocument.createElement("tbody"));var scripts=jQuery([]);jQuery.each(elems,function(){var elem=clone?jQuery(this).clone(true)[0]:this;if(jQuery.nodeName(elem,"script"))scripts=scripts.add(elem);else{if(elem.nodeType==1)scripts=scripts.add(jQuery("script",elem).remove());callback.call(obj,elem);}});scripts.each(evalScript);});}};jQuery.fn.init.prototype=jQuery.fn;function evalScript(i,elem){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else -jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}function now(){return+new Date;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};i=2;}if(typeof target!="object"&&typeof target!="function")target={};if(length==i){target=this;--i;}for(;i-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];}callback.call(elem);for(var name in options)elem.style[name]=old[name];},css:function(elem,name,force){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;var padding=0,border=0;jQuery.each(which,function(){padding+=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;border+=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});val-=Math.round(padding+border);}if(jQuery(elem).is(":visible"))getWH();else -jQuery.swap(elem,props,getWH);return Math.max(0,val);}return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret,style=elem.style;function color(elem){if(!jQuery.browser.safari)return false;var ret=defaultView.getComputedStyle(elem,null);return!ret||ret.getPropertyValue("color")=="";}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(style,"opacity");return ret==""?"1":ret;}if(jQuery.browser.opera&&name=="display"){var save=style.outline;style.outline="0 solid black";style.outline=save;}if(name.match(/float/i))name=styleFloat;if(!force&&style&&style[name])ret=style[name];else if(defaultView.getComputedStyle){if(name.match(/float/i))name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var computedStyle=defaultView.getComputedStyle(elem,null);if(computedStyle&&!color(elem))ret=computedStyle.getPropertyValue(name);else{var swap=[],stack=[],a=elem,i=0;for(;a&&color(a);a=a.parentNode)stack.unshift(a);for(;i]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+">";});var tags=jQuery.trim(elem).toLowerCase(),div=context.createElement("div");var wrap=!tags.indexOf("",""]||!tags.indexOf("",""]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
    "]||!tags.indexOf("",""]||(!tags.indexOf("",""]||!tags.indexOf("",""]||jQuery.browser.msie&&[1,"div
    ","
    "]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){var tbody=!tags.indexOf(""&&tags.indexOf("=0;--j)if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length)tbody[j].parentNode.removeChild(tbody[j]);if(/^\s/.test(elem))div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);}elem=jQuery.makeArray(div.childNodes);}if(elem.length===0&&(!jQuery.nodeName(elem,"form")&&!jQuery.nodeName(elem,"select")))return;if(elem[0]==undefined||jQuery.nodeName(elem,"form")||elem.options)ret.push(elem);else -ret=jQuery.merge(ret,elem);});return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8)return undefined;var notxml=!jQuery.isXMLDoc(elem),set=value!==undefined,msie=jQuery.browser.msie;name=notxml&&jQuery.props[name]||name;if(elem.tagName){var special=/href|src|style/.test(name);if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(name in elem&¬xml&&!special){if(set){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem[name]=value;}if(jQuery.nodeName(elem,"form")&&elem.getAttributeNode(name))return elem.getAttributeNode(name).nodeValue;return elem[name];}if(msie&¬xml&&name=="style")return jQuery.attr(elem.style,"cssText",value);if(set)elem.setAttribute(name,""+value);var attr=msie&¬xml&&special?elem.getAttribute(name,2):elem.getAttribute(name);return attr===null?undefined:attr;}if(msie&&name=="opacity"){if(set){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(value)+''=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100)+'':"";}name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();});if(set)elem[name]=value;return elem[name];},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");},makeArray:function(array){var ret=[];if(array!=null){var i=array.length;if(i==null||array.split||array.setInterval||array.call)ret[0]=array;else -while(i)ret[--i]=array[i];}return ret;},inArray:function(elem,array){for(var i=0,length=array.length;i*",this).remove();while(this.firstChild)this.removeChild(this.firstChild);}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);};});jQuery.each(["Height","Width"],function(i,name){var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?jQuery.browser.opera&&document.body["client"+name]||jQuery.browser.safari&&window["inner"+name]||document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(Math.max(document.body["scroll"+name],document.documentElement["scroll"+name]),Math.max(document.body["offset"+name],document.documentElement["offset"+name])):size==undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,size.constructor==String?size:size+"px");};});function num(elem,prop){return elem[0]&&parseInt(jQuery.curCSS(elem[0],prop,true),10)||0;}var chars=jQuery.browser.safari&&parseInt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},"#":function(a,i,m){return a.getAttribute("id")==m[2];},":":{lt:function(a,i,m){return im[3]-0;},nth:function(a,i,m){return m[3]-0==i;},eq:function(a,i,m){return m[3]-0==i;},first:function(a,i){return i==0;},last:function(a,i,m,r){return i==r.length-1;},even:function(a,i){return i%2==0;},odd:function(a,i){return i%2;},"first-child":function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},"last-child":function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},"only-child":function(a){return!jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},parent:function(a){return a.firstChild;},empty:function(a){return!a.firstChild;},contains:function(a,i,m){return(a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},visible:function(a){return"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},hidden:function(a){return"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},enabled:function(a){return!a.disabled;},disabled:function(a){return a.disabled;},checked:function(a){return a.checked;},selected:function(a){return a.selected||jQuery.attr(a,"selected");},text:function(a){return"text"==a.type;},radio:function(a){return"radio"==a.type;},checkbox:function(a){return"checkbox"==a.type;},file:function(a){return"file"==a.type;},password:function(a){return"password"==a.type;},submit:function(a){return"submit"==a.type;},image:function(a){return"image"==a.type;},reset:function(a){return"reset"==a.type;},button:function(a){return"button"==a.type||jQuery.nodeName(a,"button");},input:function(a){return/input|select|textarea|button/i.test(a.nodeName);},has:function(a,i,m){return jQuery.find(m[3],a).length;},header:function(a){return/h\d/i.test(a.nodeName);},animated:function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&context.nodeType!=1&&context.nodeType!=9)return[];context=context||document;var ret=[context],done=[],last,nodeName;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false,re=quickChild,m=re.exec(t);if(m){nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var merge={};nodeName=m[2].toUpperCase();m=m[1];for(var j=0,rl=ret.length;j=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=isSimple.test(m[3])?jQuery.filter(m[3],r,true).r:jQuery(r).not(m[3]);else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"0n+"+m[3]||m[3]),first=(test[1]+(test[2]||1))-0,last=test[3]-0;for(var i=0,rl=r.length;i=0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var fn=jQuery.expr[m[1]];if(typeof fn=="object")fn=fn[m[2]];if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+";}");r=jQuery.grep(r,function(elem,i){return fn(elem,i,m,r);},not);}}return{r:r,t:t};},dir:function(elem,dir){var matched=[],cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1)matched.push(cur);cur=cur[dir];}return matched;},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir])if(cur.nodeType==1&&++num==result)break;return cur;},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&n!=elem)r.push(n);}return r;}});jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8)return;if(jQuery.browser.msie&&elem.setInterval)elem=window;if(!handler.guid)handler.guid=this.guid++;if(data!=undefined){var fn=handler;handler=this.proxy(fn,function(){return fn.apply(this,arguments);});handler.data=data;}var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){if(typeof jQuery!="undefined"&&!jQuery.event.triggered)return jQuery.event.handle.apply(arguments.callee.elem,arguments);});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];handler.type=parts[1];var handlers=events[type];if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem)===false){if(elem.addEventListener)elem.addEventListener(type,handle,false);else if(elem.attachEvent)elem.attachEvent("on"+type,handle);}}handlers[handler.guid]=handler;jQuery.event.global[type]=true;});elem=null;},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8)return;var events=jQuery.data(elem,"events"),ret,index;if(events){if(types==undefined||(typeof types=="string"&&types.charAt(0)=="."))for(var type in events)this.remove(elem,type+(types||""));else{if(types.type){handler=types.handler;types=types.type;}jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];if(events[type]){if(handler)delete events[type][handler.guid];else -for(handler in events[type])if(!parts[1]||events[type][handler].type==parts[1])delete events[type][handler];for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem)===false){if(elem.removeEventListener)elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent)elem.detachEvent("on"+type,jQuery.data(elem,"handle"));}ret=null;delete events[type];}}});}for(ret in events)break;if(!ret){var handle=jQuery.data(elem,"handle");if(handle)handle.elem=null;jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle");}}},trigger:function(type,data,elem,donative,extra){data=jQuery.makeArray(data);if(type.indexOf("!")>=0){type=type.slice(0,-1);var exclusive=true;}if(!elem){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{if(elem.nodeType==3||elem.nodeType==8)return undefined;var val,ret,fn=jQuery.isFunction(elem[type]||null),event=!data[0]||!data[0].preventDefault;if(event){data.unshift({type:type,target:elem,preventDefault:function(){},stopPropagation:function(){},timeStamp:now()});data[0][expando]=true;}data[0].type=type;if(exclusive)data[0].exclusive=true;var handle=jQuery.data(elem,"handle");if(handle)val=handle.apply(elem,data);if((!fn||(jQuery.nodeName(elem,'a')&&type=="click"))&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false)val=false;if(event)data.shift();if(extra&&jQuery.isFunction(extra)){ret=extra.apply(elem,val==null?data:data.concat(val));if(ret!==undefined)val=ret;}if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(elem,'a')&&type=="click")){this.triggered=true;try{elem[type]();}catch(e){}}this.triggered=false;}return val;},handle:function(event){var val,ret,namespace,all,handlers;event=arguments[0]=jQuery.event.fix(event||window.event);namespace=event.type.split(".");event.type=namespace[0];namespace=namespace[1];all=!namespace&&!event.exclusive;handlers=(jQuery.data(this,"events")||{})[event.type];for(var j in handlers){var handler=handlers[j];if(all||handler.type==namespace){event.handler=handler;event.data=handler.data;ret=handler.apply(this,arguments);if(val!==false)val=ret;if(ret===false){event.preventDefault();event.stopPropagation();}}}return val;},fix:function(event){if(event[expando]==true)return event;var originalEvent=event;event={originalEvent:originalEvent};var props="altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");for(var i=props.length;i;i--)event[props[i]]=originalEvent[props[i]];event[expando]=true;event.preventDefault=function(){if(originalEvent.preventDefault)originalEvent.preventDefault();originalEvent.returnValue=false;};event.stopPropagation=function(){if(originalEvent.stopPropagation)originalEvent.stopPropagation();originalEvent.cancelBubble=true;};event.timeStamp=event.timeStamp||now();if(!event.target)event.target=event.srcElement||document;if(event.target.nodeType==3)event.target=event.target.parentNode;if(!event.relatedTarget&&event.fromElement)event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);}if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode))event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey)event.metaKey=event.ctrlKey;if(!event.which&&event.button)event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;},proxy:function(fn,proxy){proxy.guid=fn.guid=fn.guid||proxy.guid||this.guid++;return proxy;},special:{ready:{setup:function(){bindReady();return;},teardown:function(){return;}},mouseenter:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseover",jQuery.event.special.mouseenter.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseover",jQuery.event.special.mouseenter.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseenter";return jQuery.event.handle.apply(this,arguments);}},mouseleave:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseout",jQuery.event.special.mouseleave.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseout",jQuery.event.special.mouseleave.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseleave";return jQuery.event.handle.apply(this,arguments);}}}};jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){var one=jQuery.event.proxy(fn||data,function(event){jQuery(this).unbind(event,one);return(fn||data).apply(this,arguments);});return this.each(function(){jQuery.event.add(this,type,one,fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);});},triggerHandler:function(type,data,fn){return this[0]&&jQuery.event.trigger(type,data,this[0],false,fn);},toggle:function(fn){var args=arguments,i=1;while(i=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("
    ").append(res.responseText.replace(//g,"")).find(selector):res.responseText);self.each(callback,[res.responseText,status,res]);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=now();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{url:location.href,global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null,username:null,password:null,accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));var jsonp,jsre=/=\?(&|$)/g,status,data,type=s.type.toUpperCase();if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(type=="GET"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}if(head)head.removeChild(script);};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&type=="GET"){var ts=now();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");}if(s.data&&type=="GET"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");var remote=/^(?:\w+:)?\/\/([^\/?#]+)/;if(s.dataType=="script"&&type=="GET"&&remote.test(s.url)&&remote.exec(s.url)[1]!=location.host){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset)script.charset=s.scriptCharset;if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return undefined;}var requestDone=false;var xhr=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();if(s.username)xhr.open(type,s.url,s.async,s.username,s.password);else -xhr.open(type,s.url,s.async);try{if(s.data)xhr.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xhr.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");xhr.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){}if(s.beforeSend&&s.beforeSend(xhr,s)===false){s.global&&jQuery.active--;xhr.abort();return false;}if(s.global)jQuery.event.trigger("ajaxSend",[xhr,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xhr&&(xhr.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xhr)&&"error"||s.ifModified&&jQuery.httpNotModified(xhr,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xhr,s.dataType,s.dataFilter);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xhr.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else -jQuery.handleError(s,xhr,status);complete();if(s.async)xhr=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xhr){xhr.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xhr.send(s.data);}catch(e){jQuery.handleError(s,xhr,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xhr,s]);}function complete(){if(s.complete)s.complete(xhr,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xhr,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}return xhr;},handleError:function(s,xhr,status,e){if(s.error)s.error(xhr,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xhr,s,e]);},active:0,httpSuccess:function(xhr){try{return!xhr.status&&location.protocol=="file:"||(xhr.status>=200&&xhr.status<300)||xhr.status==304||xhr.status==1223||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpNotModified:function(xhr,url){try{var xhrRes=xhr.getResponseHeader("Last-Modified");return xhr.status==304||xhrRes==jQuery.lastModified[url]||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpData:function(xhr,type,filter){var ct=xhr.getResponseHeader("content-type"),xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0,data=xml?xhr.responseXML:xhr.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(filter)data=filter(data,type);if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else -for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else -s.push(encodeURIComponent(j)+"="+encodeURIComponent(jQuery.isFunction(a[j])?a[j]():a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style.display=="none")this.style.display="block";elem.remove();}}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle.apply(this,arguments):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1)return false;var opt=jQuery.extend({},optall),p,hidden=jQuery(this).is(":hidden"),self=this;for(p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return opt.complete.call(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else -e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.call(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(elem){type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",jQuery.makeArray(array));}return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].call(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:jQuery.fx.speeds[opt.duration])||jQuery.fx.speeds.def;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.call(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.call(this.elem,this.now,this);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=now();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;ithis.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done)this.options.complete.call(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.extend(jQuery.fx,{speeds:{slow:600,fast:200,def:400},step:{scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}}});jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522&&!/adobeair/i.test(userAgent),css=jQuery.curCSS,fixed=css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||css(offsetChild,"position")=="absolute"))||(mozilla&&css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l,10)||0;top+=parseInt(t,10)||0;}return results;};jQuery.fn.extend({position:function(){var left=0,top=0,results;if(this[0]){var offsetParent=this.offsetParent(),offset=this.offset(),parentOffset=/^body|html$/i.test(offsetParent[0].tagName)?{top:0,left:0}:offsetParent.offset();offset.top-=num(this,'marginTop');offset.left-=num(this,'marginLeft');parentOffset.top+=num(offsetParent,'borderTopWidth');parentOffset.left+=num(offsetParent,'borderLeftWidth');results={top:offset.top-parentOffset.top,left:offset.left-parentOffset.left};}return results;},offsetParent:function(){var offsetParent=this[0].offsetParent;while(offsetParent&&(!/^body|html$/i.test(offsetParent.tagName)&&jQuery.css(offsetParent,'position')=='static'))offsetParent=offsetParent.offsetParent;return jQuery(offsetParent);}});jQuery.each(['Left','Top'],function(i,name){var method='scroll'+name;jQuery.fn[method]=function(val){if(!this[0])return;return val!=undefined?this.each(function(){this==window||this==document?window.scrollTo(!i?val:jQuery(window).scrollLeft(),i?val:jQuery(window).scrollTop()):this[method]=val;}):this[0]==window||this[0]==document?self[i?'pageYOffset':'pageXOffset']||jQuery.boxModel&&document.documentElement[method]||document.body[method]:this[0][method];};});jQuery.each(["Height","Width"],function(i,name){var tl=i?"Left":"Top",br=i?"Right":"Bottom";jQuery.fn["inner"+name]=function(){return this[name.toLowerCase()]()+num(this,"padding"+tl)+num(this,"padding"+br);};jQuery.fn["outer"+name]=function(margin){return this["inner"+name]()+num(this,"border"+tl+"Width")+num(this,"border"+br+"Width")+(margin?num(this,"margin"+tl)+num(this,"margin"+br):0);};});})(); \ No newline at end of file diff --git a/javascript/superfish/js/jquery.bgiframe.min.js b/javascript/superfish/js/jquery.bgiframe.min.js deleted file mode 100644 index b5af52043..000000000 --- a/javascript/superfish/js/jquery.bgiframe.min.js +++ /dev/null @@ -1,10 +0,0 @@ -/* Copyright (c) 2006 Brandon Aaron (http://brandonaaron.net) - * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) - * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. - * - * $LastChangedDate: 2007-06-19 20:25:28 -0500 (Tue, 19 Jun 2007) $ - * $Rev: 2111 $ - * - * Version 2.1 - */ -(function($){$.fn.bgIframe=$.fn.bgiframe=function(s){if($.browser.msie&&parseInt($.browser.version)<=6){s=$.extend({top:'auto',left:'auto',width:'auto',height:'auto',opacity:true,src:'javascript:false;'},s||{});var prop=function(n){return n&&n.constructor==Number?n+'px':n;},html='