1<?php 2/** 3 * Elasticsearch PHP client 4 * 5 * @link https://github.com/elastic/elasticsearch-php/ 6 * @copyright Copyright (c) Elasticsearch B.V (https://www.elastic.co) 7 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 8 * @license https://www.gnu.org/licenses/lgpl-2.1.html GNU Lesser General Public License, Version 2.1 9 * 10 * Licensed to Elasticsearch B.V under one or more agreements. 11 * Elasticsearch B.V licenses this file to you under the Apache 2.0 License or 12 * the GNU Lesser General Public License, Version 2.1, at your option. 13 * See the LICENSE file in the project root for more information. 14 */ 15 16 17declare(strict_types = 1); 18 19namespace Elasticsearch\Endpoints; 20 21use Elasticsearch\Common\Exceptions\UnexpectedValueException; 22use Elasticsearch\Serializers\SerializerInterface; 23use Elasticsearch\Transport; 24use Exception; 25use GuzzleHttp\Ring\Future\FutureArrayInterface; 26 27abstract class AbstractEndpoint 28{ 29 /** 30 * @var array 31 */ 32 protected $params =[]; 33 34 /** 35 * @var string 36 */ 37 protected $index = null; 38 39 /** 40 * @var string 41 */ 42 protected $type = null; 43 44 /** 45 * @var string|int 46 */ 47 protected $id = null; 48 49 /** 50 * @var string 51 */ 52 protected $method = null; 53 54 /** 55 * @var string|array 56 */ 57 protected $body = null; 58 59 /** 60 * @var array 61 */ 62 private $options = []; 63 64 /** 65 * @var SerializerInterface 66 */ 67 protected $serializer; 68 69 /** 70 * @return string[] 71 */ 72 abstract public function getParamWhitelist(): array; 73 74 /** 75 * @return string 76 */ 77 abstract public function getURI(): string; 78 79 /** 80 * @return string 81 */ 82 abstract public function getMethod(): string; 83 84 85 /** 86 * Set the parameters for this endpoint 87 * 88 * @param string[] $params Array of parameters 89 * @return $this 90 */ 91 public function setParams(array $params) 92 { 93 $this->extractOptions($params); 94 $this->checkUserParams($params); 95 $params = $this->convertCustom($params); 96 $this->params = $this->convertArraysToStrings($params); 97 98 return $this; 99 } 100 101 public function getParams(): array 102 { 103 return $this->params; 104 } 105 106 public function getOptions(): array 107 { 108 return $this->options; 109 } 110 111 public function getIndex(): ?string 112 { 113 return $this->index; 114 } 115 116 /** 117 * @return $this 118 */ 119 public function setIndex($index) 120 { 121 if ($index === null) { 122 return $this; 123 } 124 125 if (is_array($index) === true) { 126 $index = array_map('trim', $index); 127 $index = implode(",", $index); 128 } 129 130 $this->index = urlencode($index); 131 132 return $this; 133 } 134 135 /** 136 * @deprecated 137 */ 138 public function getType(): ?string 139 { 140 return $this->type; 141 } 142 143 /** 144 * @deprecated 145 * @return $this 146 */ 147 public function setType(?string $type) 148 { 149 if ($type === null) { 150 return $this; 151 } 152 153 if (is_array($type) === true) { 154 $type = array_map('trim', $type); 155 $type = implode(",", $type); 156 } 157 158 $this->type = urlencode($type); 159 160 return $this; 161 } 162 163 /** 164 * @param int|string $docID 165 * 166 * @return $this 167 */ 168 public function setId($docID) 169 { 170 if ($docID === null) { 171 return $this; 172 } 173 174 if (is_int($docID)) { 175 $docID = (string) $docID; 176 } 177 178 $this->id = urlencode($docID); 179 180 return $this; 181 } 182 183 /** 184 * @return array|string 185 */ 186 public function getBody() 187 { 188 return $this->body; 189 } 190 191 protected function getOptionalURI(string $endpoint): string 192 { 193 $uri = []; 194 $uri[] = $this->getOptionalIndex(); 195 $uri[] = $this->getOptionalType(); 196 $uri[] = $endpoint; 197 $uri = array_filter($uri); 198 199 return '/' . implode('/', $uri); 200 } 201 202 private function getOptionalIndex(): string 203 { 204 if (isset($this->index) === true) { 205 return $this->index; 206 } else { 207 return '_all'; 208 } 209 } 210 211 private function getOptionalType(): string 212 { 213 if (isset($this->type) === true) { 214 return $this->type; 215 } else { 216 return ''; 217 } 218 } 219 220 /** 221 * @param array $params 222 * 223 * @throws UnexpectedValueException 224 */ 225 private function checkUserParams(array $params) 226 { 227 if (empty($params)) { 228 return; //no params, just return. 229 } 230 231 $whitelist = array_merge( 232 $this->getParamWhitelist(), 233 [ 'pretty', 'human', 'error_trace', 'source', 'filter_path', 'opaqueId' ] 234 ); 235 236 $invalid = array_diff(array_keys($params), $whitelist); 237 if (count($invalid) > 0) { 238 sort($invalid); 239 sort($whitelist); 240 throw new UnexpectedValueException( 241 sprintf( 242 (count($invalid) > 1 ? '"%s" are not valid parameters.' : '"%s" is not a valid parameter.').' Allowed parameters are "%s"', 243 implode('", "', $invalid), 244 implode('", "', $whitelist) 245 ) 246 ); 247 } 248 } 249 250 /** 251 * @param array $params Note: this is passed by-reference! 252 */ 253 private function extractOptions(&$params) 254 { 255 // Extract out client options, then start transforming 256 if (isset($params['client']) === true) { 257 // Check if the opaqueId is populated and add the header 258 if (isset($params['client']['opaqueId']) === true) { 259 if (isset($params['client']['headers']) === false) { 260 $params['client']['headers'] = []; 261 } 262 $params['client']['headers']['x-opaque-id'] = [trim($params['client']['opaqueId'])]; 263 unset($params['client']['opaqueId']); 264 } 265 266 $this->options['client'] = $params['client']; 267 unset($params['client']); 268 } 269 $ignore = isset($this->options['client']['ignore']) ? $this->options['client']['ignore'] : null; 270 if (isset($ignore) === true) { 271 if (is_string($ignore)) { 272 $this->options['client']['ignore'] = explode(",", $ignore); 273 } elseif (is_array($ignore)) { 274 $this->options['client']['ignore'] = $ignore; 275 } else { 276 $this->options['client']['ignore'] = [$ignore]; 277 } 278 } 279 } 280 281 private function convertCustom(array $params): array 282 { 283 if (isset($params['custom']) === true) { 284 foreach ($params['custom'] as $k => $v) { 285 $params[$k] = $v; 286 } 287 unset($params['custom']); 288 } 289 290 return $params; 291 } 292 293 private function convertArraysToStrings(array $params): array 294 { 295 foreach ($params as $key => &$value) { 296 if (!($key === 'client' || $key == 'custom') && is_array($value) === true) { 297 if ($this->isNestedArray($value) !== true) { 298 $value = implode(",", $value); 299 } 300 } 301 } 302 303 return $params; 304 } 305 306 private function isNestedArray(array $a): bool 307 { 308 foreach ($a as $v) { 309 if (is_array($v)) { 310 return true; 311 } 312 } 313 314 return false; 315 } 316} 317