[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Solr schema manipulation manager. 19 * 20 * @package search_solr 21 * @copyright 2015 David Monllao {@link http://www.davidmonllao.com} 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace search_solr; 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 require_once($CFG->dirroot . '/lib/filelib.php'); 30 31 /** 32 * Schema class to interact with Solr schema. 33 * 34 * At the moment it only implements create which should be enough for a basic 35 * moodle configuration in Solr. 36 * 37 * @package search_solr 38 * @copyright 2015 David Monllao {@link http://www.davidmonllao.com} 39 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 40 */ 41 class schema { 42 43 /** 44 * @var stdClass 45 */ 46 protected $config = null; 47 48 /** 49 * cUrl instance. 50 * @var \curl 51 */ 52 protected $curl = null; 53 54 /** 55 * An engine instance. 56 * @var engine 57 */ 58 protected $engine = null; 59 60 /** 61 * Constructor. 62 * 63 * @throws \moodle_exception 64 * @return void 65 */ 66 public function __construct() { 67 if (!$this->config = get_config('search_solr')) { 68 throw new \moodle_exception('missingconfig', 'search_solr'); 69 } 70 71 if (empty($this->config->server_hostname) || empty($this->config->indexname)) { 72 throw new \moodle_exception('missingconfig', 'search_solr'); 73 } 74 75 $this->engine = new engine(); 76 $this->curl = $this->engine->get_curl_object(); 77 78 // HTTP headers. 79 $this->curl->setHeader('Content-type: application/json'); 80 } 81 82 /** 83 * Can setup be executed against the configured server. 84 * 85 * @return true|string True or error message. 86 */ 87 public function can_setup_server() { 88 89 $engine = new \search_solr\engine(); 90 $status = $engine->is_server_configured(); 91 if ($status !== true) { 92 return $status; 93 } 94 95 // We know that the server is ready here. 96 if ($engine->get_solr_major_version() < 5) { 97 // Schema setup script only available for 5.0 onwards. 98 return get_string('schemasetupfromsolr5', 'search_solr'); 99 } 100 101 return true; 102 } 103 104 /** 105 * Setup solr stuff required by moodle. 106 * 107 * @param bool $checkexisting Whether to check if the fields already exist or not 108 * @return bool 109 */ 110 public function setup($checkexisting = true) { 111 $fields = \search_solr\document::get_default_fields_definition(); 112 113 // Field id is already there. 114 unset($fields['id']); 115 116 $this->check_index(); 117 118 return $this->add_fields($fields, $checkexisting); 119 } 120 121 /** 122 * Checks the schema is properly set up. 123 * 124 * @throws \moodle_exception 125 * @return void 126 */ 127 public function validate_setup() { 128 $fields = \search_solr\document::get_default_fields_definition(); 129 130 // Field id is already there. 131 unset($fields['id']); 132 133 $this->check_index(); 134 $this->validate_fields($fields, true); 135 } 136 137 /** 138 * Checks if the index is ready, triggers an exception otherwise. 139 * 140 * @throws \moodle_exception 141 * @return void 142 */ 143 protected function check_index() { 144 145 // Check that the server is available and the index exists. 146 $url = $this->engine->get_connection_url('/select?wt=json'); 147 $result = $this->curl->get($url); 148 if ($this->curl->error) { 149 throw new \moodle_exception('connectionerror', 'search_solr'); 150 } 151 if ($this->curl->info['http_code'] === 404) { 152 throw new \moodle_exception('connectionerror', 'search_solr'); 153 } 154 } 155 156 /** 157 * Adds the provided fields to Solr schema. 158 * 159 * Intentionally separated from create(), it can be called to add extra fields. 160 * fields separately. 161 * 162 * @throws \coding_exception 163 * @throws \moodle_exception 164 * @param array $fields \core_search\document::$requiredfields format 165 * @param bool $checkexisting Whether to check if the fields already exist or not 166 * @return bool 167 */ 168 protected function add_fields($fields, $checkexisting = true) { 169 170 if ($checkexisting) { 171 // Check that non of them exists. 172 $this->validate_fields($fields, false); 173 } 174 175 $url = $this->engine->get_connection_url('/schema'); 176 177 // Add all fields. 178 foreach ($fields as $fieldname => $data) { 179 180 if (!isset($data['type']) || !isset($data['stored']) || !isset($data['indexed'])) { 181 throw new \coding_exception($fieldname . ' does not define all required field params: type, stored and indexed.'); 182 } 183 // Changing default multiValued value to false as we want to match values easily. 184 $params = array( 185 'add-field' => array( 186 'name' => $fieldname, 187 'type' => ($data['type'] === 'text' ? 'text_general' : $data['type']), 188 'stored' => $data['stored'], 189 'multiValued' => false, 190 'indexed' => $data['indexed'] 191 ) 192 ); 193 $results = $this->curl->post($url, json_encode($params)); 194 195 // We only validate if we are interested on it. 196 if ($checkexisting) { 197 if ($this->curl->error) { 198 throw new \moodle_exception('errorcreatingschema', 'search_solr', '', $this->curl->error); 199 } 200 $this->validate_add_field_result($results); 201 } 202 } 203 204 return true; 205 } 206 207 /** 208 * Checks if the schema existing fields are properly set, triggers an exception otherwise. 209 * 210 * @throws \moodle_exception 211 * @param array $fields 212 * @param bool $requireexisting Require the fields to exist, otherwise exception. 213 * @return void 214 */ 215 protected function validate_fields(&$fields, $requireexisting = false) { 216 global $CFG; 217 218 foreach ($fields as $fieldname => $data) { 219 $url = $this->engine->get_connection_url('/schema/fields/' . $fieldname); 220 $results = $this->curl->get($url); 221 222 if ($this->curl->error) { 223 throw new \moodle_exception('errorcreatingschema', 'search_solr', '', $this->curl->error); 224 } 225 226 if (!$results) { 227 throw new \moodle_exception('errorcreatingschema', 'search_solr', '', get_string('nodatafromserver', 'search_solr')); 228 } 229 $results = json_decode($results); 230 231 if ($requireexisting && !empty($results->error) && $results->error->code === 404) { 232 $a = new \stdClass(); 233 $a->fieldname = $fieldname; 234 $a->setupurl = $CFG->wwwroot . '/search/engine/solr/setup_schema.php'; 235 throw new \moodle_exception('errorvalidatingschema', 'search_solr', '', $a); 236 } 237 238 // The field should not exist so we only accept 404 errors. 239 if (empty($results->error) || (!empty($results->error) && $results->error->code !== 404)) { 240 if (!empty($results->error)) { 241 throw new \moodle_exception('errorcreatingschema', 'search_solr', '', $results->error->msg); 242 } else { 243 // All these field attributes are set when fields are added through this script and should 244 // be returned and match the defined field's values. 245 246 if (empty($results->field) || !isset($results->field->type) || 247 !isset($results->field->multiValued) || !isset($results->field->indexed) || 248 !isset($results->field->stored)) { 249 250 throw new \moodle_exception('errorcreatingschema', 'search_solr', '', 251 get_string('schemafieldautocreated', 'search_solr', $fieldname)); 252 253 } else if (($results->field->type !== $data['type'] && 254 ($data['type'] !== 'text' || $results->field->type !== 'text_general')) || 255 $results->field->multiValued !== false || 256 $results->field->indexed !== $data['indexed'] || 257 $results->field->stored !== $data['stored']) { 258 259 throw new \moodle_exception('errorcreatingschema', 'search_solr', '', 260 get_string('schemafieldautocreated', 'search_solr', $fieldname)); 261 } else { 262 // The field already exists and it is properly defined, no need to create it. 263 unset($fields[$fieldname]); 264 } 265 } 266 } 267 } 268 } 269 270 /** 271 * Checks that the field results do not contain errors. 272 * 273 * @throws \moodle_exception 274 * @param string $results curl response body 275 * @return void 276 */ 277 protected function validate_add_field_result($result) { 278 279 if (!$result) { 280 throw new \moodle_exception('errorcreatingschema', 'search_solr', '', get_string('nodatafromserver', 'search_solr')); 281 } 282 283 $results = json_decode($result); 284 if (!$results) { 285 if (is_scalar($result)) { 286 $errormsg = $result; 287 } else { 288 $errormsg = json_encode($result); 289 } 290 throw new \moodle_exception('errorcreatingschema', 'search_solr', '', $errormsg); 291 } 292 293 // It comes as error when fetching fields data. 294 if (!empty($results->error)) { 295 throw new \moodle_exception('errorcreatingschema', 'search_solr', '', $results->error); 296 } 297 298 // It comes as errors when adding fields. 299 if (!empty($results->errors)) { 300 301 // We treat this error separately. 302 $errorstr = ''; 303 foreach ($results->errors as $error) { 304 $errorstr .= implode(', ', $error->errorMessages); 305 } 306 throw new \moodle_exception('errorcreatingschema', 'search_solr', '', $errorstr); 307 } 308 309 } 310 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |