#0 | Elasticsearch\ConnectionPool\StaticNoPingConnectionPool->nextConnection() /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Transport.php (76) <?php namespace Elasticsearch; use Elasticsearch\Common\Exceptions; use Elasticsearch\ConnectionPool\AbstractConnectionPool; use Elasticsearch\Connections\Connection; use Elasticsearch\Connections\ConnectionInterface; use GuzzleHttp\Ring\Future\FutureArrayInterface; use Psr\Log\LoggerInterface; /** * Class Transport * * @category Elasticsearch * @package Elasticsearch * @author Zachary Tong <[email protected]> * @license http://www.apache.org/licenses/LICENSE-2.0 Apache2 * @link http://elastic.co */ class Transport { /** * @var AbstractConnectionPool */ public $connectionPool; /** * @var LoggerInterface */ private $log; /** @var int */ public $retryAttempts = 0; /** @var Connection */ public $lastConnection; /** @var int */ public $retries; /** * Transport class is responsible for dispatching requests to the * underlying cluster connections * * @param $retries * @param bool $sniffOnStart * @param ConnectionPool\AbstractConnectionPool $connectionPool * @param \Psr\Log\LoggerInterface $log Monolog logger object */ // @codingStandardsIgnoreStart // "Arguments with default values must be at the end of the argument list" - cannot change the interface public function __construct($retries, $sniffOnStart = false, AbstractConnectionPool $connectionPool, LoggerInterface $log) { // @codingStandardsIgnoreEnd $this->log = $log; $this->connectionPool = $connectionPool; $this->retries = $retries; if ($sniffOnStart === true) { $this->log->notice('Sniff on Start.'); $this->connectionPool->scheduleCheck(); } } /** * Returns a single connection from the connection pool * Potentially performs a sniffing step before returning * * @return ConnectionInterface Connection */ public function getConnection() { return $this->connectionPool->nextConnection(); } /** * Perform a request to the Cluster * * @param string $method HTTP method to use * @param string $uri HTTP URI to send request to * @param null $params Optional query parameters * @param null $body Optional query body * @param array $options * * @throws Common\Exceptions\NoNodesAvailableException|\Exception * @return FutureArrayInterface */ public function performRequest($method, $uri, $params = null, $body = null, $options = []) { try { $connection = $this->getConnection(); } catch (Exceptions\NoNodesAvailableException $exception) { $this->log->critical('No alive nodes found in cluster'); throw $exception; } $response = array(); $caughtException = null; $this->lastConnection = $connection; $future = $connection->performRequest( $method, $uri, $params, $body, $options, $this ); $future->promise()->then( //onSuccess function ($response) { $this->retryAttempts = 0; // Note, this could be a 4xx or 5xx error }, //onFailure function ($response) { // Ignore 400 level errors, as that means the server responded just fine if (!(isset($response['code']) && $response['code'] >=400 && $response['code'] < 500)) { // Otherwise schedule a check $this->connectionPool->scheduleCheck(); } } ); return $future; } /** * @param FutureArrayInterface $result Response of a request (promise) * @param array $options Options for transport * * @return callable|array */ public function resultOrFuture($result, $options = []) { $response = null; $async = isset($options['client']['future']) ? $options['client']['future'] : null; if (is_null($async) || $async === false) { do { $result = $result->wait(); } while ($result instanceof FutureArrayInterface); return $result; } elseif ($async === true || $async === 'lazy') { return $result; } } /** * @param $request * * @return bool */ public function shouldRetry($request) { if ($this->retryAttempts < $this->retries) { $this->retryAttempts += 1; return true; } return false; } /** * Returns the last used connection so that it may be inspected. Mainly * for debugging/testing purposes. * * @return Connection */ public function getLastConnection() { return $this->lastConnection; } } |
#1 | Elasticsearch\Transport->getConnection() /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Transport.php (94) <?php namespace Elasticsearch; use Elasticsearch\Common\Exceptions; use Elasticsearch\ConnectionPool\AbstractConnectionPool; use Elasticsearch\Connections\Connection; use Elasticsearch\Connections\ConnectionInterface; use GuzzleHttp\Ring\Future\FutureArrayInterface; use Psr\Log\LoggerInterface; /** * Class Transport * * @category Elasticsearch * @package Elasticsearch * @author Zachary Tong <[email protected]> * @license http://www.apache.org/licenses/LICENSE-2.0 Apache2 * @link http://elastic.co */ class Transport { /** * @var AbstractConnectionPool */ public $connectionPool; /** * @var LoggerInterface */ private $log; /** @var int */ public $retryAttempts = 0; /** @var Connection */ public $lastConnection; /** @var int */ public $retries; /** * Transport class is responsible for dispatching requests to the * underlying cluster connections * * @param $retries * @param bool $sniffOnStart * @param ConnectionPool\AbstractConnectionPool $connectionPool * @param \Psr\Log\LoggerInterface $log Monolog logger object */ // @codingStandardsIgnoreStart // "Arguments with default values must be at the end of the argument list" - cannot change the interface public function __construct($retries, $sniffOnStart = false, AbstractConnectionPool $connectionPool, LoggerInterface $log) { // @codingStandardsIgnoreEnd $this->log = $log; $this->connectionPool = $connectionPool; $this->retries = $retries; if ($sniffOnStart === true) { $this->log->notice('Sniff on Start.'); $this->connectionPool->scheduleCheck(); } } /** * Returns a single connection from the connection pool * Potentially performs a sniffing step before returning * * @return ConnectionInterface Connection */ public function getConnection() { return $this->connectionPool->nextConnection(); } /** * Perform a request to the Cluster * * @param string $method HTTP method to use * @param string $uri HTTP URI to send request to * @param null $params Optional query parameters * @param null $body Optional query body * @param array $options * * @throws Common\Exceptions\NoNodesAvailableException|\Exception * @return FutureArrayInterface */ public function performRequest($method, $uri, $params = null, $body = null, $options = []) { try { $connection = $this->getConnection(); } catch (Exceptions\NoNodesAvailableException $exception) { $this->log->critical('No alive nodes found in cluster'); throw $exception; } $response = array(); $caughtException = null; $this->lastConnection = $connection; $future = $connection->performRequest( $method, $uri, $params, $body, $options, $this ); $future->promise()->then( //onSuccess function ($response) { $this->retryAttempts = 0; // Note, this could be a 4xx or 5xx error }, //onFailure function ($response) { // Ignore 400 level errors, as that means the server responded just fine if (!(isset($response['code']) && $response['code'] >=400 && $response['code'] < 500)) { // Otherwise schedule a check $this->connectionPool->scheduleCheck(); } } ); return $future; } /** * @param FutureArrayInterface $result Response of a request (promise) * @param array $options Options for transport * * @return callable|array */ public function resultOrFuture($result, $options = []) { $response = null; $async = isset($options['client']['future']) ? $options['client']['future'] : null; if (is_null($async) || $async === false) { do { $result = $result->wait(); } while ($result instanceof FutureArrayInterface); return $result; } elseif ($async === true || $async === 'lazy') { return $result; } } /** * @param $request * * @return bool */ public function shouldRetry($request) { if ($this->retryAttempts < $this->retries) { $this->retryAttempts += 1; return true; } return false; } /** * Returns the last used connection so that it may be inspected. Mainly * for debugging/testing purposes. * * @return Connection */ public function getLastConnection() { return $this->lastConnection; } } |
#2 | Elasticsearch\Transport->performRequest(GET, /drooble_users/_search?from=10&size=11, Array(), {"query":{"bool":{"should":[{"match":{"tags.equipment.en":"Protools"}}],"minimum_should_match":1}},"sort":[{"_score":"desc"}]}, Array()) /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Connections/Connection.php (246) <?php namespace Elasticsearch\Connections; use Elasticsearch\Common\Exceptions\AlreadyExpiredException; use Elasticsearch\Common\Exceptions\BadRequest400Exception; use Elasticsearch\Common\Exceptions\Conflict409Exception; use Elasticsearch\Common\Exceptions\Curl\CouldNotConnectToHost; use Elasticsearch\Common\Exceptions\Curl\CouldNotResolveHostException; use Elasticsearch\Common\Exceptions\Curl\OperationTimeoutException; use Elasticsearch\Common\Exceptions\Forbidden403Exception; use Elasticsearch\Common\Exceptions\MaxRetriesException; use Elasticsearch\Common\Exceptions\Missing404Exception; use Elasticsearch\Common\Exceptions\NoDocumentsToGetException; use Elasticsearch\Common\Exceptions\NoShardAvailableException; use Elasticsearch\Common\Exceptions\RequestTimeout408Exception; use Elasticsearch\Common\Exceptions\RoutingMissingException; use Elasticsearch\Common\Exceptions\ScriptLangNotSupportedException; use Elasticsearch\Common\Exceptions\ServerErrorResponseException; use Elasticsearch\Common\Exceptions\TransportException; use Elasticsearch\Serializers\SerializerInterface; use Elasticsearch\Transport; use GuzzleHttp\Ring\Core; use GuzzleHttp\Ring\Exception\ConnectException; use GuzzleHttp\Ring\Exception\RingException; use Psr\Log\LoggerInterface; /** * Class AbstractConnection * * @category Elasticsearch * @package Elasticsearch\Connections * @author Zachary Tong <[email protected]> * @license http://www.apache.org/licenses/LICENSE-2.0 Apache2 * @link http://elastic.co */ class Connection implements ConnectionInterface { /** @var callable */ protected $handler; /** @var SerializerInterface */ protected $serializer; /** * @var string */ protected $transportSchema = 'http'; // TODO depreciate this default /** * @var string */ protected $host; /** * @var string || null */ protected $path; /** * @var LoggerInterface */ protected $log; /** * @var LoggerInterface */ protected $trace; /** * @var array */ protected $connectionParams; /** @var array */ protected $headers = []; /** @var bool */ protected $isAlive = false; /** @var float */ private $pingTimeout = 1; //TODO expose this /** @var int */ private $lastPing = 0; /** @var int */ private $failedPings = 0; private $lastRequest = array(); /** * Constructor * * @param $handler * @param array $hostDetails * @param array $connectionParams Array of connection-specific parameters * @param \Elasticsearch\Serializers\SerializerInterface $serializer * @param \Psr\Log\LoggerInterface $log Logger object * @param \Psr\Log\LoggerInterface $trace */ public function __construct( $handler, $hostDetails, $connectionParams, SerializerInterface $serializer, LoggerInterface $log, LoggerInterface $trace ) { if (isset($hostDetails['port']) !== true) { $hostDetails['port'] = 9200; } if (isset($hostDetails['scheme'])) { $this->transportSchema = $hostDetails['scheme']; } if (isset($hostDetails['user']) && isset($hostDetails['pass'])) { $connectionParams['client']['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_BASIC; $connectionParams['client']['curl'][CURLOPT_USERPWD] = $hostDetails['user'].':'.$hostDetails['pass']; } if (isset($connectionParams['client']['headers']) === true) { $this->headers = $connectionParams['client']['headers']; unset($connectionParams['client']['headers']); } $host = $hostDetails['host'].':'.$hostDetails['port']; $path = null; if (isset($hostDetails['path']) === true) { $path = $hostDetails['path']; } $this->host = $host; $this->path = $path; $this->log = $log; $this->trace = $trace; $this->connectionParams = $connectionParams; $this->serializer = $serializer; $this->handler = $this->wrapHandler($handler, $log, $trace); } /** * @param $method * @param $uri * @param null $params * @param null $body * @param array $options * @param \Elasticsearch\Transport $transport * @return mixed */ public function performRequest($method, $uri, $params = null, $body = null, $options = [], Transport $transport = null) { if (isset($body) === true) { $body = $this->serializer->serialize($body); } $request = [ 'http_method' => $method, 'scheme' => $this->transportSchema, 'uri' => $this->getURI($uri, $params), 'body' => $body, 'headers' => array_merge([ 'Host' => [$this->host] ], $this->headers) ]; $request = array_replace_recursive($request, $this->connectionParams, $options); // RingPHP does not like if client is empty if (empty($request['client'])) { unset($request['client']); } $handler = $this->handler; $future = $handler($request, $this, $transport, $options); return $future; } /** @return string */ public function getTransportSchema() { return $this->transportSchema; } /** @return array */ public function getLastRequestInfo() { return $this->lastRequest; } private function wrapHandler(callable $handler, LoggerInterface $logger, LoggerInterface $tracer) { return function (array $request, Connection $connection, Transport $transport = null, $options) use ($handler, $logger, $tracer) { $this->lastRequest = []; $this->lastRequest['request'] = $request; // Send the request using the wrapped handler. $response = Core::proxy($handler($request), function ($response) use ($connection, $transport, $logger, $tracer, $request, $options) { $this->lastRequest['response'] = $response; if (isset($response['error']) === true) { if ($response['error'] instanceof ConnectException || $response['error'] instanceof RingException) { $this->log->warning("Curl exception encountered."); $exception = $this->getCurlRetryException($request, $response); $this->logRequestFail( $request['http_method'], $response['effective_url'], $request['body'], $request['headers'], $response['status'], $response['body'], $response['transfer_stats']['total_time'], $exception ); $node = $connection->getHost(); $this->log->warning("Marking node $node dead."); $connection->markDead(); // If the transport has not been set, we are inside a Ping or Sniff, // so we don't want to retrigger retries anyway. // // TODO this could be handled better, but we are limited because connectionpools do not // have access to Transport. Architecturally, all of this needs to be refactored if (isset($transport) === true) { $transport->connectionPool->scheduleCheck(); $neverRetry = isset($request['client']['never_retry']) ? $request['client']['never_retry'] : false; $shouldRetry = $transport->shouldRetry($request); $shouldRetryText = ($shouldRetry) ? 'true' : 'false'; $this->log->warning("Retries left? $shouldRetryText"); if ($shouldRetry && !$neverRetry) { return $transport->performRequest( $request['http_method'], $request['uri'], [], $request['body'], $options ); } } $this->log->warning("Out of retries, throwing exception from $node"); // Only throw if we run out of retries throw $exception; } else { // Something went seriously wrong, bail $exception = new TransportException($response['error']->getMessage()); $this->logRequestFail( $request['http_method'], $response['effective_url'], $request['body'], $request['headers'], $response['status'], $response['body'], $response['transfer_stats']['total_time'], $exception ); throw $exception; } } else { $connection->markAlive(); if (isset($response['body']) === true) { $response['body'] = stream_get_contents($response['body']); $this->lastRequest['response']['body'] = $response['body']; } if ($response['status'] >= 400 && $response['status'] < 500) { $ignore = isset($request['client']['ignore']) ? $request['client']['ignore'] : []; $this->process4xxError($request, $response, $ignore); } elseif ($response['status'] >= 500) { $ignore = isset($request['client']['ignore']) ? $request['client']['ignore'] : []; $this->process5xxError($request, $response, $ignore); } // No error, deserialize $response['body'] = $this->serializer->deserialize($response['body'], $response['transfer_stats']); } $this->logRequestSuccess( $request['http_method'], $response['effective_url'], $request['body'], $request['headers'], $response['status'], $response['body'], $response['transfer_stats']['total_time'] ); return isset($request['client']['verbose']) && $request['client']['verbose'] === true ? $response : $response['body']; }); return $response; }; } /** * @param string $uri * @param array $params * * @return string */ private function getURI($uri, $params) { if (isset($params) === true && !empty($params)) { array_walk($params, function (&$value, &$key) { if ($value === true) { $value = 'true'; } elseif ($value === false) { $value = 'false'; } }); $uri .= '?' . http_build_query($params); } if ($this->path !== null) { $uri = $this->path . $uri; } return $uri; } /** * Log a successful request * * @param string $method * @param string $fullURI * @param string $body * @param array $headers * @param string $statusCode * @param string $response * @param string $duration * * @return void */ public function logRequestSuccess($method, $fullURI, $body, $headers, $statusCode, $response, $duration) { $this->log->debug('Request Body', array($body)); $this->log->info( 'Request Success:', array( 'method' => $method, 'uri' => $fullURI, 'headers' => $headers, 'HTTP code' => $statusCode, 'duration' => $duration, ) ); $this->log->debug('Response', array($response)); // Build the curl command for Trace. $curlCommand = $this->buildCurlCommand($method, $fullURI, $body); $this->trace->info($curlCommand); $this->trace->debug( 'Response:', array( 'response' => $response, 'method' => $method, 'uri' => $fullURI, 'HTTP code' => $statusCode, 'duration' => $duration, ) ); } /** * Log a a failed request * * @param string $method * @param string $fullURI * @param string $body * @param array $headers * @param null|string $statusCode * @param null|string $response * @param string $duration * @param \Exception|null $exception * * @return void */ public function logRequestFail($method, $fullURI, $body, $headers, $statusCode, $response, $duration, \Exception $exception) { $this->log->debug('Request Body', array($body)); $this->log->warning( 'Request Failure:', array( 'method' => $method, 'uri' => $fullURI, 'headers' => $headers, 'HTTP code' => $statusCode, 'duration' => $duration, 'error' => $exception->getMessage(), ) ); $this->log->warning('Response', array($response)); // Build the curl command for Trace. $curlCommand = $this->buildCurlCommand($method, $fullURI, $body); $this->trace->info($curlCommand); $this->trace->debug( 'Response:', array( 'response' => $response, 'method' => $method, 'uri' => $fullURI, 'HTTP code' => $statusCode, 'duration' => $duration, ) ); } /** * @return bool */ public function ping() { $options = [ 'client' => [ 'timeout' => $this->pingTimeout, 'never_retry' => true, 'verbose' => true ] ]; try { $response = $this->performRequest('HEAD', '/', null, null, $options); $response = $response->wait(); } catch (TransportException $exception) { $this->markDead(); return false; } if ($response['status'] === 200) { $this->markAlive(); return true; } else { $this->markDead(); return false; } } /** * @return array */ public function sniff() { $options = [ 'client' => [ 'timeout' => $this->pingTimeout, 'never_retry' => true ] ]; return $this->performRequest('GET', '/_nodes/', null, null, $options); } /** * @return bool */ public function isAlive() { return $this->isAlive; } public function markAlive() { $this->failedPings = 0; $this->isAlive = true; $this->lastPing = time(); } public function markDead() { $this->isAlive = false; $this->failedPings += 1; $this->lastPing = time(); } /** * @return int */ public function getLastPing() { return $this->lastPing; } /** * @return int */ public function getPingFailures() { return $this->failedPings; } /** * @return string */ public function getHost() { return $this->host; } /** * @return null|string */ public function getUserPass() { if (isset($this->connectionParams['client']['curl'][CURLOPT_USERPWD]) === true) { return $this->connectionParams['client']['curl'][CURLOPT_USERPWD]; } return null; } /** * @return null|string */ public function getPath() { return $this->path; } /** * @param $request * @param $response * @return \Elasticsearch\Common\Exceptions\Curl\CouldNotConnectToHost|\Elasticsearch\Common\Exceptions\Curl\CouldNotResolveHostException|\Elasticsearch\Common\Exceptions\Curl\OperationTimeoutException|\Elasticsearch\Common\Exceptions\MaxRetriesException */ protected function getCurlRetryException($request, $response) { $exception = null; $message = $response['error']->getMessage(); $exception = new MaxRetriesException($message); switch ($response['curl']['errno']) { case 6: $exception = new CouldNotResolveHostException($message, null, $exception); break; case 7: $exception = new CouldNotConnectToHost($message, null, $exception); break; case 28: $exception = new OperationTimeoutException($message, null, $exception); break; } return $exception; } /** * Construct a string cURL command * * @param string $method HTTP method * @param string $uri Full URI of request * @param string $body Request body * * @return string */ private function buildCurlCommand($method, $uri, $body) { if (strpos($uri, '?') === false) { $uri .= '?pretty=true'; } else { str_replace('?', '?pretty=true', $uri); } $curlCommand = 'curl -X' . strtoupper($method); $curlCommand .= " '" . $uri . "'"; if (isset($body) === true && $body !== '') { $curlCommand .= " -d '" . $body . "'"; } return $curlCommand; } /** * @param $request * @param $response * @param $ignore * @throws \Elasticsearch\Common\Exceptions\AlreadyExpiredException|\Elasticsearch\Common\Exceptions\BadRequest400Exception|\Elasticsearch\Common\Exceptions\Conflict409Exception|\Elasticsearch\Common\Exceptions\Forbidden403Exception|\Elasticsearch\Common\Exceptions\Missing404Exception|\Elasticsearch\Common\Exceptions\ScriptLangNotSupportedException|null */ private function process4xxError($request, $response, $ignore) { $statusCode = $response['status']; $responseBody = $response['body']; /** @var \Exception $exception */ $exception = $this->tryDeserialize400Error($response); if (array_search($response['status'], $ignore) !== false) { return; } if ($statusCode === 400 && strpos($responseBody, "AlreadyExpiredException") !== false) { $exception = new AlreadyExpiredException($responseBody, $statusCode); } elseif ($statusCode === 403) { $exception = new Forbidden403Exception($responseBody, $statusCode); } elseif ($statusCode === 404) { $exception = new Missing404Exception($responseBody, $statusCode); } elseif ($statusCode === 409) { $exception = new Conflict409Exception($responseBody, $statusCode); } elseif ($statusCode === 400 && strpos($responseBody, 'script_lang not supported') !== false) { $exception = new ScriptLangNotSupportedException($responseBody. $statusCode); } elseif ($statusCode === 408) { $exception = new RequestTimeout408Exception($responseBody, $statusCode); } else { $exception = new BadRequest400Exception($responseBody, $statusCode); } $this->logRequestFail( $request['http_method'], $response['effective_url'], $request['body'], $request['headers'], $response['status'], $response['body'], $response['transfer_stats']['total_time'], $exception ); throw $exception; } /** * @param $request * @param $response * @param $ignore * @throws \Elasticsearch\Common\Exceptions\NoDocumentsToGetException|\Elasticsearch\Common\Exceptions\NoShardAvailableException|\Elasticsearch\Common\Exceptions\RoutingMissingException|\Elasticsearch\Common\Exceptions\ServerErrorResponseException */ private function process5xxError($request, $response, $ignore) { $statusCode = $response['status']; $responseBody = $response['body']; /** @var \Exception $exception */ $exception = $this->tryDeserialize500Error($response); $exceptionText = "[$statusCode Server Exception] ".$exception->getMessage(); $this->log->error($exceptionText); $this->log->error($exception->getTraceAsString()); if (array_search($statusCode, $ignore) !== false) { return; } if ($statusCode === 500 && strpos($responseBody, "RoutingMissingException") !== false) { $exception = new RoutingMissingException($exception->getMessage(), $statusCode, $exception); } elseif ($statusCode === 500 && preg_match('/ActionRequestValidationException.+ no documents to get/', $responseBody) === 1) { $exception = new NoDocumentsToGetException($exception->getMessage(), $statusCode, $exception); } elseif ($statusCode === 500 && strpos($responseBody, 'NoShardAvailableActionException') !== false) { $exception = new NoShardAvailableException($exception->getMessage(), $statusCode, $exception); } else { $exception = new ServerErrorResponseException($responseBody, $statusCode); } $this->logRequestFail( $request['http_method'], $response['effective_url'], $request['body'], $request['headers'], $response['status'], $response['body'], $response['transfer_stats']['total_time'], $exception ); throw $exception; } private function tryDeserialize400Error($response) { return $this->tryDeserializeError($response, 'Elasticsearch\Common\Exceptions\BadRequest400Exception'); } private function tryDeserialize500Error($response) { return $this->tryDeserializeError($response, 'Elasticsearch\Common\Exceptions\ServerErrorResponseException'); } private function tryDeserializeError($response, $errorClass) { $error = $this->serializer->deserialize($response['body'], $response['transfer_stats']); if (is_array($error) === true) { // 2.0 structured exceptions if (isset($error['error']['reason']) === true) { // Try to use root cause first (only grabs the first root cause) $root = $error['error']['root_cause']; if (isset($root) && isset($root[0])) { $cause = $root[0]['reason']; $type = $root[0]['type']; } else { $cause = $error['error']['reason']; $type = $error['error']['type']; } $original = new $errorClass($response['body'], $response['status']); return new $errorClass("$type: $cause", $response['status'], $original); } elseif (isset($error['error']) === true) { // <2.0 semi-structured exceptions $original = new $errorClass($response['body'], $response['status']); return new $errorClass($error['error'], $response['status'], $original); } // <2.0 "i just blew up" nonstructured exception // $error is an array but we don't know the format, reuse the response body instead return new $errorClass($response['body'], $response['status']); } // <2.0 "i just blew up" nonstructured exception return new $errorClass($response['body']); } } |
#3 | Elasticsearch\Connections\Connection->Elasticsearch\Connections\{closure}(Array([transfer_stats] => Array(28), [curl] => Array([error] => Could not resolve host: search-drooble1-irvhqoehqpblnqmd5va6n5pmsy.us-west-2.es.amazonaws.com, [errno] => 6), [effective_url] => http://search-drooble1-irvhqoehqpblnqmd5va6n5pmsy.us-west-2.es.amazonaws.com:80/drooble_users/_search?from=10&size=11, [status] => (empty string), [reason] => (empty string), [body] => (empty string), [headers] => Array(), [error] => Object(GuzzleHttp\Ring\Exception\ConnectException))) /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/react/promise/src/FulfilledPromise.php (25) <?php namespace React\Promise; class FulfilledPromise implements ExtendedPromiseInterface, CancellablePromiseInterface { private $value; public function __construct($value = null) { if ($value instanceof PromiseInterface) { throw new \InvalidArgumentException('You cannot create React\Promise\FulfilledPromise with a promise. Use React\Promise\resolve($promiseOrValue) instead.'); } $this->value = $value; } public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null) { if (null === $onFulfilled) { return $this; } try { return resolve($onFulfilled($this->value)); } catch (\Throwable $exception) { return new RejectedPromise($exception); } catch (\Exception $exception) { return new RejectedPromise($exception); } } public function done(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null) { if (null === $onFulfilled) { return; } $result = $onFulfilled($this->value); if ($result instanceof ExtendedPromiseInterface) { $result->done(); } } public function otherwise(callable $onRejected) { return $this; } public function always(callable $onFulfilledOrRejected) { return $this->then(function ($value) use ($onFulfilledOrRejected) { return resolve($onFulfilledOrRejected())->then(function () use ($value) { return $value; }); }); } public function progress(callable $onProgress) { return $this; } public function cancel() { } } |
#4 | React\Promise\FulfilledPromise->then(Object(Closure), null, null) /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/guzzlehttp/ringphp/src/Future/CompletedFutureValue.php (55) <?php namespace GuzzleHttp\Ring\Future; use React\Promise\FulfilledPromise; use React\Promise\RejectedPromise; /** * Represents a future value that has been resolved or rejected. */ class CompletedFutureValue implements FutureInterface { protected $result; protected $error; private $cachedPromise; /** * @param mixed $result Resolved result * @param \Exception $e Error. Pass a GuzzleHttp\Ring\Exception\CancelledFutureAccessException * to mark the future as cancelled. */ public function __construct($result, \Exception $e = null) { $this->result = $result; $this->error = $e; } public function wait() { if ($this->error) { throw $this->error; } return $this->result; } public function cancel() {} public function promise() { if (!$this->cachedPromise) { $this->cachedPromise = $this->error ? new RejectedPromise($this->error) : new FulfilledPromise($this->result); } return $this->cachedPromise; } public function then( callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null ) { return $this->promise()->then($onFulfilled, $onRejected, $onProgress); } } |
#5 | GuzzleHttp\Ring\Future\CompletedFutureValue->then(Object(Closure), null, null) /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/guzzlehttp/ringphp/src/Core.php (341) <?php namespace GuzzleHttp\Ring; use GuzzleHttp\Stream\StreamInterface; use GuzzleHttp\Ring\Future\FutureArrayInterface; use GuzzleHttp\Ring\Future\FutureArray; /** * Provides core functionality of Ring handlers and middleware. */ class Core { /** * Returns a function that calls all of the provided functions, in order, * passing the arguments provided to the composed function to each function. * * @param callable[] $functions Array of functions to proxy to. * * @return callable */ public static function callArray(array $functions) { return function () use ($functions) { $args = func_get_args(); foreach ($functions as $fn) { call_user_func_array($fn, $args); } }; } /** * Gets an array of header line values from a message for a specific header * * This method searches through the "headers" key of a message for a header * using a case-insensitive search. * * @param array $message Request or response hash. * @param string $header Header to retrieve * * @return array */ public static function headerLines($message, $header) { $result = []; if (!empty($message['headers'])) { foreach ($message['headers'] as $name => $value) { if (!strcasecmp($name, $header)) { $result = array_merge($result, $value); } } } return $result; } /** * Gets a header value from a message as a string or null * * This method searches through the "headers" key of a message for a header * using a case-insensitive search. The lines of the header are imploded * using commas into a single string return value. * * @param array $message Request or response hash. * @param string $header Header to retrieve * * @return string|null Returns the header string if found, or null if not. */ public static function header($message, $header) { $match = self::headerLines($message, $header); return $match ? implode(', ', $match) : null; } /** * Returns the first header value from a message as a string or null. If * a header line contains multiple values separated by a comma, then this * function will return the first value in the list. * * @param array $message Request or response hash. * @param string $header Header to retrieve * * @return string|null Returns the value as a string if found. */ public static function firstHeader($message, $header) { if (!empty($message['headers'])) { foreach ($message['headers'] as $name => $value) { if (!strcasecmp($name, $header)) { // Return the match itself if it is a single value. $pos = strpos($value[0], ','); return $pos ? substr($value[0], 0, $pos) : $value[0]; } } } return null; } /** * Returns true if a message has the provided case-insensitive header. * * @param array $message Request or response hash. * @param string $header Header to check * * @return bool */ public static function hasHeader($message, $header) { if (!empty($message['headers'])) { foreach ($message['headers'] as $name => $value) { if (!strcasecmp($name, $header)) { return true; } } } return false; } /** * Parses an array of header lines into an associative array of headers. * * @param array $lines Header lines array of strings in the following * format: "Name: Value" * @return array */ public static function headersFromLines($lines) { $headers = []; foreach ($lines as $line) { $parts = explode(':', $line, 2); $headers[trim($parts[0])][] = isset($parts[1]) ? trim($parts[1]) : null; } return $headers; } /** * Removes a header from a message using a case-insensitive comparison. * * @param array $message Message that contains 'headers' * @param string $header Header to remove * * @return array */ public static function removeHeader(array $message, $header) { if (isset($message['headers'])) { foreach (array_keys($message['headers']) as $key) { if (!strcasecmp($header, $key)) { unset($message['headers'][$key]); } } } return $message; } /** * Replaces any existing case insensitive headers with the given value. * * @param array $message Message that contains 'headers' * @param string $header Header to set. * @param array $value Value to set. * * @return array */ public static function setHeader(array $message, $header, array $value) { $message = self::removeHeader($message, $header); $message['headers'][$header] = $value; return $message; } /** * Creates a URL string from a request. * * If the "url" key is present on the request, it is returned, otherwise * the url is built up based on the scheme, host, uri, and query_string * request values. * * @param array $request Request to get the URL from * * @return string Returns the request URL as a string. * @throws \InvalidArgumentException if no Host header is present. */ public static function url(array $request) { if (isset($request['url'])) { return $request['url']; } $uri = (isset($request['scheme']) ? $request['scheme'] : 'http') . '://'; if ($host = self::header($request, 'host')) { $uri .= $host; } else { throw new \InvalidArgumentException('No Host header was provided'); } if (isset($request['uri'])) { $uri .= $request['uri']; } if (isset($request['query_string'])) { $uri .= '?' . $request['query_string']; } return $uri; } /** * Reads the body of a message into a string. * * @param array|FutureArrayInterface $message Array containing a "body" key * * @return null|string Returns the body as a string or null if not set. * @throws \InvalidArgumentException if a request body is invalid. */ public static function body($message) { if (!isset($message['body'])) { return null; } if ($message['body'] instanceof StreamInterface) { return (string) $message['body']; } switch (gettype($message['body'])) { case 'string': return $message['body']; case 'resource': return stream_get_contents($message['body']); case 'object': if ($message['body'] instanceof \Iterator) { return implode('', iterator_to_array($message['body'])); } elseif (method_exists($message['body'], '__toString')) { return (string) $message['body']; } default: throw new \InvalidArgumentException('Invalid request body: ' . self::describeType($message['body'])); } } /** * Rewind the body of the provided message if possible. * * @param array $message Message that contains a 'body' field. * * @return bool Returns true on success, false on failure */ public static function rewindBody($message) { if ($message['body'] instanceof StreamInterface) { return $message['body']->seek(0); } if ($message['body'] instanceof \Generator) { return false; } if ($message['body'] instanceof \Iterator) { $message['body']->rewind(); return true; } if (is_resource($message['body'])) { return rewind($message['body']); } return is_string($message['body']) || (is_object($message['body']) && method_exists($message['body'], '__toString')); } /** * Debug function used to describe the provided value type and class. * * @param mixed $input * * @return string Returns a string containing the type of the variable and * if a class is provided, the class name. */ public static function describeType($input) { switch (gettype($input)) { case 'object': return 'object(' . get_class($input) . ')'; case 'array': return 'array(' . count($input) . ')'; default: ob_start(); var_dump($input); // normalize float vs double return str_replace('double(', 'float(', rtrim(ob_get_clean())); } } /** * Sleep for the specified amount of time specified in the request's * ['client']['delay'] option if present. * * This function should only be used when a non-blocking sleep is not * possible. * * @param array $request Request to sleep */ public static function doSleep(array $request) { if (isset($request['client']['delay'])) { usleep($request['client']['delay'] * 1000); } } /** * Returns a proxied future that modifies the dereferenced value of another * future using a promise. * * @param FutureArrayInterface $future Future to wrap with a new future * @param callable $onFulfilled Invoked when the future fulfilled * @param callable $onRejected Invoked when the future rejected * @param callable $onProgress Invoked when the future progresses * * @return FutureArray */ public static function proxy( FutureArrayInterface $future, callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null ) { return new FutureArray( $future->then($onFulfilled, $onRejected, $onProgress), [$future, 'wait'], [$future, 'cancel'] ); } /** * Returns a debug stream based on the provided variable. * * @param mixed $value Optional value * * @return resource */ public static function getDebugResource($value = null) { if (is_resource($value)) { return $value; } elseif (defined('STDOUT')) { return STDOUT; } else { return fopen('php://output', 'w'); } } } |
#6 | GuzzleHttp\Ring\Core::proxy(Object(GuzzleHttp\Ring\Future\CompletedFutureArray), Object(Closure)) /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Connections/Connection.php (299) <?php namespace Elasticsearch\Connections; use Elasticsearch\Common\Exceptions\AlreadyExpiredException; use Elasticsearch\Common\Exceptions\BadRequest400Exception; use Elasticsearch\Common\Exceptions\Conflict409Exception; use Elasticsearch\Common\Exceptions\Curl\CouldNotConnectToHost; use Elasticsearch\Common\Exceptions\Curl\CouldNotResolveHostException; use Elasticsearch\Common\Exceptions\Curl\OperationTimeoutException; use Elasticsearch\Common\Exceptions\Forbidden403Exception; use Elasticsearch\Common\Exceptions\MaxRetriesException; use Elasticsearch\Common\Exceptions\Missing404Exception; use Elasticsearch\Common\Exceptions\NoDocumentsToGetException; use Elasticsearch\Common\Exceptions\NoShardAvailableException; use Elasticsearch\Common\Exceptions\RequestTimeout408Exception; use Elasticsearch\Common\Exceptions\RoutingMissingException; use Elasticsearch\Common\Exceptions\ScriptLangNotSupportedException; use Elasticsearch\Common\Exceptions\ServerErrorResponseException; use Elasticsearch\Common\Exceptions\TransportException; use Elasticsearch\Serializers\SerializerInterface; use Elasticsearch\Transport; use GuzzleHttp\Ring\Core; use GuzzleHttp\Ring\Exception\ConnectException; use GuzzleHttp\Ring\Exception\RingException; use Psr\Log\LoggerInterface; /** * Class AbstractConnection * * @category Elasticsearch * @package Elasticsearch\Connections * @author Zachary Tong <[email protected]> * @license http://www.apache.org/licenses/LICENSE-2.0 Apache2 * @link http://elastic.co */ class Connection implements ConnectionInterface { /** @var callable */ protected $handler; /** @var SerializerInterface */ protected $serializer; /** * @var string */ protected $transportSchema = 'http'; // TODO depreciate this default /** * @var string */ protected $host; /** * @var string || null */ protected $path; /** * @var LoggerInterface */ protected $log; /** * @var LoggerInterface */ protected $trace; /** * @var array */ protected $connectionParams; /** @var array */ protected $headers = []; /** @var bool */ protected $isAlive = false; /** @var float */ private $pingTimeout = 1; //TODO expose this /** @var int */ private $lastPing = 0; /** @var int */ private $failedPings = 0; private $lastRequest = array(); /** * Constructor * * @param $handler * @param array $hostDetails * @param array $connectionParams Array of connection-specific parameters * @param \Elasticsearch\Serializers\SerializerInterface $serializer * @param \Psr\Log\LoggerInterface $log Logger object * @param \Psr\Log\LoggerInterface $trace */ public function __construct( $handler, $hostDetails, $connectionParams, SerializerInterface $serializer, LoggerInterface $log, LoggerInterface $trace ) { if (isset($hostDetails['port']) !== true) { $hostDetails['port'] = 9200; } if (isset($hostDetails['scheme'])) { $this->transportSchema = $hostDetails['scheme']; } if (isset($hostDetails['user']) && isset($hostDetails['pass'])) { $connectionParams['client']['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_BASIC; $connectionParams['client']['curl'][CURLOPT_USERPWD] = $hostDetails['user'].':'.$hostDetails['pass']; } if (isset($connectionParams['client']['headers']) === true) { $this->headers = $connectionParams['client']['headers']; unset($connectionParams['client']['headers']); } $host = $hostDetails['host'].':'.$hostDetails['port']; $path = null; if (isset($hostDetails['path']) === true) { $path = $hostDetails['path']; } $this->host = $host; $this->path = $path; $this->log = $log; $this->trace = $trace; $this->connectionParams = $connectionParams; $this->serializer = $serializer; $this->handler = $this->wrapHandler($handler, $log, $trace); } /** * @param $method * @param $uri * @param null $params * @param null $body * @param array $options * @param \Elasticsearch\Transport $transport * @return mixed */ public function performRequest($method, $uri, $params = null, $body = null, $options = [], Transport $transport = null) { if (isset($body) === true) { $body = $this->serializer->serialize($body); } $request = [ 'http_method' => $method, 'scheme' => $this->transportSchema, 'uri' => $this->getURI($uri, $params), 'body' => $body, 'headers' => array_merge([ 'Host' => [$this->host] ], $this->headers) ]; $request = array_replace_recursive($request, $this->connectionParams, $options); // RingPHP does not like if client is empty if (empty($request['client'])) { unset($request['client']); } $handler = $this->handler; $future = $handler($request, $this, $transport, $options); return $future; } /** @return string */ public function getTransportSchema() { return $this->transportSchema; } /** @return array */ public function getLastRequestInfo() { return $this->lastRequest; } private function wrapHandler(callable $handler, LoggerInterface $logger, LoggerInterface $tracer) { return function (array $request, Connection $connection, Transport $transport = null, $options) use ($handler, $logger, $tracer) { $this->lastRequest = []; $this->lastRequest['request'] = $request; // Send the request using the wrapped handler. $response = Core::proxy($handler($request), function ($response) use ($connection, $transport, $logger, $tracer, $request, $options) { $this->lastRequest['response'] = $response; if (isset($response['error']) === true) { if ($response['error'] instanceof ConnectException || $response['error'] instanceof RingException) { $this->log->warning("Curl exception encountered."); $exception = $this->getCurlRetryException($request, $response); $this->logRequestFail( $request['http_method'], $response['effective_url'], $request['body'], $request['headers'], $response['status'], $response['body'], $response['transfer_stats']['total_time'], $exception ); $node = $connection->getHost(); $this->log->warning("Marking node $node dead."); $connection->markDead(); // If the transport has not been set, we are inside a Ping or Sniff, // so we don't want to retrigger retries anyway. // // TODO this could be handled better, but we are limited because connectionpools do not // have access to Transport. Architecturally, all of this needs to be refactored if (isset($transport) === true) { $transport->connectionPool->scheduleCheck(); $neverRetry = isset($request['client']['never_retry']) ? $request['client']['never_retry'] : false; $shouldRetry = $transport->shouldRetry($request); $shouldRetryText = ($shouldRetry) ? 'true' : 'false'; $this->log->warning("Retries left? $shouldRetryText"); if ($shouldRetry && !$neverRetry) { return $transport->performRequest( $request['http_method'], $request['uri'], [], $request['body'], $options ); } } $this->log->warning("Out of retries, throwing exception from $node"); // Only throw if we run out of retries throw $exception; } else { // Something went seriously wrong, bail $exception = new TransportException($response['error']->getMessage()); $this->logRequestFail( $request['http_method'], $response['effective_url'], $request['body'], $request['headers'], $response['status'], $response['body'], $response['transfer_stats']['total_time'], $exception ); throw $exception; } } else { $connection->markAlive(); if (isset($response['body']) === true) { $response['body'] = stream_get_contents($response['body']); $this->lastRequest['response']['body'] = $response['body']; } if ($response['status'] >= 400 && $response['status'] < 500) { $ignore = isset($request['client']['ignore']) ? $request['client']['ignore'] : []; $this->process4xxError($request, $response, $ignore); } elseif ($response['status'] >= 500) { $ignore = isset($request['client']['ignore']) ? $request['client']['ignore'] : []; $this->process5xxError($request, $response, $ignore); } // No error, deserialize $response['body'] = $this->serializer->deserialize($response['body'], $response['transfer_stats']); } $this->logRequestSuccess( $request['http_method'], $response['effective_url'], $request['body'], $request['headers'], $response['status'], $response['body'], $response['transfer_stats']['total_time'] ); return isset($request['client']['verbose']) && $request['client']['verbose'] === true ? $response : $response['body']; }); return $response; }; } /** * @param string $uri * @param array $params * * @return string */ private function getURI($uri, $params) { if (isset($params) === true && !empty($params)) { array_walk($params, function (&$value, &$key) { if ($value === true) { $value = 'true'; } elseif ($value === false) { $value = 'false'; } }); $uri .= '?' . http_build_query($params); } if ($this->path !== null) { $uri = $this->path . $uri; } return $uri; } /** * Log a successful request * * @param string $method * @param string $fullURI * @param string $body * @param array $headers * @param string $statusCode * @param string $response * @param string $duration * * @return void */ public function logRequestSuccess($method, $fullURI, $body, $headers, $statusCode, $response, $duration) { $this->log->debug('Request Body', array($body)); $this->log->info( 'Request Success:', array( 'method' => $method, 'uri' => $fullURI, 'headers' => $headers, 'HTTP code' => $statusCode, 'duration' => $duration, ) ); $this->log->debug('Response', array($response)); // Build the curl command for Trace. $curlCommand = $this->buildCurlCommand($method, $fullURI, $body); $this->trace->info($curlCommand); $this->trace->debug( 'Response:', array( 'response' => $response, 'method' => $method, 'uri' => $fullURI, 'HTTP code' => $statusCode, 'duration' => $duration, ) ); } /** * Log a a failed request * * @param string $method * @param string $fullURI * @param string $body * @param array $headers * @param null|string $statusCode * @param null|string $response * @param string $duration * @param \Exception|null $exception * * @return void */ public function logRequestFail($method, $fullURI, $body, $headers, $statusCode, $response, $duration, \Exception $exception) { $this->log->debug('Request Body', array($body)); $this->log->warning( 'Request Failure:', array( 'method' => $method, 'uri' => $fullURI, 'headers' => $headers, 'HTTP code' => $statusCode, 'duration' => $duration, 'error' => $exception->getMessage(), ) ); $this->log->warning('Response', array($response)); // Build the curl command for Trace. $curlCommand = $this->buildCurlCommand($method, $fullURI, $body); $this->trace->info($curlCommand); $this->trace->debug( 'Response:', array( 'response' => $response, 'method' => $method, 'uri' => $fullURI, 'HTTP code' => $statusCode, 'duration' => $duration, ) ); } /** * @return bool */ public function ping() { $options = [ 'client' => [ 'timeout' => $this->pingTimeout, 'never_retry' => true, 'verbose' => true ] ]; try { $response = $this->performRequest('HEAD', '/', null, null, $options); $response = $response->wait(); } catch (TransportException $exception) { $this->markDead(); return false; } if ($response['status'] === 200) { $this->markAlive(); return true; } else { $this->markDead(); return false; } } /** * @return array */ public function sniff() { $options = [ 'client' => [ 'timeout' => $this->pingTimeout, 'never_retry' => true ] ]; return $this->performRequest('GET', '/_nodes/', null, null, $options); } /** * @return bool */ public function isAlive() { return $this->isAlive; } public function markAlive() { $this->failedPings = 0; $this->isAlive = true; $this->lastPing = time(); } public function markDead() { $this->isAlive = false; $this->failedPings += 1; $this->lastPing = time(); } /** * @return int */ public function getLastPing() { return $this->lastPing; } /** * @return int */ public function getPingFailures() { return $this->failedPings; } /** * @return string */ public function getHost() { return $this->host; } /** * @return null|string */ public function getUserPass() { if (isset($this->connectionParams['client']['curl'][CURLOPT_USERPWD]) === true) { return $this->connectionParams['client']['curl'][CURLOPT_USERPWD]; } return null; } /** * @return null|string */ public function getPath() { return $this->path; } /** * @param $request * @param $response * @return \Elasticsearch\Common\Exceptions\Curl\CouldNotConnectToHost|\Elasticsearch\Common\Exceptions\Curl\CouldNotResolveHostException|\Elasticsearch\Common\Exceptions\Curl\OperationTimeoutException|\Elasticsearch\Common\Exceptions\MaxRetriesException */ protected function getCurlRetryException($request, $response) { $exception = null; $message = $response['error']->getMessage(); $exception = new MaxRetriesException($message); switch ($response['curl']['errno']) { case 6: $exception = new CouldNotResolveHostException($message, null, $exception); break; case 7: $exception = new CouldNotConnectToHost($message, null, $exception); break; case 28: $exception = new OperationTimeoutException($message, null, $exception); break; } return $exception; } /** * Construct a string cURL command * * @param string $method HTTP method * @param string $uri Full URI of request * @param string $body Request body * * @return string */ private function buildCurlCommand($method, $uri, $body) { if (strpos($uri, '?') === false) { $uri .= '?pretty=true'; } else { str_replace('?', '?pretty=true', $uri); } $curlCommand = 'curl -X' . strtoupper($method); $curlCommand .= " '" . $uri . "'"; if (isset($body) === true && $body !== '') { $curlCommand .= " -d '" . $body . "'"; } return $curlCommand; } /** * @param $request * @param $response * @param $ignore * @throws \Elasticsearch\Common\Exceptions\AlreadyExpiredException|\Elasticsearch\Common\Exceptions\BadRequest400Exception|\Elasticsearch\Common\Exceptions\Conflict409Exception|\Elasticsearch\Common\Exceptions\Forbidden403Exception|\Elasticsearch\Common\Exceptions\Missing404Exception|\Elasticsearch\Common\Exceptions\ScriptLangNotSupportedException|null */ private function process4xxError($request, $response, $ignore) { $statusCode = $response['status']; $responseBody = $response['body']; /** @var \Exception $exception */ $exception = $this->tryDeserialize400Error($response); if (array_search($response['status'], $ignore) !== false) { return; } if ($statusCode === 400 && strpos($responseBody, "AlreadyExpiredException") !== false) { $exception = new AlreadyExpiredException($responseBody, $statusCode); } elseif ($statusCode === 403) { $exception = new Forbidden403Exception($responseBody, $statusCode); } elseif ($statusCode === 404) { $exception = new Missing404Exception($responseBody, $statusCode); } elseif ($statusCode === 409) { $exception = new Conflict409Exception($responseBody, $statusCode); } elseif ($statusCode === 400 && strpos($responseBody, 'script_lang not supported') !== false) { $exception = new ScriptLangNotSupportedException($responseBody. $statusCode); } elseif ($statusCode === 408) { $exception = new RequestTimeout408Exception($responseBody, $statusCode); } else { $exception = new BadRequest400Exception($responseBody, $statusCode); } $this->logRequestFail( $request['http_method'], $response['effective_url'], $request['body'], $request['headers'], $response['status'], $response['body'], $response['transfer_stats']['total_time'], $exception ); throw $exception; } /** * @param $request * @param $response * @param $ignore * @throws \Elasticsearch\Common\Exceptions\NoDocumentsToGetException|\Elasticsearch\Common\Exceptions\NoShardAvailableException|\Elasticsearch\Common\Exceptions\RoutingMissingException|\Elasticsearch\Common\Exceptions\ServerErrorResponseException */ private function process5xxError($request, $response, $ignore) { $statusCode = $response['status']; $responseBody = $response['body']; /** @var \Exception $exception */ $exception = $this->tryDeserialize500Error($response); $exceptionText = "[$statusCode Server Exception] ".$exception->getMessage(); $this->log->error($exceptionText); $this->log->error($exception->getTraceAsString()); if (array_search($statusCode, $ignore) !== false) { return; } if ($statusCode === 500 && strpos($responseBody, "RoutingMissingException") !== false) { $exception = new RoutingMissingException($exception->getMessage(), $statusCode, $exception); } elseif ($statusCode === 500 && preg_match('/ActionRequestValidationException.+ no documents to get/', $responseBody) === 1) { $exception = new NoDocumentsToGetException($exception->getMessage(), $statusCode, $exception); } elseif ($statusCode === 500 && strpos($responseBody, 'NoShardAvailableActionException') !== false) { $exception = new NoShardAvailableException($exception->getMessage(), $statusCode, $exception); } else { $exception = new ServerErrorResponseException($responseBody, $statusCode); } $this->logRequestFail( $request['http_method'], $response['effective_url'], $request['body'], $request['headers'], $response['status'], $response['body'], $response['transfer_stats']['total_time'], $exception ); throw $exception; } private function tryDeserialize400Error($response) { return $this->tryDeserializeError($response, 'Elasticsearch\Common\Exceptions\BadRequest400Exception'); } private function tryDeserialize500Error($response) { return $this->tryDeserializeError($response, 'Elasticsearch\Common\Exceptions\ServerErrorResponseException'); } private function tryDeserializeError($response, $errorClass) { $error = $this->serializer->deserialize($response['body'], $response['transfer_stats']); if (is_array($error) === true) { // 2.0 structured exceptions if (isset($error['error']['reason']) === true) { // Try to use root cause first (only grabs the first root cause) $root = $error['error']['root_cause']; if (isset($root) && isset($root[0])) { $cause = $root[0]['reason']; $type = $root[0]['type']; } else { $cause = $error['error']['reason']; $type = $error['error']['type']; } $original = new $errorClass($response['body'], $response['status']); return new $errorClass("$type: $cause", $response['status'], $original); } elseif (isset($error['error']) === true) { // <2.0 semi-structured exceptions $original = new $errorClass($response['body'], $response['status']); return new $errorClass($error['error'], $response['status'], $original); } // <2.0 "i just blew up" nonstructured exception // $error is an array but we don't know the format, reuse the response body instead return new $errorClass($response['body'], $response['status']); } // <2.0 "i just blew up" nonstructured exception return new $errorClass($response['body']); } } |
#7 | Elasticsearch\Connections\Connection->Elasticsearch\Connections\{closure}(Array([http_method] => GET, [scheme] => http, [uri] => /drooble_users/_search?from=10&size=11, [body] => {"query":{"bool":{"should":[{"match":{"tags.equipment.en":"Protools"}}],"minimum_should_match":1}},"sort":[{"_score":"desc"}]}, [headers] => Array([Host] => Array([0] => search-drooble1-irvhqoehqpblnqmd5va6n5pmsy.us-west-2.es.amazonaws.com:80), [Content-Type] => Array([0] => application/json), [Accept] => Array([0] => application/json))), Object(Elasticsearch\Connections\Connection), Object(Elasticsearch\Transport), Array()) /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Connections/Connection.php (177) <?php namespace Elasticsearch\Connections; use Elasticsearch\Common\Exceptions\AlreadyExpiredException; use Elasticsearch\Common\Exceptions\BadRequest400Exception; use Elasticsearch\Common\Exceptions\Conflict409Exception; use Elasticsearch\Common\Exceptions\Curl\CouldNotConnectToHost; use Elasticsearch\Common\Exceptions\Curl\CouldNotResolveHostException; use Elasticsearch\Common\Exceptions\Curl\OperationTimeoutException; use Elasticsearch\Common\Exceptions\Forbidden403Exception; use Elasticsearch\Common\Exceptions\MaxRetriesException; use Elasticsearch\Common\Exceptions\Missing404Exception; use Elasticsearch\Common\Exceptions\NoDocumentsToGetException; use Elasticsearch\Common\Exceptions\NoShardAvailableException; use Elasticsearch\Common\Exceptions\RequestTimeout408Exception; use Elasticsearch\Common\Exceptions\RoutingMissingException; use Elasticsearch\Common\Exceptions\ScriptLangNotSupportedException; use Elasticsearch\Common\Exceptions\ServerErrorResponseException; use Elasticsearch\Common\Exceptions\TransportException; use Elasticsearch\Serializers\SerializerInterface; use Elasticsearch\Transport; use GuzzleHttp\Ring\Core; use GuzzleHttp\Ring\Exception\ConnectException; use GuzzleHttp\Ring\Exception\RingException; use Psr\Log\LoggerInterface; /** * Class AbstractConnection * * @category Elasticsearch * @package Elasticsearch\Connections * @author Zachary Tong <[email protected]> * @license http://www.apache.org/licenses/LICENSE-2.0 Apache2 * @link http://elastic.co */ class Connection implements ConnectionInterface { /** @var callable */ protected $handler; /** @var SerializerInterface */ protected $serializer; /** * @var string */ protected $transportSchema = 'http'; // TODO depreciate this default /** * @var string */ protected $host; /** * @var string || null */ protected $path; /** * @var LoggerInterface */ protected $log; /** * @var LoggerInterface */ protected $trace; /** * @var array */ protected $connectionParams; /** @var array */ protected $headers = []; /** @var bool */ protected $isAlive = false; /** @var float */ private $pingTimeout = 1; //TODO expose this /** @var int */ private $lastPing = 0; /** @var int */ private $failedPings = 0; private $lastRequest = array(); /** * Constructor * * @param $handler * @param array $hostDetails * @param array $connectionParams Array of connection-specific parameters * @param \Elasticsearch\Serializers\SerializerInterface $serializer * @param \Psr\Log\LoggerInterface $log Logger object * @param \Psr\Log\LoggerInterface $trace */ public function __construct( $handler, $hostDetails, $connectionParams, SerializerInterface $serializer, LoggerInterface $log, LoggerInterface $trace ) { if (isset($hostDetails['port']) !== true) { $hostDetails['port'] = 9200; } if (isset($hostDetails['scheme'])) { $this->transportSchema = $hostDetails['scheme']; } if (isset($hostDetails['user']) && isset($hostDetails['pass'])) { $connectionParams['client']['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_BASIC; $connectionParams['client']['curl'][CURLOPT_USERPWD] = $hostDetails['user'].':'.$hostDetails['pass']; } if (isset($connectionParams['client']['headers']) === true) { $this->headers = $connectionParams['client']['headers']; unset($connectionParams['client']['headers']); } $host = $hostDetails['host'].':'.$hostDetails['port']; $path = null; if (isset($hostDetails['path']) === true) { $path = $hostDetails['path']; } $this->host = $host; $this->path = $path; $this->log = $log; $this->trace = $trace; $this->connectionParams = $connectionParams; $this->serializer = $serializer; $this->handler = $this->wrapHandler($handler, $log, $trace); } /** * @param $method * @param $uri * @param null $params * @param null $body * @param array $options * @param \Elasticsearch\Transport $transport * @return mixed */ public function performRequest($method, $uri, $params = null, $body = null, $options = [], Transport $transport = null) { if (isset($body) === true) { $body = $this->serializer->serialize($body); } $request = [ 'http_method' => $method, 'scheme' => $this->transportSchema, 'uri' => $this->getURI($uri, $params), 'body' => $body, 'headers' => array_merge([ 'Host' => [$this->host] ], $this->headers) ]; $request = array_replace_recursive($request, $this->connectionParams, $options); // RingPHP does not like if client is empty if (empty($request['client'])) { unset($request['client']); } $handler = $this->handler; $future = $handler($request, $this, $transport, $options); return $future; } /** @return string */ public function getTransportSchema() { return $this->transportSchema; } /** @return array */ public function getLastRequestInfo() { return $this->lastRequest; } private function wrapHandler(callable $handler, LoggerInterface $logger, LoggerInterface $tracer) { return function (array $request, Connection $connection, Transport $transport = null, $options) use ($handler, $logger, $tracer) { $this->lastRequest = []; $this->lastRequest['request'] = $request; // Send the request using the wrapped handler. $response = Core::proxy($handler($request), function ($response) use ($connection, $transport, $logger, $tracer, $request, $options) { $this->lastRequest['response'] = $response; if (isset($response['error']) === true) { if ($response['error'] instanceof ConnectException || $response['error'] instanceof RingException) { $this->log->warning("Curl exception encountered."); $exception = $this->getCurlRetryException($request, $response); $this->logRequestFail( $request['http_method'], $response['effective_url'], $request['body'], $request['headers'], $response['status'], $response['body'], $response['transfer_stats']['total_time'], $exception ); $node = $connection->getHost(); $this->log->warning("Marking node $node dead."); $connection->markDead(); // If the transport has not been set, we are inside a Ping or Sniff, // so we don't want to retrigger retries anyway. // // TODO this could be handled better, but we are limited because connectionpools do not // have access to Transport. Architecturally, all of this needs to be refactored if (isset($transport) === true) { $transport->connectionPool->scheduleCheck(); $neverRetry = isset($request['client']['never_retry']) ? $request['client']['never_retry'] : false; $shouldRetry = $transport->shouldRetry($request); $shouldRetryText = ($shouldRetry) ? 'true' : 'false'; $this->log->warning("Retries left? $shouldRetryText"); if ($shouldRetry && !$neverRetry) { return $transport->performRequest( $request['http_method'], $request['uri'], [], $request['body'], $options ); } } $this->log->warning("Out of retries, throwing exception from $node"); // Only throw if we run out of retries throw $exception; } else { // Something went seriously wrong, bail $exception = new TransportException($response['error']->getMessage()); $this->logRequestFail( $request['http_method'], $response['effective_url'], $request['body'], $request['headers'], $response['status'], $response['body'], $response['transfer_stats']['total_time'], $exception ); throw $exception; } } else { $connection->markAlive(); if (isset($response['body']) === true) { $response['body'] = stream_get_contents($response['body']); $this->lastRequest['response']['body'] = $response['body']; } if ($response['status'] >= 400 && $response['status'] < 500) { $ignore = isset($request['client']['ignore']) ? $request['client']['ignore'] : []; $this->process4xxError($request, $response, $ignore); } elseif ($response['status'] >= 500) { $ignore = isset($request['client']['ignore']) ? $request['client']['ignore'] : []; $this->process5xxError($request, $response, $ignore); } // No error, deserialize $response['body'] = $this->serializer->deserialize($response['body'], $response['transfer_stats']); } $this->logRequestSuccess( $request['http_method'], $response['effective_url'], $request['body'], $request['headers'], $response['status'], $response['body'], $response['transfer_stats']['total_time'] ); return isset($request['client']['verbose']) && $request['client']['verbose'] === true ? $response : $response['body']; }); return $response; }; } /** * @param string $uri * @param array $params * * @return string */ private function getURI($uri, $params) { if (isset($params) === true && !empty($params)) { array_walk($params, function (&$value, &$key) { if ($value === true) { $value = 'true'; } elseif ($value === false) { $value = 'false'; } }); $uri .= '?' . http_build_query($params); } if ($this->path !== null) { $uri = $this->path . $uri; } return $uri; } /** * Log a successful request * * @param string $method * @param string $fullURI * @param string $body * @param array $headers * @param string $statusCode * @param string $response * @param string $duration * * @return void */ public function logRequestSuccess($method, $fullURI, $body, $headers, $statusCode, $response, $duration) { $this->log->debug('Request Body', array($body)); $this->log->info( 'Request Success:', array( 'method' => $method, 'uri' => $fullURI, 'headers' => $headers, 'HTTP code' => $statusCode, 'duration' => $duration, ) ); $this->log->debug('Response', array($response)); // Build the curl command for Trace. $curlCommand = $this->buildCurlCommand($method, $fullURI, $body); $this->trace->info($curlCommand); $this->trace->debug( 'Response:', array( 'response' => $response, 'method' => $method, 'uri' => $fullURI, 'HTTP code' => $statusCode, 'duration' => $duration, ) ); } /** * Log a a failed request * * @param string $method * @param string $fullURI * @param string $body * @param array $headers * @param null|string $statusCode * @param null|string $response * @param string $duration * @param \Exception|null $exception * * @return void */ public function logRequestFail($method, $fullURI, $body, $headers, $statusCode, $response, $duration, \Exception $exception) { $this->log->debug('Request Body', array($body)); $this->log->warning( 'Request Failure:', array( 'method' => $method, 'uri' => $fullURI, 'headers' => $headers, 'HTTP code' => $statusCode, 'duration' => $duration, 'error' => $exception->getMessage(), ) ); $this->log->warning('Response', array($response)); // Build the curl command for Trace. $curlCommand = $this->buildCurlCommand($method, $fullURI, $body); $this->trace->info($curlCommand); $this->trace->debug( 'Response:', array( 'response' => $response, 'method' => $method, 'uri' => $fullURI, 'HTTP code' => $statusCode, 'duration' => $duration, ) ); } /** * @return bool */ public function ping() { $options = [ 'client' => [ 'timeout' => $this->pingTimeout, 'never_retry' => true, 'verbose' => true ] ]; try { $response = $this->performRequest('HEAD', '/', null, null, $options); $response = $response->wait(); } catch (TransportException $exception) { $this->markDead(); return false; } if ($response['status'] === 200) { $this->markAlive(); return true; } else { $this->markDead(); return false; } } /** * @return array */ public function sniff() { $options = [ 'client' => [ 'timeout' => $this->pingTimeout, 'never_retry' => true ] ]; return $this->performRequest('GET', '/_nodes/', null, null, $options); } /** * @return bool */ public function isAlive() { return $this->isAlive; } public function markAlive() { $this->failedPings = 0; $this->isAlive = true; $this->lastPing = time(); } public function markDead() { $this->isAlive = false; $this->failedPings += 1; $this->lastPing = time(); } /** * @return int */ public function getLastPing() { return $this->lastPing; } /** * @return int */ public function getPingFailures() { return $this->failedPings; } /** * @return string */ public function getHost() { return $this->host; } /** * @return null|string */ public function getUserPass() { if (isset($this->connectionParams['client']['curl'][CURLOPT_USERPWD]) === true) { return $this->connectionParams['client']['curl'][CURLOPT_USERPWD]; } return null; } /** * @return null|string */ public function getPath() { return $this->path; } /** * @param $request * @param $response * @return \Elasticsearch\Common\Exceptions\Curl\CouldNotConnectToHost|\Elasticsearch\Common\Exceptions\Curl\CouldNotResolveHostException|\Elasticsearch\Common\Exceptions\Curl\OperationTimeoutException|\Elasticsearch\Common\Exceptions\MaxRetriesException */ protected function getCurlRetryException($request, $response) { $exception = null; $message = $response['error']->getMessage(); $exception = new MaxRetriesException($message); switch ($response['curl']['errno']) { case 6: $exception = new CouldNotResolveHostException($message, null, $exception); break; case 7: $exception = new CouldNotConnectToHost($message, null, $exception); break; case 28: $exception = new OperationTimeoutException($message, null, $exception); break; } return $exception; } /** * Construct a string cURL command * * @param string $method HTTP method * @param string $uri Full URI of request * @param string $body Request body * * @return string */ private function buildCurlCommand($method, $uri, $body) { if (strpos($uri, '?') === false) { $uri .= '?pretty=true'; } else { str_replace('?', '?pretty=true', $uri); } $curlCommand = 'curl -X' . strtoupper($method); $curlCommand .= " '" . $uri . "'"; if (isset($body) === true && $body !== '') { $curlCommand .= " -d '" . $body . "'"; } return $curlCommand; } /** * @param $request * @param $response * @param $ignore * @throws \Elasticsearch\Common\Exceptions\AlreadyExpiredException|\Elasticsearch\Common\Exceptions\BadRequest400Exception|\Elasticsearch\Common\Exceptions\Conflict409Exception|\Elasticsearch\Common\Exceptions\Forbidden403Exception|\Elasticsearch\Common\Exceptions\Missing404Exception|\Elasticsearch\Common\Exceptions\ScriptLangNotSupportedException|null */ private function process4xxError($request, $response, $ignore) { $statusCode = $response['status']; $responseBody = $response['body']; /** @var \Exception $exception */ $exception = $this->tryDeserialize400Error($response); if (array_search($response['status'], $ignore) !== false) { return; } if ($statusCode === 400 && strpos($responseBody, "AlreadyExpiredException") !== false) { $exception = new AlreadyExpiredException($responseBody, $statusCode); } elseif ($statusCode === 403) { $exception = new Forbidden403Exception($responseBody, $statusCode); } elseif ($statusCode === 404) { $exception = new Missing404Exception($responseBody, $statusCode); } elseif ($statusCode === 409) { $exception = new Conflict409Exception($responseBody, $statusCode); } elseif ($statusCode === 400 && strpos($responseBody, 'script_lang not supported') !== false) { $exception = new ScriptLangNotSupportedException($responseBody. $statusCode); } elseif ($statusCode === 408) { $exception = new RequestTimeout408Exception($responseBody, $statusCode); } else { $exception = new BadRequest400Exception($responseBody, $statusCode); } $this->logRequestFail( $request['http_method'], $response['effective_url'], $request['body'], $request['headers'], $response['status'], $response['body'], $response['transfer_stats']['total_time'], $exception ); throw $exception; } /** * @param $request * @param $response * @param $ignore * @throws \Elasticsearch\Common\Exceptions\NoDocumentsToGetException|\Elasticsearch\Common\Exceptions\NoShardAvailableException|\Elasticsearch\Common\Exceptions\RoutingMissingException|\Elasticsearch\Common\Exceptions\ServerErrorResponseException */ private function process5xxError($request, $response, $ignore) { $statusCode = $response['status']; $responseBody = $response['body']; /** @var \Exception $exception */ $exception = $this->tryDeserialize500Error($response); $exceptionText = "[$statusCode Server Exception] ".$exception->getMessage(); $this->log->error($exceptionText); $this->log->error($exception->getTraceAsString()); if (array_search($statusCode, $ignore) !== false) { return; } if ($statusCode === 500 && strpos($responseBody, "RoutingMissingException") !== false) { $exception = new RoutingMissingException($exception->getMessage(), $statusCode, $exception); } elseif ($statusCode === 500 && preg_match('/ActionRequestValidationException.+ no documents to get/', $responseBody) === 1) { $exception = new NoDocumentsToGetException($exception->getMessage(), $statusCode, $exception); } elseif ($statusCode === 500 && strpos($responseBody, 'NoShardAvailableActionException') !== false) { $exception = new NoShardAvailableException($exception->getMessage(), $statusCode, $exception); } else { $exception = new ServerErrorResponseException($responseBody, $statusCode); } $this->logRequestFail( $request['http_method'], $response['effective_url'], $request['body'], $request['headers'], $response['status'], $response['body'], $response['transfer_stats']['total_time'], $exception ); throw $exception; } private function tryDeserialize400Error($response) { return $this->tryDeserializeError($response, 'Elasticsearch\Common\Exceptions\BadRequest400Exception'); } private function tryDeserialize500Error($response) { return $this->tryDeserializeError($response, 'Elasticsearch\Common\Exceptions\ServerErrorResponseException'); } private function tryDeserializeError($response, $errorClass) { $error = $this->serializer->deserialize($response['body'], $response['transfer_stats']); if (is_array($error) === true) { // 2.0 structured exceptions if (isset($error['error']['reason']) === true) { // Try to use root cause first (only grabs the first root cause) $root = $error['error']['root_cause']; if (isset($root) && isset($root[0])) { $cause = $root[0]['reason']; $type = $root[0]['type']; } else { $cause = $error['error']['reason']; $type = $error['error']['type']; } $original = new $errorClass($response['body'], $response['status']); return new $errorClass("$type: $cause", $response['status'], $original); } elseif (isset($error['error']) === true) { // <2.0 semi-structured exceptions $original = new $errorClass($response['body'], $response['status']); return new $errorClass($error['error'], $response['status'], $original); } // <2.0 "i just blew up" nonstructured exception // $error is an array but we don't know the format, reuse the response body instead return new $errorClass($response['body'], $response['status']); } // <2.0 "i just blew up" nonstructured exception return new $errorClass($response['body']); } } |
#8 | Elasticsearch\Connections\Connection->performRequest(GET, /drooble_users/_search, Array([from] => 10, [size] => 11), {"query":{"bool":{"should":[{"match":{"tags.equipment.en":"Protools"}}],"minimum_should_match":1}},"sort":[{"_score":"desc"}]}, Array(), Object(Elasticsearch\Transport)) /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Transport.php (110) <?php namespace Elasticsearch; use Elasticsearch\Common\Exceptions; use Elasticsearch\ConnectionPool\AbstractConnectionPool; use Elasticsearch\Connections\Connection; use Elasticsearch\Connections\ConnectionInterface; use GuzzleHttp\Ring\Future\FutureArrayInterface; use Psr\Log\LoggerInterface; /** * Class Transport * * @category Elasticsearch * @package Elasticsearch * @author Zachary Tong <[email protected]> * @license http://www.apache.org/licenses/LICENSE-2.0 Apache2 * @link http://elastic.co */ class Transport { /** * @var AbstractConnectionPool */ public $connectionPool; /** * @var LoggerInterface */ private $log; /** @var int */ public $retryAttempts = 0; /** @var Connection */ public $lastConnection; /** @var int */ public $retries; /** * Transport class is responsible for dispatching requests to the * underlying cluster connections * * @param $retries * @param bool $sniffOnStart * @param ConnectionPool\AbstractConnectionPool $connectionPool * @param \Psr\Log\LoggerInterface $log Monolog logger object */ // @codingStandardsIgnoreStart // "Arguments with default values must be at the end of the argument list" - cannot change the interface public function __construct($retries, $sniffOnStart = false, AbstractConnectionPool $connectionPool, LoggerInterface $log) { // @codingStandardsIgnoreEnd $this->log = $log; $this->connectionPool = $connectionPool; $this->retries = $retries; if ($sniffOnStart === true) { $this->log->notice('Sniff on Start.'); $this->connectionPool->scheduleCheck(); } } /** * Returns a single connection from the connection pool * Potentially performs a sniffing step before returning * * @return ConnectionInterface Connection */ public function getConnection() { return $this->connectionPool->nextConnection(); } /** * Perform a request to the Cluster * * @param string $method HTTP method to use * @param string $uri HTTP URI to send request to * @param null $params Optional query parameters * @param null $body Optional query body * @param array $options * * @throws Common\Exceptions\NoNodesAvailableException|\Exception * @return FutureArrayInterface */ public function performRequest($method, $uri, $params = null, $body = null, $options = []) { try { $connection = $this->getConnection(); } catch (Exceptions\NoNodesAvailableException $exception) { $this->log->critical('No alive nodes found in cluster'); throw $exception; } $response = array(); $caughtException = null; $this->lastConnection = $connection; $future = $connection->performRequest( $method, $uri, $params, $body, $options, $this ); $future->promise()->then( //onSuccess function ($response) { $this->retryAttempts = 0; // Note, this could be a 4xx or 5xx error }, //onFailure function ($response) { // Ignore 400 level errors, as that means the server responded just fine if (!(isset($response['code']) && $response['code'] >=400 && $response['code'] < 500)) { // Otherwise schedule a check $this->connectionPool->scheduleCheck(); } } ); return $future; } /** * @param FutureArrayInterface $result Response of a request (promise) * @param array $options Options for transport * * @return callable|array */ public function resultOrFuture($result, $options = []) { $response = null; $async = isset($options['client']['future']) ? $options['client']['future'] : null; if (is_null($async) || $async === false) { do { $result = $result->wait(); } while ($result instanceof FutureArrayInterface); return $result; } elseif ($async === true || $async === 'lazy') { return $result; } } /** * @param $request * * @return bool */ public function shouldRetry($request) { if ($this->retryAttempts < $this->retries) { $this->retryAttempts += 1; return true; } return false; } /** * Returns the last used connection so that it may be inspected. Mainly * for debugging/testing purposes. * * @return Connection */ public function getLastConnection() { return $this->lastConnection; } } |
#9 | Elasticsearch\Transport->performRequest(GET, /drooble_users/_search, Array([from] => 10, [size] => 11), Array([query] => Array([bool] => Array([should] => Array(), [minimum_should_match] => 1)), [sort] => Array([0] => Array([_score] => desc))), Array()) /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Client.php (1553) <?php namespace Elasticsearch; use Elasticsearch\Common\Exceptions\BadMethodCallException; use Elasticsearch\Common\Exceptions\InvalidArgumentException; use Elasticsearch\Common\Exceptions\NoNodesAvailableException; use Elasticsearch\Common\Exceptions\BadRequest400Exception; use Elasticsearch\Common\Exceptions\Missing404Exception; use Elasticsearch\Common\Exceptions\TransportException; use Elasticsearch\Endpoints\AbstractEndpoint; use Elasticsearch\Namespaces\AbstractNamespace; use Elasticsearch\Namespaces\CatNamespace; use Elasticsearch\Namespaces\ClusterNamespace; use Elasticsearch\Namespaces\IndicesNamespace; use Elasticsearch\Namespaces\IngestNamespace; use Elasticsearch\Namespaces\NamespaceBuilderInterface; use Elasticsearch\Namespaces\NodesNamespace; use Elasticsearch\Namespaces\RemoteNamespace; use Elasticsearch\Namespaces\SnapshotNamespace; use Elasticsearch\Namespaces\BooleanRequestWrapper; use Elasticsearch\Namespaces\TasksNamespace; /** * Class Client * * @category Elasticsearch * @package Elasticsearch * @author Zachary Tong <[email protected]> * @license http://www.apache.org/licenses/LICENSE-2.0 Apache2 * @link http://elastic.co */ class Client { /** * @var Transport */ public $transport; /** * @var array */ protected $params; /** * @var IndicesNamespace */ protected $indices; /** * @var ClusterNamespace */ protected $cluster; /** * @var NodesNamespace */ protected $nodes; /** * @var SnapshotNamespace */ protected $snapshot; /** * @var CatNamespace */ protected $cat; /** * @var IngestNamespace */ protected $ingest; /** * @var TasksNamespace */ protected $tasks; /** * @var RemoteNamespace */ protected $remote; /** @var callback */ protected $endpoints; /** @var NamespaceBuilderInterface[] */ protected $registeredNamespaces = []; /** * Client constructor * * @param Transport $transport * @param callable $endpoint * @param AbstractNamespace[] $registeredNamespaces */ public function __construct(Transport $transport, callable $endpoint, array $registeredNamespaces) { $this->transport = $transport; $this->endpoints = $endpoint; $this->indices = new IndicesNamespace($transport, $endpoint); $this->cluster = new ClusterNamespace($transport, $endpoint); $this->nodes = new NodesNamespace($transport, $endpoint); $this->snapshot = new SnapshotNamespace($transport, $endpoint); $this->cat = new CatNamespace($transport, $endpoint); $this->ingest = new IngestNamespace($transport, $endpoint); $this->tasks = new TasksNamespace($transport, $endpoint); $this->remote = new RemoteNamespace($transport, $endpoint); $this->registeredNamespaces = $registeredNamespaces; } /** * @param $params * @return array */ public function info($params = []) { /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Info $endpoint */ $endpoint = $endpointBuilder('Info'); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * @param $params array Associative array of parameters * * @return bool */ public function ping($params = []) { /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Ping $endpoint */ $endpoint = $endpointBuilder('Ping'); $endpoint->setParams($params); try { $this->performRequest($endpoint); } catch (Missing404Exception $exception) { return false; } catch (TransportException $exception) { return false; } catch (NoNodesAvailableException $exception) { return false; } return true; } /** * $params['id'] = (string) The document ID (Required) * ['index'] = (string) The name of the index (Required) * ['type'] = (string) The type of the document (use `_all` to fetch the first document matching the ID across all types) (Required) * ['ignore_missing'] = ?? * ['fields'] = (list) A comma-separated list of fields to return in the response * ['parent'] = (string) The ID of the parent document * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) * ['realtime'] = (boolean) Specify whether to perform the operation in realtime or search mode * ['refresh'] = (boolean) Refresh the shard containing the document before performing the operation * ['routing'] = (string) Specific routing value * ['_source'] = (list) True or false to return the _source field or not, or a list of fields to return * ['_source_exclude'] = (list) A list of fields to exclude from the returned _source field * ['_source_include'] = (list) A list of fields to extract and return from the _source field * * @param $params array Associative array of parameters * * @return array */ public function get($params) { $id = $this->extractArgument($params, 'id'); $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Get $endpoint */ $endpoint = $endpointBuilder('Get'); $endpoint->setID($id) ->setIndex($index) ->setType($type); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['id'] = (string) The document ID (Required) * ['index'] = (string) The name of the index (Required) * ['type'] = (string) The type of the document (use `_all` to fetch the first document matching the ID across all types) (Required) * ['ignore_missing'] = ?? * ['parent'] = (string) The ID of the parent document * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) * ['realtime'] = (boolean) Specify whether to perform the operation in realtime or search mode * ['refresh'] = (boolean) Refresh the shard containing the document before performing the operation * ['routing'] = (string) Specific routing value * * @param $params array Associative array of parameters * * @return array */ public function getSource($params) { $id = $this->extractArgument($params, 'id'); $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Get $endpoint */ $endpoint = $endpointBuilder('Get'); $endpoint->setID($id) ->setIndex($index) ->setType($type) ->returnOnlySource(); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['id'] = (string) The document ID (Required) * ['index'] = (string) The name of the index (Required) * ['type'] = (string) The type of the document (Required) * ['consistency'] = (enum) Specific write consistency setting for the operation * ['parent'] = (string) ID of parent document * ['refresh'] = (boolean) Refresh the index after performing the operation * ['replication'] = (enum) Specific replication type * ['routing'] = (string) Specific routing value * ['timeout'] = (time) Explicit operation timeout * ['version_type'] = (enum) Specific version type * * @param $params array Associative array of parameters * * @return array */ public function delete($params) { $id = $this->extractArgument($params, 'id'); $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $this->verifyNotNullOrEmpty("id", $id); $this->verifyNotNullOrEmpty("type", $type); $this->verifyNotNullOrEmpty("index", $index); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Delete $endpoint */ $endpoint = $endpointBuilder('Delete'); $endpoint->setID($id) ->setIndex($index) ->setType($type); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * * $params['_source'] = (list) True or false to return the _source field or not, or a list of fields to return * ['_source_exclude'] = (array) A list of fields to exclude from the returned _source field * ['_source_include'] = (array) A list of fields to extract and return from the _source field * ['allow_no_indices'] = (bool) Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) * ['analyze_wildcard'] = (bool) Specify whether wildcard and prefix queries should be analyzed (default: false) * ['analyzer'] = (string) The analyzer to use for the query string * ['conflicts'] = (enum) What to do when the delete-by-query hits version conflicts? * ['default_operator'] = (enum) The default operator for query string query (AND or OR) * ['df'] = (string) The field to use as default where no field prefix is given in the query string * ['expand_wildcards'] = (enum) Whether to expand wildcard expression to concrete indices that are open, closed or both. * ['from'] = (number) Starting offset (default: 0) * ['ignore_unavailable'] = (bool) Whether specified concrete indices should be ignored when unavailable (missing or closed) * ['lenient'] = (bool) Specify whether format-based query failures (such as providing text to a numeric field) should be ignored * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) * ['q'] = (string) Query in the Lucene query string syntax * ['refresh'] = (bool) Should the effected indexes be refreshed? * ['request_cache'] = (bool) Specify if request cache should be used for this request or not, defaults to index level setting * ['requests_per_second'] = (number) The throttle for this request in sub-requests per second. -1 means no throttle. * ['routing'] = (array) A comma-separated list of specific routing values * ['scroll'] = (number) Specify how long a consistent view of the index should be maintained for scrolled search * ['scroll_size'] = (number) Size on the scroll request powering the update_by_query * ['search_timeout'] = (number) Explicit timeout for each search request. Defaults to no timeout. * ['search_type'] = (enum) Search operation type * ['size'] = (number) Number of hits to return (default: 10) * ['slices'] = (integer) The number of slices this task should be divided into. Defaults to 1 meaning the task isn't sliced into subtasks. * ['sort'] = (array) A comma-separated list of <field>:<direction> pairs * ['stats'] = (array) Specific 'tag' of the request for logging and statistical purposes * ['terminate_after'] = (number) The maximum number of documents to collect for each shard, upon reaching which the query execution will terminate early. * ['timeout'] = (number) Time each individual bulk request should wait for shards that are unavailable. * ['version'] = (bool) Specify whether to return document version as part of a hit * ['wait_for_active_shards'] = (string) Sets the number of shard copies that must be active before proceeding with the delete by query operation. Defaults to 1, meaning the primary shard only. Set to `all` for all shard copies, otherwise set to any non-negative value less than or equal to the total number of copies for the shard (number of replicas + 1) * ['wait_for_completion'] = (bool) Should the request should block until the delete-by-query is complete. * * @param array $params * * @return array */ public function deleteByQuery($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\DeleteByQuery $endpoint */ $endpoint = $endpointBuilder('DeleteByQuery'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (list) A comma-separated list of indices to restrict the results * ['type'] = (list) A comma-separated list of types to restrict the results * ['min_score'] = (number) Include only documents with a specific `_score` value in the result * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) * ['routing'] = (string) Specific routing value * ['source'] = (string) The URL-encoded query definition (instead of using the request body) * ['body'] = (array) A query to restrict the results (optional) * ['ignore_unavailable'] = (bool) Whether specified concrete indices should be ignored when unavailable (missing or closed) * ['allow_no_indices'] = (bool) Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) * ['expand_wildcards'] = (enum) Whether to expand wildcard expression to concrete indices that are open, closed or both. * * @param $params array Associative array of parameters * * @return array */ public function count($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Count $endpoint */ $endpoint = $endpointBuilder('Count'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (list) A comma-separated list of indices to restrict the results * ['type'] = (list) A comma-separated list of types to restrict the results * ['id'] = (string) ID of document * ['ignore_unavailable'] = (boolean) Whether specified concrete indices should be ignored when unavailable (missing or closed) * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) * ['routing'] = (string) Specific routing value * ['allow_no_indices'] = (boolean) Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) * ['body'] = (array) A query to restrict the results (optional) * ['ignore_unavailable'] = (bool) Whether specified concrete indices should be ignored when unavailable (missing or closed) * ['percolate_index'] = (string) The index to count percolate the document into. Defaults to index. * ['expand_wildcards'] = (enum) Whether to expand wildcard expression to concrete indices that are open, closed or both. * ['version'] = (number) Explicit version number for concurrency control * ['version_type'] = (enum) Specific version type * * @param $params array Associative array of parameters * * @return array * * @deprecated */ public function countPercolate($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $id = $this->extractArgument($params, 'id'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\CountPercolate $endpoint */ $endpoint = $endpointBuilder('CountPercolate'); $endpoint->setIndex($index) ->setType($type) ->setID($id) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (string) The name of the index with a registered percolator query (Required) * ['type'] = (string) The document type (Required) * ['prefer_local'] = (boolean) With `true`, specify that a local shard should be used if available, with `false`, use a random shard (default: true) * ['body'] = (array) The document (`doc`) to percolate against registered queries; optionally also a `query` to limit the percolation to specific registered queries * * @param $params array Associative array of parameters * * @return array * * @deprecated */ public function percolate($params) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $id = $this->extractArgument($params, 'id'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Percolate $endpoint */ $endpoint = $endpointBuilder('Percolate'); $endpoint->setIndex($index) ->setType($type) ->setID($id) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (string) Default index for items which don't provide one * ['type'] = (string) Default document type for items which don't provide one * ['ignore_unavailable'] = (boolean) Whether specified concrete indices should be ignored when unavailable (missing or closed) * ['allow_no_indices'] = (boolean) Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) * ['expand_wildcards'] = (enum) Whether to expand wildcard expression to concrete indices that are open, closed or both. * * @param $params array Associative array of parameters * * @return array * * @deprecated */ public function mpercolate($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\MPercolate $endpoint */ $endpoint = $endpointBuilder('MPercolate'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (string) Default index for items which don't provide one * ['type'] = (string) Default document type for items which don't provide one * ['term_statistics'] = (boolean) Specifies if total term frequency and document frequency should be returned. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\"." * ['field_statistics'] = (boolean) Specifies if document count, sum of document frequencies and sum of total term frequencies should be returned. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\"." * ['fields'] = (list) A comma-separated list of fields to return. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\"." * ['offsets'] = (boolean) Specifies if term offsets should be returned. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\"." * ['positions'] = (boolean) Specifies if term positions should be returned. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\"." * ['payloads'] = (boolean) Specifies if term payloads should be returned. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\". * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) .Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\". * ['routing'] = (string) Specific routing value. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\". * ['parent'] = (string) Parent id of documents. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\". * ['realtime'] = (boolean) Specifies if request is real-time as opposed to near-real-time (default: true). * * @param $params array Associative array of parameters * * @return array */ public function termvectors($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $id = $this->extractArgument($params, 'id'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\TermVectors $endpoint */ $endpoint = $endpointBuilder('TermVectors'); $endpoint->setIndex($index) ->setType($type) ->setID($id) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (string) Default index for items which don't provide one * ['type'] = (string) Default document type for items which don't provide one * ['ids'] = (list) A comma-separated list of documents ids. You must define ids as parameter or set \"ids\" or \"docs\" in the request body * ['term_statistics'] = (boolean) Specifies if total term frequency and document frequency should be returned. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\"." * ['field_statistics'] = (boolean) Specifies if document count, sum of document frequencies and sum of total term frequencies should be returned. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\"." * ['fields'] = (list) A comma-separated list of fields to return. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\"." * ['offsets'] = (boolean) Specifies if term offsets should be returned. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\"." * ['positions'] = (boolean) Specifies if term positions should be returned. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\"." * ['payloads'] = (boolean) Specifies if term payloads should be returned. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\". * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) .Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\". * ['routing'] = (string) Specific routing value. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\". * ['parent'] = (string) Parent id of documents. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\". * ['realtime'] = (boolean) Specifies if request is real-time as opposed to near-real-time (default: true). * * @param $params array Associative array of parameters * * @return array */ public function mtermvectors($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\MTermVectors $endpoint */ $endpoint = $endpointBuilder('MTermVectors'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['id'] = (string) The document ID (Required) * ['index'] = (string) The name of the index (Required) * ['type'] = (string) The type of the document (use `_all` to fetch the first document matching the ID across all types) (Required) * ['parent'] = (string) The ID of the parent document * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) * ['realtime'] = (boolean) Specify whether to perform the operation in realtime or search mode * ['refresh'] = (boolean) Refresh the shard containing the document before performing the operation * ['routing'] = (string) Specific routing value * * @param $params array Associative array of parameters * * @return array | boolean */ public function exists($params) { $id = $this->extractArgument($params, 'id'); $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); //manually make this verbose so we can check status code $params['client']['verbose'] = true; /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Exists $endpoint */ $endpoint = $endpointBuilder('Exists'); $endpoint->setID($id) ->setIndex($index) ->setType($type); $endpoint->setParams($params); return BooleanRequestWrapper::performRequest($endpoint, $this->transport); } /** * $params['index'] = (string) The name of the index * ['type'] = (string) The type of the document * ['fields'] = (list) A comma-separated list of fields to return in the response * ['parent'] = (string) The ID of the parent document * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) * ['realtime'] = (boolean) Specify whether to perform the operation in realtime or search mode * ['refresh'] = (boolean) Refresh the shard containing the document before performing the operation * ['routing'] = (string) Specific routing value * ['body'] = (array) Document identifiers; can be either `docs` (containing full document information) or `ids` (when index and type is provided in the URL. * ['_source'] = (list) True or false to return the _source field or not, or a list of fields to return * ['_source_exclude'] = (list) A list of fields to exclude from the returned _source field * ['_source_include'] = (list) A list of fields to extract and return from the _source field * * @param $params array Associative array of parameters * * @return array */ public function mget($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Mget $endpoint */ $endpoint = $endpointBuilder('Mget'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (list) A comma-separated list of index names to use as default * ['type'] = (list) A comma-separated list of document types to use as default * ['search_type'] = (enum) Search operation type * ['body'] = (array|string) The request definitions (metadata-search request definition pairs), separated by newlines * * @param $params array Associative array of parameters * * @return array */ public function msearch($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Msearch $endpoint */ $endpoint = $endpointBuilder('Msearch'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (list) A comma-separated list of index names to use as default * ['type'] = (list) A comma-separated list of document types to use as default * ['search_type'] = (enum) Search operation type * ['body'] = (array|string) The request definitions (metadata-search request definition pairs), separated by newlines * ['max_concurrent_searches'] = (number) Controls the maximum number of concurrent searches the multi search api will execute * * @param $params array Associative array of parameters * * @return array */ public function msearchTemplate($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\MsearchTemplate $endpoint */ $endpoint = $endpointBuilder('MsearchTemplate'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (string) The name of the index (Required) * ['type'] = (string) The type of the document (Required) * ['id'] = (string) Specific document ID (when the POST method is used) * ['consistency'] = (enum) Explicit write consistency setting for the operation * ['parent'] = (string) ID of the parent document * ['refresh'] = (boolean) Refresh the index after performing the operation * ['replication'] = (enum) Specific replication type * ['routing'] = (string) Specific routing value * ['timeout'] = (time) Explicit operation timeout * ['timestamp'] = (time) Explicit timestamp for the document * ['ttl'] = (duration) Expiration time for the document * ['version'] = (number) Explicit version number for concurrency control * ['version_type'] = (enum) Specific version type * ['body'] = (array) The document * * @param $params array Associative array of parameters * * @return array */ public function create($params) { $id = $this->extractArgument($params, 'id'); $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Create $endpoint */ $endpoint = $endpointBuilder('Create'); $endpoint->setID($id) ->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (string) Default index for items which don't provide one * ['type'] = (string) Default document type for items which don't provide one * ['consistency'] = (enum) Explicit write consistency setting for the operation * ['refresh'] = (boolean) Refresh the index after performing the operation * ['replication'] = (enum) Explicitly set the replication type * ['fields'] = (list) Default comma-separated list of fields to return in the response for updates * ['body'] = (array) The document * * @param $params array Associative array of parameters * * @return array */ public function bulk($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Bulk $endpoint */ $endpoint = $endpointBuilder('Bulk'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (string) The name of the index (Required) * ['type'] = (string) The type of the document (Required) * ['id'] = (string) Specific document ID (when the POST method is used) * ['consistency'] = (enum) Explicit write consistency setting for the operation * ['op_type'] = (enum) Explicit operation type * ['parent'] = (string) ID of the parent document * ['refresh'] = (boolean) Refresh the index after performing the operation * ['replication'] = (enum) Specific replication type * ['routing'] = (string) Specific routing value * ['timeout'] = (time) Explicit operation timeout * ['timestamp'] = (time) Explicit timestamp for the document * ['ttl'] = (duration) Expiration time for the document * ['version'] = (number) Explicit version number for concurrency control * ['version_type'] = (enum) Specific version type * ['body'] = (array) The document * * @param $params array Associative array of parameters * * @return array */ public function index($params) { $id = $this->extractArgument($params, 'id'); $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Index $endpoint */ $endpoint = $endpointBuilder('Index'); $endpoint->setID($id) ->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['refresh'] = (boolean) Should the effected indexes be refreshed? * ['timeout'] = (time) Time each individual bulk request should wait for shards that are unavailable * ['consistency'] = (enum) Explicit write consistency setting for the operation * ['wait_for_completion'] = (boolean) Should the request should block until the reindex is complete * ['requests_per_second'] = (float) The throttle for this request in sub-requests per second. 0 means set no throttle * ['body'] = (array) The search definition using the Query DSL and the prototype for the index request (Required) * * @param $params array Associative array of parameters * * @return array */ public function reindex($params) { $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Reindex $endpoint */ $endpoint = $endpointBuilder('Reindex'); $endpoint->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (list) A comma-separated list of index names to restrict the operation; use `_all` or empty string to perform the operation on all indices * ['ignore_indices'] = (enum) When performed on multiple indices, allows to ignore `missing` ones * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) * ['routing'] = (string) Specific routing value * ['source'] = (string) The URL-encoded request definition (instead of using request body) * ['body'] = (array) The request definition * * @param $params array Associative array of parameters * * @return array */ public function suggest($params = array()) { $index = $this->extractArgument($params, 'index'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Suggest $endpoint */ $endpoint = $endpointBuilder('Suggest'); $endpoint->setIndex($index) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['id'] = (string) The document ID (Required) * ['index'] = (string) The name of the index (Required) * ['type'] = (string) The type of the document (Required) * ['analyze_wildcard'] = (boolean) Specify whether wildcards and prefix queries in the query string query should be analyzed (default: false) * ['analyzer'] = (string) The analyzer for the query string query * ['default_operator'] = (enum) The default operator for query string query (AND or OR) * ['df'] = (string) The default field for query string query (default: _all) * ['fields'] = (list) A comma-separated list of fields to return in the response * ['lenient'] = (boolean) Specify whether format-based query failures (such as providing text to a numeric field) should be ignored * ['lowercase_expanded_terms'] = (boolean) Specify whether query terms should be lowercased * ['parent'] = (string) The ID of the parent document * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) * ['q'] = (string) Query in the Lucene query string syntax * ['routing'] = (string) Specific routing value * ['source'] = (string) The URL-encoded query definition (instead of using the request body) * ['_source'] = (list) True or false to return the _source field or not, or a list of fields to return * ['_source_exclude'] = (list) A list of fields to exclude from the returned _source field * ['_source_include'] = (list) A list of fields to extract and return from the _source field * ['body'] = (string) The URL-encoded query definition (instead of using the request body) * * @param $params array Associative array of parameters * * @return array */ public function explain($params) { $id = $this->extractArgument($params, 'id'); $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Explain $endpoint */ $endpoint = $endpointBuilder('Explain'); $endpoint->setID($id) ->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (list) A comma-separated list of index names to search; use `_all` or empty string to perform the operation on all indices * ['type'] = (list) A comma-separated list of document types to search; leave empty to perform the operation on all types * ['analyzer'] = (string) The analyzer to use for the query string * ['analyze_wildcard'] = (boolean) Specify whether wildcard and prefix queries should be analyzed (default: false) * ['default_operator'] = (enum) The default operator for query string query (AND or OR) * ['df'] = (string) The field to use as default where no field prefix is given in the query string * ['explain'] = (boolean) Specify whether to return detailed information about score computation as part of a hit * ['fields'] = (list) A comma-separated list of fields to return as part of a hit * ['from'] = (number) Starting offset (default: 0) * ['ignore_indices'] = (enum) When performed on multiple indices, allows to ignore `missing` ones * ['indices_boost'] = (list) Comma-separated list of index boosts * ['lenient'] = (boolean) Specify whether format-based query failures (such as providing text to a numeric field) should be ignored * ['lowercase_expanded_terms'] = (boolean) Specify whether query terms should be lowercased * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) * ['q'] = (string) Query in the Lucene query string syntax * ['query_cache'] = (boolean) Enable query cache for this request * ['request_cache'] = (boolean) Enable request cache for this request * ['routing'] = (list) A comma-separated list of specific routing values * ['scroll'] = (duration) Specify how long a consistent view of the index should be maintained for scrolled search * ['search_type'] = (enum) Search operation type * ['size'] = (number) Number of hits to return (default: 10) * ['sort'] = (list) A comma-separated list of <field>:<direction> pairs * ['source'] = (string) The URL-encoded request definition using the Query DSL (instead of using request body) * ['_source'] = (list) True or false to return the _source field or not, or a list of fields to return * ['_source_exclude'] = (list) A list of fields to exclude from the returned _source field * ['_source_include'] = (list) A list of fields to extract and return from the _source field * ['stats'] = (list) Specific 'tag' of the request for logging and statistical purposes * ['suggest_field'] = (string) Specify which field to use for suggestions * ['suggest_mode'] = (enum) Specify suggest mode * ['suggest_size'] = (number) How many suggestions to return in response * ['suggest_text'] = (text) The source text for which the suggestions should be returned * ['timeout'] = (time) Explicit operation timeout * ['terminate_after'] = (number) The maximum number of documents to collect for each shard, upon reaching which the query execution will terminate early. * ['version'] = (boolean) Specify whether to return document version as part of a hit * ['body'] = (array|string) The search definition using the Query DSL * * @param $params array Associative array of parameters * * @return array */ public function search($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Search $endpoint */ $endpoint = $endpointBuilder('Search'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (list) A comma-separated list of index names to search; use `_all` or empty string to perform the operation on all indices * ['type'] = (list) A comma-separated list of document types to search; leave empty to perform the operation on all types * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) * ['routing'] = (string) Specific routing value * ['local'] = (bool) Return local information, do not retrieve the state from master node (default: false) * ['ignore_unavailable'] = (bool) Whether specified concrete indices should be ignored when unavailable (missing or closed) * ['allow_no_indices'] = (bool) Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) * ['expand_wildcards'] = (enum) Whether to expand wildcard expression to concrete indices that are open, closed or both. * * @param $params array Associative array of parameters * * @return array */ public function searchShards($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\SearchShards $endpoint */ $endpoint = $endpointBuilder('SearchShards'); $endpoint->setIndex($index) ->setType($type); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (list) A comma-separated list of index names to search; use `_all` or empty string to perform the operation on all indices * ['type'] = (list) A comma-separated list of document types to search; leave empty to perform the operation on all types * * @param $params array Associative array of parameters * * @return array */ public function searchTemplate($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Search $endpoint */ $endpoint = $endpointBuilder('SearchTemplate'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['scroll_id'] = (string) The scroll ID for scrolled search * ['scroll'] = (duration) Specify how long a consistent view of the index should be maintained for scrolled search * ['body'] = (string) The scroll ID for scrolled search * * @param $params array Associative array of parameters * * @return array */ public function scroll($params = array()) { $scrollID = $this->extractArgument($params, 'scroll_id'); $body = $this->extractArgument($params, 'body'); $scroll = $this->extractArgument($params, 'scroll'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Scroll $endpoint */ $endpoint = $endpointBuilder('Scroll'); $endpoint->setScrollID($scrollID) ->setScroll($scroll) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['scroll_id'] = (string) The scroll ID for scrolled search * ['scroll'] = (duration) Specify how long a consistent view of the index should be maintained for scrolled search * ['body'] = (string) The scroll ID for scrolled search * * @param $params array Associative array of parameters * * @return array */ public function clearScroll($params = array()) { $scrollID = $this->extractArgument($params, 'scroll_id'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\ClearScroll $endpoint */ $endpoint = $endpointBuilder('ClearScroll'); $endpoint->setScrollID($scrollID) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['id'] = (string) Document ID (Required) * ['index'] = (string) The name of the index (Required) * ['type'] = (string) The type of the document (Required) * ['consistency'] = (enum) Explicit write consistency setting for the operation * ['fields'] = (list) A comma-separated list of fields to return in the response * ['lang'] = (string) The script language (default: mvel) * ['parent'] = (string) ID of the parent document * ['refresh'] = (boolean) Refresh the index after performing the operation * ['replication'] = (enum) Specific replication type * ['retry_on_conflict'] = (number) Specify how many times should the operation be retried when a conflict occurs (default: 0) * ['routing'] = (string) Specific routing value * ['script'] = () The URL-encoded script definition (instead of using request body) * ['timeout'] = (time) Explicit operation timeout * ['timestamp'] = (time) Explicit timestamp for the document * ['ttl'] = (duration) Expiration time for the document * ['version_type'] = (number) Explicit version number for concurrency control * ['body'] = (array) The request definition using either `script` or partial `doc` * * @param $params array Associative array of parameters * * @return array */ public function update($params) { $id = $this->extractArgument($params, 'id'); $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Update $endpoint */ $endpoint = $endpointBuilder('Update'); $endpoint->setID($id) ->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (list) A comma-separated list of index names to search; use `_all` or * empty string to perform the operation on all indices (Required) * ['type'] = (list) A comma-separated list of document types to search; leave empty to * perform the operation on all types * ['analyzer'] = (string) The analyzer to use for the query string * ['analyze_wildcard'] = (boolean) Specify whether wildcard and prefix queries should be analyzed * (default: false) * ['default_operator'] = (enum) The default operator for query string query (AND or OR) (AND,OR) * (default: OR) * ['df'] = (string) The field to use as default where no field prefix is given in the * query string * ['explain'] = (boolean) Specify whether to return detailed information about score * computation as part of a hit * ['fields'] = (list) A comma-separated list of fields to return as part of a hit * ['fielddata_fields'] = (list) A comma-separated list of fields to return as the field data * representation of a field for each hit * ['from'] = (number) Starting offset (default: 0) * ['ignore_unavailable'] = (boolean) Whether specified concrete indices should be ignored when * unavailable (missing or closed) * ['allow_no_indices'] = (boolean) Whether to ignore if a wildcard indices expression resolves into * no concrete indices. (This includes `_all` string or when no indices have been specified) * ['conflicts'] = (enum) What to do when the reindex hits version conflicts? (abort,proceed) * (default: abort) * ['expand_wildcards'] = (enum) Whether to expand wildcard expression to concrete indices that are * open, closed or both. (open,closed,none,all) (default: open) * ['lenient'] = (boolean) Specify whether format-based query failures (such as providing * text to a numeric field) should be ignored * ['lowercase_expanded_terms'] = (boolean) Specify whether query terms should be lowercased * ['preference'] = (string) Specify the node or shard the operation should be performed on * (default: random) * ['q'] = (string) Query in the Lucene query string syntax * ['routing'] = (list) A comma-separated list of specific routing values * ['scroll'] = (duration) Specify how long a consistent view of the index should be * maintained for scrolled search * ['search_type'] = (enum) Search operation type (query_then_fetch,dfs_query_then_fetch) * ['search_timeout'] = (time) Explicit timeout for each search request. Defaults to no timeout. * ['size'] = (number) Number of hits to return (default: 10) * ['sort'] = (list) A comma-separated list of <field>:<direction> pairs * ['_source'] = (list) True or false to return the _source field or not, or a list of * fields to return * ['_source_exclude'] = (list) A list of fields to exclude from the returned _source field * ['_source_include'] = (list) A list of fields to extract and return from the _source field * ['terminate_after'] = (number) The maximum number of documents to collect for each shard, upon * reaching which the query execution will terminate early. * ['stats'] = (list) Specific 'tag' of the request for logging and statistical purposes * ['suggest_field'] = (string) Specify which field to use for suggestions * ['suggest_mode'] = (enum) Specify suggest mode (missing,popular,always) (default: missing) * ['suggest_size'] = (number) How many suggestions to return in response * ['suggest_text'] = (text) The source text for which the suggestions should be returned * ['timeout'] = (time) Time each individual bulk request should wait for shards that are * unavailable. (default: 1m) * ['track_scores'] = (boolean) Whether to calculate and return scores even if they are not used * for sorting * ['version'] = (boolean) Specify whether to return document version as part of a hit * ['version_type'] = (boolean) Should the document increment the version number (internal) on * hit or not (reindex) * ['request_cache'] = (boolean) Specify if request cache should be used for this request or not, * defaults to index level setting * ['refresh'] = (boolean) Should the effected indexes be refreshed? * ['consistency'] = (enum) Explicit write consistency setting for the operation * (one,quorum,all) * ['scroll_size'] = (integer) Size on the scroll request powering the update_by_query * ['wait_for_completion'] = (boolean) Should the request should block until the reindex is complete. * (default: false) * ['body'] = The search definition using the Query DSL * * @param array $params * * @return array */ public function updateByQuery($params = array()) { $index = $this->extractArgument($params, 'index'); $body = $this->extractArgument($params, 'body'); $type = $this->extractArgument($params, 'type'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\UpdateByQuery $endpoint */ $endpoint = $endpointBuilder('UpdateByQuery'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['id'] = (string) The script ID (Required) * ['lang'] = (string) The script language (Required) * * @param $params array Associative array of parameters * * @return array */ public function getScript($params) { $id = $this->extractArgument($params, 'id'); $lang = $this->extractArgument($params, 'lang'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Script\Get $endpoint */ $endpoint = $endpointBuilder('Script\Get'); $endpoint->setID($id) ->setLang($lang); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['id'] = (string) The script ID (Required) * ['lang'] = (string) The script language (Required) * * @param $params array Associative array of parameters * * @return array */ public function deleteScript($params) { $id = $this->extractArgument($params, 'id'); $lang = $this->extractArgument($params, 'lang'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Script\Delete $endpoint */ $endpoint = $endpointBuilder('Script\Delete'); $endpoint->setID($id) ->setLang($lang); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['id'] = (string) The script ID (Required) * ['lang'] = (string) The script language (Required) * * @param $params array Associative array of parameters * * @return array */ public function putScript($params) { $id = $this->extractArgument($params, 'id'); $lang = $this->extractArgument($params, 'lang'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Script\Put $endpoint */ $endpoint = $endpointBuilder('Script\Put'); $endpoint->setID($id) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['id'] = (string) The search template ID (Required) * * @param $params array Associative array of parameters * * @return array */ public function getTemplate($params) { $id = $this->extractArgument($params, 'id'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Template\Get $endpoint */ $endpoint = $endpointBuilder('Template\Get'); $endpoint->setID($id); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['id'] = (string) The search template ID (Required) * * @param $params array Associative array of parameters * * @return array */ public function deleteTemplate($params) { $id = $this->extractArgument($params, 'id'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Template\Delete $endpoint */ $endpoint = $endpointBuilder('Template\Delete'); $endpoint->setID($id); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (list) A comma-separated list of indices to restrict the results * ['fields'] = (list) A comma-separated list of fields for to get field statistics for (min value, max value, and more) * ['level'] = (enum) Defines if field stats should be returned on a per index level or on a cluster wide level * ['ignore_unavailable'] = (bool) Whether specified concrete indices should be ignored when unavailable (missing or closed) * ['allow_no_indices'] = (bool) Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) * ['expand_wildcards'] = (enum) Whether to expand wildcard expression to concrete indices that are open, closed or both. * * @param $params array Associative array of parameters * * @return array */ public function fieldStats($params = array()) { $index = $this->extractArgument($params, 'index'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\FieldStats $endpoint */ $endpoint = $endpointBuilder('FieldStats'); $endpoint->setIndex($index) ->setBody($body) ->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (list) A comma-separated list of indices to restrict the results * ['ignore_unavailable'] = (bool) Whether specified concrete indices should be ignored when unavailable (missing or closed) * ['allow_no_indices'] = (bool) Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) * ['expand_wildcards'] = (enum) Whether to expand wildcard expression to concrete indices that are open, closed or both. * * @param $params array Associative array of parameters * * @return array */ public function fieldCaps($params = array()) { $index = $this->extractArgument($params, 'index'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\FieldCaps $endpoint */ $endpoint = $endpointBuilder('FieldCaps'); $endpoint->setIndex($index) ->setBody($body) ->setParams($params); return $this->performRequest($endpoint); } /** * $params['id'] = (string) ID of the template to render * * @param $params array Associative array of parameters * * @return array */ public function renderSearchTemplate($params = array()) { $body = $this->extractArgument($params, 'body'); $id = $this->extractArgument($params, 'id'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\RenderSearchTemplate $endpoint */ $endpoint = $endpointBuilder('RenderSearchTemplate'); $endpoint->setBody($body) ->setID($id); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * Operate on the Indices Namespace of commands * * @return IndicesNamespace */ public function indices() { return $this->indices; } /** * Operate on the Cluster namespace of commands * * @return ClusterNamespace */ public function cluster() { return $this->cluster; } /** * Operate on the Nodes namespace of commands * * @return NodesNamespace */ public function nodes() { return $this->nodes; } /** * Operate on the Snapshot namespace of commands * * @return SnapshotNamespace */ public function snapshot() { return $this->snapshot; } /** * Operate on the Cat namespace of commands * * @return CatNamespace */ public function cat() { return $this->cat; } /** * Operate on the Ingest namespace of commands * * @return IngestNamespace */ public function ingest() { return $this->ingest; } /** * Operate on the Tasks namespace of commands * * @return TasksNamespace */ public function tasks() { return $this->tasks; } /** * Operate on the Remote namespace of commands * * @return RemoteNamespace */ public function remote() { return $this->remote; } /** * Catchall for registered namespaces * * @param $name * @param $arguments * @return Object * @throws BadMethodCallException if the namespace cannot be found */ public function __call($name, $arguments) { if (isset($this->registeredNamespaces[$name])) { return $this->registeredNamespaces[$name]; } throw new BadMethodCallException("Namespace [$name] not found"); } /** * @param array $params * @param string $arg * * @return null|mixed */ public function extractArgument(&$params, $arg) { if (is_object($params) === true) { $params = (array) $params; } if (array_key_exists($arg, $params) === true) { $val = $params[$arg]; unset($params[$arg]); return $val; } else { return null; } } private function verifyNotNullOrEmpty($name, $var) { if ($var === null) { throw new InvalidArgumentException("$name cannot be null."); } if (is_string($var)) { if (strlen($var) === 0) { throw new InvalidArgumentException("$name cannot be an empty string"); } } if (is_array($var)) { if (strlen(implode("", $var)) === 0) { throw new InvalidArgumentException("$name cannot be an array of empty strings"); } } } /** * @param $endpoint AbstractEndpoint * * @throws \Exception * @return array */ private function performRequest(AbstractEndpoint $endpoint) { $promise = $this->transport->performRequest( $endpoint->getMethod(), $endpoint->getURI(), $endpoint->getParams(), $endpoint->getBody(), $endpoint->getOptions() ); return $this->transport->resultOrFuture($promise, $endpoint->getOptions()); } } |
#10 | Elasticsearch\Client->performRequest(Object(Elasticsearch\Endpoints\Search)) /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Client.php (952) <?php namespace Elasticsearch; use Elasticsearch\Common\Exceptions\BadMethodCallException; use Elasticsearch\Common\Exceptions\InvalidArgumentException; use Elasticsearch\Common\Exceptions\NoNodesAvailableException; use Elasticsearch\Common\Exceptions\BadRequest400Exception; use Elasticsearch\Common\Exceptions\Missing404Exception; use Elasticsearch\Common\Exceptions\TransportException; use Elasticsearch\Endpoints\AbstractEndpoint; use Elasticsearch\Namespaces\AbstractNamespace; use Elasticsearch\Namespaces\CatNamespace; use Elasticsearch\Namespaces\ClusterNamespace; use Elasticsearch\Namespaces\IndicesNamespace; use Elasticsearch\Namespaces\IngestNamespace; use Elasticsearch\Namespaces\NamespaceBuilderInterface; use Elasticsearch\Namespaces\NodesNamespace; use Elasticsearch\Namespaces\RemoteNamespace; use Elasticsearch\Namespaces\SnapshotNamespace; use Elasticsearch\Namespaces\BooleanRequestWrapper; use Elasticsearch\Namespaces\TasksNamespace; /** * Class Client * * @category Elasticsearch * @package Elasticsearch * @author Zachary Tong <[email protected]> * @license http://www.apache.org/licenses/LICENSE-2.0 Apache2 * @link http://elastic.co */ class Client { /** * @var Transport */ public $transport; /** * @var array */ protected $params; /** * @var IndicesNamespace */ protected $indices; /** * @var ClusterNamespace */ protected $cluster; /** * @var NodesNamespace */ protected $nodes; /** * @var SnapshotNamespace */ protected $snapshot; /** * @var CatNamespace */ protected $cat; /** * @var IngestNamespace */ protected $ingest; /** * @var TasksNamespace */ protected $tasks; /** * @var RemoteNamespace */ protected $remote; /** @var callback */ protected $endpoints; /** @var NamespaceBuilderInterface[] */ protected $registeredNamespaces = []; /** * Client constructor * * @param Transport $transport * @param callable $endpoint * @param AbstractNamespace[] $registeredNamespaces */ public function __construct(Transport $transport, callable $endpoint, array $registeredNamespaces) { $this->transport = $transport; $this->endpoints = $endpoint; $this->indices = new IndicesNamespace($transport, $endpoint); $this->cluster = new ClusterNamespace($transport, $endpoint); $this->nodes = new NodesNamespace($transport, $endpoint); $this->snapshot = new SnapshotNamespace($transport, $endpoint); $this->cat = new CatNamespace($transport, $endpoint); $this->ingest = new IngestNamespace($transport, $endpoint); $this->tasks = new TasksNamespace($transport, $endpoint); $this->remote = new RemoteNamespace($transport, $endpoint); $this->registeredNamespaces = $registeredNamespaces; } /** * @param $params * @return array */ public function info($params = []) { /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Info $endpoint */ $endpoint = $endpointBuilder('Info'); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * @param $params array Associative array of parameters * * @return bool */ public function ping($params = []) { /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Ping $endpoint */ $endpoint = $endpointBuilder('Ping'); $endpoint->setParams($params); try { $this->performRequest($endpoint); } catch (Missing404Exception $exception) { return false; } catch (TransportException $exception) { return false; } catch (NoNodesAvailableException $exception) { return false; } return true; } /** * $params['id'] = (string) The document ID (Required) * ['index'] = (string) The name of the index (Required) * ['type'] = (string) The type of the document (use `_all` to fetch the first document matching the ID across all types) (Required) * ['ignore_missing'] = ?? * ['fields'] = (list) A comma-separated list of fields to return in the response * ['parent'] = (string) The ID of the parent document * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) * ['realtime'] = (boolean) Specify whether to perform the operation in realtime or search mode * ['refresh'] = (boolean) Refresh the shard containing the document before performing the operation * ['routing'] = (string) Specific routing value * ['_source'] = (list) True or false to return the _source field or not, or a list of fields to return * ['_source_exclude'] = (list) A list of fields to exclude from the returned _source field * ['_source_include'] = (list) A list of fields to extract and return from the _source field * * @param $params array Associative array of parameters * * @return array */ public function get($params) { $id = $this->extractArgument($params, 'id'); $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Get $endpoint */ $endpoint = $endpointBuilder('Get'); $endpoint->setID($id) ->setIndex($index) ->setType($type); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['id'] = (string) The document ID (Required) * ['index'] = (string) The name of the index (Required) * ['type'] = (string) The type of the document (use `_all` to fetch the first document matching the ID across all types) (Required) * ['ignore_missing'] = ?? * ['parent'] = (string) The ID of the parent document * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) * ['realtime'] = (boolean) Specify whether to perform the operation in realtime or search mode * ['refresh'] = (boolean) Refresh the shard containing the document before performing the operation * ['routing'] = (string) Specific routing value * * @param $params array Associative array of parameters * * @return array */ public function getSource($params) { $id = $this->extractArgument($params, 'id'); $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Get $endpoint */ $endpoint = $endpointBuilder('Get'); $endpoint->setID($id) ->setIndex($index) ->setType($type) ->returnOnlySource(); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['id'] = (string) The document ID (Required) * ['index'] = (string) The name of the index (Required) * ['type'] = (string) The type of the document (Required) * ['consistency'] = (enum) Specific write consistency setting for the operation * ['parent'] = (string) ID of parent document * ['refresh'] = (boolean) Refresh the index after performing the operation * ['replication'] = (enum) Specific replication type * ['routing'] = (string) Specific routing value * ['timeout'] = (time) Explicit operation timeout * ['version_type'] = (enum) Specific version type * * @param $params array Associative array of parameters * * @return array */ public function delete($params) { $id = $this->extractArgument($params, 'id'); $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $this->verifyNotNullOrEmpty("id", $id); $this->verifyNotNullOrEmpty("type", $type); $this->verifyNotNullOrEmpty("index", $index); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Delete $endpoint */ $endpoint = $endpointBuilder('Delete'); $endpoint->setID($id) ->setIndex($index) ->setType($type); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * * $params['_source'] = (list) True or false to return the _source field or not, or a list of fields to return * ['_source_exclude'] = (array) A list of fields to exclude from the returned _source field * ['_source_include'] = (array) A list of fields to extract and return from the _source field * ['allow_no_indices'] = (bool) Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) * ['analyze_wildcard'] = (bool) Specify whether wildcard and prefix queries should be analyzed (default: false) * ['analyzer'] = (string) The analyzer to use for the query string * ['conflicts'] = (enum) What to do when the delete-by-query hits version conflicts? * ['default_operator'] = (enum) The default operator for query string query (AND or OR) * ['df'] = (string) The field to use as default where no field prefix is given in the query string * ['expand_wildcards'] = (enum) Whether to expand wildcard expression to concrete indices that are open, closed or both. * ['from'] = (number) Starting offset (default: 0) * ['ignore_unavailable'] = (bool) Whether specified concrete indices should be ignored when unavailable (missing or closed) * ['lenient'] = (bool) Specify whether format-based query failures (such as providing text to a numeric field) should be ignored * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) * ['q'] = (string) Query in the Lucene query string syntax * ['refresh'] = (bool) Should the effected indexes be refreshed? * ['request_cache'] = (bool) Specify if request cache should be used for this request or not, defaults to index level setting * ['requests_per_second'] = (number) The throttle for this request in sub-requests per second. -1 means no throttle. * ['routing'] = (array) A comma-separated list of specific routing values * ['scroll'] = (number) Specify how long a consistent view of the index should be maintained for scrolled search * ['scroll_size'] = (number) Size on the scroll request powering the update_by_query * ['search_timeout'] = (number) Explicit timeout for each search request. Defaults to no timeout. * ['search_type'] = (enum) Search operation type * ['size'] = (number) Number of hits to return (default: 10) * ['slices'] = (integer) The number of slices this task should be divided into. Defaults to 1 meaning the task isn't sliced into subtasks. * ['sort'] = (array) A comma-separated list of <field>:<direction> pairs * ['stats'] = (array) Specific 'tag' of the request for logging and statistical purposes * ['terminate_after'] = (number) The maximum number of documents to collect for each shard, upon reaching which the query execution will terminate early. * ['timeout'] = (number) Time each individual bulk request should wait for shards that are unavailable. * ['version'] = (bool) Specify whether to return document version as part of a hit * ['wait_for_active_shards'] = (string) Sets the number of shard copies that must be active before proceeding with the delete by query operation. Defaults to 1, meaning the primary shard only. Set to `all` for all shard copies, otherwise set to any non-negative value less than or equal to the total number of copies for the shard (number of replicas + 1) * ['wait_for_completion'] = (bool) Should the request should block until the delete-by-query is complete. * * @param array $params * * @return array */ public function deleteByQuery($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\DeleteByQuery $endpoint */ $endpoint = $endpointBuilder('DeleteByQuery'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (list) A comma-separated list of indices to restrict the results * ['type'] = (list) A comma-separated list of types to restrict the results * ['min_score'] = (number) Include only documents with a specific `_score` value in the result * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) * ['routing'] = (string) Specific routing value * ['source'] = (string) The URL-encoded query definition (instead of using the request body) * ['body'] = (array) A query to restrict the results (optional) * ['ignore_unavailable'] = (bool) Whether specified concrete indices should be ignored when unavailable (missing or closed) * ['allow_no_indices'] = (bool) Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) * ['expand_wildcards'] = (enum) Whether to expand wildcard expression to concrete indices that are open, closed or both. * * @param $params array Associative array of parameters * * @return array */ public function count($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Count $endpoint */ $endpoint = $endpointBuilder('Count'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (list) A comma-separated list of indices to restrict the results * ['type'] = (list) A comma-separated list of types to restrict the results * ['id'] = (string) ID of document * ['ignore_unavailable'] = (boolean) Whether specified concrete indices should be ignored when unavailable (missing or closed) * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) * ['routing'] = (string) Specific routing value * ['allow_no_indices'] = (boolean) Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) * ['body'] = (array) A query to restrict the results (optional) * ['ignore_unavailable'] = (bool) Whether specified concrete indices should be ignored when unavailable (missing or closed) * ['percolate_index'] = (string) The index to count percolate the document into. Defaults to index. * ['expand_wildcards'] = (enum) Whether to expand wildcard expression to concrete indices that are open, closed or both. * ['version'] = (number) Explicit version number for concurrency control * ['version_type'] = (enum) Specific version type * * @param $params array Associative array of parameters * * @return array * * @deprecated */ public function countPercolate($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $id = $this->extractArgument($params, 'id'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\CountPercolate $endpoint */ $endpoint = $endpointBuilder('CountPercolate'); $endpoint->setIndex($index) ->setType($type) ->setID($id) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (string) The name of the index with a registered percolator query (Required) * ['type'] = (string) The document type (Required) * ['prefer_local'] = (boolean) With `true`, specify that a local shard should be used if available, with `false`, use a random shard (default: true) * ['body'] = (array) The document (`doc`) to percolate against registered queries; optionally also a `query` to limit the percolation to specific registered queries * * @param $params array Associative array of parameters * * @return array * * @deprecated */ public function percolate($params) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $id = $this->extractArgument($params, 'id'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Percolate $endpoint */ $endpoint = $endpointBuilder('Percolate'); $endpoint->setIndex($index) ->setType($type) ->setID($id) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (string) Default index for items which don't provide one * ['type'] = (string) Default document type for items which don't provide one * ['ignore_unavailable'] = (boolean) Whether specified concrete indices should be ignored when unavailable (missing or closed) * ['allow_no_indices'] = (boolean) Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) * ['expand_wildcards'] = (enum) Whether to expand wildcard expression to concrete indices that are open, closed or both. * * @param $params array Associative array of parameters * * @return array * * @deprecated */ public function mpercolate($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\MPercolate $endpoint */ $endpoint = $endpointBuilder('MPercolate'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (string) Default index for items which don't provide one * ['type'] = (string) Default document type for items which don't provide one * ['term_statistics'] = (boolean) Specifies if total term frequency and document frequency should be returned. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\"." * ['field_statistics'] = (boolean) Specifies if document count, sum of document frequencies and sum of total term frequencies should be returned. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\"." * ['fields'] = (list) A comma-separated list of fields to return. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\"." * ['offsets'] = (boolean) Specifies if term offsets should be returned. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\"." * ['positions'] = (boolean) Specifies if term positions should be returned. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\"." * ['payloads'] = (boolean) Specifies if term payloads should be returned. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\". * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) .Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\". * ['routing'] = (string) Specific routing value. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\". * ['parent'] = (string) Parent id of documents. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\". * ['realtime'] = (boolean) Specifies if request is real-time as opposed to near-real-time (default: true). * * @param $params array Associative array of parameters * * @return array */ public function termvectors($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $id = $this->extractArgument($params, 'id'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\TermVectors $endpoint */ $endpoint = $endpointBuilder('TermVectors'); $endpoint->setIndex($index) ->setType($type) ->setID($id) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (string) Default index for items which don't provide one * ['type'] = (string) Default document type for items which don't provide one * ['ids'] = (list) A comma-separated list of documents ids. You must define ids as parameter or set \"ids\" or \"docs\" in the request body * ['term_statistics'] = (boolean) Specifies if total term frequency and document frequency should be returned. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\"." * ['field_statistics'] = (boolean) Specifies if document count, sum of document frequencies and sum of total term frequencies should be returned. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\"." * ['fields'] = (list) A comma-separated list of fields to return. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\"." * ['offsets'] = (boolean) Specifies if term offsets should be returned. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\"." * ['positions'] = (boolean) Specifies if term positions should be returned. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\"." * ['payloads'] = (boolean) Specifies if term payloads should be returned. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\". * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) .Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\". * ['routing'] = (string) Specific routing value. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\". * ['parent'] = (string) Parent id of documents. Applies to all returned documents unless otherwise specified in body \"params\" or \"docs\". * ['realtime'] = (boolean) Specifies if request is real-time as opposed to near-real-time (default: true). * * @param $params array Associative array of parameters * * @return array */ public function mtermvectors($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\MTermVectors $endpoint */ $endpoint = $endpointBuilder('MTermVectors'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['id'] = (string) The document ID (Required) * ['index'] = (string) The name of the index (Required) * ['type'] = (string) The type of the document (use `_all` to fetch the first document matching the ID across all types) (Required) * ['parent'] = (string) The ID of the parent document * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) * ['realtime'] = (boolean) Specify whether to perform the operation in realtime or search mode * ['refresh'] = (boolean) Refresh the shard containing the document before performing the operation * ['routing'] = (string) Specific routing value * * @param $params array Associative array of parameters * * @return array | boolean */ public function exists($params) { $id = $this->extractArgument($params, 'id'); $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); //manually make this verbose so we can check status code $params['client']['verbose'] = true; /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Exists $endpoint */ $endpoint = $endpointBuilder('Exists'); $endpoint->setID($id) ->setIndex($index) ->setType($type); $endpoint->setParams($params); return BooleanRequestWrapper::performRequest($endpoint, $this->transport); } /** * $params['index'] = (string) The name of the index * ['type'] = (string) The type of the document * ['fields'] = (list) A comma-separated list of fields to return in the response * ['parent'] = (string) The ID of the parent document * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) * ['realtime'] = (boolean) Specify whether to perform the operation in realtime or search mode * ['refresh'] = (boolean) Refresh the shard containing the document before performing the operation * ['routing'] = (string) Specific routing value * ['body'] = (array) Document identifiers; can be either `docs` (containing full document information) or `ids` (when index and type is provided in the URL. * ['_source'] = (list) True or false to return the _source field or not, or a list of fields to return * ['_source_exclude'] = (list) A list of fields to exclude from the returned _source field * ['_source_include'] = (list) A list of fields to extract and return from the _source field * * @param $params array Associative array of parameters * * @return array */ public function mget($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Mget $endpoint */ $endpoint = $endpointBuilder('Mget'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (list) A comma-separated list of index names to use as default * ['type'] = (list) A comma-separated list of document types to use as default * ['search_type'] = (enum) Search operation type * ['body'] = (array|string) The request definitions (metadata-search request definition pairs), separated by newlines * * @param $params array Associative array of parameters * * @return array */ public function msearch($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Msearch $endpoint */ $endpoint = $endpointBuilder('Msearch'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (list) A comma-separated list of index names to use as default * ['type'] = (list) A comma-separated list of document types to use as default * ['search_type'] = (enum) Search operation type * ['body'] = (array|string) The request definitions (metadata-search request definition pairs), separated by newlines * ['max_concurrent_searches'] = (number) Controls the maximum number of concurrent searches the multi search api will execute * * @param $params array Associative array of parameters * * @return array */ public function msearchTemplate($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\MsearchTemplate $endpoint */ $endpoint = $endpointBuilder('MsearchTemplate'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (string) The name of the index (Required) * ['type'] = (string) The type of the document (Required) * ['id'] = (string) Specific document ID (when the POST method is used) * ['consistency'] = (enum) Explicit write consistency setting for the operation * ['parent'] = (string) ID of the parent document * ['refresh'] = (boolean) Refresh the index after performing the operation * ['replication'] = (enum) Specific replication type * ['routing'] = (string) Specific routing value * ['timeout'] = (time) Explicit operation timeout * ['timestamp'] = (time) Explicit timestamp for the document * ['ttl'] = (duration) Expiration time for the document * ['version'] = (number) Explicit version number for concurrency control * ['version_type'] = (enum) Specific version type * ['body'] = (array) The document * * @param $params array Associative array of parameters * * @return array */ public function create($params) { $id = $this->extractArgument($params, 'id'); $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Create $endpoint */ $endpoint = $endpointBuilder('Create'); $endpoint->setID($id) ->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (string) Default index for items which don't provide one * ['type'] = (string) Default document type for items which don't provide one * ['consistency'] = (enum) Explicit write consistency setting for the operation * ['refresh'] = (boolean) Refresh the index after performing the operation * ['replication'] = (enum) Explicitly set the replication type * ['fields'] = (list) Default comma-separated list of fields to return in the response for updates * ['body'] = (array) The document * * @param $params array Associative array of parameters * * @return array */ public function bulk($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Bulk $endpoint */ $endpoint = $endpointBuilder('Bulk'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (string) The name of the index (Required) * ['type'] = (string) The type of the document (Required) * ['id'] = (string) Specific document ID (when the POST method is used) * ['consistency'] = (enum) Explicit write consistency setting for the operation * ['op_type'] = (enum) Explicit operation type * ['parent'] = (string) ID of the parent document * ['refresh'] = (boolean) Refresh the index after performing the operation * ['replication'] = (enum) Specific replication type * ['routing'] = (string) Specific routing value * ['timeout'] = (time) Explicit operation timeout * ['timestamp'] = (time) Explicit timestamp for the document * ['ttl'] = (duration) Expiration time for the document * ['version'] = (number) Explicit version number for concurrency control * ['version_type'] = (enum) Specific version type * ['body'] = (array) The document * * @param $params array Associative array of parameters * * @return array */ public function index($params) { $id = $this->extractArgument($params, 'id'); $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Index $endpoint */ $endpoint = $endpointBuilder('Index'); $endpoint->setID($id) ->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['refresh'] = (boolean) Should the effected indexes be refreshed? * ['timeout'] = (time) Time each individual bulk request should wait for shards that are unavailable * ['consistency'] = (enum) Explicit write consistency setting for the operation * ['wait_for_completion'] = (boolean) Should the request should block until the reindex is complete * ['requests_per_second'] = (float) The throttle for this request in sub-requests per second. 0 means set no throttle * ['body'] = (array) The search definition using the Query DSL and the prototype for the index request (Required) * * @param $params array Associative array of parameters * * @return array */ public function reindex($params) { $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Reindex $endpoint */ $endpoint = $endpointBuilder('Reindex'); $endpoint->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (list) A comma-separated list of index names to restrict the operation; use `_all` or empty string to perform the operation on all indices * ['ignore_indices'] = (enum) When performed on multiple indices, allows to ignore `missing` ones * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) * ['routing'] = (string) Specific routing value * ['source'] = (string) The URL-encoded request definition (instead of using request body) * ['body'] = (array) The request definition * * @param $params array Associative array of parameters * * @return array */ public function suggest($params = array()) { $index = $this->extractArgument($params, 'index'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Suggest $endpoint */ $endpoint = $endpointBuilder('Suggest'); $endpoint->setIndex($index) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['id'] = (string) The document ID (Required) * ['index'] = (string) The name of the index (Required) * ['type'] = (string) The type of the document (Required) * ['analyze_wildcard'] = (boolean) Specify whether wildcards and prefix queries in the query string query should be analyzed (default: false) * ['analyzer'] = (string) The analyzer for the query string query * ['default_operator'] = (enum) The default operator for query string query (AND or OR) * ['df'] = (string) The default field for query string query (default: _all) * ['fields'] = (list) A comma-separated list of fields to return in the response * ['lenient'] = (boolean) Specify whether format-based query failures (such as providing text to a numeric field) should be ignored * ['lowercase_expanded_terms'] = (boolean) Specify whether query terms should be lowercased * ['parent'] = (string) The ID of the parent document * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) * ['q'] = (string) Query in the Lucene query string syntax * ['routing'] = (string) Specific routing value * ['source'] = (string) The URL-encoded query definition (instead of using the request body) * ['_source'] = (list) True or false to return the _source field or not, or a list of fields to return * ['_source_exclude'] = (list) A list of fields to exclude from the returned _source field * ['_source_include'] = (list) A list of fields to extract and return from the _source field * ['body'] = (string) The URL-encoded query definition (instead of using the request body) * * @param $params array Associative array of parameters * * @return array */ public function explain($params) { $id = $this->extractArgument($params, 'id'); $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Explain $endpoint */ $endpoint = $endpointBuilder('Explain'); $endpoint->setID($id) ->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (list) A comma-separated list of index names to search; use `_all` or empty string to perform the operation on all indices * ['type'] = (list) A comma-separated list of document types to search; leave empty to perform the operation on all types * ['analyzer'] = (string) The analyzer to use for the query string * ['analyze_wildcard'] = (boolean) Specify whether wildcard and prefix queries should be analyzed (default: false) * ['default_operator'] = (enum) The default operator for query string query (AND or OR) * ['df'] = (string) The field to use as default where no field prefix is given in the query string * ['explain'] = (boolean) Specify whether to return detailed information about score computation as part of a hit * ['fields'] = (list) A comma-separated list of fields to return as part of a hit * ['from'] = (number) Starting offset (default: 0) * ['ignore_indices'] = (enum) When performed on multiple indices, allows to ignore `missing` ones * ['indices_boost'] = (list) Comma-separated list of index boosts * ['lenient'] = (boolean) Specify whether format-based query failures (such as providing text to a numeric field) should be ignored * ['lowercase_expanded_terms'] = (boolean) Specify whether query terms should be lowercased * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) * ['q'] = (string) Query in the Lucene query string syntax * ['query_cache'] = (boolean) Enable query cache for this request * ['request_cache'] = (boolean) Enable request cache for this request * ['routing'] = (list) A comma-separated list of specific routing values * ['scroll'] = (duration) Specify how long a consistent view of the index should be maintained for scrolled search * ['search_type'] = (enum) Search operation type * ['size'] = (number) Number of hits to return (default: 10) * ['sort'] = (list) A comma-separated list of <field>:<direction> pairs * ['source'] = (string) The URL-encoded request definition using the Query DSL (instead of using request body) * ['_source'] = (list) True or false to return the _source field or not, or a list of fields to return * ['_source_exclude'] = (list) A list of fields to exclude from the returned _source field * ['_source_include'] = (list) A list of fields to extract and return from the _source field * ['stats'] = (list) Specific 'tag' of the request for logging and statistical purposes * ['suggest_field'] = (string) Specify which field to use for suggestions * ['suggest_mode'] = (enum) Specify suggest mode * ['suggest_size'] = (number) How many suggestions to return in response * ['suggest_text'] = (text) The source text for which the suggestions should be returned * ['timeout'] = (time) Explicit operation timeout * ['terminate_after'] = (number) The maximum number of documents to collect for each shard, upon reaching which the query execution will terminate early. * ['version'] = (boolean) Specify whether to return document version as part of a hit * ['body'] = (array|string) The search definition using the Query DSL * * @param $params array Associative array of parameters * * @return array */ public function search($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Search $endpoint */ $endpoint = $endpointBuilder('Search'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (list) A comma-separated list of index names to search; use `_all` or empty string to perform the operation on all indices * ['type'] = (list) A comma-separated list of document types to search; leave empty to perform the operation on all types * ['preference'] = (string) Specify the node or shard the operation should be performed on (default: random) * ['routing'] = (string) Specific routing value * ['local'] = (bool) Return local information, do not retrieve the state from master node (default: false) * ['ignore_unavailable'] = (bool) Whether specified concrete indices should be ignored when unavailable (missing or closed) * ['allow_no_indices'] = (bool) Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) * ['expand_wildcards'] = (enum) Whether to expand wildcard expression to concrete indices that are open, closed or both. * * @param $params array Associative array of parameters * * @return array */ public function searchShards($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\SearchShards $endpoint */ $endpoint = $endpointBuilder('SearchShards'); $endpoint->setIndex($index) ->setType($type); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (list) A comma-separated list of index names to search; use `_all` or empty string to perform the operation on all indices * ['type'] = (list) A comma-separated list of document types to search; leave empty to perform the operation on all types * * @param $params array Associative array of parameters * * @return array */ public function searchTemplate($params = array()) { $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Search $endpoint */ $endpoint = $endpointBuilder('SearchTemplate'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['scroll_id'] = (string) The scroll ID for scrolled search * ['scroll'] = (duration) Specify how long a consistent view of the index should be maintained for scrolled search * ['body'] = (string) The scroll ID for scrolled search * * @param $params array Associative array of parameters * * @return array */ public function scroll($params = array()) { $scrollID = $this->extractArgument($params, 'scroll_id'); $body = $this->extractArgument($params, 'body'); $scroll = $this->extractArgument($params, 'scroll'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Scroll $endpoint */ $endpoint = $endpointBuilder('Scroll'); $endpoint->setScrollID($scrollID) ->setScroll($scroll) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['scroll_id'] = (string) The scroll ID for scrolled search * ['scroll'] = (duration) Specify how long a consistent view of the index should be maintained for scrolled search * ['body'] = (string) The scroll ID for scrolled search * * @param $params array Associative array of parameters * * @return array */ public function clearScroll($params = array()) { $scrollID = $this->extractArgument($params, 'scroll_id'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\ClearScroll $endpoint */ $endpoint = $endpointBuilder('ClearScroll'); $endpoint->setScrollID($scrollID) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['id'] = (string) Document ID (Required) * ['index'] = (string) The name of the index (Required) * ['type'] = (string) The type of the document (Required) * ['consistency'] = (enum) Explicit write consistency setting for the operation * ['fields'] = (list) A comma-separated list of fields to return in the response * ['lang'] = (string) The script language (default: mvel) * ['parent'] = (string) ID of the parent document * ['refresh'] = (boolean) Refresh the index after performing the operation * ['replication'] = (enum) Specific replication type * ['retry_on_conflict'] = (number) Specify how many times should the operation be retried when a conflict occurs (default: 0) * ['routing'] = (string) Specific routing value * ['script'] = () The URL-encoded script definition (instead of using request body) * ['timeout'] = (time) Explicit operation timeout * ['timestamp'] = (time) Explicit timestamp for the document * ['ttl'] = (duration) Expiration time for the document * ['version_type'] = (number) Explicit version number for concurrency control * ['body'] = (array) The request definition using either `script` or partial `doc` * * @param $params array Associative array of parameters * * @return array */ public function update($params) { $id = $this->extractArgument($params, 'id'); $index = $this->extractArgument($params, 'index'); $type = $this->extractArgument($params, 'type'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Update $endpoint */ $endpoint = $endpointBuilder('Update'); $endpoint->setID($id) ->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (list) A comma-separated list of index names to search; use `_all` or * empty string to perform the operation on all indices (Required) * ['type'] = (list) A comma-separated list of document types to search; leave empty to * perform the operation on all types * ['analyzer'] = (string) The analyzer to use for the query string * ['analyze_wildcard'] = (boolean) Specify whether wildcard and prefix queries should be analyzed * (default: false) * ['default_operator'] = (enum) The default operator for query string query (AND or OR) (AND,OR) * (default: OR) * ['df'] = (string) The field to use as default where no field prefix is given in the * query string * ['explain'] = (boolean) Specify whether to return detailed information about score * computation as part of a hit * ['fields'] = (list) A comma-separated list of fields to return as part of a hit * ['fielddata_fields'] = (list) A comma-separated list of fields to return as the field data * representation of a field for each hit * ['from'] = (number) Starting offset (default: 0) * ['ignore_unavailable'] = (boolean) Whether specified concrete indices should be ignored when * unavailable (missing or closed) * ['allow_no_indices'] = (boolean) Whether to ignore if a wildcard indices expression resolves into * no concrete indices. (This includes `_all` string or when no indices have been specified) * ['conflicts'] = (enum) What to do when the reindex hits version conflicts? (abort,proceed) * (default: abort) * ['expand_wildcards'] = (enum) Whether to expand wildcard expression to concrete indices that are * open, closed or both. (open,closed,none,all) (default: open) * ['lenient'] = (boolean) Specify whether format-based query failures (such as providing * text to a numeric field) should be ignored * ['lowercase_expanded_terms'] = (boolean) Specify whether query terms should be lowercased * ['preference'] = (string) Specify the node or shard the operation should be performed on * (default: random) * ['q'] = (string) Query in the Lucene query string syntax * ['routing'] = (list) A comma-separated list of specific routing values * ['scroll'] = (duration) Specify how long a consistent view of the index should be * maintained for scrolled search * ['search_type'] = (enum) Search operation type (query_then_fetch,dfs_query_then_fetch) * ['search_timeout'] = (time) Explicit timeout for each search request. Defaults to no timeout. * ['size'] = (number) Number of hits to return (default: 10) * ['sort'] = (list) A comma-separated list of <field>:<direction> pairs * ['_source'] = (list) True or false to return the _source field or not, or a list of * fields to return * ['_source_exclude'] = (list) A list of fields to exclude from the returned _source field * ['_source_include'] = (list) A list of fields to extract and return from the _source field * ['terminate_after'] = (number) The maximum number of documents to collect for each shard, upon * reaching which the query execution will terminate early. * ['stats'] = (list) Specific 'tag' of the request for logging and statistical purposes * ['suggest_field'] = (string) Specify which field to use for suggestions * ['suggest_mode'] = (enum) Specify suggest mode (missing,popular,always) (default: missing) * ['suggest_size'] = (number) How many suggestions to return in response * ['suggest_text'] = (text) The source text for which the suggestions should be returned * ['timeout'] = (time) Time each individual bulk request should wait for shards that are * unavailable. (default: 1m) * ['track_scores'] = (boolean) Whether to calculate and return scores even if they are not used * for sorting * ['version'] = (boolean) Specify whether to return document version as part of a hit * ['version_type'] = (boolean) Should the document increment the version number (internal) on * hit or not (reindex) * ['request_cache'] = (boolean) Specify if request cache should be used for this request or not, * defaults to index level setting * ['refresh'] = (boolean) Should the effected indexes be refreshed? * ['consistency'] = (enum) Explicit write consistency setting for the operation * (one,quorum,all) * ['scroll_size'] = (integer) Size on the scroll request powering the update_by_query * ['wait_for_completion'] = (boolean) Should the request should block until the reindex is complete. * (default: false) * ['body'] = The search definition using the Query DSL * * @param array $params * * @return array */ public function updateByQuery($params = array()) { $index = $this->extractArgument($params, 'index'); $body = $this->extractArgument($params, 'body'); $type = $this->extractArgument($params, 'type'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\UpdateByQuery $endpoint */ $endpoint = $endpointBuilder('UpdateByQuery'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['id'] = (string) The script ID (Required) * ['lang'] = (string) The script language (Required) * * @param $params array Associative array of parameters * * @return array */ public function getScript($params) { $id = $this->extractArgument($params, 'id'); $lang = $this->extractArgument($params, 'lang'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Script\Get $endpoint */ $endpoint = $endpointBuilder('Script\Get'); $endpoint->setID($id) ->setLang($lang); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['id'] = (string) The script ID (Required) * ['lang'] = (string) The script language (Required) * * @param $params array Associative array of parameters * * @return array */ public function deleteScript($params) { $id = $this->extractArgument($params, 'id'); $lang = $this->extractArgument($params, 'lang'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Script\Delete $endpoint */ $endpoint = $endpointBuilder('Script\Delete'); $endpoint->setID($id) ->setLang($lang); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['id'] = (string) The script ID (Required) * ['lang'] = (string) The script language (Required) * * @param $params array Associative array of parameters * * @return array */ public function putScript($params) { $id = $this->extractArgument($params, 'id'); $lang = $this->extractArgument($params, 'lang'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Script\Put $endpoint */ $endpoint = $endpointBuilder('Script\Put'); $endpoint->setID($id) ->setBody($body); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['id'] = (string) The search template ID (Required) * * @param $params array Associative array of parameters * * @return array */ public function getTemplate($params) { $id = $this->extractArgument($params, 'id'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Template\Get $endpoint */ $endpoint = $endpointBuilder('Template\Get'); $endpoint->setID($id); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['id'] = (string) The search template ID (Required) * * @param $params array Associative array of parameters * * @return array */ public function deleteTemplate($params) { $id = $this->extractArgument($params, 'id'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Template\Delete $endpoint */ $endpoint = $endpointBuilder('Template\Delete'); $endpoint->setID($id); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (list) A comma-separated list of indices to restrict the results * ['fields'] = (list) A comma-separated list of fields for to get field statistics for (min value, max value, and more) * ['level'] = (enum) Defines if field stats should be returned on a per index level or on a cluster wide level * ['ignore_unavailable'] = (bool) Whether specified concrete indices should be ignored when unavailable (missing or closed) * ['allow_no_indices'] = (bool) Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) * ['expand_wildcards'] = (enum) Whether to expand wildcard expression to concrete indices that are open, closed or both. * * @param $params array Associative array of parameters * * @return array */ public function fieldStats($params = array()) { $index = $this->extractArgument($params, 'index'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\FieldStats $endpoint */ $endpoint = $endpointBuilder('FieldStats'); $endpoint->setIndex($index) ->setBody($body) ->setParams($params); return $this->performRequest($endpoint); } /** * $params['index'] = (list) A comma-separated list of indices to restrict the results * ['ignore_unavailable'] = (bool) Whether specified concrete indices should be ignored when unavailable (missing or closed) * ['allow_no_indices'] = (bool) Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified) * ['expand_wildcards'] = (enum) Whether to expand wildcard expression to concrete indices that are open, closed or both. * * @param $params array Associative array of parameters * * @return array */ public function fieldCaps($params = array()) { $index = $this->extractArgument($params, 'index'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\FieldCaps $endpoint */ $endpoint = $endpointBuilder('FieldCaps'); $endpoint->setIndex($index) ->setBody($body) ->setParams($params); return $this->performRequest($endpoint); } /** * $params['id'] = (string) ID of the template to render * * @param $params array Associative array of parameters * * @return array */ public function renderSearchTemplate($params = array()) { $body = $this->extractArgument($params, 'body'); $id = $this->extractArgument($params, 'id'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\RenderSearchTemplate $endpoint */ $endpoint = $endpointBuilder('RenderSearchTemplate'); $endpoint->setBody($body) ->setID($id); $endpoint->setParams($params); return $this->performRequest($endpoint); } /** * Operate on the Indices Namespace of commands * * @return IndicesNamespace */ public function indices() { return $this->indices; } /** * Operate on the Cluster namespace of commands * * @return ClusterNamespace */ public function cluster() { return $this->cluster; } /** * Operate on the Nodes namespace of commands * * @return NodesNamespace */ public function nodes() { return $this->nodes; } /** * Operate on the Snapshot namespace of commands * * @return SnapshotNamespace */ public function snapshot() { return $this->snapshot; } /** * Operate on the Cat namespace of commands * * @return CatNamespace */ public function cat() { return $this->cat; } /** * Operate on the Ingest namespace of commands * * @return IngestNamespace */ public function ingest() { return $this->ingest; } /** * Operate on the Tasks namespace of commands * * @return TasksNamespace */ public function tasks() { return $this->tasks; } /** * Operate on the Remote namespace of commands * * @return RemoteNamespace */ public function remote() { return $this->remote; } /** * Catchall for registered namespaces * * @param $name * @param $arguments * @return Object * @throws BadMethodCallException if the namespace cannot be found */ public function __call($name, $arguments) { if (isset($this->registeredNamespaces[$name])) { return $this->registeredNamespaces[$name]; } throw new BadMethodCallException("Namespace [$name] not found"); } /** * @param array $params * @param string $arg * * @return null|mixed */ public function extractArgument(&$params, $arg) { if (is_object($params) === true) { $params = (array) $params; } if (array_key_exists($arg, $params) === true) { $val = $params[$arg]; unset($params[$arg]); return $val; } else { return null; } } private function verifyNotNullOrEmpty($name, $var) { if ($var === null) { throw new InvalidArgumentException("$name cannot be null."); } if (is_string($var)) { if (strlen($var) === 0) { throw new InvalidArgumentException("$name cannot be an empty string"); } } if (is_array($var)) { if (strlen(implode("", $var)) === 0) { throw new InvalidArgumentException("$name cannot be an array of empty strings"); } } } /** * @param $endpoint AbstractEndpoint * * @throws \Exception * @return array */ private function performRequest(AbstractEndpoint $endpoint) { $promise = $this->transport->performRequest( $endpoint->getMethod(), $endpoint->getURI(), $endpoint->getParams(), $endpoint->getBody(), $endpoint->getOptions() ); return $this->transport->resultOrFuture($promise, $endpoint->getOptions()); } } |
#11 | Elasticsearch\Client->search(Array([from] => 10, [size] => 11)) /var/www/rc/drooble/trunk/projects/drooble_v1/resources/library/Drooble/Search/DroobleSearchClient.php (91) <?php namespace Drooble\Search; class DroobleSearchClient //implements \Lib\Drooble\Interfaces\DroobleSearchClient { private $di; private $pageTypes = []; // page tyeps in every language private $user_schema = array( "username"=>"", "email"=>"", "first_name"=>"", "last_name"=>"", "gender"=>"", "country"=>"", "city"=>"", "jam"=>"", "teach"=>"", "is_looking_for_a_band"=>"", "record_label"=>"", // "tags"=>[ // "equipment"=>[], // "genres"=>[], // "influences"=>[], // "instruments"=>[], // "languages"=>[], // "profile"=>[] // ], /*todo "audios"=>array( "songs"=>[], "samples"=>[] ), "videos"=>array( "videos"=>[] )*/ /*TODO "engagements"=>[]*/ ); private $page_schema = array( "username"=>"", "email"=>"", "name"=>"", "type"=>[], "country"=>"", "city"=>"", "tags"=>array( "equipment"=>[], "genres"=>[], "influences"=>[], "instruments"=>[], "languages"=>[], "profile"=>[] ),/*todo "audios"=>array( "songs"=>[], "samples"=>[] ), "videos"=>array( "videos"=>[] )*/ /*TODO "engagements"=>[]*/ ); private $client; public function __construct($elastic_client) { //$this->di = $di; //\Helpers\Debug::log("getDi",$di->get('elastic')); //$this->client = $di->get('elastic'); $this->client = $elastic_client; } public function search($params) { $response = $this->client->search($params); return $response; } public function query($index,$type,$q_json){ $params = [ 'index' => $index, 'type' => $type, 'body' => $q_json ]; try{ $response = $this->client->search($params); }catch(\Exception $e){ $response = false; } /*\Helpers\Debug::log("elastic indeces"); $response = $this->client->indices()->getSettings(['index' => [ 'profiles' ]]); \Helpers\Debug::log("indeces" ,$response); */ return $response; } // TODO after merge: use query function (if made generic) public function queryTest($q_json) { $params = [ 'index' => \Config::elasticsearch()->INDICES->tags,//'tags', 'type' => 'tags', 'body' => $q_json ]; try{ $response = $this->client->search($params); }catch(\Exception $e){ $response = false; } return $response; } public function getUserById($userId){ $params = [ 'index' => \Config::elasticsearch()->INDICES->users,//'users', 'type' => 'users', 'id' => $userId ]; try{ $response = $this->client->get($params); }catch(\Exception $e){ $response = false; } /*\Helpers\Debug::log("elastic indeces"); $response = $this->client->indices()->getSettings(['index' => [ 'profiles' ]]); \Helpers\Debug::log("indeces" ,$response); */ return $response; } public function getTagById($tagId){ $params = [ 'index' => \Config::elasticsearch()->INDICES->tags,//'tags', 'type' => 'tags', 'id' => $tagId ]; try{ $response = $this->client->get($params); }catch(\Exception $e){ $response = false; } $response = $this->client->indices()->getSettings(['index' => [ \Config::elasticsearch()->INDICES->tags, ]]); \Helpers\Debug::log("indeces" ,$response); return $response; } public function addTag(\Collections\Tags $tag) { $body = []; $rating = 0; $types = []; foreach (unserialize(TAGS_TYPES) as $tagType) { if ( (bool) $tag->type->{$tagType}->status && !(bool) $tag->type->{$tagType}->banned && !(bool) $tag->type->{$tagType}->is_delete ) { $rating += (int) $tag->type->{$tagType}->user_rating + (int) $tag->type->{$tagType}->moderator_rating; $types[] = $tagType; } } $body['types'] = $types; $body['rating'] = $rating; $indices = \Config::elasticsearch()->INDICES->tags; foreach ($indices as $lang => $idx) { $body['text'] = $tag->translation->{$lang}->text; if ( strlen($body['text']) == 0 ) { $body['text'] = $tag->translation->en->text; } if ( strlen($body['text']) ) { $body['text_suggest'] = $body['text']; $params = [ 'index' => $idx, 'type' => 'tag', 'id' => (string) $tag->_id, 'body' => $body ]; $this->client->index($params); } } return true; } public function removeTag(\Collections\Tags $tag){ $indices = \Config::elasticsearch()->INDICES->tags; foreach ($indices as $lang => $idx) { $params = [ 'index' => $idx, 'type' => 'tag', 'id' => (string) $tag->_id ]; try{ $this->client->delete($params); }catch(\Elasticsearch\Common\Exceptions\Missing404Exception $e){ return false; } } return true; } public function addUser(\Models\Users $user){ $u = $this->user_schema; $u['username'] = $user->username; $u['email'] = $user->email; $u['name'] = $user->first_name . " " . $user->last_name; // it's better to have the same field for Users and Pages $u['first_name'] = $user->first_name; $u['last_name'] = $user->last_name; $u['gender'] = $user->gender; // $u['country'] = $user->country; $u['city'] = $user->city; $u['jam'] = $user->is_jam; $u['teach'] = $user->is_teach; $u['lastseen'] = (int) $user->lastseen; $u['is_looking_for_a_band'] = $user->is_looking_for_a_band; $u['record_label'] = $user->record_label; $text = \Models\UserTexts::findFirst(array( "conditions" => "scene = 'about' AND user_id = :uid: AND is_deleted = '0'", "bind" => array("uid" => $user->id) )); $u['about'] = []; if ($text) { $u['about']['title'] = $text->title; $u['about']['text'] = $text->text; } $cachedInfo = \Models\UserCache::findFirst("user_id = {$user->id}"); $u['price'] = $cachedInfo->price; $avatars=\Helpers\Pictures::getDefault($user->id); if ( strpos($avatars['avatar_icon'], $user->id . "/avatars_icon" ) ) { $u['has_avatar'] = true; // many searches will be sorted by "has avatar that is not default" } else { $u['has_avatar'] = false; } $u['avatar'] = $avatars['avatar']; $u['avatar_icon'] = $avatars['avatar_icon']; if ($user->city) { $selected_place = \Models\GooglePlaces::findFirst([ "conditions" => "google_place_id = :google_place_id:", "bind" => ["google_place_id" => $user->city] ]); $u['place'] = $selected_place->google_place_details_en; $u['country'] = $selected_place->country_code; $u['location'] = (object) ['lat' => floatval($user->lat), 'lon' => floatval($user->lng)]; } else { $u['place'] = ""; $u['location'] = (object) ['lat' => floatval($user->lat), 'lon' => floatval($user->lng)]; } $pin = new \stdClass(); $pin->location = $u['location']; $u['pin']= $pin; $ucommunities = []; $utags = []; $utags['equipment']=[]; $utags['genres_primary']=[]; $utags['genres_secondary']=[]; $utags['influences']=[]; $utags['instruments_primary']=[]; $utags['instruments_secondary']=[]; $utags['languages']=[]; $utags['profile']=[]; // foreach($user->Tags as $tag){ // if( in_array($tag->type, array_keys($utags)) ){ // $utags[$tag->type][] = $tag->name; // } // } $allCommunities = \Helpers\Tags::getCommunities($user->id); // from apc cache (is_member is NOT cached) foreach ($allCommunities as $community) { if ($community['is_member']) { $data = new \stdClass(); // NOTE! getCommunities returns translations even for missing languages! // e.g. (tags that miss 'es' translation is filled with 'en' text foreach ($community['translation'] as $code => $info) { $data->{$code} = $info->text; } $ucommunities[] = $data; } } $userTags = \Helpers\Users::getUserTags($user->id, 3, true, null, false); foreach ($userTags as $type => $tags) { foreach ($tags as $tag) { $data = new \stdClass(); foreach ($tag->translation as $code => $info) { $data->{$code} = $info->text; } $utags[$type][] = $data; } } //\Helpers\Debug::log("test"); //\Helpers\Debug::log($utags); $u['tags'] = $utags; $u['communities'] = $ucommunities; $forSearch = \Helpers\UserValues::getComputed('profile-completed-for-search', null, $user->id); if ($forSearch['value']) { // It seems that 'visible' is a reserved word in Elasticsearch!!! but not documented ... calculate .. smqtaj $u['visibility'] = [ 'profile_completed' ]; } $params = [ 'index' => \Config::elasticsearch()->INDICES->users,//'users', 'type' => 'users', 'id' => $user->id, 'body' => $u ]; // Document will be indexed to my_index/my_type/my_id $response = $this->client->index($params); // var_dump($response); //\Helpers\Debug::log("resp ", $response); return $response; } public function removeUser(\Models\Users $user){ $params = [ 'index' => \Config::elasticsearch()->INDICES->users,//'users', 'type' => 'users', 'id' => $user->id ]; // Delete doc at /my_index/my_type/my_id try{ $response = $this->client->delete($params); }catch(\Elasticsearch\Common\Exceptions\Missing404Exception $e){ //\Helpers\Debug::log("ne mogia da iztria s parametri", $params); $response = false; } return $response; } private function loadPageTypesTranslations() { if (!$this->types_loaded) { $di = \Phalcon\DI\FactoryDefault::getDefault(); $this->db = $di->getDb(); $sql = "SELECT language_id, `key`, `value` FROM `text_translations` tt JOIN text_keys tk ON tk.id = tt.text_key_id WHERE description = 'users_page_types.title'"; $res = $this->db->query($sql); $res->setFetchMode(\Phalcon\Db::FETCH_ASSOC); $trRes = $res->fetchAll(); foreach ($trRes as $data) { if (is_array($this->pageTypes[$data['key']])) { $this->pageTypes[$data['key']][$data['language_id']] = $data['value']; } else { $this->pageTypes[$data['key']] = []; $this->pageTypes[$data['key']][$data['language_id']] = $data['value']; } } $this->types_loaded = true; } } public function addPage(\Models\Users $page){ $this->loadPageTypesTranslations(); $p = $this->page_schema; $p['username'] = $page->username; $p['email'] = $page->email; $p['name'] = trim($page->first_name); $p['type'] = []; $languages_config = json_decode(json_encode(\Config::languages()->language), true); $typeKey = strtolower(str_replace([" ", "/"], ["_", "_"], $page->PageType->title)); if ($typeKey == "band") { $typeKey = "page_band"; } foreach ($languages_config as $code => $info) { $p['type'][$code] = $this->pageTypes[$typeKey][$info['id']]; } $text = \Models\UserTexts::findFirst(array( "conditions" => "scene = 'about' AND user_id = :uid: AND is_deleted = '0'", "bind" => array("uid" => $page->id) )); $p['about'] = []; if ($text) { $p['about']['title'] = $text->title; $p['about']['text'] = $text->text; } // all visible for now $p['visibility'] = [ 'profile_completed' ]; $p['country'] = $page->country; $p['city'] = $page->city; $p['page_type_id'] = (int) $page->page_type_id; $p['lastseen'] = (int) $page->lastseen; // set by last interaction from Page (via DroobleHooksManager) $utags = []; $utags['equipment']=[]; $utags['genres_primary']=[]; $utags['influences']=[]; $utags['instruments_primary']=[]; $utags['languages']=[]; $utags['profile']=[]; $avatars=\Helpers\Pictures::getDefault($page->id); if ( strpos($avatars['avatar_icon'], $page->id . "/avatars_icon" ) ) { $p['has_avatar'] = true; // many searches will be sorted by "has avatar that is not default" } else { $p['has_avatar'] = false; } $p['avatar'] = $avatars['avatar']; $p['avatar_icon'] = $avatars['avatar_icon']; if ($page->city) { $selected_place = \Models\GooglePlaces::findFirst([ "conditions" => "google_place_id = :google_place_id:", "bind" => ["google_place_id" => $page->city] ]); $p['place'] = $selected_place->google_place_details_en; $p['location'] = (object) ['lat' => floatval($page->lat), 'lon' => floatval($page->lng)]; } else { $p['place'] = ""; $p['location'] = null; } $pin = new \stdClass(); $pin->location = $p['location']; $p['pin']= $pin; $pageTags = \Helpers\Users::getUserTags($page->id, 3, true, null, false); foreach ($pageTags as $type => $tags) { foreach ($tags as $tag) { $data = new \stdClass(); foreach ($tag->translation as $code => $info) { $data->{$code} = $info->text; } $utags[$type][] = $data; } } //\Helpers\Debug::log("test"); //\Helpers\Debug::log($utags); $p['tags'] = $utags; $params = [ 'index' => \Config::elasticsearch()->INDICES->pages,//'pages', 'type' => 'pages', 'id' => $page->id, 'body' => $p ]; // Document will be indexed to my_index/my_type/my_id $response = $this->client->index($params); return $response; } public function removePage(\Models\Users $page){ $params = [ 'index' => \Config::elasticsearch()->INDICES->pages,//'pages', 'type' => 'pages', 'id' => $page->id ]; // Delete doc at /my_index/my_type/my_id try{ $response = $this->client->delete($params); }catch(\Elasticsearch\Common\Exceptions\Missing404Exception $e){ //\Helpers\Debug::log("ne mogia da iztria s parametri", $params); $response = false; } catch (\Elasticsearch\Common\Exceptions\BadRequest400Exception $e) { \Helpers\Debug::error( $e->getTraceAsString() ); $response = false; } return $response; } public function getPageById($pageId){ $params = [ 'index' => \Config::elasticsearch()->INDICES->pages,//'pages', 'type' => 'pages', 'id' => $pageId ]; try{ $response = $this->client->get($params); }catch(Exception $e){ $response = false; } /*\Helpers\Debug::log("elastic indeces"); $response = $this->client->indices()->getSettings(['index' => [ 'profiles' ]]); \Helpers\Debug::log("indeces" ,$response); */ return $response; } } |
#12 | Drooble\Search\DroobleSearchClient->search(Array([from] => 10, [size] => 11, [index] => drooble_users, [body] => Array([query] => Array([bool] => Array()), [sort] => Array([0] => Array())))) /var/www/rc/drooble/trunk/projects/drooble_v1/resources/library/Drooble/Search/DroobleSearchManager.php (20) <?php namespace Drooble\Search; class DroobleSearchManager extends \Phalcon\Mvc\User\Component { private $client; public function __construct() { $elastic = \Phalcon\Di::getDefault()->getElastic(); //$elastic = null; //\Helpers\Debug::log($elastic); $this->client = new \Drooble\Search\DroobleSearchClient($elastic); //$this->client = new \StdClass(); } public function search($params) { $response = $this->client->search($params); return $response; } // DEPRECATED public function usersSearch($query){ /* $json = '{ "from" : 0, "size" : 5, "_source": [ "profile.username", "profile.first_name","profile.last_name","profile.email"], "query": { "multi_match": { "fields": [ "profile.username", "profile.first_name","profile.last_name","profile.email" ], "query": "'.$query.'", "fuzziness": "AUTO" } } }'; $json = '{ "from" : 0, "size" : 5, "_source": [ "profile.username", "profile.first_name","profile.last_name","profile.email"], "query": { "dis_max": { "tie_breaker": 0.1, "boost": 1.2, "queries": [ { "multi_match": { "fields": [ "profile.username", "profile.first_name","profile.last_name","profile.email" ], "query": "'.$query.'", "type": "phrase", "boost": 5 } }, { "multi_match": { "fields": [ "profile.username", "profile.first_name","profile.last_name","profile.email" ], "query": "'.$query.'", "type": "phrase", "fuzziness": "AUTO", "boost": 3 } }, { "query_string": { "default_field": "profile.username", "query": "'.$query.'" } } ] } } }'; $json = '{ "from" : 0, "size" : 5, "_source": [ "profile.username", "profile.first_name","profile.last_name","profile.email"], "query": { "multi_match": { "fields": [ "profile.username", "profile.first_name","profile.last_name","profile.email" ], "query": "'.$query.'", "fuzziness": "AUTO", "type": "cross_fields", "operator": "and" } } }'; $json = '{ "from" : 0, "size" : 5, "_source": [ "profile.first_name", "profile.last_name"], "query": { "multi_match": { "fields": [ "profile.username", "profile.first_name","profile.last_name","profile.email" ], "query": "'.$query.'", "fuzziness": "AUTO", "type": "cross_fields", "operator": "and" } } }'; */ $json = '{ "from" : 0, "size" : 5, "_source": [ "first_name", "last_name"], "query": { "bool": { "should":[ { "match_phrase_prefix" : { "full_name" : { "query": "'.$query.'", "slop":"100", "fuzziness": "AUTO" } } }, { "multi_match": { "fields": [ "username", "first_name","last_name","email" ], "query": "'.$query.'", "fuzziness": "AUTO" } } ] } } }'; \Helpers\Debug::log($json); $searched_users = $this->client->query("users","users",$json); //\Helpers\Debug::log($searched_users['hits']['hits']); $users = []; foreach($searched_users['hits']['hits'] as $user){ //$u = \Models\Users::findFirst($user["_id"]); //$users[] = \Patterns\UserSearchInfo::doAll($u); $users[] = \Helpers\Users::getUserShortInfoFromId($user["_id"]); } return ["users"=>$users,"raw_result"=>$searched_users]; //return []; } // DEPRECATED public function pagesSearch($query){ $json = '{ "from" : 0, "size" : 5, "_source": [ "first_name", "last_name"], "query": { "bool": { "should":[ { "match_phrase_prefix" : { "name" : { "query": "'.$query.'", "slop":"100", "fuzziness": "AUTO" } } }, { "multi_match": { "fields": [ "username", "name", "type" ], "query": "'.$query.'", "fuzziness": "AUTO" } } ] } } }'; \Helpers\Debug::log($json); $searched_pages = $this->client->query("pages","pages",$json); //\Helpers\Debug::log($searched_users['hits']['hits']); $pages = []; foreach($searched_pages['hits']['hits'] as $page){ //$u = \Models\Users::findFirst($user["_id"]); //$users[] = \Patterns\UserSearchInfo::doAll($u); $pages[] = \Helpers\Users::getUserShortInfoFromId($page["_id"]); } return ["pages"=>$pages,"raw_result"=>$searched_pages]; } public function addTag(\Collections\Tags $tag) { return $this->client->addTag($tag); } public function removeTag(\Collections\Tags $tag) { return $this->client->removeTag($tag); } public function addUser(\Models\Users $user) { return $this->client->addUser($user); } public function removeUser(\Models\Users $user){ return $this->client->removeUser($user); } public function getUserById($userId){ return $this->client->getUserById($userId); } public function addPage(\Models\Users $page) { return $this->client->addPage($page); } public function removePage(\Models\Users $page){ return $this->client->removePage($page); } public function getPageById($pageId){ return $this->client->getPageById($pageId); } } |
#13 | Drooble\Search\DroobleSearchManager->search(Array([from] => 10, [size] => 11, [index] => drooble_users, [body] => Array([query] => Array([bool] => Array()), [sort] => Array([0] => Array())))) /var/www/rc/drooble/trunk/projects/drooble_v1/services/web/private/logic/search.class.php (1587) <?php class search{ private $db; private $c; private $app; public function __construct($db,&$c, $app) { $this->db = $db; $this->c = $c; $this->app = $app; } /* public function doReindex($data){ $ret=array(); foreach($this->db->q("SELECT `id` FROM `users_profiles` WHERE 1") as $el){ $ret[]=$this->lib->profileSearchIndexing($el['id']); } return array(true,$ret); } */ public function searchCity($data) { $return = new \stdClass(); $return->items = \Helpers\Search::getInstance()->searchCity($data['name']); return array(true, $return); /* // SELECT *, CASE WHEN name LIKE 'Sofia%' THEN 1 ELSE 0 END AS keymatch FROM `cities` WHERE MATCH (name) AGAINST ('+Sofia' IN BOOLEAN MODE) ORDER BY keymatch DESC $cities = $this->app->db->fetchAll(" SELECT *, CASE WHEN search_by_me LIKE ".$this->app->db->escapeString($keywords)." THEN 4 WHEN search_by_me LIKE ".$this->app->db->escapeString($keywords." %")." THEN 3 WHEN search_by_me LIKE ".$this->app->db->escapeString("% ".$keywords." %")." THEN 2 WHEN search_by_me LIKE ".$this->app->db->escapeString("% ".$keywords)." THEN 1 ELSE 0 END AS keymatch FROM `cities` WHERE MATCH (search_by_me) AGAINST (".$this->app->db->escapeString($keywords).") ORDER BY keymatch DESC LIMIT 22 "); $items = array(); if ($cities) { foreach($cities as $city) { $title_suffix = $city['country']; if ($city['region']) { $title_suffix = $city['region'].", ".$city['country']; } $items[] = array( 'id' => $city['id'], 'title' => $city['name'].", ".$title_suffix, 'name' => $city['name'], 'country' => $city['country'], 'region' => $city['region'] ); } } $return->items = $items; return array(true, $return); */ } public function searchByMail($data){ $email=$data['email']; if(!filter_var($email, FILTER_VALIDATE_EMAIL)){ return array(false,"not valid"); } /* $search=$email; $search=str_replace("*","",$search); $search=str_replace(" ","",$search); $search=str_replace(")","",$search); $search=str_replace("(","",$search); $sql="SELECT `short_info` FROM `search_cache` WHERE MATCH (`email`) AGAINST ('".'"'.$search.'"'."')"; $r=$this->db->one($sql); * */ $person = \Models\UserCache::findFirst([ 'conditions' => 'email LIKE {email:str}', 'bind' => ['email' => $email] ]); if ($person) { return array(true, json_decode($person->short_info_json, true)); } else { return array(true,'notexists'); } } public function otherPersonContactsSuggester($data){ $user_id=\Helpers\Users::getIdFromUsername($data['profile']); if(isset($data['circle_id']) && $data['profile'] != $_SESSION['profile']['username']){ unset($data['circle_id']); } if(!$data['results']){ $data['results']=9; } if(isset($data['mix_order'])){ $data['mix_order']=true; } // \Helpers\Debug::alert($data['profile']); if($user_id){ return $this->ContactsSuggester($user_id,$data); }else{ return array(false); } } public function myContactsSuggester($data){ return $this->ContactsSuggester($_SESSION['profile']['id'],$data,true, isset($data['online_first']) ? $data['online_first'] : true); } public function otherPersonFollowSuggester($data) { $data["filterUsername"] = $data["profile"]; unset($data["profile"]); $data["follow_type"] = "followings"; return $this->ContactsSuggester($_SESSION['profile']['id'],$data,true, false); } public function searchInMyMessages($data){ // Used data $user_id = (int)$_SESSION['profile']['id']; if ($data['band_id'] > 0) { if (!\Helpers\Basic::checkUserRights((int) $data['band_id'], $user_id)) { return array(false,false); } else { $user_id = (int) $data['band_id']; } } $offset = $data['offset']; $limit = $data['limit']; $search = trim(strip_tags($data['search'])); $search = str_replace(array("%", "'", '"'), "", $search); $length_to_get = 50; // How much characters to get $symbols_before = 10; // How much symbols before match to get $return = array(); // Search query $query = " SELECT * FROM ( SELECT um.text, um.conversations_id, c.is_group, c.members, IF (um.reciever_id = '".$user_id."', scsender.short_info_json, screciever.short_info_json) as partner, IF (um.reciever_id = '".$user_id."', scsender.user_id, screciever.user_id) as partner_id FROM users_messages as um LEFT JOIN conversations AS c ON c.id = um.conversations_id LEFT JOIN search_cache AS scsender ON scsender.user_id = um.sender_id LEFT JOIN search_cache AS screciever ON screciever.user_id = um.reciever_id WHERE um.sender_id != um.reciever_id AND (um.sender_id = '".$user_id."' OR um.reciever_id = '".$user_id."') AND um.is_deleted=0 AND ( um.text LIKE :keywords OR (scsender.cache LIKE :keywords AND scsender.user_id != '".$user_id."') OR (screciever.cache LIKE :keywords AND screciever.user_id != '".$user_id."') ) ORDER BY um.send_time DESC ) as results GROUP BY results.conversations_id, results.text, results.partner, results.partner_id "; $prepare = array( 'keywords' => "%".$search."%" ); // Here we store user information - reason - when we have a user, does not look for it again $cache_profiles = array(); // So... lets begin... just in case string was more than 3 symbols if (mb_strlen($search) >= 3) { $cids = []; // Put information foreach($this->db->prepare($query, $prepare)->execute()->fetchAllAssoc()->cache( 1 )->result as $el) { $cids[] = $el['conversations_id']; continue; // !!!! NOTE we'll be using getMail at end of func to parse the response //this below -- NOT executed !!! $text = trim(strip_tags($el['text'])); $find_position = mb_strpos($search, $text); $text_length = mb_strlen($text); $string_length = mb_strlen($search); // Stupid way but... i cant regex :/ if ($text_length > $length_to_get) { if (($find_position - $symbols_before) <= 0) { $text = mb_substr($text, 0, $length_to_get)."..."; } else if (($find_position - $symbols_before) > 0 AND ($find_position - $symbols_before + $length_to_get) <= $text_length) { $text = "...".mb_substr($text, ($find_position - $symbols_before), $length_to_get)."..."; } else { $text = "...".mb_substr($text, ($length_to_get*-1)); } } $line = array( 'quote' => $text, 'conversation' => "#".$el['conversations_id'] ); // Put information about users in converstation if ((int)$el['is_group'] == 0) { if (!isset($cache_profiles[$el['partner_id']])) { $user = unserialize($el['partner']); $cache_profiles[$el['partner_id']] = array( 'names' => $user['display_name'] ); if (isset($user['avatar_icon']) AND $user['avatar_icon'] != "") { $cache_profiles[$el['partner_id']]['avatar_icon'] = $user['avatar_icon']; } } $line['names'] = $cache_profiles[$el['partner_id']]['names']; $line['avatar_icon'] = $cache_profiles[$el['partner_id']]['avatar_icon']; } else { // Check collection $collection = array(); $user_ids = explode(",", $el['members']); foreach($user_ids as $key => $val) { if ((int)$val != 0 AND (int)$val != $user_id) { $collection[(int)$val] = false; } } // Filter which users we have $search_user_ids = array(); foreach($collection as $key => $val) { if (isset($cache_profiles[$key])) { // Put it in our collection $collection[$key] = $cache_profiles[$key]['names']; } else { $search_user_ids[] = $key; } } // Get missed users if (!empty($search_user_ids)) { $query = "SELECT user_id, short_info_json FROM search_cache WHERE user_id IN (".implode(",", $search_user_ids).")"; foreach($this->db->prepare($query, array())->execute()->fetchAllAssoc()->cache( 1 )->result as $usr) { $user = json_decode($usr['short_info_json'], true); $cache_profiles[(int)$usr['user_id']] = array( 'names' => $user['display_name'] ); if (isset($user['avatar_icon']) AND $user['avatar_icon'] != "") { $cache_profiles[(int)$usr['user_id']]['avatar_icon'] = $user['avatar_icon']; } // Put it in our collection $collection[(int)$usr['user_id']] = $cache_profiles[(int)$usr['user_id']]['names']; } } // Now merge names $line['names'] = implode(", ", $collection); $line['avatar_icon'] = DEF_GROUP_CHAT_ICON; } // Some modifications // $text = str_replace($search, "<em>".$search."</em>", $text); $seek_and_destroy = '#\b'.$search.'\b#iu'; $line['quote'] = preg_replace($seek_and_destroy, '<em>$0</em>', $line['quote']); $line['names'] = preg_replace($seek_and_destroy, '<em>$0</em>', $line['names']); $return[] = $line; } } // NOTE!! overwrite response here $mc = new \Controllers\API\MessengerController(); $cids = array_reverse($cids); $cids = array_slice($cids, $offset, $limit); $getMailData = [ 'folder' => 'All', 'mode' => 'search', 'results' => $limit, 'cids' => $cids, 'pid' => $data['band_id'] ]; $getMailRe = $mc->getMail($getMailData); $return = is_array($getMailRe) ? $getMailRe : ['conversations' => []]; // Return return array(true, array("length" => count($return['conversations']) , "conversations" => $return['conversations'])); } private function ContactsSuggester($user_id,$data,$myContactsOnly=false, $onlineFirst = false){ $uid=$user_id; $prepare=array(); $excludeMothership = array_key_exists('exclude_mothership', $data) ? $data['exclude_mothership'] : true; // $prepare['uid']=$uid; $search=$data['search']; /*if (empty($search)) { return array(false, 'empty search query'); }*/ $select = array(); $leftJoin = array(); $order = array(); if($myContactsOnly){ $data['follow_type']='followings'; } $search=trim($search); $search=str_replace("*","",$search); $search=str_replace(")","",$search); $search=str_replace("(","",$search); $search=str_replace(" ","* +*",$search); if($search){ $search=$this->db->quote("*".$search."*"); }else{ $search=NULL; } $circle_id=$data['circle_id']; // $prepare['circle_id']=$circle_id; $show_status=$onlineFirst ? true : $data['show_status']; $latest=isset($data['latest']) ? true : false; $is_online=$data['is_online']; $mix_order=$data['mix_order']; $where = [ '`up`.`is_banned` IS NULL AND `up`.`is_disabled` = 0' ]; if($is_online){ $show_status=1; $where[]="(`up`.`user_status`>0 AND `up`.`lastseen`> " . (time() - \Config::defaults()->DEF_LASTSEEN_OFFLINE_TIME).") "; } if (isset($data["user_type"])) { // $LeftJoinUserStatus="LEFT JOIN `users_profiles` AS `up` ON `up`.`id` = `sc`.`user_id` "; // if ($data["user_type"] == "page") { // $where[] = "`up`.`is_page` = 1"; // } else if ($data["user_type"] == "user") { // $where[] = "`up`.`is_page` IS NULL"; // } } if(isset($show_status)){ $SelectUserStatus=" fn_calculateProfilePublicStatus(`up`.`user_status`,`up`.`system_status`,`up`.`lastseen`) as `publicStatus`, `up`.`id` as `user_suggest_id`, if(`chat_status` > 0,fn_calculateProfilePublicStatus(`user_status`, `system_status`, `lastseen`),0) as `cstatus`,"; //$SelectUserStatus="`up`.`user_status`, `up`.`lastseen`, `up`.`system_status`, "; // $LeftJoinUserStatus="LEFT JOIN `users_profiles` AS `up` ON `up`.`id` = `sc`.`user_id` "; $where[] = "`up`.`is_page` IS NULL"; } if ( $data['gender'] ) { $select[] = "`up`.`gender`"; // if ( !$LeftJoinUserStatus ) { // $leftJoin[] = "LEFT JOIN `users_profiles` AS `up` ON `up`.`id` = `sc`.`user_id` "; // } } if ( $data['is_page'] ) { //\Helpers\Debug::log('is_page passed'); $select[] = "`up`.`is_page`"; // if ( !$LeftJoinUserStatus ) { // $leftJoin[] = "LEFT JOIN `users_profiles` AS `up` ON `up`.`id` = `sc`.`user_id` "; // } } if ( $data['pictures_first'] ) { $select[] = 'IF(`upi`.`id`, 1, 0) AS `has_picture`'; // moje da stane greshka, zashtoto ne znaeme koi e profile album-a //$leftJoin[] = "LEFT JOIN `users_pictures` AS `upi` ON ( `upi`.`user_id` = `sc`.`user_id` AND `upi`.`profilepic` = 1 ) "; $leftJoin[] = "LEFT JOIN `users_elements` AS `upi` ON `sc`.`id` = `upi`.`creator_id` AND `upi`.`type`='picture' AND `upi`.`is_default` = '1' AND `upi`.`deleted_time` IS NULL AND `upi`.`published_time` IS NOT NULL AND `upi`.`deployed_time` IS NOT NULL "; $order[] = '`has_picture` DESC'; } if ( $data['compare_followers'] && in_array($data['follow_type'], array('followers', 'followings')) && isset($_SESSION['profile']['id']) ) { $select[] = 'IF(`my_ucm`.`id`, 1, 0) AS `same_follower`'; $select[] = 'IF(`my_ucm`.`id`, `my_ucm`.`circle_id`, -1) AS `circle_id`'; $leftJoin[] = "LEFT JOIN `users_circles_members` AS `my_ucm` ON ( `my_ucm`.`user_id` = " . $_SESSION['profile']['id'] . " AND `my_ucm`.`target_user_id` = " . ( $data['follow_type'] == 'followers' ? "`ucm`.`user_id`" : "`ucm`.`target_user_id`" ) . " ) "; $order[] = '`same_follower` DESC'; } if ($data['filterUsername']) { $otherUserId = \Helpers\Users::getIdFromUsername($data['filterUsername']); if ($otherUserId) { $leftJoin[] = "LEFT JOIN `users_circles_members` AS `other_ucm` ON ( `other_ucm`.`user_id` = " . $otherUserId . " AND `other_ucm`.`target_user_id` = `ucm`.`target_user_id` ) "; $where[] = "`other_ucm`.`id` IS NULL"; $where[] = "`up`.`id` != {$otherUserId}"; } } switch($data['follow_type']){ case "followers": $where[]="`ucm`.`target_user_id` = '{$uid}'"; $leftJoinCS="LEFT JOIN `search_cache` AS `sc` ON `sc`.`user_id` = `ucm`.`user_id`"; break; case "followings": $where[]="`ucm`.`user_id` = '{$uid}'"; $leftJoinCS="LEFT JOIN `search_cache` AS `sc` ON `sc`.`user_id` = `ucm`.`target_user_id`"; break; default: $leftJoinCS="LEFT JOIN `search_cache` AS `sc` ON (`sc`.`user_id` = `ucm`.`target_user_id` OR `sc`.`user_id` =`ucm`.`user_id`)"; } $limit = " "; if(isset($data["limit"])){ $prepare['limit']=$data['limit']; $limit = " LIMIT :limit "; if (isset($data["offset"])) { $prepare['offset']=$data['offset']; $limit .= "OFFSET :offset "; } } if($search){ $where[]="MATCH (`cache`) AGAINST ($search IN BOOLEAN MODE)"; } if($circle_id and $circle_id!='All'){ $where[]="`uc`.`id` = '{$circle_id}'"; } $where[] ="`sc`.`user_id`!= '{$uid}'"; if ( $uid != 1 && $excludeMothership) { $where[]="`ucm`.`target_user_id` != 1"; } if (isset($data['exclude_ids'])) { $exclude = is_array($data['exclude_ids']) ? implode(',', $data['exclude_ids']) : $data['exclude_ids']; if ( strlen($exclude) > 0 ) { $where[]="`ucm`.`target_user_id` NOT IN ($exclude)"; } } $where = implode(" AND ",$where); if($where=='') $where = '1'; if ($latest) { $order[] = "`ucm`.`create_time` DESC"; } if ($onlineFirst) { $order[]='FIELD(`publicStatus`, 2) DESC'; $order[]='`up`.`first_name`'; $order[]='`up`.`last_name`'; } if(isset($mix_order)) { $order[]='RAND()'; } if ( count($select) > 0 ) { $select = implode(', ', $select) . ','; } else { $select = ''; } $leftJoin = implode(' ', $leftJoin); if ( count($order) > 0 ) { $order = 'ORDER BY ' . implode(', ', $order); } else { $order = ''; } $sql="SELECT {$select} {$SelectUserStatus} `sc`.`short_info_json`, `uc`.`name` as `circle_name`, `ucm`.`target_user_id` FROM `users_circles_members` AS `ucm` {$leftJoinCS} {$LeftJoinUserStatus} {$leftJoinProfiles} {$leftJoin} LEFT JOIN `users_circles` AS `uc` ON `uc`.`id` = `ucm`.`circle_id` LEFT JOIN `users_profiles` AS `up` ON `up`.`id` = `sc`.`user_id` WHERE ( {$where} ) AND `sc`.`is_disabled` = 0 /*AND `ucm`.`target_user_id`!='1'*/ GROUP BY `sc`.`id` {$order} {$limit} "; // \Helpers\Debug::log($sql); // echo $sql; $ret=array(); //foreach($this->db->q($sql,$prepare) as $el){ $cache = isset($data['cache']) ? $data['cache'] : 1; // echo print_r(array($sql, $prepare), 1); // \Helpers\Debug::log($sql); if (isset($prepare["limit"])) $prepare["limit"] = intval($prepare["limit"]); if (isset($prepare["offset"])) $prepare["offset"] = intval($prepare["offset"]); $mem_before = memory_get_usage(); $res = $this->db->prepare($sql,$prepare)->execute()->fetchAllAssoc()->result; // \Helpers\Debug::log("Memory used by the contacts array: ", memory_get_usage() - $mem_before); // $res = $this->db->prepare($sql,$prepare)->execute()->fetchAllAssoc()->cache( $cache )->result; // echo "$sql - " . print_r($prepare,1); foreach($res as $el){ $a=json_decode($el['short_info_json'], true); if($show_status){ $status=array(); $statuses=unserialize(USER_STATUS_STATEMENTS); $status['status_id']=$el['publicStatus']; $status['status_name']=$statuses[$status['status_id']]; $chatStatus=array(); $chatStatus['status_id']=$el['cstatus']; $chatStatus['status_name']=$statuses[$chatStatus['status_id']]; $a['status']=$status; $a['chat_status']=$chatStatus; } if($a!=false){ $a['gender'] = $el['gender']; $a['has_picture'] = $el['has_picture']; $a['same_follower'] = $el['same_follower']; $a['circle_id'] = $el['circle_id']; //Compatibility $a['profile_tags'] = $a['tags']['profile']; if($el['user_id'] == $_SESSION['profile']['id'] and $uid == $_SESSION['profile']['id']){ $a['circle']=$el['circle_name']; } $ret[]=$a; } } return array(true,array("profiles"=>$ret)); //return array(true,array("profiles"=>$ret),str_replace("\t","",str_replace("\n", "", $sql)),$prepare); //return array(true,$ret); } public function chatBarSuggester($data) { $uid = (int)$_SESSION['profile']['id']; $limit = isset($data['limit']) ? $data['limit'] : 15; $return = array(); $query = " SELECT DISTINCT `sender_id`, `reciever_id`, /*fn_calculateProfilePublicStatus(`up`.`user_status`,`up`.`system_status`,`up`.`lastseen`) as `publicStatus`,*/ if(`chat_status` > 0,fn_calculateProfilePublicStatus(`user_status`, `system_status`, `lastseen`),0) as `cstatus` FROM `users_messages` AS `um` JOIN `conversations` AS `c` ON (`um`.`conversations_id` = `c`.`id`) LEFT JOIN `users_profiles` AS `up` ON `up`.`id` = IF(`sender_id` = :uid, `reciever_id`, `sender_id`) WHERE (`sender_id` = :sid OR `reciever_id` = :rid) AND `sender_id` <> `reciever_id` AND `up`.`is_page` IS NULL GROUP BY `um`.`conversations_id` ORDER BY `send_time` DESC LIMIT 0,$limit"; $prep = array("uid" => $uid, "sid" => $uid, "rid" => $uid); $result = $this->db->prepare($query, $prep)->execute()->fetchAllAssoc()->result; $exclude = array(); $statuses=unserialize(USER_STATUS_STATEMENTS); $chatstatuses=unserialize(CHAT_STATUS_STATEMENTS); foreach ( $result as $r ) { $id = $r['sender_id'] == $uid ? $r['reciever_id'] : $r['sender_id']; $user = \Helpers\Users::getUserShortInfoFromId($id); $status=array(); $status['status_id']=\Helpers\Users::getInstance()->getProfilePublicStatus($id);//$r['publicStatus']; $status['status_name']=$statuses[$status['status_id']]; $chatStatus=array(); $chatStatus['status_id']=\Helpers\Users::getInstance()->getProfilePublicChatStatus($id); $chatStatus['status_name']=$chatstatuses[$chatStatus['status_id']]; $user['status']=$status; $user['chat_status']=$chatStatus; if (!in_array($id, $exclude)) { $return[] = $user; $exclude[] = $id; //\Helpers\Debug::log($id,$status); } } if ( count($return) < $limit ) { $data["limit"] = $limit - count($return); $data["exclude_ids"] = $exclude; $additional = $this->myContactsSuggester($data); if ($additional[0] && count($additional[1]['profiles']) > 0) { $return = array_merge($return, $additional[1]['profiles']); } } foreach ( $return as &$r ) { $r['profile_tags'] = $r['tags']['profile']; } return array(true, array("profiles" => $return)); } /* DEPRECATED public function followSuggester($data) { return array(true); $users = array(); $offset = $data['offset'] || 0; $lat = $this->app->request->ipInfo["latitude"]; $long = $this->app->request->ipInfo["longitude"]; $userTags = array(); //$results = $this->db->q( "SELECT `name`, `type` FROM `users_tags` WHERE `user_id` = :uid", array("uid" => $_SESSION['profile']['id'])); $results = $this->db->prepare( "SELECT `name`, `type` FROM `users_tags` WHERE `user_id` = :uid", array("uid" => $_SESSION['profile']['id']))->execute()->fetchAllAssoc()->cache()->result; foreach ( $results as $el ) { $userTags[ $el[ 'type' ] ][] = ucwords(strtolower($el['name'])); } // foreach ( $userTags as $k => $e ) { // $tagsCache[$k] = implode( " ", str_replace( " ", "_", $e ) ); // } $query = " SELECT `upr`.`id` as `user_id`, `sc`.`short_info`, " . ( ( $lat != 0 && $long != 0 ) ? "IF ( " . ($lat - 10) . " < `upr`.`lat` AND `upr`.`lat` < " . ($lat + 10) . " AND " . ($long - 10) . " < `upr`.`long` AND `upr`.`long` < " . ($long + 10) . ", 1, 0 )" : "0" ) . " as `is_near`, MATCH (instruments) AGAINST (:instruments IN NATURAL LANGUAGE MODE) AS score_instruments, MATCH (genres) AGAINST (:genres IN NATURAL LANGUAGE MODE) AS score_genres, MATCH (influences) AGAINST (:influences IN NATURAL LANGUAGE MODE) AS score_influences, IF ( `ucm`.`id` IS NOT NULL, 1, 0 ) as `followed`, IF ( `uc`.`id` IS NOT NULL, 1, 0 ) as `has_posts` FROM `users_profiles` `upr` JOIN `users_elements` `upi` ON (`upr`.`id` = `upi`.`creator_id` AND `upr`.`profile_album_id` = `upi`.`album_id` AND `upi`.`type`='picture' AND `upi`.`is_default` = '1' AND `upi`.`deleted_time` IS NULL AND `upi`.`published_time` IS NOT NULL AND `upi`.`deployed_time` IS NOT NULL) JOIN `search_cache` `sc` ON (`sc`.`user_id` = `upr`.`id`) LEFT JOIN `users_comments` `uc` ON (`uc`.`owner_element_id` = `upr`.`id` AND `uc`.`model` = 'post') LEFT JOIN `users_circles_members` `ucm` ON (`ucm`.`user_id` = :uid AND `ucm`.`target_user_id` = `upr`.`id`) WHERE `upr`.`id` != :uuid GROUP BY `uc`.`owner_element_id` HAVING `followed` = 0 ORDER BY `score_genres` DESC, `score_influences` DESC, `score_instruments` DESC, `is_near` DESC, `has_posts` DESC LIMIT :offset, 9 "; $results = $this->db->prepare($query, array( 'offset' => $offset, 'uid' => $_SESSION['profile']['id'], 'uuid' => $_SESSION['profile']['id'], 'genres' => ( isset( $userTags['genres'] ) ? implode( " ", str_replace( " ", "_", $userTags['genres'] ) ) : '' ), 'instruments' => ( isset( $userTags['instruments'] ) ? implode( " ", str_replace( " ", "_", $userTags['instruments'] ) ) : '' ), 'influences' => ( isset( $userTags['influences'] ) ? implode( " ", str_replace( " ", "_", $userTags['influences'] ) ) : '' ) ))->execute()->fetchAllAssoc()->cache()->result; foreach ( $results as $result ) { $user = unserialize( $result['short_info'] ); if ( $user != false ) { $users[] = $user; } } return array(true, $users); }*/ public function searchSuggester($data) { $results = isset($data['limit']) ? $data['limit'] : \Config::defaults()->RESULTS_TO_SHOW->search; if ($results > \Config::defaults()->MAX_RESULTS_TO_SHOW->search) { $results = \Config::defaults()->MAX_RESULTS_TO_SHOW->search; } $reminder = $result % 2; $search = $data['autocomplete']; $msc = microtime(true); if (!isset($data['skipTags']) || !$data['skipTags']) { $tags = $this->tagsSuggester(array('autocomplete' => $search, 'limit' => (int) ($results / 2) + $reminder)); } $profiles = []; $pages = []; if (isset($data['skipPages']) || $data['skipPages'] == 'true') { // legacy string true $profilesRes = $this->search(array('autocomplete' => $search, 'show_profiles' => true, 'visible' => $data['visible'])); if ($profilesRes[0]) { $profiles = $profilesRes[1]; } } else { // search both users and pages and separate them here $searchRes = $this->search(['autocomplete' => $search, 'visible' => $data['visible']]); if ($searchRes[0]) { foreach ($searchRes[1] as $i => $sr) { if ($i == 0) { $firstType = $sr['is_page'] ? "page" : "profile"; } if ($sr['is_page']) { $pages[] = $sr; } else { $profiles[] = $sr; } } } } $communities = \Helpers\Tags::getCommunities(null, false, $search, $results); $sCtrl = new \Controllers\API\SearchController(); $posts = $sCtrl->searchPosts($data); $msc=microtime(true)-$msc; $res=array(); $res['profiles'] = $profiles; $res['pages'] = $pages; $res['posts'] = $posts; $res['communities'] = $communities; $res['tags'] = $tags[0] ? $tags[1]['tags'] : array(); $res['first_type'] = isset($firstType) ? $firstType : false; return array(true, $res); } public function getFacebookFriends () { $uid = (int)$this->app->session->profile['id']; $friends = \Helpers\Users::getUnfollowedFacebookFriends($uid); return [true, $friends]; } //polzva se samo za chat-a, no i tam e spriano i vrushta [] public function generatePeopleSuggestions ($data) { return array(true,[]); if (isset($data['chat'])) { $uid = $_SESSION["profile"]["id"]; $usedUids = []; if (isset($data['used_ids']) AND is_array($data['used_ids'])) { $usedUids = $data['used_ids']; } $result = [ 'explore' => \Helpers\Suggestions::generateExploreSuggestions($uid, $usedUids) ]; return array(true, $result); } if (!isset($data["sideMenu"]) && !isset($data["explore"])) { return array( "sideMenu" => array(), "explore" => array() ); } $result = \Helpers\Suggestions::generateSuggestions($_SESSION['profile']['id'], $data["sideMenu"], $data["explore"]); if (!$result) { return array(false, "insert/update failed"); } return array(true, $result); } public function tagsSuggesterDEPRECATED($data){ // DEPRECATED !!!!!! ! !! ! // DONE elasticsearch! $search=trim($data['search']); $type = $data['type']; if(!$search) return array(true,array()); if ( strlen($search) < 3 ) { return [true, []]; } $limit = isset($data['limit']) ? intval($data['limit']) : \Config::defaults()->RESULTS_TO_SHOW->search; if($limit > \Config::defaults()->MAX_RESULTS_TO_SHOW->search){ $limit = \Config::defaults()->MAX_RESULTS_TO_SHOW->search; } $offset = isset($data['offset']) ? intval($data['offset']) : 0; $lang = \Helpers\Basic::lang(); $regex = new \MongoDB\BSON\Regex('^'.$search, 'i'); if ($type == "" || $type == "all") { $conditions = [ "translation.{$lang}.text" => $regex, ]; $project = [ "type" => 1, 'translation' => 1, 'posts_rating' => ['$sum' => ['$type.posts.moderator_rating', '$type.posts.user_rating']], 'profile_rating' => ['$sum' => ['$type.profile.moderator_rating', '$type.profile.user_rating']], 'instruments_rating' => ['$sum' => ['$type.instruments.moderator_rating', '$type.instruments.user_rating']], 'influences_rating' => ['$sum' => ['$type.influences.moderator_rating', '$type.influences.user_rating']], 'equipment_rating' => ['$sum' => ['$type.equipment.moderator_rating', '$type.equipment.user_rating']], 'genres_rating' => ['$sum' => ['$type.genres.moderator_rating', '$type.genres.user_rating']], 'rating' => ['$max' => ['$posts_rating', '$profile_rating', '$instruments_rating', '$influences_rating', '$equipment_rating', '$genres_rating']], ]; } else { $conditions = [ "translation.{$lang}.text" => $regex, ]; $project = [ "type.{$type}" => 1, 'translation' => 1, 'rating' => ['$sum' => ['$' . "type.{$type}." . 'moderator_rating', '$' . "type.{$type}." . 'user_rating']] ]; } $res = \Collections\Tags::aggregate([ ['$match' => $conditions], ['$project' => $project], ['$sort' => ['rating' => -1]], ['$skip' => $offset], ['$limit' => $limit], ]); $tags = []; foreach ($res as $tag) { $tagName = mb_convert_case(stripslashes($tag->translation->{$lang}->text), MB_CASE_TITLE, 'UTF-8'); foreach ($tag->type as $type => $notneed) { $tags[$type][] = ['index' => \Helpers\Tags::transformIndex($tagName), "url" => \Helpers\Basic::getUrl($tagName, $type), "name"=> $tagName ]; } } return array(true,array("tags"=>$tags)); } public function tagsSuggester($data) { $search = trim($data['search']); $type = $data['type']; if (!$search) { return [true, []]; } if (strlen($search) < 3) { return [true, []]; } $limit = isset($data['limit']) ? intval($data['limit']) : \Config::defaults()->RESULTS_TO_SHOW->search; if ($limit > \Config::defaults()->MAX_RESULTS_TO_SHOW->search) { $limit = \Config::defaults()->MAX_RESULTS_TO_SHOW->search; } $offset = isset($data['offset']) ? intval($data['offset']) : 0; $lang = \Helpers\Basic::lang(); $sort = [["rating" => "desc"]]; $bool = []; if (strlen($type) && $type != 'all') { $tagTypes = unserialize(TAGS_TYPES); if (!in_array($type, $tagTypes)) { return [true, []]; } $bool['filter'] = [ 'term' => [ 'types' => $type ] ]; } $bool["must"] = [ [ "match_phrase_prefix" => [ "text" => $search ] ] ]; $query = ["bool" => $bool]; $params = [ "from" => $offset, "size" => $limit, "index" => \Config::elasticsearch()->INDICES->tags->{$lang}, // "explain" => 1, "body" => [ "query" => $query, "sort" => $sort, ] ]; $dsm = $this->app->droobleSearchManager; $result = $dsm->search($params); $tags = []; foreach ($result['hits']['hits'] as $item){ $tagName = mb_convert_case(stripslashes($item['_source']['text']), MB_CASE_TITLE, 'UTF-8'); $tags[$type][] = ["name"=> $tagName ]; } return [true, ['tags' => $tags]]; } // looks like I did this to track stuff for Segment, without making too many requests (due to the $data['count'] that is used for counting search results, // but now it just wraps the search() func public function advancedSearchPage($data){ $searchStr = strlen(trim($data['autocomplete'])) ? $data['autocomplete'] : trim($data['search']); $properties =array( "category" => 'Home page', "search_query" => "'".$searchStr."'" ); if (isset($data['profile']) && is_array($data['profile'])) { // create Segment properties from search tags foreach ($data['profile'] as $tag) { if (preg_match('/^[0-9a-z\s]+$/i', $tag)) { $properties[ preg_replace('/\s+/', '_', strtolower($tag)) ] = true; } } } // why not just 0/1 ? ... strings 'true' | 'false' if(isset($data['bands']) && ($data['bands'] == 'true' or $data['bands'] == true)){ $properties['bands'] = true; } if(isset($data['venues']) && ($data['venues'] == 'true' or $data['venues'] == true)){ $properties['venues'] = true; } if(isset($data['clubs']) && ($data['clubs'] == 'true' or $data['clubs'] == true)){ $properties['clubs'] = true; } if(isset($data['recording_studios']) && ($data['recording_studios'] == 'true' or $data['recording_studios'] == true)){ $properties['recording_studios'] = true; } if(isset($data['rehearsal_space']) && ($data['rehearsal_space'] == 'true' or $data['rehearsal_space'] == true)){ $properties['rehearsal_space'] = true; } if(isset($data['music_school']) && ($data['music_school'] == 'true' or $data['music_school'] == true)){ $properties['music_school'] = true; } if(isset($data['jam']) && ($data['jam'] == 'true' or $data['jam'] == true)) { $properties['jammers'] = true; } if(isset($data['teach']) && ($data['teach'] == 'true' or $data['teach'] == true)){ $properties['teachers'] = true; if (isset($data['price_min'])) { $properties['price_min'] = $data['price_min']; } if (isset($data['price_max'])) { $properties['price_max'] = $data['price_max']; // When its picked maximum of 150+... if ((int)$data['price_max'] == 150) { $properties['price_max'] = 999; } } } if(isset($data['available']) && ($data['available'] == 'true' or $data['available'] == true)){ $properties['available'] = true; } if(isset($data['looking_bandmates']) && ($data['looking_bandmates'] == 'true' or $data['looking_bandmates'] == true)){ $properties['looking_bandmates'] = true; } if(isset($data['instruments']) && $data['instruments']){ $properties['instruments'] = $data['instruments']; } if(isset($data['instruments_primary_to_join']) && $data['instruments_primary_to_join']){ $properties['instruments_primary_to_join'] = $data['instruments_primary_to_join']; } if(isset($data['instruments_primary_for_bandmates']) && $data['instruments_primary_for_bandmates']){ $properties['instruments_primary_for_bandmates'] = $data['instruments_primary_for_bandmates']; } if(isset($data['genres']) && $data['genres']){ $properties['genres'] = $data['genres']; } if(isset($data['influences']) && $data['influences']){ $properties['influences'] = $data['influences']; } if(isset($data['equipment']) && $data['equipment']){ $properties['equipment'] = $data['equipment']; } if(isset($data['languages']) && $data['languages']){ $properties['languages'] = $data['languages']; } if(isset($data['location']) && $data['location']){ $properties['location'] = $data['location']; } if(isset($data['place']) && $data['place']){ $properties['place'] = $data['place']; } $track = array(); $track['event'] = "Advanced Search"; if($this->app->session->has('profile')){ $track['userId'] = $this->app->session->get('profile')['id']; }else{ // $track['anonymousId'] = rand(100000,999999); } $track['properties'] = $properties; if( $this->app->session->has('profile') && (!isset($data['count']) or $data['count'] == 2) ){ if(!$_COOKIE["druast"]) { $secureConnection = strtolower(\Helpers\Basic::getInstance()->get_php_http_scheme()) == 'https' ? true : false; setcookie("druast", date("Y-m-d"), time() + 60 * 60, '/', NULL, $secureConnection, true); // 60 minutes \Drooble\Activities\Activities::add( "advancedSearch", $track['userId'], (object) ['type' => 'user', 'id' => $track['userId']], ['segment' => ['track' => $track]] ); } } return $this->search($data); } // $data['autocomplete'] string - the search works as autocomplete e.g. Joh -> John // $data['search'] string - the search works as search (bad at autocomplete, but with more accurate results) // TODO - think if possible to use instead of getContacts - you'll need your 'followings/folloers' on top of results public function search($data) { $go_search=false; foreach(array_keys($data) as $e){ if(!in_array($e, array_keys( get_object_vars( \Config::api()->MAP->search->data ) ))){ return array(false,"input error1 '".$e."'"); } if($data[$e]){ $go_search=true; } } if(!$go_search){ return array(false,"empty search"); } $dsm = $this->app->droobleSearchManager; $lang = \Helpers\Basic::lang(); $analyzer = strtolower(\Config::languages()->language->{$lang}->name_in_english); $offset = $data['offset'] ? $data['offset'] : 0; $results = isset($data['limit']) ? $data['limit'] : \Config::defaults()->RESULTS_TO_SHOW->search; if($results > 100){ // way too many $results = \Config::defaults()->MAX_RESULTS_TO_SHOW->search; } $count = false; $pageTypeIds = []; $matchTags = [ 'profile' => [], 'instruments' => [], 'genres' => [], 'equipment' => [], 'influences' => [], 'languages' => [], 'instruments_primary_to_join' => [], 'instruments_primary_for_bandmates' => [], ]; if ((int) $data['venues'] == 1) { $pageTypeIds[] = 106; } if ((int) $data['clubs'] == 1) { $pageTypeIds[] = 107; } if ((int) $data['music_school'] == 1) { $pageTypeIds[] = 120; } if ((int) $data['recording_studios'] == 1) { $pageTypeIds[] = 115; } if ((int) $data['rehearsal_space'] == 1) { $pageTypeIds[] = 128; } if (is_array($data['instruments']) AND ! empty($data['instruments'])) { foreach ($data['instruments'] as $item) { $matchTags['instruments']['should'][] = $item; } } if (is_array($data['genres']) AND ! empty($data['genres'])) { foreach ($data['genres'] as $genre) { $matchTags['genres']['should'][] = $genre; } } if (is_array($data['equipment']) AND ! empty($data['equipment'])) { foreach ($data['equipment'] as $item) { $matchTags['equipment']['should'][] = $item; } } if (is_array($data['influences']) AND ! empty($data['influences'])) { foreach ($data['influences'] as $item) { $matchTags['influences']['should'][] = $item; } } if (is_array($data['languages']) AND ! empty($data['languages'])) { foreach ($data['languages'] as $item) { $matchTags['languages']['should'][] = $item; } } // these are reversed ... to match users who want to play an instrument and bands that are looking for the same if (is_array($data['instruments_primary_to_join']) AND ! empty($data['instruments_primary_to_join'])) { foreach ($data['instruments_primary_to_join'] as $item) { $matchTags['instruments_primary_for_bandmates']['should'][] = $item; } } if (is_array($data['instruments_primary_for_bandmates']) AND ! empty($data['instruments_primary_for_bandmates'])) { foreach ($data['instruments_primary_for_bandmates'] as $item) { $matchTags['instruments_primary_to_join']['should'][] = $item;// } } if (is_array($data['profile']) AND !empty($data['profile'])) { $tmp = array(); foreach ($data['profile'] as $el) { if (!trim($el)) continue; // Some predefined // TODO config with translations in all languages VS cache ... if ($el == $this->app->translate->get('drummers')) { $tag = \Helpers\Tags::findByText('drums', null); if ($tag) { $matchTags['instruments']['should'][] = $tag->name; } $tag = \Helpers\Tags::findByText('drummer', null); if ($tag) { $matchTags['profile']['should'][] = $tag->name; } } if ($el == $this->app->translate->get('singers') || $el == $this->app->translate->get('vocalists')) { $tag = \Helpers\Tags::findByText('vocals', null); if ($tag) { $matchTags['profile']['should'][] = $tag->name; $matchTags['instruments']['should'][] = $tag->name; } $tag = \Helpers\Tags::findByText('singer', null); if ($tag) { $matchTags['profile']['should'][] = $tag->name; } $tag = \Helpers\Tags::findByText('vocalist', null); if ($tag) { $matchTags['profile']['should'][] = $tag->name; } } if ($el == $this->app->translate->get('guitarists')) { $tag = \Helpers\Tags::findByText($this->app->translate->get('guitar'), null); if ($tag) { $matchTags['instruments']['should'][] = $tag->name; } $tag = \Helpers\Tags::findByText($this->app->translate->get('guitarist'), null); if ($tag) { $matchTags['profile']['should'][] = $tag->name; } $tag = \Helpers\Tags::findByText($this->app->translate->get('acoustic_guitar'), null); if ($tag) { $matchTags['instruments']['should'][] = $tag->name; } $tag = \Helpers\Tags::findByText($this->app->translate->get('electric_guitar'), null); if ($tag) { $matchTags['instruments']['should'][] = $tag->name; } } if ($el == $this->app->translate->get('bass_players') || $el == $this->app->translate->get('bassists')) { $tag = \Helpers\Tags::findByText($this->app->translate->get('bass'), null); if ($tag) { $matchTags['instruments']['should'][] = $tag->name; } $tag = \Helpers\Tags::findByText($this->app->translate->get('bass_player'), null); if ($tag) { $matchTags['profile']['should'][] = $tag->name; } $tag = \Helpers\Tags::findByText($this->app->translate->get('bassist'), null); if ($tag) { $matchTags['profile']['should'][] = $tag->name; } } if ($el == $this->app->translate->get('producers')) { $tag = \Helpers\Tags::findByText($this->app->translate->get('producer'), null); if ($tag) { $matchTags['profile']['should'][] = $tag->name; } } if ($el == $this->app->translate->get('musicians')) { $tag = \Helpers\Tags::findByText($this->app->translate->get('musician'), null); if ($tag) { $matchTags['profile']['should'][] = $tag->name; } } } } $bool = []; $must = []; $should = []; if (isset($data['autocomplete']) && trim($data['autocomplete'])) { $searchStr = trim($data['autocomplete']); // phrase_prefix is the "poorman's autocomplete" of Elastic. Works great // In future we can create more complex autocomplete, but it's totally unnecessary for now $combineType = "phrase_prefix"; $minLength = 2; } else { $searchStr = trim($data['search']); $combineType = "cross_fields"; $minLength = 3; } if (strtolower($searchStr) == "search" || strtolower($searchStr) == "%%tag%%") { try { // we got weird "search" requests .. log em // \Helpers\Debug::log("weird search ", $_SERVER['HTTP_REFERER']); // \Helpers\Debug::log($_SERVER['REQUEST_URI']); // \Helpers\Debug::log($_SERVER['QUERY_STRING']); // \Helpers\Debug::log($_SERVER['HTTP_USER_AGENT']); } catch (\Exception $e) { } } if (strlen($searchStr) >= $minLength) { // keep search string for 'tag' cloud of frequent searches \Helpers\SearchTags::add($searchStr); $combine = []; $combine[] = [ "multi_match" => [ "query" => $searchStr, "analyzer" => $analyzer, "type" => $combineType, "fields" => [ "name^5", // full name of User / Page "username^1", // "about.title^4", // "about.text^2", // "type.{$lang}^2", // Pages only // "tags.profile.{$lang}^3", // "tags.equipment.{$lang}^2", // "tags.genres.{$lang}^2", // Pages only // "tags.genres_primary.{$lang}^2", // "tags.genres_secondary.{$lang}", // "tags.influences.{$lang}^2", // "tags.instruments_primary.{$lang}^2", // "tags.instruments_secondary.{$lang}", // "tags.languages.{$lang}", ] ] ]; $combine[] = [ "multi_match" => [ "query" => $searchStr, "analyzer" => $analyzer, "fields" => [ "name^3", // full name of User / Page // "username^1", // "about.title^3", // "about.text^2", // "type.{$lang}^2", // Pages only // "tags.profile.{$lang}^3", // "tags.equipment.{$lang}^2", // "tags.genres.{$lang}^2", // Pages only // "tags.genres_primary.{$lang}^2", // "tags.genres_secondary.{$lang}", // "tags.influences.{$lang}^2", // "tags.instruments_primary.{$lang}^2", // "tags.instruments_secondary.{$lang}", // "tags.languages.{$lang}", ], "fuzziness" => "AUTO" ] ]; $must[] = ['bool' => ['should' => $combine, "boost" => 5]]; } /* if ($data['teach'] == 1) { $must[] = ['match' => ['teach' => 1]]; } if (intval($data['price_min']) > 0 || intval($data['price_max']) > 0) { $price = []; if (intval($data['price_min']) > 0) { $this_drooble_fee = (intval($data['price_min']) / (\Config::defaults()->DROOBLE_FEE_IN_PERCENTS + 100) * \Config::defaults()->DROOBLE_FEE_IN_PERCENTS); $price_from = intval($data['price_min']) - $this_drooble_fee; if ($price_from < 0) { $price_from = 0; } $price['gte'] = intval($price_from); } if (intval($data['price_max']) > 0) { $this_drooble_fee = (intval($data['price_max']) / (\Config::defaults()->DROOBLE_FEE_IN_PERCENTS + 100) * \Config::defaults()->DROOBLE_FEE_IN_PERCENTS); $price_to = intval($data['price_max']) - $this_drooble_fee; if ($price_to < 0) { $price_to = 0; } $price['lte'] = intval($price_to); } $must[] = ['range' => ['price' => $price] ]; } */ if ($data['place']) { $data['place'] = str_replace("'", "", $data['place']); $data['place'] = str_replace("`", "", $data['place']); $data['place'] = str_replace("\"", "", $data['place']); $place = \Helpers\Basic::getGooglePlace($data['place']); if ($place && $place->is_country) { $must[] = ['match' => ['country' => $place->country_code]]; } else { $must[] = ['match' => ['city' => $data['place']]]; } }elseif($data['location']){ $google_places = new \Lib\GooglePlaces(\Config::googleplaces()->API_KEY); $cor = array($this->app->request->ipInfo['latitude'], $this->app->request->ipInfo['longitude']); $google_places->location = $cor; $google_places->radius = 100; $google_places->rankby = 'distance'; $google_places->types = '(cities)'; $google_places->input = $data['location']; $google_places_result = $google_places->autocomplete(); $searched_places_ids = array(); if($google_places_result['status'] == 'OK' AND count($google_places_result['predictions'])>0){ foreach($google_places_result['predictions'] as $__prediction){ $searched_places_ids[] = $__prediction['place_id']; } } if (count($searched_places_ids)) { $tmp = []; foreach ($searched_places_ids as $placeid) { $tmp[] = ['match' => ["city" => $placeid]]; } $must[] = ['bool' => ['should' => $tmp]]; } } if (count($data['tags'])) { foreach ($data['tags'] as $tag) { foreach ($matchTags as $type => $info) { $matchTags[$type]['should'][] = $tag; } } } foreach ($matchTags as $type => $info) { foreach ($info as $boolOperator => $tags) { // $boolOperator fills $must or $should arrays if (count($tags)) { foreach ($tags as $tag) { if ($type == "genres") { ${$boolOperator}[] = ['match' => ["tags.genres.{$lang}" => $tag]]; // this is for Pages ${$boolOperator}[] = ['match' => ["tags.genres_primary.{$lang}" => $tag]]; ${$boolOperator}[] = ['match' => ["tags.genres_secondary.{$lang}" => $tag]]; } elseif ($type == "instruments") { ${$boolOperator}[] = ['match' => ["tags.instruments_primary.{$lang}" => $tag]]; ${$boolOperator}[] = ['match' => ["tags.instruments_secondary.{$lang}" => $tag]]; } else { ${$boolOperator}[] = ['match' => ["tags.{$type}.{$lang}" => $tag]]; } /* this here was again because someone doesn't follow YAGNI if ($type == "genres") { $tmp[] = ['match_phrase' => ["tags.genres.{$lang}" => $tag]]; // this is for Pages $tmp[] = ['match_phrase' => ["tags.genres_primary.{$lang}" => $tag]]; $tmp[] = ['match_phrase' => ["tags.genres_secondary.{$lang}" => $tag]]; } elseif ($type == "instruments") { $tmp[] = ['match_phrase' => ["tags.instruments_primary.{$lang}" => $tag]]; $tmp[] = ['match_phrase' => ["tags.instruments_secondary.{$lang}" => $tag]]; } else { $tmp[] = ['match_phrase' => ["tags.{$type}.{$lang}" => $tag]]; } if ($tmp) { ${$boolOperator}[] = ['bool' => ['should' => $tmp]]; }*/ } } } } // if ($data['visible'] == 'profile_completed') { // $must[] = [ // 'term' => [ // 'visibility' => 'profile_completed' // ] // ]; // } if (count($pageTypeIds)) { $must[] = ['terms' => ['page_type_id' => $pageTypeIds]]; } if (count($must)) { $bool['must'] = $must; } if (count($should)) { $bool['should'] = $should; $bool['minimum_should_match'] = 1; // setting minimum_should_match would mess up the has_avatar boost } // if ($data['autocomplete']) { // $indexStr = \Config::elasticsearch()->INDICES->users . ',' . \Config::elasticsearch()->INDICES->pages; $indexStr = \Config::elasticsearch()->INDICES->users; // } else { // $indexStr = \Config::elasticsearch()->INDICES->users; // } // if ((int) $data['bands'] == 1 || count($pageTypeIds) || $data['show_pages'] || $data['type'] == "pages") { // $indexStr = \Config::elasticsearch()->INDICES->pages; // } if ($data['show_profiles'] /*|| $data['type'] == "people" */) { $indexStr = \Config::elasticsearch()->INDICES->users; } if (count($bool)) { // boost has_avatar. I personally argued that we should not boost, but rather filter by has_avatar, but it was pointless .. so enjoy // if (!isset($tagBoost)) { // NO SOLUTION for now ... // $bool['should'][] = ['term' => ['has_avatar' => ["value" => true, "boost" => 100 ]]]; // } // // enough BS // if ($indexStr == \Config::elasticsearch()->INDICES->users) { // $bool['should'][] = ['exists' => ['field' => 'tags.profile', 'boost' => 80]]; // $bool['should'][] = ['exists' => ['field' => 'tags.instruments_primary', 'boost' => 70]]; // $bool['should'][] = ['exists' => ['field' => 'tags.genres_primary', 'boost' => 60]]; // } else { // $bool['should'][] = ['exists' => ['field' => 'tags.genres', 'boost' => 80]]; // $bool['should'][] = ['exists' => ['field' => 'tags.influences', 'boost' => 70]]; // } $query = ["bool" => $bool]; } else { // empty search $bool = [ 'must' => [ ['match' => ['has_avatar' => true]] ] ]; // enough BS // if ($indexStr == \Config::elasticsearch()->INDICES->users) { // $boostTags = [ // ['exists' => ['field' => 'tags.profile', 'boost' => 80]], // ['exists' => ['field' => 'tags.instruments_primary', 'boost' => 70]], // ['exists' => ['field' => 'tags.genres_primary', 'boost' => 60]], // ]; // } else { // $boostTags = [ // ['exists' => ['field' => 'tags.genres', 'boost' => 80]], // ['exists' => ['field' => 'tags.influences', 'boost' => 70]], // ]; // } // if (isset($boostTags)) { // $bool['should'] = $boostTags; // } $query = [ 'function_score' => [ 'query' => ['bool' => $bool], 'random_score' => new \stdClass() ] ]; } $sort = [["_score" => "desc"]]; // second and third sort params were ["has_avatar" => "desc"], ["lastseen" => "desc"] they are insignificant $params = [ "from" => $offset, "size" => $results, "index" => $indexStr, // "explain" => 1, "body" => [ "query" => $query, "sort" => $sort, ] ]; //\Helpers\Debug::log('dht', json_encode($params)); $result = $dsm->search($params); if ((int) $data['count'] === 1) { //OMG all the legacy .. humanity $count = $result['hits']['total']; return array(true, $count); } else { return $this->viewSearchUsersAndPages($result, $searchStr); } } /* * @result DroobleSearchManager search result (Elastic client search result) * @searchStr - string from search (needed to 'inject' the search string as a Tag to all Users in the View) */ public function viewSearchUsersAndPages($result, $searchStr) { $lang = \Helpers\Basic::lang(); $hitIds = []; foreach ($result['hits']['hits'] as $item){ $hitIds[] = $item['_id']; } $hitIdsImploded = implode(",", $hitIds); $count = $result['hits']['total']; $ret = []; // get data for hits if ($count) { if (strlen($searchStr)) { $foundTag = \Helpers\Tags::findByText($searchStr, null); } $elsCtrl = new \Controllers\API\ElementsController(); $sql=" SELECT `search_cache`.`short_info_json` , `up`.`id`, `up`.`user_status`, `up`.`system_status`, `up`.`lastseen`, `up`.`is_page`, IF ( `ucm`.`id` IS NOT NULL, 1, 0 ) as `isInCircle` FROM `search_cache` JOIN `users_profiles` `up` ON `up`.`id` = `search_cache`.`user_id` LEFT JOIN `users_circles_members` `ucm` ON (`ucm`.`user_id` = :fuid AND `ucm`.`target_user_id` = `up`.`id`) WHERE `up`.`id` IN(" . $hitIdsImploded . ") ORDER BY FIELD(up.id, " . $hitIdsImploded . ") LIMIT " . $count . " ;"; $prepare = [ 'fuid' => $_SESSION['profile']['id'] ]; $qres = $this->app->db->query($sql, $prepare); $qres->setFetchMode(\Phalcon\Db::FETCH_ASSOC); $qelements = $qres->fetchAll(); foreach ($qelements as $el) { $a = json_decode($el['short_info_json'], true); if ($a != false) { $a['uid'] = $el['id']; $a['isInCircle'] = $el['isInCircle']; // $a['status'] = $el['publicStatus']; $a['is_page'] = $el['is_page']; // if ($a['rates']['session_price'] and $el['id'] != $_SESSION['profile']['id']) { // $a['rates']['session_price'] = floatval($a['rates']['session_price']) + floatval($a['rates']['session_price']) * ( \Config::defaults()->DROOBLE_FEE_IN_PERCENTS / 100 ); // } if ((int) $count >= 0) { $a['counter'] = $count; } $tags = \Helpers\Users::getUserTags($a['uid'], 3); // get with 3 - categorized with remapped type, cause otherwise you'll get random instruments (they have 4 subtypes) if ($a['uid'] == 1) { $a['open_to_string'] = "All music"; } else { $open_to_string = ""; if ( count($tags['profile']) > 1 ) { $open_to_string = $tags['profile'][0] . " " . $this->app->translate->get('and') . " " . $tags['profile'][1]; } elseif (count($tags['profile']) == 1) { $open_to_string = $tags['profile'][0]; } $a['open_to_string'] = $open_to_string; } $flatList = []; foreach ($tags as $arr) { foreach ($arr as $tag) { $flatList[] = $tag; } } if ($foundTag) { $searchAsTag = mb_convert_case(stripslashes($foundTag->translation->{$lang}->text), MB_CASE_TITLE, 'UTF-8'); if (!in_array($searchAsTag, array_slice($flatList, 0, 2))) { // 'inject' the search string as a Tag @ first position if it's not in the top 2 tags foreach ($tags as $key => $arr) { array_unshift($arr, $searchAsTag); $tags[$key] = $arr; break; } } } // remove duplicates $firstParts = array_slice($tags, 0, 3); $first3keys = array_keys($firstParts); $countTypes = count($first3keys); if ($countTypes > 1) { $tags[$first3keys[1]] = array_diff($tags[$first3keys[1]], $tags[$first3keys[0]]); } if ($countTypes > 2) { $tags[$first3keys[2]] = array_diff($tags[$first3keys[2]], $tags[$first3keys[1]]); $tags[$first3keys[2]] = array_diff($tags[$first3keys[2]], $tags[$first3keys[0]]); } $a['tags'] = $tags; $ret[] = $a; } } } return [true, $ret]; } public function getContacts($data) { return array(true, \Helpers\Search::getContactsAndTheRest($data['uid'], $data)); } } ?> |
#14 | search->search(Array(10)) /var/www/rc/drooble/trunk/projects/drooble_v1/services/web/private/logic/search.class.php (1113) <?php class search{ private $db; private $c; private $app; public function __construct($db,&$c, $app) { $this->db = $db; $this->c = $c; $this->app = $app; } /* public function doReindex($data){ $ret=array(); foreach($this->db->q("SELECT `id` FROM `users_profiles` WHERE 1") as $el){ $ret[]=$this->lib->profileSearchIndexing($el['id']); } return array(true,$ret); } */ public function searchCity($data) { $return = new \stdClass(); $return->items = \Helpers\Search::getInstance()->searchCity($data['name']); return array(true, $return); /* // SELECT *, CASE WHEN name LIKE 'Sofia%' THEN 1 ELSE 0 END AS keymatch FROM `cities` WHERE MATCH (name) AGAINST ('+Sofia' IN BOOLEAN MODE) ORDER BY keymatch DESC $cities = $this->app->db->fetchAll(" SELECT *, CASE WHEN search_by_me LIKE ".$this->app->db->escapeString($keywords)." THEN 4 WHEN search_by_me LIKE ".$this->app->db->escapeString($keywords." %")." THEN 3 WHEN search_by_me LIKE ".$this->app->db->escapeString("% ".$keywords." %")." THEN 2 WHEN search_by_me LIKE ".$this->app->db->escapeString("% ".$keywords)." THEN 1 ELSE 0 END AS keymatch FROM `cities` WHERE MATCH (search_by_me) AGAINST (".$this->app->db->escapeString($keywords).") ORDER BY keymatch DESC LIMIT 22 "); $items = array(); if ($cities) { foreach($cities as $city) { $title_suffix = $city['country']; if ($city['region']) { $title_suffix = $city['region'].", ".$city['country']; } $items[] = array( 'id' => $city['id'], 'title' => $city['name'].", ".$title_suffix, 'name' => $city['name'], 'country' => $city['country'], 'region' => $city['region'] ); } } $return->items = $items; return array(true, $return); */ } public function searchByMail($data){ $email=$data['email']; if(!filter_var($email, FILTER_VALIDATE_EMAIL)){ return array(false,"not valid"); } /* $search=$email; $search=str_replace("*","",$search); $search=str_replace(" ","",$search); $search=str_replace(")","",$search); $search=str_replace("(","",$search); $sql="SELECT `short_info` FROM `search_cache` WHERE MATCH (`email`) AGAINST ('".'"'.$search.'"'."')"; $r=$this->db->one($sql); * */ $person = \Models\UserCache::findFirst([ 'conditions' => 'email LIKE {email:str}', 'bind' => ['email' => $email] ]); if ($person) { return array(true, json_decode($person->short_info_json, true)); } else { return array(true,'notexists'); } } public function otherPersonContactsSuggester($data){ $user_id=\Helpers\Users::getIdFromUsername($data['profile']); if(isset($data['circle_id']) && $data['profile'] != $_SESSION['profile']['username']){ unset($data['circle_id']); } if(!$data['results']){ $data['results']=9; } if(isset($data['mix_order'])){ $data['mix_order']=true; } // \Helpers\Debug::alert($data['profile']); if($user_id){ return $this->ContactsSuggester($user_id,$data); }else{ return array(false); } } public function myContactsSuggester($data){ return $this->ContactsSuggester($_SESSION['profile']['id'],$data,true, isset($data['online_first']) ? $data['online_first'] : true); } public function otherPersonFollowSuggester($data) { $data["filterUsername"] = $data["profile"]; unset($data["profile"]); $data["follow_type"] = "followings"; return $this->ContactsSuggester($_SESSION['profile']['id'],$data,true, false); } public function searchInMyMessages($data){ // Used data $user_id = (int)$_SESSION['profile']['id']; if ($data['band_id'] > 0) { if (!\Helpers\Basic::checkUserRights((int) $data['band_id'], $user_id)) { return array(false,false); } else { $user_id = (int) $data['band_id']; } } $offset = $data['offset']; $limit = $data['limit']; $search = trim(strip_tags($data['search'])); $search = str_replace(array("%", "'", '"'), "", $search); $length_to_get = 50; // How much characters to get $symbols_before = 10; // How much symbols before match to get $return = array(); // Search query $query = " SELECT * FROM ( SELECT um.text, um.conversations_id, c.is_group, c.members, IF (um.reciever_id = '".$user_id."', scsender.short_info_json, screciever.short_info_json) as partner, IF (um.reciever_id = '".$user_id."', scsender.user_id, screciever.user_id) as partner_id FROM users_messages as um LEFT JOIN conversations AS c ON c.id = um.conversations_id LEFT JOIN search_cache AS scsender ON scsender.user_id = um.sender_id LEFT JOIN search_cache AS screciever ON screciever.user_id = um.reciever_id WHERE um.sender_id != um.reciever_id AND (um.sender_id = '".$user_id."' OR um.reciever_id = '".$user_id."') AND um.is_deleted=0 AND ( um.text LIKE :keywords OR (scsender.cache LIKE :keywords AND scsender.user_id != '".$user_id."') OR (screciever.cache LIKE :keywords AND screciever.user_id != '".$user_id."') ) ORDER BY um.send_time DESC ) as results GROUP BY results.conversations_id, results.text, results.partner, results.partner_id "; $prepare = array( 'keywords' => "%".$search."%" ); // Here we store user information - reason - when we have a user, does not look for it again $cache_profiles = array(); // So... lets begin... just in case string was more than 3 symbols if (mb_strlen($search) >= 3) { $cids = []; // Put information foreach($this->db->prepare($query, $prepare)->execute()->fetchAllAssoc()->cache( 1 )->result as $el) { $cids[] = $el['conversations_id']; continue; // !!!! NOTE we'll be using getMail at end of func to parse the response //this below -- NOT executed !!! $text = trim(strip_tags($el['text'])); $find_position = mb_strpos($search, $text); $text_length = mb_strlen($text); $string_length = mb_strlen($search); // Stupid way but... i cant regex :/ if ($text_length > $length_to_get) { if (($find_position - $symbols_before) <= 0) { $text = mb_substr($text, 0, $length_to_get)."..."; } else if (($find_position - $symbols_before) > 0 AND ($find_position - $symbols_before + $length_to_get) <= $text_length) { $text = "...".mb_substr($text, ($find_position - $symbols_before), $length_to_get)."..."; } else { $text = "...".mb_substr($text, ($length_to_get*-1)); } } $line = array( 'quote' => $text, 'conversation' => "#".$el['conversations_id'] ); // Put information about users in converstation if ((int)$el['is_group'] == 0) { if (!isset($cache_profiles[$el['partner_id']])) { $user = unserialize($el['partner']); $cache_profiles[$el['partner_id']] = array( 'names' => $user['display_name'] ); if (isset($user['avatar_icon']) AND $user['avatar_icon'] != "") { $cache_profiles[$el['partner_id']]['avatar_icon'] = $user['avatar_icon']; } } $line['names'] = $cache_profiles[$el['partner_id']]['names']; $line['avatar_icon'] = $cache_profiles[$el['partner_id']]['avatar_icon']; } else { // Check collection $collection = array(); $user_ids = explode(",", $el['members']); foreach($user_ids as $key => $val) { if ((int)$val != 0 AND (int)$val != $user_id) { $collection[(int)$val] = false; } } // Filter which users we have $search_user_ids = array(); foreach($collection as $key => $val) { if (isset($cache_profiles[$key])) { // Put it in our collection $collection[$key] = $cache_profiles[$key]['names']; } else { $search_user_ids[] = $key; } } // Get missed users if (!empty($search_user_ids)) { $query = "SELECT user_id, short_info_json FROM search_cache WHERE user_id IN (".implode(",", $search_user_ids).")"; foreach($this->db->prepare($query, array())->execute()->fetchAllAssoc()->cache( 1 )->result as $usr) { $user = json_decode($usr['short_info_json'], true); $cache_profiles[(int)$usr['user_id']] = array( 'names' => $user['display_name'] ); if (isset($user['avatar_icon']) AND $user['avatar_icon'] != "") { $cache_profiles[(int)$usr['user_id']]['avatar_icon'] = $user['avatar_icon']; } // Put it in our collection $collection[(int)$usr['user_id']] = $cache_profiles[(int)$usr['user_id']]['names']; } } // Now merge names $line['names'] = implode(", ", $collection); $line['avatar_icon'] = DEF_GROUP_CHAT_ICON; } // Some modifications // $text = str_replace($search, "<em>".$search."</em>", $text); $seek_and_destroy = '#\b'.$search.'\b#iu'; $line['quote'] = preg_replace($seek_and_destroy, '<em>$0</em>', $line['quote']); $line['names'] = preg_replace($seek_and_destroy, '<em>$0</em>', $line['names']); $return[] = $line; } } // NOTE!! overwrite response here $mc = new \Controllers\API\MessengerController(); $cids = array_reverse($cids); $cids = array_slice($cids, $offset, $limit); $getMailData = [ 'folder' => 'All', 'mode' => 'search', 'results' => $limit, 'cids' => $cids, 'pid' => $data['band_id'] ]; $getMailRe = $mc->getMail($getMailData); $return = is_array($getMailRe) ? $getMailRe : ['conversations' => []]; // Return return array(true, array("length" => count($return['conversations']) , "conversations" => $return['conversations'])); } private function ContactsSuggester($user_id,$data,$myContactsOnly=false, $onlineFirst = false){ $uid=$user_id; $prepare=array(); $excludeMothership = array_key_exists('exclude_mothership', $data) ? $data['exclude_mothership'] : true; // $prepare['uid']=$uid; $search=$data['search']; /*if (empty($search)) { return array(false, 'empty search query'); }*/ $select = array(); $leftJoin = array(); $order = array(); if($myContactsOnly){ $data['follow_type']='followings'; } $search=trim($search); $search=str_replace("*","",$search); $search=str_replace(")","",$search); $search=str_replace("(","",$search); $search=str_replace(" ","* +*",$search); if($search){ $search=$this->db->quote("*".$search."*"); }else{ $search=NULL; } $circle_id=$data['circle_id']; // $prepare['circle_id']=$circle_id; $show_status=$onlineFirst ? true : $data['show_status']; $latest=isset($data['latest']) ? true : false; $is_online=$data['is_online']; $mix_order=$data['mix_order']; $where = [ '`up`.`is_banned` IS NULL AND `up`.`is_disabled` = 0' ]; if($is_online){ $show_status=1; $where[]="(`up`.`user_status`>0 AND `up`.`lastseen`> " . (time() - \Config::defaults()->DEF_LASTSEEN_OFFLINE_TIME).") "; } if (isset($data["user_type"])) { // $LeftJoinUserStatus="LEFT JOIN `users_profiles` AS `up` ON `up`.`id` = `sc`.`user_id` "; // if ($data["user_type"] == "page") { // $where[] = "`up`.`is_page` = 1"; // } else if ($data["user_type"] == "user") { // $where[] = "`up`.`is_page` IS NULL"; // } } if(isset($show_status)){ $SelectUserStatus=" fn_calculateProfilePublicStatus(`up`.`user_status`,`up`.`system_status`,`up`.`lastseen`) as `publicStatus`, `up`.`id` as `user_suggest_id`, if(`chat_status` > 0,fn_calculateProfilePublicStatus(`user_status`, `system_status`, `lastseen`),0) as `cstatus`,"; //$SelectUserStatus="`up`.`user_status`, `up`.`lastseen`, `up`.`system_status`, "; // $LeftJoinUserStatus="LEFT JOIN `users_profiles` AS `up` ON `up`.`id` = `sc`.`user_id` "; $where[] = "`up`.`is_page` IS NULL"; } if ( $data['gender'] ) { $select[] = "`up`.`gender`"; // if ( !$LeftJoinUserStatus ) { // $leftJoin[] = "LEFT JOIN `users_profiles` AS `up` ON `up`.`id` = `sc`.`user_id` "; // } } if ( $data['is_page'] ) { //\Helpers\Debug::log('is_page passed'); $select[] = "`up`.`is_page`"; // if ( !$LeftJoinUserStatus ) { // $leftJoin[] = "LEFT JOIN `users_profiles` AS `up` ON `up`.`id` = `sc`.`user_id` "; // } } if ( $data['pictures_first'] ) { $select[] = 'IF(`upi`.`id`, 1, 0) AS `has_picture`'; // moje da stane greshka, zashtoto ne znaeme koi e profile album-a //$leftJoin[] = "LEFT JOIN `users_pictures` AS `upi` ON ( `upi`.`user_id` = `sc`.`user_id` AND `upi`.`profilepic` = 1 ) "; $leftJoin[] = "LEFT JOIN `users_elements` AS `upi` ON `sc`.`id` = `upi`.`creator_id` AND `upi`.`type`='picture' AND `upi`.`is_default` = '1' AND `upi`.`deleted_time` IS NULL AND `upi`.`published_time` IS NOT NULL AND `upi`.`deployed_time` IS NOT NULL "; $order[] = '`has_picture` DESC'; } if ( $data['compare_followers'] && in_array($data['follow_type'], array('followers', 'followings')) && isset($_SESSION['profile']['id']) ) { $select[] = 'IF(`my_ucm`.`id`, 1, 0) AS `same_follower`'; $select[] = 'IF(`my_ucm`.`id`, `my_ucm`.`circle_id`, -1) AS `circle_id`'; $leftJoin[] = "LEFT JOIN `users_circles_members` AS `my_ucm` ON ( `my_ucm`.`user_id` = " . $_SESSION['profile']['id'] . " AND `my_ucm`.`target_user_id` = " . ( $data['follow_type'] == 'followers' ? "`ucm`.`user_id`" : "`ucm`.`target_user_id`" ) . " ) "; $order[] = '`same_follower` DESC'; } if ($data['filterUsername']) { $otherUserId = \Helpers\Users::getIdFromUsername($data['filterUsername']); if ($otherUserId) { $leftJoin[] = "LEFT JOIN `users_circles_members` AS `other_ucm` ON ( `other_ucm`.`user_id` = " . $otherUserId . " AND `other_ucm`.`target_user_id` = `ucm`.`target_user_id` ) "; $where[] = "`other_ucm`.`id` IS NULL"; $where[] = "`up`.`id` != {$otherUserId}"; } } switch($data['follow_type']){ case "followers": $where[]="`ucm`.`target_user_id` = '{$uid}'"; $leftJoinCS="LEFT JOIN `search_cache` AS `sc` ON `sc`.`user_id` = `ucm`.`user_id`"; break; case "followings": $where[]="`ucm`.`user_id` = '{$uid}'"; $leftJoinCS="LEFT JOIN `search_cache` AS `sc` ON `sc`.`user_id` = `ucm`.`target_user_id`"; break; default: $leftJoinCS="LEFT JOIN `search_cache` AS `sc` ON (`sc`.`user_id` = `ucm`.`target_user_id` OR `sc`.`user_id` =`ucm`.`user_id`)"; } $limit = " "; if(isset($data["limit"])){ $prepare['limit']=$data['limit']; $limit = " LIMIT :limit "; if (isset($data["offset"])) { $prepare['offset']=$data['offset']; $limit .= "OFFSET :offset "; } } if($search){ $where[]="MATCH (`cache`) AGAINST ($search IN BOOLEAN MODE)"; } if($circle_id and $circle_id!='All'){ $where[]="`uc`.`id` = '{$circle_id}'"; } $where[] ="`sc`.`user_id`!= '{$uid}'"; if ( $uid != 1 && $excludeMothership) { $where[]="`ucm`.`target_user_id` != 1"; } if (isset($data['exclude_ids'])) { $exclude = is_array($data['exclude_ids']) ? implode(',', $data['exclude_ids']) : $data['exclude_ids']; if ( strlen($exclude) > 0 ) { $where[]="`ucm`.`target_user_id` NOT IN ($exclude)"; } } $where = implode(" AND ",$where); if($where=='') $where = '1'; if ($latest) { $order[] = "`ucm`.`create_time` DESC"; } if ($onlineFirst) { $order[]='FIELD(`publicStatus`, 2) DESC'; $order[]='`up`.`first_name`'; $order[]='`up`.`last_name`'; } if(isset($mix_order)) { $order[]='RAND()'; } if ( count($select) > 0 ) { $select = implode(', ', $select) . ','; } else { $select = ''; } $leftJoin = implode(' ', $leftJoin); if ( count($order) > 0 ) { $order = 'ORDER BY ' . implode(', ', $order); } else { $order = ''; } $sql="SELECT {$select} {$SelectUserStatus} `sc`.`short_info_json`, `uc`.`name` as `circle_name`, `ucm`.`target_user_id` FROM `users_circles_members` AS `ucm` {$leftJoinCS} {$LeftJoinUserStatus} {$leftJoinProfiles} {$leftJoin} LEFT JOIN `users_circles` AS `uc` ON `uc`.`id` = `ucm`.`circle_id` LEFT JOIN `users_profiles` AS `up` ON `up`.`id` = `sc`.`user_id` WHERE ( {$where} ) AND `sc`.`is_disabled` = 0 /*AND `ucm`.`target_user_id`!='1'*/ GROUP BY `sc`.`id` {$order} {$limit} "; // \Helpers\Debug::log($sql); // echo $sql; $ret=array(); //foreach($this->db->q($sql,$prepare) as $el){ $cache = isset($data['cache']) ? $data['cache'] : 1; // echo print_r(array($sql, $prepare), 1); // \Helpers\Debug::log($sql); if (isset($prepare["limit"])) $prepare["limit"] = intval($prepare["limit"]); if (isset($prepare["offset"])) $prepare["offset"] = intval($prepare["offset"]); $mem_before = memory_get_usage(); $res = $this->db->prepare($sql,$prepare)->execute()->fetchAllAssoc()->result; // \Helpers\Debug::log("Memory used by the contacts array: ", memory_get_usage() - $mem_before); // $res = $this->db->prepare($sql,$prepare)->execute()->fetchAllAssoc()->cache( $cache )->result; // echo "$sql - " . print_r($prepare,1); foreach($res as $el){ $a=json_decode($el['short_info_json'], true); if($show_status){ $status=array(); $statuses=unserialize(USER_STATUS_STATEMENTS); $status['status_id']=$el['publicStatus']; $status['status_name']=$statuses[$status['status_id']]; $chatStatus=array(); $chatStatus['status_id']=$el['cstatus']; $chatStatus['status_name']=$statuses[$chatStatus['status_id']]; $a['status']=$status; $a['chat_status']=$chatStatus; } if($a!=false){ $a['gender'] = $el['gender']; $a['has_picture'] = $el['has_picture']; $a['same_follower'] = $el['same_follower']; $a['circle_id'] = $el['circle_id']; //Compatibility $a['profile_tags'] = $a['tags']['profile']; if($el['user_id'] == $_SESSION['profile']['id'] and $uid == $_SESSION['profile']['id']){ $a['circle']=$el['circle_name']; } $ret[]=$a; } } return array(true,array("profiles"=>$ret)); //return array(true,array("profiles"=>$ret),str_replace("\t","",str_replace("\n", "", $sql)),$prepare); //return array(true,$ret); } public function chatBarSuggester($data) { $uid = (int)$_SESSION['profile']['id']; $limit = isset($data['limit']) ? $data['limit'] : 15; $return = array(); $query = " SELECT DISTINCT `sender_id`, `reciever_id`, /*fn_calculateProfilePublicStatus(`up`.`user_status`,`up`.`system_status`,`up`.`lastseen`) as `publicStatus`,*/ if(`chat_status` > 0,fn_calculateProfilePublicStatus(`user_status`, `system_status`, `lastseen`),0) as `cstatus` FROM `users_messages` AS `um` JOIN `conversations` AS `c` ON (`um`.`conversations_id` = `c`.`id`) LEFT JOIN `users_profiles` AS `up` ON `up`.`id` = IF(`sender_id` = :uid, `reciever_id`, `sender_id`) WHERE (`sender_id` = :sid OR `reciever_id` = :rid) AND `sender_id` <> `reciever_id` AND `up`.`is_page` IS NULL GROUP BY `um`.`conversations_id` ORDER BY `send_time` DESC LIMIT 0,$limit"; $prep = array("uid" => $uid, "sid" => $uid, "rid" => $uid); $result = $this->db->prepare($query, $prep)->execute()->fetchAllAssoc()->result; $exclude = array(); $statuses=unserialize(USER_STATUS_STATEMENTS); $chatstatuses=unserialize(CHAT_STATUS_STATEMENTS); foreach ( $result as $r ) { $id = $r['sender_id'] == $uid ? $r['reciever_id'] : $r['sender_id']; $user = \Helpers\Users::getUserShortInfoFromId($id); $status=array(); $status['status_id']=\Helpers\Users::getInstance()->getProfilePublicStatus($id);//$r['publicStatus']; $status['status_name']=$statuses[$status['status_id']]; $chatStatus=array(); $chatStatus['status_id']=\Helpers\Users::getInstance()->getProfilePublicChatStatus($id); $chatStatus['status_name']=$chatstatuses[$chatStatus['status_id']]; $user['status']=$status; $user['chat_status']=$chatStatus; if (!in_array($id, $exclude)) { $return[] = $user; $exclude[] = $id; //\Helpers\Debug::log($id,$status); } } if ( count($return) < $limit ) { $data["limit"] = $limit - count($return); $data["exclude_ids"] = $exclude; $additional = $this->myContactsSuggester($data); if ($additional[0] && count($additional[1]['profiles']) > 0) { $return = array_merge($return, $additional[1]['profiles']); } } foreach ( $return as &$r ) { $r['profile_tags'] = $r['tags']['profile']; } return array(true, array("profiles" => $return)); } /* DEPRECATED public function followSuggester($data) { return array(true); $users = array(); $offset = $data['offset'] || 0; $lat = $this->app->request->ipInfo["latitude"]; $long = $this->app->request->ipInfo["longitude"]; $userTags = array(); //$results = $this->db->q( "SELECT `name`, `type` FROM `users_tags` WHERE `user_id` = :uid", array("uid" => $_SESSION['profile']['id'])); $results = $this->db->prepare( "SELECT `name`, `type` FROM `users_tags` WHERE `user_id` = :uid", array("uid" => $_SESSION['profile']['id']))->execute()->fetchAllAssoc()->cache()->result; foreach ( $results as $el ) { $userTags[ $el[ 'type' ] ][] = ucwords(strtolower($el['name'])); } // foreach ( $userTags as $k => $e ) { // $tagsCache[$k] = implode( " ", str_replace( " ", "_", $e ) ); // } $query = " SELECT `upr`.`id` as `user_id`, `sc`.`short_info`, " . ( ( $lat != 0 && $long != 0 ) ? "IF ( " . ($lat - 10) . " < `upr`.`lat` AND `upr`.`lat` < " . ($lat + 10) . " AND " . ($long - 10) . " < `upr`.`long` AND `upr`.`long` < " . ($long + 10) . ", 1, 0 )" : "0" ) . " as `is_near`, MATCH (instruments) AGAINST (:instruments IN NATURAL LANGUAGE MODE) AS score_instruments, MATCH (genres) AGAINST (:genres IN NATURAL LANGUAGE MODE) AS score_genres, MATCH (influences) AGAINST (:influences IN NATURAL LANGUAGE MODE) AS score_influences, IF ( `ucm`.`id` IS NOT NULL, 1, 0 ) as `followed`, IF ( `uc`.`id` IS NOT NULL, 1, 0 ) as `has_posts` FROM `users_profiles` `upr` JOIN `users_elements` `upi` ON (`upr`.`id` = `upi`.`creator_id` AND `upr`.`profile_album_id` = `upi`.`album_id` AND `upi`.`type`='picture' AND `upi`.`is_default` = '1' AND `upi`.`deleted_time` IS NULL AND `upi`.`published_time` IS NOT NULL AND `upi`.`deployed_time` IS NOT NULL) JOIN `search_cache` `sc` ON (`sc`.`user_id` = `upr`.`id`) LEFT JOIN `users_comments` `uc` ON (`uc`.`owner_element_id` = `upr`.`id` AND `uc`.`model` = 'post') LEFT JOIN `users_circles_members` `ucm` ON (`ucm`.`user_id` = :uid AND `ucm`.`target_user_id` = `upr`.`id`) WHERE `upr`.`id` != :uuid GROUP BY `uc`.`owner_element_id` HAVING `followed` = 0 ORDER BY `score_genres` DESC, `score_influences` DESC, `score_instruments` DESC, `is_near` DESC, `has_posts` DESC LIMIT :offset, 9 "; $results = $this->db->prepare($query, array( 'offset' => $offset, 'uid' => $_SESSION['profile']['id'], 'uuid' => $_SESSION['profile']['id'], 'genres' => ( isset( $userTags['genres'] ) ? implode( " ", str_replace( " ", "_", $userTags['genres'] ) ) : '' ), 'instruments' => ( isset( $userTags['instruments'] ) ? implode( " ", str_replace( " ", "_", $userTags['instruments'] ) ) : '' ), 'influences' => ( isset( $userTags['influences'] ) ? implode( " ", str_replace( " ", "_", $userTags['influences'] ) ) : '' ) ))->execute()->fetchAllAssoc()->cache()->result; foreach ( $results as $result ) { $user = unserialize( $result['short_info'] ); if ( $user != false ) { $users[] = $user; } } return array(true, $users); }*/ public function searchSuggester($data) { $results = isset($data['limit']) ? $data['limit'] : \Config::defaults()->RESULTS_TO_SHOW->search; if ($results > \Config::defaults()->MAX_RESULTS_TO_SHOW->search) { $results = \Config::defaults()->MAX_RESULTS_TO_SHOW->search; } $reminder = $result % 2; $search = $data['autocomplete']; $msc = microtime(true); if (!isset($data['skipTags']) || !$data['skipTags']) { $tags = $this->tagsSuggester(array('autocomplete' => $search, 'limit' => (int) ($results / 2) + $reminder)); } $profiles = []; $pages = []; if (isset($data['skipPages']) || $data['skipPages'] == 'true') { // legacy string true $profilesRes = $this->search(array('autocomplete' => $search, 'show_profiles' => true, 'visible' => $data['visible'])); if ($profilesRes[0]) { $profiles = $profilesRes[1]; } } else { // search both users and pages and separate them here $searchRes = $this->search(['autocomplete' => $search, 'visible' => $data['visible']]); if ($searchRes[0]) { foreach ($searchRes[1] as $i => $sr) { if ($i == 0) { $firstType = $sr['is_page'] ? "page" : "profile"; } if ($sr['is_page']) { $pages[] = $sr; } else { $profiles[] = $sr; } } } } $communities = \Helpers\Tags::getCommunities(null, false, $search, $results); $sCtrl = new \Controllers\API\SearchController(); $posts = $sCtrl->searchPosts($data); $msc=microtime(true)-$msc; $res=array(); $res['profiles'] = $profiles; $res['pages'] = $pages; $res['posts'] = $posts; $res['communities'] = $communities; $res['tags'] = $tags[0] ? $tags[1]['tags'] : array(); $res['first_type'] = isset($firstType) ? $firstType : false; return array(true, $res); } public function getFacebookFriends () { $uid = (int)$this->app->session->profile['id']; $friends = \Helpers\Users::getUnfollowedFacebookFriends($uid); return [true, $friends]; } //polzva se samo za chat-a, no i tam e spriano i vrushta [] public function generatePeopleSuggestions ($data) { return array(true,[]); if (isset($data['chat'])) { $uid = $_SESSION["profile"]["id"]; $usedUids = []; if (isset($data['used_ids']) AND is_array($data['used_ids'])) { $usedUids = $data['used_ids']; } $result = [ 'explore' => \Helpers\Suggestions::generateExploreSuggestions($uid, $usedUids) ]; return array(true, $result); } if (!isset($data["sideMenu"]) && !isset($data["explore"])) { return array( "sideMenu" => array(), "explore" => array() ); } $result = \Helpers\Suggestions::generateSuggestions($_SESSION['profile']['id'], $data["sideMenu"], $data["explore"]); if (!$result) { return array(false, "insert/update failed"); } return array(true, $result); } public function tagsSuggesterDEPRECATED($data){ // DEPRECATED !!!!!! ! !! ! // DONE elasticsearch! $search=trim($data['search']); $type = $data['type']; if(!$search) return array(true,array()); if ( strlen($search) < 3 ) { return [true, []]; } $limit = isset($data['limit']) ? intval($data['limit']) : \Config::defaults()->RESULTS_TO_SHOW->search; if($limit > \Config::defaults()->MAX_RESULTS_TO_SHOW->search){ $limit = \Config::defaults()->MAX_RESULTS_TO_SHOW->search; } $offset = isset($data['offset']) ? intval($data['offset']) : 0; $lang = \Helpers\Basic::lang(); $regex = new \MongoDB\BSON\Regex('^'.$search, 'i'); if ($type == "" || $type == "all") { $conditions = [ "translation.{$lang}.text" => $regex, ]; $project = [ "type" => 1, 'translation' => 1, 'posts_rating' => ['$sum' => ['$type.posts.moderator_rating', '$type.posts.user_rating']], 'profile_rating' => ['$sum' => ['$type.profile.moderator_rating', '$type.profile.user_rating']], 'instruments_rating' => ['$sum' => ['$type.instruments.moderator_rating', '$type.instruments.user_rating']], 'influences_rating' => ['$sum' => ['$type.influences.moderator_rating', '$type.influences.user_rating']], 'equipment_rating' => ['$sum' => ['$type.equipment.moderator_rating', '$type.equipment.user_rating']], 'genres_rating' => ['$sum' => ['$type.genres.moderator_rating', '$type.genres.user_rating']], 'rating' => ['$max' => ['$posts_rating', '$profile_rating', '$instruments_rating', '$influences_rating', '$equipment_rating', '$genres_rating']], ]; } else { $conditions = [ "translation.{$lang}.text" => $regex, ]; $project = [ "type.{$type}" => 1, 'translation' => 1, 'rating' => ['$sum' => ['$' . "type.{$type}." . 'moderator_rating', '$' . "type.{$type}." . 'user_rating']] ]; } $res = \Collections\Tags::aggregate([ ['$match' => $conditions], ['$project' => $project], ['$sort' => ['rating' => -1]], ['$skip' => $offset], ['$limit' => $limit], ]); $tags = []; foreach ($res as $tag) { $tagName = mb_convert_case(stripslashes($tag->translation->{$lang}->text), MB_CASE_TITLE, 'UTF-8'); foreach ($tag->type as $type => $notneed) { $tags[$type][] = ['index' => \Helpers\Tags::transformIndex($tagName), "url" => \Helpers\Basic::getUrl($tagName, $type), "name"=> $tagName ]; } } return array(true,array("tags"=>$tags)); } public function tagsSuggester($data) { $search = trim($data['search']); $type = $data['type']; if (!$search) { return [true, []]; } if (strlen($search) < 3) { return [true, []]; } $limit = isset($data['limit']) ? intval($data['limit']) : \Config::defaults()->RESULTS_TO_SHOW->search; if ($limit > \Config::defaults()->MAX_RESULTS_TO_SHOW->search) { $limit = \Config::defaults()->MAX_RESULTS_TO_SHOW->search; } $offset = isset($data['offset']) ? intval($data['offset']) : 0; $lang = \Helpers\Basic::lang(); $sort = [["rating" => "desc"]]; $bool = []; if (strlen($type) && $type != 'all') { $tagTypes = unserialize(TAGS_TYPES); if (!in_array($type, $tagTypes)) { return [true, []]; } $bool['filter'] = [ 'term' => [ 'types' => $type ] ]; } $bool["must"] = [ [ "match_phrase_prefix" => [ "text" => $search ] ] ]; $query = ["bool" => $bool]; $params = [ "from" => $offset, "size" => $limit, "index" => \Config::elasticsearch()->INDICES->tags->{$lang}, // "explain" => 1, "body" => [ "query" => $query, "sort" => $sort, ] ]; $dsm = $this->app->droobleSearchManager; $result = $dsm->search($params); $tags = []; foreach ($result['hits']['hits'] as $item){ $tagName = mb_convert_case(stripslashes($item['_source']['text']), MB_CASE_TITLE, 'UTF-8'); $tags[$type][] = ["name"=> $tagName ]; } return [true, ['tags' => $tags]]; } // looks like I did this to track stuff for Segment, without making too many requests (due to the $data['count'] that is used for counting search results, // but now it just wraps the search() func public function advancedSearchPage($data){ $searchStr = strlen(trim($data['autocomplete'])) ? $data['autocomplete'] : trim($data['search']); $properties =array( "category" => 'Home page', "search_query" => "'".$searchStr."'" ); if (isset($data['profile']) && is_array($data['profile'])) { // create Segment properties from search tags foreach ($data['profile'] as $tag) { if (preg_match('/^[0-9a-z\s]+$/i', $tag)) { $properties[ preg_replace('/\s+/', '_', strtolower($tag)) ] = true; } } } // why not just 0/1 ? ... strings 'true' | 'false' if(isset($data['bands']) && ($data['bands'] == 'true' or $data['bands'] == true)){ $properties['bands'] = true; } if(isset($data['venues']) && ($data['venues'] == 'true' or $data['venues'] == true)){ $properties['venues'] = true; } if(isset($data['clubs']) && ($data['clubs'] == 'true' or $data['clubs'] == true)){ $properties['clubs'] = true; } if(isset($data['recording_studios']) && ($data['recording_studios'] == 'true' or $data['recording_studios'] == true)){ $properties['recording_studios'] = true; } if(isset($data['rehearsal_space']) && ($data['rehearsal_space'] == 'true' or $data['rehearsal_space'] == true)){ $properties['rehearsal_space'] = true; } if(isset($data['music_school']) && ($data['music_school'] == 'true' or $data['music_school'] == true)){ $properties['music_school'] = true; } if(isset($data['jam']) && ($data['jam'] == 'true' or $data['jam'] == true)) { $properties['jammers'] = true; } if(isset($data['teach']) && ($data['teach'] == 'true' or $data['teach'] == true)){ $properties['teachers'] = true; if (isset($data['price_min'])) { $properties['price_min'] = $data['price_min']; } if (isset($data['price_max'])) { $properties['price_max'] = $data['price_max']; // When its picked maximum of 150+... if ((int)$data['price_max'] == 150) { $properties['price_max'] = 999; } } } if(isset($data['available']) && ($data['available'] == 'true' or $data['available'] == true)){ $properties['available'] = true; } if(isset($data['looking_bandmates']) && ($data['looking_bandmates'] == 'true' or $data['looking_bandmates'] == true)){ $properties['looking_bandmates'] = true; } if(isset($data['instruments']) && $data['instruments']){ $properties['instruments'] = $data['instruments']; } if(isset($data['instruments_primary_to_join']) && $data['instruments_primary_to_join']){ $properties['instruments_primary_to_join'] = $data['instruments_primary_to_join']; } if(isset($data['instruments_primary_for_bandmates']) && $data['instruments_primary_for_bandmates']){ $properties['instruments_primary_for_bandmates'] = $data['instruments_primary_for_bandmates']; } if(isset($data['genres']) && $data['genres']){ $properties['genres'] = $data['genres']; } if(isset($data['influences']) && $data['influences']){ $properties['influences'] = $data['influences']; } if(isset($data['equipment']) && $data['equipment']){ $properties['equipment'] = $data['equipment']; } if(isset($data['languages']) && $data['languages']){ $properties['languages'] = $data['languages']; } if(isset($data['location']) && $data['location']){ $properties['location'] = $data['location']; } if(isset($data['place']) && $data['place']){ $properties['place'] = $data['place']; } $track = array(); $track['event'] = "Advanced Search"; if($this->app->session->has('profile')){ $track['userId'] = $this->app->session->get('profile')['id']; }else{ // $track['anonymousId'] = rand(100000,999999); } $track['properties'] = $properties; if( $this->app->session->has('profile') && (!isset($data['count']) or $data['count'] == 2) ){ if(!$_COOKIE["druast"]) { $secureConnection = strtolower(\Helpers\Basic::getInstance()->get_php_http_scheme()) == 'https' ? true : false; setcookie("druast", date("Y-m-d"), time() + 60 * 60, '/', NULL, $secureConnection, true); // 60 minutes \Drooble\Activities\Activities::add( "advancedSearch", $track['userId'], (object) ['type' => 'user', 'id' => $track['userId']], ['segment' => ['track' => $track]] ); } } return $this->search($data); } // $data['autocomplete'] string - the search works as autocomplete e.g. Joh -> John // $data['search'] string - the search works as search (bad at autocomplete, but with more accurate results) // TODO - think if possible to use instead of getContacts - you'll need your 'followings/folloers' on top of results public function search($data) { $go_search=false; foreach(array_keys($data) as $e){ if(!in_array($e, array_keys( get_object_vars( \Config::api()->MAP->search->data ) ))){ return array(false,"input error1 '".$e."'"); } if($data[$e]){ $go_search=true; } } if(!$go_search){ return array(false,"empty search"); } $dsm = $this->app->droobleSearchManager; $lang = \Helpers\Basic::lang(); $analyzer = strtolower(\Config::languages()->language->{$lang}->name_in_english); $offset = $data['offset'] ? $data['offset'] : 0; $results = isset($data['limit']) ? $data['limit'] : \Config::defaults()->RESULTS_TO_SHOW->search; if($results > 100){ // way too many $results = \Config::defaults()->MAX_RESULTS_TO_SHOW->search; } $count = false; $pageTypeIds = []; $matchTags = [ 'profile' => [], 'instruments' => [], 'genres' => [], 'equipment' => [], 'influences' => [], 'languages' => [], 'instruments_primary_to_join' => [], 'instruments_primary_for_bandmates' => [], ]; if ((int) $data['venues'] == 1) { $pageTypeIds[] = 106; } if ((int) $data['clubs'] == 1) { $pageTypeIds[] = 107; } if ((int) $data['music_school'] == 1) { $pageTypeIds[] = 120; } if ((int) $data['recording_studios'] == 1) { $pageTypeIds[] = 115; } if ((int) $data['rehearsal_space'] == 1) { $pageTypeIds[] = 128; } if (is_array($data['instruments']) AND ! empty($data['instruments'])) { foreach ($data['instruments'] as $item) { $matchTags['instruments']['should'][] = $item; } } if (is_array($data['genres']) AND ! empty($data['genres'])) { foreach ($data['genres'] as $genre) { $matchTags['genres']['should'][] = $genre; } } if (is_array($data['equipment']) AND ! empty($data['equipment'])) { foreach ($data['equipment'] as $item) { $matchTags['equipment']['should'][] = $item; } } if (is_array($data['influences']) AND ! empty($data['influences'])) { foreach ($data['influences'] as $item) { $matchTags['influences']['should'][] = $item; } } if (is_array($data['languages']) AND ! empty($data['languages'])) { foreach ($data['languages'] as $item) { $matchTags['languages']['should'][] = $item; } } // these are reversed ... to match users who want to play an instrument and bands that are looking for the same if (is_array($data['instruments_primary_to_join']) AND ! empty($data['instruments_primary_to_join'])) { foreach ($data['instruments_primary_to_join'] as $item) { $matchTags['instruments_primary_for_bandmates']['should'][] = $item; } } if (is_array($data['instruments_primary_for_bandmates']) AND ! empty($data['instruments_primary_for_bandmates'])) { foreach ($data['instruments_primary_for_bandmates'] as $item) { $matchTags['instruments_primary_to_join']['should'][] = $item;// } } if (is_array($data['profile']) AND !empty($data['profile'])) { $tmp = array(); foreach ($data['profile'] as $el) { if (!trim($el)) continue; // Some predefined // TODO config with translations in all languages VS cache ... if ($el == $this->app->translate->get('drummers')) { $tag = \Helpers\Tags::findByText('drums', null); if ($tag) { $matchTags['instruments']['should'][] = $tag->name; } $tag = \Helpers\Tags::findByText('drummer', null); if ($tag) { $matchTags['profile']['should'][] = $tag->name; } } if ($el == $this->app->translate->get('singers') || $el == $this->app->translate->get('vocalists')) { $tag = \Helpers\Tags::findByText('vocals', null); if ($tag) { $matchTags['profile']['should'][] = $tag->name; $matchTags['instruments']['should'][] = $tag->name; } $tag = \Helpers\Tags::findByText('singer', null); if ($tag) { $matchTags['profile']['should'][] = $tag->name; } $tag = \Helpers\Tags::findByText('vocalist', null); if ($tag) { $matchTags['profile']['should'][] = $tag->name; } } if ($el == $this->app->translate->get('guitarists')) { $tag = \Helpers\Tags::findByText($this->app->translate->get('guitar'), null); if ($tag) { $matchTags['instruments']['should'][] = $tag->name; } $tag = \Helpers\Tags::findByText($this->app->translate->get('guitarist'), null); if ($tag) { $matchTags['profile']['should'][] = $tag->name; } $tag = \Helpers\Tags::findByText($this->app->translate->get('acoustic_guitar'), null); if ($tag) { $matchTags['instruments']['should'][] = $tag->name; } $tag = \Helpers\Tags::findByText($this->app->translate->get('electric_guitar'), null); if ($tag) { $matchTags['instruments']['should'][] = $tag->name; } } if ($el == $this->app->translate->get('bass_players') || $el == $this->app->translate->get('bassists')) { $tag = \Helpers\Tags::findByText($this->app->translate->get('bass'), null); if ($tag) { $matchTags['instruments']['should'][] = $tag->name; } $tag = \Helpers\Tags::findByText($this->app->translate->get('bass_player'), null); if ($tag) { $matchTags['profile']['should'][] = $tag->name; } $tag = \Helpers\Tags::findByText($this->app->translate->get('bassist'), null); if ($tag) { $matchTags['profile']['should'][] = $tag->name; } } if ($el == $this->app->translate->get('producers')) { $tag = \Helpers\Tags::findByText($this->app->translate->get('producer'), null); if ($tag) { $matchTags['profile']['should'][] = $tag->name; } } if ($el == $this->app->translate->get('musicians')) { $tag = \Helpers\Tags::findByText($this->app->translate->get('musician'), null); if ($tag) { $matchTags['profile']['should'][] = $tag->name; } } } } $bool = []; $must = []; $should = []; if (isset($data['autocomplete']) && trim($data['autocomplete'])) { $searchStr = trim($data['autocomplete']); // phrase_prefix is the "poorman's autocomplete" of Elastic. Works great // In future we can create more complex autocomplete, but it's totally unnecessary for now $combineType = "phrase_prefix"; $minLength = 2; } else { $searchStr = trim($data['search']); $combineType = "cross_fields"; $minLength = 3; } if (strtolower($searchStr) == "search" || strtolower($searchStr) == "%%tag%%") { try { // we got weird "search" requests .. log em // \Helpers\Debug::log("weird search ", $_SERVER['HTTP_REFERER']); // \Helpers\Debug::log($_SERVER['REQUEST_URI']); // \Helpers\Debug::log($_SERVER['QUERY_STRING']); // \Helpers\Debug::log($_SERVER['HTTP_USER_AGENT']); } catch (\Exception $e) { } } if (strlen($searchStr) >= $minLength) { // keep search string for 'tag' cloud of frequent searches \Helpers\SearchTags::add($searchStr); $combine = []; $combine[] = [ "multi_match" => [ "query" => $searchStr, "analyzer" => $analyzer, "type" => $combineType, "fields" => [ "name^5", // full name of User / Page "username^1", // "about.title^4", // "about.text^2", // "type.{$lang}^2", // Pages only // "tags.profile.{$lang}^3", // "tags.equipment.{$lang}^2", // "tags.genres.{$lang}^2", // Pages only // "tags.genres_primary.{$lang}^2", // "tags.genres_secondary.{$lang}", // "tags.influences.{$lang}^2", // "tags.instruments_primary.{$lang}^2", // "tags.instruments_secondary.{$lang}", // "tags.languages.{$lang}", ] ] ]; $combine[] = [ "multi_match" => [ "query" => $searchStr, "analyzer" => $analyzer, "fields" => [ "name^3", // full name of User / Page // "username^1", // "about.title^3", // "about.text^2", // "type.{$lang}^2", // Pages only // "tags.profile.{$lang}^3", // "tags.equipment.{$lang}^2", // "tags.genres.{$lang}^2", // Pages only // "tags.genres_primary.{$lang}^2", // "tags.genres_secondary.{$lang}", // "tags.influences.{$lang}^2", // "tags.instruments_primary.{$lang}^2", // "tags.instruments_secondary.{$lang}", // "tags.languages.{$lang}", ], "fuzziness" => "AUTO" ] ]; $must[] = ['bool' => ['should' => $combine, "boost" => 5]]; } /* if ($data['teach'] == 1) { $must[] = ['match' => ['teach' => 1]]; } if (intval($data['price_min']) > 0 || intval($data['price_max']) > 0) { $price = []; if (intval($data['price_min']) > 0) { $this_drooble_fee = (intval($data['price_min']) / (\Config::defaults()->DROOBLE_FEE_IN_PERCENTS + 100) * \Config::defaults()->DROOBLE_FEE_IN_PERCENTS); $price_from = intval($data['price_min']) - $this_drooble_fee; if ($price_from < 0) { $price_from = 0; } $price['gte'] = intval($price_from); } if (intval($data['price_max']) > 0) { $this_drooble_fee = (intval($data['price_max']) / (\Config::defaults()->DROOBLE_FEE_IN_PERCENTS + 100) * \Config::defaults()->DROOBLE_FEE_IN_PERCENTS); $price_to = intval($data['price_max']) - $this_drooble_fee; if ($price_to < 0) { $price_to = 0; } $price['lte'] = intval($price_to); } $must[] = ['range' => ['price' => $price] ]; } */ if ($data['place']) { $data['place'] = str_replace("'", "", $data['place']); $data['place'] = str_replace("`", "", $data['place']); $data['place'] = str_replace("\"", "", $data['place']); $place = \Helpers\Basic::getGooglePlace($data['place']); if ($place && $place->is_country) { $must[] = ['match' => ['country' => $place->country_code]]; } else { $must[] = ['match' => ['city' => $data['place']]]; } }elseif($data['location']){ $google_places = new \Lib\GooglePlaces(\Config::googleplaces()->API_KEY); $cor = array($this->app->request->ipInfo['latitude'], $this->app->request->ipInfo['longitude']); $google_places->location = $cor; $google_places->radius = 100; $google_places->rankby = 'distance'; $google_places->types = '(cities)'; $google_places->input = $data['location']; $google_places_result = $google_places->autocomplete(); $searched_places_ids = array(); if($google_places_result['status'] == 'OK' AND count($google_places_result['predictions'])>0){ foreach($google_places_result['predictions'] as $__prediction){ $searched_places_ids[] = $__prediction['place_id']; } } if (count($searched_places_ids)) { $tmp = []; foreach ($searched_places_ids as $placeid) { $tmp[] = ['match' => ["city" => $placeid]]; } $must[] = ['bool' => ['should' => $tmp]]; } } if (count($data['tags'])) { foreach ($data['tags'] as $tag) { foreach ($matchTags as $type => $info) { $matchTags[$type]['should'][] = $tag; } } } foreach ($matchTags as $type => $info) { foreach ($info as $boolOperator => $tags) { // $boolOperator fills $must or $should arrays if (count($tags)) { foreach ($tags as $tag) { if ($type == "genres") { ${$boolOperator}[] = ['match' => ["tags.genres.{$lang}" => $tag]]; // this is for Pages ${$boolOperator}[] = ['match' => ["tags.genres_primary.{$lang}" => $tag]]; ${$boolOperator}[] = ['match' => ["tags.genres_secondary.{$lang}" => $tag]]; } elseif ($type == "instruments") { ${$boolOperator}[] = ['match' => ["tags.instruments_primary.{$lang}" => $tag]]; ${$boolOperator}[] = ['match' => ["tags.instruments_secondary.{$lang}" => $tag]]; } else { ${$boolOperator}[] = ['match' => ["tags.{$type}.{$lang}" => $tag]]; } /* this here was again because someone doesn't follow YAGNI if ($type == "genres") { $tmp[] = ['match_phrase' => ["tags.genres.{$lang}" => $tag]]; // this is for Pages $tmp[] = ['match_phrase' => ["tags.genres_primary.{$lang}" => $tag]]; $tmp[] = ['match_phrase' => ["tags.genres_secondary.{$lang}" => $tag]]; } elseif ($type == "instruments") { $tmp[] = ['match_phrase' => ["tags.instruments_primary.{$lang}" => $tag]]; $tmp[] = ['match_phrase' => ["tags.instruments_secondary.{$lang}" => $tag]]; } else { $tmp[] = ['match_phrase' => ["tags.{$type}.{$lang}" => $tag]]; } if ($tmp) { ${$boolOperator}[] = ['bool' => ['should' => $tmp]]; }*/ } } } } // if ($data['visible'] == 'profile_completed') { // $must[] = [ // 'term' => [ // 'visibility' => 'profile_completed' // ] // ]; // } if (count($pageTypeIds)) { $must[] = ['terms' => ['page_type_id' => $pageTypeIds]]; } if (count($must)) { $bool['must'] = $must; } if (count($should)) { $bool['should'] = $should; $bool['minimum_should_match'] = 1; // setting minimum_should_match would mess up the has_avatar boost } // if ($data['autocomplete']) { // $indexStr = \Config::elasticsearch()->INDICES->users . ',' . \Config::elasticsearch()->INDICES->pages; $indexStr = \Config::elasticsearch()->INDICES->users; // } else { // $indexStr = \Config::elasticsearch()->INDICES->users; // } // if ((int) $data['bands'] == 1 || count($pageTypeIds) || $data['show_pages'] || $data['type'] == "pages") { // $indexStr = \Config::elasticsearch()->INDICES->pages; // } if ($data['show_profiles'] /*|| $data['type'] == "people" */) { $indexStr = \Config::elasticsearch()->INDICES->users; } if (count($bool)) { // boost has_avatar. I personally argued that we should not boost, but rather filter by has_avatar, but it was pointless .. so enjoy // if (!isset($tagBoost)) { // NO SOLUTION for now ... // $bool['should'][] = ['term' => ['has_avatar' => ["value" => true, "boost" => 100 ]]]; // } // // enough BS // if ($indexStr == \Config::elasticsearch()->INDICES->users) { // $bool['should'][] = ['exists' => ['field' => 'tags.profile', 'boost' => 80]]; // $bool['should'][] = ['exists' => ['field' => 'tags.instruments_primary', 'boost' => 70]]; // $bool['should'][] = ['exists' => ['field' => 'tags.genres_primary', 'boost' => 60]]; // } else { // $bool['should'][] = ['exists' => ['field' => 'tags.genres', 'boost' => 80]]; // $bool['should'][] = ['exists' => ['field' => 'tags.influences', 'boost' => 70]]; // } $query = ["bool" => $bool]; } else { // empty search $bool = [ 'must' => [ ['match' => ['has_avatar' => true]] ] ]; // enough BS // if ($indexStr == \Config::elasticsearch()->INDICES->users) { // $boostTags = [ // ['exists' => ['field' => 'tags.profile', 'boost' => 80]], // ['exists' => ['field' => 'tags.instruments_primary', 'boost' => 70]], // ['exists' => ['field' => 'tags.genres_primary', 'boost' => 60]], // ]; // } else { // $boostTags = [ // ['exists' => ['field' => 'tags.genres', 'boost' => 80]], // ['exists' => ['field' => 'tags.influences', 'boost' => 70]], // ]; // } // if (isset($boostTags)) { // $bool['should'] = $boostTags; // } $query = [ 'function_score' => [ 'query' => ['bool' => $bool], 'random_score' => new \stdClass() ] ]; } $sort = [["_score" => "desc"]]; // second and third sort params were ["has_avatar" => "desc"], ["lastseen" => "desc"] they are insignificant $params = [ "from" => $offset, "size" => $results, "index" => $indexStr, // "explain" => 1, "body" => [ "query" => $query, "sort" => $sort, ] ]; //\Helpers\Debug::log('dht', json_encode($params)); $result = $dsm->search($params); if ((int) $data['count'] === 1) { //OMG all the legacy .. humanity $count = $result['hits']['total']; return array(true, $count); } else { return $this->viewSearchUsersAndPages($result, $searchStr); } } /* * @result DroobleSearchManager search result (Elastic client search result) * @searchStr - string from search (needed to 'inject' the search string as a Tag to all Users in the View) */ public function viewSearchUsersAndPages($result, $searchStr) { $lang = \Helpers\Basic::lang(); $hitIds = []; foreach ($result['hits']['hits'] as $item){ $hitIds[] = $item['_id']; } $hitIdsImploded = implode(",", $hitIds); $count = $result['hits']['total']; $ret = []; // get data for hits if ($count) { if (strlen($searchStr)) { $foundTag = \Helpers\Tags::findByText($searchStr, null); } $elsCtrl = new \Controllers\API\ElementsController(); $sql=" SELECT `search_cache`.`short_info_json` , `up`.`id`, `up`.`user_status`, `up`.`system_status`, `up`.`lastseen`, `up`.`is_page`, IF ( `ucm`.`id` IS NOT NULL, 1, 0 ) as `isInCircle` FROM `search_cache` JOIN `users_profiles` `up` ON `up`.`id` = `search_cache`.`user_id` LEFT JOIN `users_circles_members` `ucm` ON (`ucm`.`user_id` = :fuid AND `ucm`.`target_user_id` = `up`.`id`) WHERE `up`.`id` IN(" . $hitIdsImploded . ") ORDER BY FIELD(up.id, " . $hitIdsImploded . ") LIMIT " . $count . " ;"; $prepare = [ 'fuid' => $_SESSION['profile']['id'] ]; $qres = $this->app->db->query($sql, $prepare); $qres->setFetchMode(\Phalcon\Db::FETCH_ASSOC); $qelements = $qres->fetchAll(); foreach ($qelements as $el) { $a = json_decode($el['short_info_json'], true); if ($a != false) { $a['uid'] = $el['id']; $a['isInCircle'] = $el['isInCircle']; // $a['status'] = $el['publicStatus']; $a['is_page'] = $el['is_page']; // if ($a['rates']['session_price'] and $el['id'] != $_SESSION['profile']['id']) { // $a['rates']['session_price'] = floatval($a['rates']['session_price']) + floatval($a['rates']['session_price']) * ( \Config::defaults()->DROOBLE_FEE_IN_PERCENTS / 100 ); // } if ((int) $count >= 0) { $a['counter'] = $count; } $tags = \Helpers\Users::getUserTags($a['uid'], 3); // get with 3 - categorized with remapped type, cause otherwise you'll get random instruments (they have 4 subtypes) if ($a['uid'] == 1) { $a['open_to_string'] = "All music"; } else { $open_to_string = ""; if ( count($tags['profile']) > 1 ) { $open_to_string = $tags['profile'][0] . " " . $this->app->translate->get('and') . " " . $tags['profile'][1]; } elseif (count($tags['profile']) == 1) { $open_to_string = $tags['profile'][0]; } $a['open_to_string'] = $open_to_string; } $flatList = []; foreach ($tags as $arr) { foreach ($arr as $tag) { $flatList[] = $tag; } } if ($foundTag) { $searchAsTag = mb_convert_case(stripslashes($foundTag->translation->{$lang}->text), MB_CASE_TITLE, 'UTF-8'); if (!in_array($searchAsTag, array_slice($flatList, 0, 2))) { // 'inject' the search string as a Tag @ first position if it's not in the top 2 tags foreach ($tags as $key => $arr) { array_unshift($arr, $searchAsTag); $tags[$key] = $arr; break; } } } // remove duplicates $firstParts = array_slice($tags, 0, 3); $first3keys = array_keys($firstParts); $countTypes = count($first3keys); if ($countTypes > 1) { $tags[$first3keys[1]] = array_diff($tags[$first3keys[1]], $tags[$first3keys[0]]); } if ($countTypes > 2) { $tags[$first3keys[2]] = array_diff($tags[$first3keys[2]], $tags[$first3keys[1]]); $tags[$first3keys[2]] = array_diff($tags[$first3keys[2]], $tags[$first3keys[0]]); } $a['tags'] = $tags; $ret[] = $a; } } } return [true, $ret]; } public function getContacts($data) { return array(true, \Helpers\Search::getContactsAndTheRest($data['uid'], $data)); } } ?> |
#15 | search->advancedSearchPage(Array(10), true) /var/www/rc/drooble/trunk/projects/drooble_v1/services/web/private/lib/client.class.php (294) <?php class client{ public $t; public $p; public $l; public $c; public $pname;//page name private $db; // private $lib; public $lang; public $init=false; public $cached_profiles=array();// stre selected profiles; public $globalTexts; private $pageTexts; private $jsTexts; private $app; public function __construct($db,$app,$lang='en'){ $this->db = $db; // $this->lib = $lib; $this->lang = $lang; $this->app = $app; } // DEPRECATED //page in english (default) //TODO: move in init // public function initPageTexts($page) { // $di = Phalcon\DI\FactoryDefault::getDefault(); // $translate = $di->getShared('translate'); // $translate->initPageTexts($page); // $this->globalTexts = $translate->getGlobalTexts(); // $this->pageTexts = $translate->getPageTexts(); // $this->jsTexts = $translate->getJsTexts(); // return; // // } // DEPRECATED //page in english (default) // public function getPageText ($code) { // // if (!isset($this->globalTexts) || !isset($this->pageTexts)) { // $this->initPageTexts(); // } // // // Defautl // $text = $code; // // if (isset($this->globalTexts[$code])) { // $text = $this->globalTexts[$code]; // } // // if (isset($this->pageTexts[$code])) { // $text = $this->pageTexts[$code]; // } // // return $text; // } // DEPRECATED // public function getJsJsonTexts () { // if (!isset($this->jsTexts)) // return ""; // // return json_encode($this->jsTexts); // } public function setTitle ($title) { if (!isset($this->globalTexts) || !isset($this->pageTexts)) return; $this->pageTexts['title'] = $title; } // DEPRECATED // public function get_page_button($page){ // return $this->t["page"][$page]["button"]; // } public function downloadAttach($file){ //'/'.$_b.'/'.$_c.'/'.$_d //DEPRECATED - see ElementsController.php DownloadAction() exit(); if($uid=$_SESSION['profile']['id']){ $tmp = explode('/', $file); $prof_id = $tmp[1]; //uid if ($prof_id != $uid) { // probably band, so check it's authorized $pr = \Models\UserPageRights::findFirst(array('page_id = :page_id:', 'bind' => array('page_id' => $prof_id))); if (is_object($pr) && $pr->user_id == $_SESSION['profile']['id']) { $uid = $prof_id; } } $sql="SELECT `uma`.`original_filename` AS `filename`, `uma`.`stored_filename` FROM `users_messages_attachment` AS `uma` LEFT JOIN `users_messages` AS `um` ON `um`.`sender_id` = `uma`.`user_id` AND `um`.`attachments` LIKE CONCAT('%',`uma`.`attach_id`,'%') WHERE `uma`.`stored_filename` = :file AND `um`.`reciever_id` = :rid"; if(!isset($_GET['element']) AND $r=$this->db->q($sql,array("file"=>$file, "rid" => $uid))){ // SOME FILE $filename=$r[0]['filename']; if ($tmp[2] == 'attachments') { $stored_filename = $r[0]['stored_filename']; try { require __DIR__."/../../../../resources/library/aws/aws-autoloader.php"; $configArr = json_decode(json_encode(\Config::aws()->S3->CONFIG), true); $s3 = new \Aws\S3\S3Client($configArr); $original_key = \Config::paths()->UPLOAD_WEB_STORAGE_ROOT_FOLDER . $stored_filename; //\Helpers\Debug::log('$original_key', $original_key); $result = $s3->getObject(array( 'Bucket' => \Config::aws()->S3->BUKCETS->ATTACHMENTS, 'Key' => $original_key, )); // Display the object in the browser header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header("Content-Type: {$result['ContentType']}"); header('Content-Disposition: attachment; filename='.basename($filename)); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); echo $result['Body']; exit; } catch (Exception $e) { \Helpers\Debug::log($e->getTraceAsString()); return array(false, "can't get object"); } }/* else { $file = \Config::paths()->ATTACH_DIR . $file; }*/ if (file_exists($file)) { header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename='.basename($filename)); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); header('Content-Length: ' . filesize($file)); //Remove ob_clean(); flush(); readfile($file); exit; } exit ('File does not exist!'); } else if (isset($_GET['element'])) { // ELEMENT (AUDIO FOR NOW) if ($_GET['b'] == 'audio') { $check = \Models\UserElements::findFirst(array( 'conditions' => "type='audio' AND id=:id: AND is_downloadable=1", 'bind' => array( 'id' => (int)$_GET['element'] ) )); if ($check) { // $original_filename = explode(".", $check->original_filename); // To remove extension // array_pop($original_filename); // $original_filename = implode("_", $original_filename); $new_extension = explode(".", $check->external_media_url); $new_extension = array_pop($new_extension); $creator_name = $check->Creator->first_name; if ($check->Creator->last_name) { $creator_name .= " ".$check->Creator->last_name; } $title = \Helpers\Inflector::urlize($creator_name); $title .= "-".\Helpers\Inflector::urlize($check->title); header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename='.$title.'.'.$new_extension); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); header('Content-Length: ' . filesize($check->external_media_url)); //Remove ob_clean(); flush(); readfile($check->external_media_url); exit; } else { exit("error 1"); } } else { exit("error 2"); } } else { exit("error"); } }else{ exit("access denied"); } } public function load_square($page){ // $this->initPageTexts(); if (!isset($c)) { $c = $this; } ob_start(); if(file_exists( SQUARE_PAGES_LOGIC . $page . ".php" )){ include( SQUARE_PAGES_LOGIC . $page . ".php" ); } if(file_exists( SQUARE_PAGES_CSS . $page . ".css" )){ include( SQUARE_PAGES_CSS . $page . ".css" ); } if(file_exists( SQUARE_PAGES_HTML . $page . ".html" )){ include( SQUARE_PAGES_HTML . $page . ".html" ); } if(file_exists(SQUARE_PAGES_JS . $page . ".js")){ echo "<script type=\"text/javascript\">"; include( SQUARE_PAGES_JS . $page . ".js" ); echo "</script>"; } $content = ob_get_clean(); echo $content; } public function api($type,$action=false,$data=false,$internal=true){ //$this->lib->api($type,$action=false,$data=false); $app = $this->app; // expose app (to use in squares) switch($type){ case "php": if(!isset($action)){ $action=$data['action']; } //$API1_MAP = $this->lib->config['API1']['MAP']; if(\Config::api()->MAP->{$action}->status===true){ if(\Config::api()->MAP->{$action}->sessionRequire==true and !isset($_SESSION['profile']['id'])){ return(array(false,"nosess")); } $object=\Config::api()->MAP->{$action}->class; //TODO check za input data-ta file_exists(LOGIC . $object . ".class.php") || exit("wrong file"); class_exists($object) || include(LOGIC . $object . ".class.php"); class_exists($object) || exit("wrong class1"); // $module = new $object($this->db,$this->lib, $this, $this->app); $module = new $object($this->db, $this, $this->app); method_exists($module, $action) || exit("wrong method"); // Valio: Turned validator off for 'php' calls, because there was a bad case with Advanced search page. I actually fixed it since then, but haven't tested if its ok in this case. But anyway - this api function will be deprecated at some point. // $validator = \Helpers\Basic::validator(); // if ( $data && !is_array($data) ) { // In theory we should not get inside this if statement. // $data = array(); // \Helpers\Debug::log('validateActionData expects array as first param'); // } // if (!$data) { // $data = array(); // } // $validator->validateActionData($data, $action); // $cleanData = $validator->getInput(); //Valio: keep the legacy filter for now // strip html $filter = new \Phalcon\Filter(); $stripHTML = function(&$val) use ($filter) { $val = $filter->sanitize($val, 'striptags'); }; array_walk_recursive($data, $stripHTML); return( $module->$action( $data , $internal) ); }else{ return( array(false,"api error1")); } break; //ajax case "api1": //\Helpers\Debug::log("action name",$this->app->router->getActionName(),$this->app->router->getParams()); //$start = microtime(1); if($this->app->router->getActionName()){ $action = $this->app->router->getActionName(); }elseif($_POST['action']){ $action=$_POST['action']; }else{ $a=json_decode($_POST['data'],true); $action=$a['action']; } header('Content-Type: application/json'); if($action AND \Config::api()->MAP->{$action}->status===true){ if(\Config::api()->MAP->{$action}->sessionRequire==true and !isset($_SESSION['profile']['id'])){ exit(json_encode(array(false,"nosess"))); } $object=\Config::api()->MAP->{$action}->class; file_exists(LOGIC . $object . ".class.php") || exit("wrong file"); class_exists($object) || include(LOGIC . $object . ".class.php"); class_exists($object) || exit("wrong class2"); // $module = new $object($this->db,$this->lib, $this, $this->app); $module = new $object($this->db, $this, $this->app); method_exists($module, $action) || exit("wrong method"); // Valio: I commented the old filters //check za input data-ta // if(isset($_POST["data"])){ // foreach($_POST["data"] as $key=>$val){ // switch(\Config::api()->MAP->{$action}->data->{$key}){ // case "text": // // $val=$this->db->quote($val); // $_POST["data"][$key]=$val; // break; // case "int": // $val=intval($val); // $_POST["data"][$key]=$val; // break; // // } // } // } //$this->requests_intensity_checker($_SERVER['REMOTE_ADDR'],$object,$action); if($this->app->router->getParams()){ $cleanData = $this->app->router->getParams(); }else{ $dirtyData = []; if (is_array($_POST['data'])) { $dirtyData = $_POST['data']; } else if (is_numeric($_POST['data'])) { $dirtyData['id'] = (int)$_POST['data']; } // $dirtyData = is_array($_POST['data']) ? $_POST['data'] : array(); $di = \Phalcon\DI\FactoryDefault::getDefault(); $validator = $di->getValidator(); $validator->validateActionData($dirtyData, $action); $cleanData = $validator->getInput(); } // LEGACY (we now use DroobleValidator): // strip html // $filter = new \Phalcon\Filter(); // $stripHTML = function(&$val) use ($filter) { // $val = str_replace('<3', '<3', $val); // temporary fix for <3 emoticon // $val = $filter->sanitize($val, 'striptags'); // }; // array_walk_recursive($_POST['data'], $stripHTML); $result=$module->$action( $cleanData ); //$result['queryCount']=$this->db->queryCount; //$result['queries']=$this->db->queries; // \Helpers\Debug::log("metchod :".$action." time: ".(microtime(1)-$start)); exit( json_encode( $result ) ); }else{ exit( json_encode(array(false,"api error 1"))); } break; case "square": $this->init(); // $this->initPageTexts(); $page = $_POST["square"]; if (!isset($c)) { $c = $this; } //$_SESSION["t"]["square"][$page] || exit("wrong page"); $this->t["square"][$page] || exit("wrong page"); ob_start(); if(file_exists( SQUARE_PAGES_LOGIC . $page . ".php" )){ include( SQUARE_PAGES_LOGIC . $page . ".php" ); } if(file_exists( SQUARE_PAGES_CSS . $page . ".css" )){ include( SQUARE_PAGES_CSS . $page . ".css" ); } if(file_exists( SQUARE_PAGES_HTML . $page . ".html" )){ include( SQUARE_PAGES_HTML . $page . ".html" ); } if(file_exists(SQUARE_PAGES_JS . $page . ".js")){ echo "<script type=\"text/javascript\">"; include( SQUARE_PAGES_JS . $page . ".js" ); echo "</script>"; } $content = ob_get_clean(); exit($content); break; default: exit("wrong type"); break; } } } $c = new client($db,$app); ?> |
#16 | client->api(php, advancedSearchPage, Array(10)) /var/www/rc/drooble/trunk/projects/drooble_v1/services/web/private/pages_content/0_php_scripting/search_result_page.php (35) <?php $type = $_GET['type']== "people" ? "people" : "pages"; $looking_bandmates = $_GET['looking_bandmates'] ? true : false; $search = $_b; $profile = (array) $_GET['profile']; $instruments = (array) $_GET['instruments']; $genres = (array) $_GET['genres']; $influences = (array) $_GET['influences']; $equipment = (array) $_GET['equipment']; $place = (string) $_GET['place']; $languages = (string) $_GET['languages']; $search_params = [ "search" => $search, "profile" => $profile, "instruments" => $instruments, "genres" => $genres, "influences" => $influences, "equipment" => $equipment, "place" => $place, "languages" => $languages, ]; $page_number = (int)$_GET['page'] ? (int)$_GET['page'] : 1; $elements_per_page = 10; $offset = ($page_number - 1) * $elements_per_page ? ($page_number - 1) * $elements_per_page : 0; $search_params['offset'] = $offset; $search_params['limit'] = $elements_per_page+1; $s_results = $c->api("php", "advancedSearchPage", $search_params); if($s_results[0]){ $results = $s_results[1]; } $query = parse_url($_SERVER['REQUEST_URI'], PHP_URL_QUERY); parse_str($query, $url_params); //print_r($url_params); // Returns a string if the URL has parameters or NULL if not if ($query) { $url_params['page'] = $page_number - 1; $prev_url = http_build_query($url_params); $prev_url = '/search/?' . preg_replace('/%5B[0-9]+%5D/simU', '[]', $prev_url); $url_params['page'] = $page_number + 1; $next_url = http_build_query($url_params); $next_url = '/search/?' . preg_replace('/%5B[0-9]+%5D/simU', '[]', $next_url); } else { $prev_url = $_SERVER['REQUEST_URI'] . '?page=' . ($page_number - 1); $next_url = $_SERVER['REQUEST_URI'] . '?page=' . ($page_number + 1); } //print_r([$query, $prev_url, $next_url, $url_params]); if (count($results) > $elements_per_page) { $has_next_page = true; array_pop($results); } else { $has_next_page = false; } |
#17 | include(/var/www/rc/drooble/trunk/projects/drooble_v1/services/web/private/pages_content/0_php_scripting/search_result_page.php) /var/www/rc/drooble/trunk/projects/drooble_v1/services/web/private/pages_content/layout.php (9) <?php // needed for frontend segment events $forward_segment = \Drooble\FW\DroobleSegment::isForward(); setcookie("forward_segment", $forward_segment, time() + 2 * 3600, '/'); /** PHP SCRIPTIONG ON PAGE BEGIN */ if(file_exists( $_SCRIPTING_FILE = BACKEND_GENERATED_PHP_SCRIPTING_DIR ."/" .$app->getLegacyPageName() . ".php")){ include( $_SCRIPTING_FILE ); } /** PHP SCRIPTIONG ON PAGE END */ /** GENERATING HEADER HTML BEGIN */ ob_start(); if(file_exists( $FILE = BACKEND_GENERATED_HEADERS_DIR . "/" .$app->getLegacyPageName() . ".html")) { include( $FILE ); } else { include( BACKEND_GENERATED_HEADERS_DIR . "/__default_header.html" ); } $header_html = ob_get_clean(); /** GENERATING HEADER HTML END */ /** GENERATING BODY HTML BEGIN */ ob_start(); if(file_exists( $FILE = BACKEND_GENERATED_BODIES_DIR . "/" .$app->getLegacyPageName() . ".html")) { include($FILE ); } else { include( BACKEND_GENERATED_BODIES_DIR . "/__default_body.html" ); } $body_html = ob_get_clean(); /** GENERATING BODY HTML END */ /** GENERATING BODY HTML BEGIN */ ob_start(); if(file_exists( $FILE = BACKEND_GENERATED_FOOTERS_DIR . "/" .$app->getLegacyPageName() . ".html")) { include( $FILE ); } else { include( BACKEND_GENERATED_FOOTERS_DIR . "/__default_footer.html" ); } $footer_html = ob_get_clean(); /** GENERATING BODY HTML END */ ob_start(); echo $header_html; echo $body_html; echo $footer_html; echo "<!-- ". $app->getLegacyPageName() ." -->"; $html = ob_get_clean(); echo $html; //echo \Helpers\Basic::getInstance()->sanitize_output($html); |
#18 | include(/var/www/rc/drooble/trunk/projects/drooble_v1/services/web/private/pages_content/layout.php) /var/www/rc/drooble/trunk/projects/drooble_v1/services/web/public/index.php (158) <?php error_reporting(E_ERROR | E_PARSE); if (preg_match('~MSIE|Internet Explorer~i', $_SERVER['HTTP_USER_AGENT']) or (strpos($_SERVER['HTTP_USER_AGENT'], 'Trident/7.0; rv:11.0') !== false) or (strpos($_SERVER['HTTP_USER_AGENT'], 'Trident/7.0; Touch; rv:11.0') !== false)) { //is IE 11 or below header('Location: /no-support-browser.html'); exit; } try { define('CURRENT_MODULE',"web"); chdir(dirname(__DIR__)); $_SERVER["REMOTE_ADDR"]=isset($_SERVER['HTTP_CF_CONNECTING_IP']) ? $_SERVER['HTTP_CF_CONNECTING_IP'] : $_SERVER["REMOTE_ADDR"]; //cloudflare IP address parsing; if ($_GET['rb']) { setcookie("rb", $_GET['rb'], time() + 2 * 3600, '/'); $_COOKIE["rb"] = $_GET['rb']; } if (isset($_GET['rb']) && !$_GET['rb']) { setcookie("rb", $_GET['rb'], time() - 2 * 3600, '/'); } if(file_exists(__DIR__ . '/../../../config/defines.php')){ include(__DIR__ . '/../../../config/defines.php'); } date_default_timezone_set('Etc/UTC'); mb_internal_encoding("UTF-8"); if(file_exists("private/config/common.php")) $_CONFIG = include("private/config/common.php"); if(file_exists("/etc/drooble/configs/".CURRENT_MODULE."/config.php")) $_CONFIG = array_replace_recursive($_CONFIG, include("/etc/drooble/configs/".CURRENT_MODULE."/config.php")); require __DIR__ . '/../../../config/wrapper.php'; $config = include __DIR__ . '/../../../config/config.php'; $loader = require __DIR__ . '/../../../resources/lib/autoload.php'; include __DIR__ . "/../../../config/services.php"; $di['router'] = function () { return include __DIR__ . "/../private/config/router.php"; }; // include __DIR__ . "/../../../config/segment.php"; $segment_options = []; if ($_GET['test_segment']) { $test_segment = ($_GET['test_segment'] == "true" || $_GET['test_segment'] == 1) ? 1 : 0; // need to overwrite segment ip rules when testing setcookie("test_segment", $test_segment, time() + 2 * 3600, '/'); $segment_options['forward_anyway'] = $test_segment ? true : false; } if (isset($_COOKIE['test_segment'])) { $segment_options['forward_anyway'] = $_COOKIE['test_segment'] == 1 ? true : false; } \Drooble\FW\DroobleSegment::init(\Config::segment_analytics()->PROJECT_KEYS->WRITE_KEY, $segment_options); $app = new \Drooble\FW\DroobleApp($di); //10ms $app->view->setViewsDir( __DIR__ . "/../private/views/" ); $handle = $app->handle(); $content = $handle->getContent(); \Drooble\FW\DroobleSegment::flush(); exit( $content ); } catch (\Phalcon\Exception $e) { echo $e->getMessage(); exit; } catch (\PDOException $e){ echo $e->getMessage(); exit; } catch (\Drooble\Exceptions\InvalidParameters $e){ exit(json_encode(array(false,["error"=>"InvalidParameters","hint"=>$e->getMessage()]))); } catch (\Drooble\Exceptions\NotFound $e){ exit(json_encode(array(false,["error"=>"NotFound","hint"=>$e->getMessage()]))); } catch (\Drooble\Exceptions\AccessDenied $e){ exit(json_encode(array(false,["error"=>"AccessDenied","hint"=>$e->getMessage()]))); } catch (\Drooble\Exceptions\GeneralError $e){ exit(json_encode(array(false,["error"=>"GeneralError","hint"=>$e->getMessage()]))); } catch (\Exception $e){ if($e->getMessage()=='nosess'){ exit(json_encode(array(false,"nosess"))); } if($e->getMessage()=='wrong_method'){ exit(json_encode([false,"api error"])); } if($e->getMessage()=='action_not_alowed' || $e->getCode()==103){ exit(json_encode([false,"not alowd"])); } if($e->getMessage()!='action_not_found' and $e->getCode()!=101 and $e->getCode() != 100){ echo $e->getMessage(); } /* if( $e->getMessage()=='not_implemented' AND ( $e->getCode() == 100 OR $e->getCode() == 101 ) ){ //GO TO CONTENT BUILDER }else{ exit(json_encode([false,"general error"])); } */ } // END Phalcon foreach(array( "a", "b", "c", "d", "e" ) as $get) ${"_" . $get} = isset($_GET[$get]) ? $_GET[$get] : ""; if (\Helpers\Basic::getAppMode() == DEVELOPMENT_MODE) { (new \Phalcon\Debug)->listen(); } //include(LIB . "cache.class.php"); // deprecated include(LIB . "mysql.class.php"); include(LIB . "client.class.php"); if ($_POST['ajax'] == 'api1' || ($app->getRoutingType() == "ajaxAPI")){ $c->api('api1'); //GO TO API AND EXIT } //handle action if($_a=='a'){ include(LIB."action_handler.php"); } if($_a=='fbHandler'){ include(LIB."facebook_handler.php"); } $router = $di->getRouter(); if ($router->getClientPlatformType() == 'MB') { // $loadSmartBanner = false; TODO set to true if you want it back } //PREPARE HTML include(BACKEND_GENERATED_CONTENT . "/layout.php"); \Drooble\FW\DroobleSegment::flush(); |
Key | Value |
---|---|
a | search |
b | |
c | |
d | |
e | |
equipment | Array ( [0] => Protools ) |
page | 2 |
Key | Value |
---|---|
USER | www-data |
HOME | /var/www |
HTTP_CONNECTION | keep-alive |
HTTP_X_FORWARDED_PROTO | http |
HTTP_X_FORWARDED_PORT | 80 |
HTTP_X_FORWARDED_FOR | 18.118.16.170, 172.70.126.42 |
HTTP_USER_AGENT | Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; [email protected]) |
HTTP_CF_VISITOR | {"scheme":"https"} |
HTTP_CF_RAY | 8bfb2b772ac6292b-ORD |
HTTP_CF_IPCOUNTRY | US |
HTTP_CF_CONNECTING_IP | 18.118.16.170 |
HTTP_CDN_LOOP | cloudflare; loops=1 |
HTTP_ACCEPT_ENCODING | gzip, br |
HTTP_ACCEPT | */* |
HTTP_HOST | rc.drooble.com |
REDIRECT_STATUS | 200 |
SERVER_NAME | rc.drooble.com |
SERVER_PORT | 443 |
SERVER_ADDR | 172.31.25.120 |
REMOTE_PORT | 47994 |
REMOTE_ADDR | 18.118.16.170 |
SERVER_SOFTWARE | nginx/1.14.0 |
GATEWAY_INTERFACE | CGI/1.1 |
HTTPS | on |
REQUEST_SCHEME | https |
SERVER_PROTOCOL | HTTP/1.1 |
DOCUMENT_ROOT | /var/www/rc/drooble/trunk/projects/drooble_v1/services/web/public |
DOCUMENT_URI | /index.php |
REQUEST_URI | /search/?equipment%5B%5D=Protools&page=2 |
SCRIPT_NAME | /index.php |
CONTENT_LENGTH | |
CONTENT_TYPE | |
REQUEST_METHOD | GET |
QUERY_STRING | a=search&b=&c=&d=&e=&equipment%5B%5D=Protools&page=2 |
SCRIPT_FILENAME | /var/www/rc/drooble/trunk/projects/drooble_v1/services/web/public/index.php |
PATH_INFO | |
FCGI_ROLE | RESPONDER |
PHP_SELF | /index.php |
REQUEST_TIME_FLOAT | 1725758990.0325 |
REQUEST_TIME | 1725758990 |
# | Path |
---|---|
0 | /var/www/rc/drooble/trunk/projects/drooble_v1/services/web/public/index.php |
1 | /var/www/rc/drooble/trunk/projects/drooble_v1/config/defines.php |
2 | /var/www/rc/drooble/trunk/projects/drooble_v1/services/web/private/config/common.php |
3 | /var/www/rc/drooble/trunk/projects/drooble_v1/config/wrapper.php |
4 | /var/www/rc/drooble/trunk/projects/drooble_v1/config/config.php |
5 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/autoload.php |
6 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/composer/autoload_real.php |
7 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/composer/ClassLoader.php |
8 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/composer/autoload_static.php |
9 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/ralouphie/getallheaders/src/getallheaders.php |
10 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/guzzlehttp/promises/src/functions_include.php |
11 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/guzzlehttp/promises/src/functions.php |
12 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/guzzlehttp/psr7/src/functions_include.php |
13 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/guzzlehttp/psr7/src/functions.php |
14 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/guzzlehttp/guzzle/src/functions_include.php |
15 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/guzzlehttp/guzzle/src/functions.php |
16 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/react/promise/src/functions_include.php |
17 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/react/promise/src/functions.php |
18 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/mtdowling/jmespath.php/src/JmesPath.php |
19 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/aws/aws-sdk-php/src/functions.php |
20 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/facebook/php-sdk-v4/src/Facebook/polyfills.php |
21 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/mixpanel/mixpanel-php/lib/Mixpanel.php |
22 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/mixpanel/mixpanel-php/lib/Base/MixpanelBase.php |
23 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/mixpanel/mixpanel-php/lib/Producers/MixpanelPeople.php |
24 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/mixpanel/mixpanel-php/lib/Producers/MixpanelBaseProducer.php |
25 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/mixpanel/mixpanel-php/lib/ConsumerStrategies/FileConsumer.php |
26 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/mixpanel/mixpanel-php/lib/ConsumerStrategies/AbstractConsumer.php |
27 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/mixpanel/mixpanel-php/lib/ConsumerStrategies/CurlConsumer.php |
28 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/mixpanel/mixpanel-php/lib/ConsumerStrategies/SocketConsumer.php |
29 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/mixpanel/mixpanel-php/lib/Producers/MixpanelEvents.php |
30 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/mongodb/mongodb/src/functions.php |
31 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/segmentio/analytics-php/lib/Segment.php |
32 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/segmentio/analytics-php/lib/Segment/Client.php |
33 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/segmentio/analytics-php/lib/Segment/Consumer.php |
34 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/segmentio/analytics-php/lib/Segment/QueueConsumer.php |
35 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/segmentio/analytics-php/lib/Segment/Consumer/File.php |
36 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/segmentio/analytics-php/lib/Segment/Consumer/ForkCurl.php |
37 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/segmentio/analytics-php/lib/Segment/Consumer/LibCurl.php |
38 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/segmentio/analytics-php/lib/Segment/Consumer/Socket.php |
39 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/segmentio/analytics-php/lib/Segment/Version.php |
40 | /var/www/rc/drooble/trunk/projects/drooble_v1/config/services.php |
41 | /var/www/rc/drooble/trunk/projects/drooble_v1/services/web/private/plugins/APIPrefetcher.php |
42 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/library/Drooble/FW/DroobleSegment.php |
43 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/helpers/DroobleApc.php |
44 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/library/Drooble/FW/DroobleApp.php |
45 | /var/www/rc/drooble/trunk/projects/drooble_v1/services/web/private/config/router.php |
46 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/library/Drooble/FW/DroobleRouter.php |
47 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/helpers/Basic.php |
48 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/library/Drooble/FW/DroobleHelper.php |
49 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/library/Drooble/FW/DroobleSessionManager.php |
50 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/library/Drooble/FW/DroobleRedisSessionAdapter.php |
51 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/library/Drooble/FW/DroobleRedisDriver.php |
52 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/helpers/UserSessions.php |
53 | /var/www/rc/drooble/trunk/projects/drooble_v1/services/web/private/lib/mysql.class.php |
54 | /var/www/rc/drooble/trunk/projects/drooble_v1/services/web/private/lib/client.class.php |
55 | /var/www/rc/drooble/trunk/projects/drooble_v1/services/web/private/pages_content/layout.php |
56 | /var/www/rc/drooble/trunk/projects/drooble_v1/services/web/private/pages_content/0_php_scripting/search_result_page.php |
57 | /var/www/rc/drooble/trunk/projects/drooble_v1/services/web/private/logic/search.class.php |
58 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/library/Drooble/Search/DroobleSearchManager.php |
59 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/ClientBuilder.php |
60 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/psr/log/Psr/Log/NullLogger.php |
61 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/psr/log/Psr/Log/AbstractLogger.php |
62 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/psr/log/Psr/Log/LoggerInterface.php |
63 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/guzzlehttp/ringphp/src/Client/CurlHandler.php |
64 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/guzzlehttp/ringphp/src/Client/CurlFactory.php |
65 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/guzzlehttp/ringphp/src/Client/CurlMultiHandler.php |
66 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/guzzlehttp/ringphp/src/Client/Middleware.php |
67 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Serializers/SmartSerializer.php |
68 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Serializers/SerializerInterface.php |
69 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Connections/ConnectionFactory.php |
70 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Connections/ConnectionFactoryInterface.php |
71 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/ConnectionPool/Selectors/RoundRobinSelector.php |
72 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/ConnectionPool/Selectors/SelectorInterface.php |
73 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Connections/Connection.php |
74 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Connections/ConnectionInterface.php |
75 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/ConnectionPool/StaticNoPingConnectionPool.php |
76 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/ConnectionPool/AbstractConnectionPool.php |
77 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/ConnectionPool/ConnectionPoolInterface.php |
78 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Transport.php |
79 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Client.php |
80 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Namespaces/IndicesNamespace.php |
81 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Namespaces/AbstractNamespace.php |
82 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Namespaces/ClusterNamespace.php |
83 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Namespaces/NodesNamespace.php |
84 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Namespaces/SnapshotNamespace.php |
85 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Namespaces/CatNamespace.php |
86 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Namespaces/IngestNamespace.php |
87 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Namespaces/TasksNamespace.php |
88 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Namespaces/RemoteNamespace.php |
89 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/library/Drooble/Search/DroobleSearchClient.php |
90 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Endpoints/Search.php |
91 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Endpoints/AbstractEndpoint.php |
92 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/guzzlehttp/ringphp/src/Core.php |
93 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/guzzlehttp/ringphp/src/Future/CompletedFutureArray.php |
94 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/guzzlehttp/ringphp/src/Future/CompletedFutureValue.php |
95 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/guzzlehttp/ringphp/src/Future/FutureInterface.php |
96 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/react/promise/src/PromiseInterface.php |
97 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/react/promise/src/PromisorInterface.php |
98 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/guzzlehttp/ringphp/src/Future/FutureArrayInterface.php |
99 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/guzzlehttp/ringphp/src/Exception/ConnectException.php |
100 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/guzzlehttp/ringphp/src/Exception/RingException.php |
101 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/guzzlehttp/ringphp/src/Future/FutureArray.php |
102 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/guzzlehttp/ringphp/src/Future/MagicFutureTrait.php |
103 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/guzzlehttp/ringphp/src/Future/BaseFutureTrait.php |
104 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/react/promise/src/FulfilledPromise.php |
105 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/react/promise/src/ExtendedPromiseInterface.php |
106 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/react/promise/src/CancellablePromiseInterface.php |
107 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/psr/log/Psr/Log/LogLevel.php |
108 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Common/Exceptions/MaxRetriesException.php |
109 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Common/Exceptions/TransportException.php |
110 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Common/Exceptions/ElasticsearchException.php |
111 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Common/Exceptions/Curl/CouldNotResolveHostException.php |
112 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/elasticsearch/elasticsearch/src/Elasticsearch/Common/Exceptions/NoNodesAvailableException.php |
113 | /var/www/rc/drooble/trunk/projects/drooble_v1/resources/lib/react/promise/src/RejectedPromise.php |
Memory | |
---|---|
Usage | 4194304 |