#0 | Elasticsearch\Connections\Connection->process4xxError(Array([http_method] => GET, [scheme] => https, [uri] => /partsit/parts/_search, [body] => {"query":{"query_string":{"query":"*","default_operator":"and"}},"filter":{"and":[{"bool":{"must":{"term":{"sectionID":1}}}},{"bool":{"must":{"term":{"categoryID":16}}}},{"bool":{"must":{"term":{"subCategoryID":133}}}}]}}, [headers] => Array([host] => Array([0] => search-partsit-amts77ss2mcide4iwmj4hu6f6e.eu-west-1.es.amazonaws.com:443))), Array([transfer_stats] => Array(28), [curl] => Array([error] => (empty string), [errno] => 0), [effective_url] => https://search-partsit-amts77ss2mcide4iwmj4hu6f6e.eu-west-1.es.amazonaws.com:443/partsit/parts/_search, [headers] => Array([Access-Control-Allow-Origin] => Array([0] => *), [Content-Type] => Array([0] => application/json; charset=UTF-8), [Content-Length] => Array([0] => 65), [Connection] => Array([0] => keep-alive)), [version] => 1.1, [status] => 404, [reason] => Not Found, [body] => {"error":"IndexMissingException[[partsit] missing]","status":404}), Array()) /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Connections/Connection.php (262) <?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 <zachary.tong@elasticsearch.com> * @license http://www.apache.org/licenses/LICENSE-2.0 Apache2 * @link http://elasticsearch.org */ 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 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']; } $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' => [ 'host' => [$this->host] ] ]; $request = array_merge_recursive($request, $this->connectionParams, $options); $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)) { $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/_all/clear', 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; } /** * @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); } $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); } $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($error, $response['status']); } } |
#1 | Elasticsearch\Connections\Connection->Elasticsearch\Connections\{closure}(Array([transfer_stats] => Array(28), [curl] => Array([error] => (empty string), [errno] => 0), [effective_url] => https://search-partsit-amts77ss2mcide4iwmj4hu6f6e.eu-west-1.es.amazonaws.com:443/partsit/parts/_search, [headers] => Array([Access-Control-Allow-Origin] => Array([0] => *), [Content-Type] => Array([0] => application/json; charset=UTF-8), [Content-Length] => Array([0] => 65), [Connection] => Array([0] => keep-alive)), [version] => 1.1, [status] => 404, [reason] => Not Found, [body] => Resource id #24)) /home/ubuntu/partsit-site/vendor/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 (\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() { } } |
#2 | React\Promise\FulfilledPromise->then(Object(Closure), null, null) /home/ubuntu/partsit-site/vendor/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); } } |
#3 | GuzzleHttp\Ring\Future\CompletedFutureValue->then(Object(Closure), null, null) /home/ubuntu/partsit-site/vendor/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'); } } } |
#4 | GuzzleHttp\Ring\Core::proxy(Object(GuzzleHttp\Ring\Future\CompletedFutureArray), Object(Closure)) /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Connections/Connection.php (283) <?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 <zachary.tong@elasticsearch.com> * @license http://www.apache.org/licenses/LICENSE-2.0 Apache2 * @link http://elasticsearch.org */ 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 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']; } $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' => [ 'host' => [$this->host] ] ]; $request = array_merge_recursive($request, $this->connectionParams, $options); $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)) { $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/_all/clear', 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; } /** * @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); } $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); } $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($error, $response['status']); } } |
#5 | Elasticsearch\Connections\Connection->Elasticsearch\Connections\{closure}(Array([http_method] => GET, [scheme] => https, [uri] => /partsit/parts/_search, [body] => {"query":{"query_string":{"query":"*","default_operator":"and"}},"filter":{"and":[{"bool":{"must":{"term":{"sectionID":1}}}},{"bool":{"must":{"term":{"categoryID":16}}}},{"bool":{"must":{"term":{"subCategoryID":133}}}}]}}, [headers] => Array([host] => Array([0] => search-partsit-amts77ss2mcide4iwmj4hu6f6e.eu-west-1.es.amazonaws.com:443))), Object(Elasticsearch\Connections\Connection), Object(Elasticsearch\Transport), Array()) /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Connections/Connection.php (159) <?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 <zachary.tong@elasticsearch.com> * @license http://www.apache.org/licenses/LICENSE-2.0 Apache2 * @link http://elasticsearch.org */ 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 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']; } $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' => [ 'host' => [$this->host] ] ]; $request = array_merge_recursive($request, $this->connectionParams, $options); $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)) { $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/_all/clear', 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; } /** * @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); } $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); } $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($error, $response['status']); } } |
#6 | Elasticsearch\Connections\Connection->performRequest(GET, /partsit/parts/_search, Array(), Array([query] => Array([query_string] => Array([query] => *, [default_operator] => and)), [filter] => Array([and] => Array([0] => Array(), [1] => Array(), [2] => Array()))), Array(), Object(Elasticsearch\Transport)) /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Transport.php (106) <?php namespace Elasticsearch; use Elasticsearch\Common\Exceptions; use Elasticsearch\ConnectionPool\AbstractConnectionPool; use Elasticsearch\Connections\Connection; use Elasticsearch\Connections\ConnectionInterface; use Psr\Log\LoggerInterface; /** * Class Transport * * @category Elasticsearch * @package Elasticsearch * @author Zachary Tong <zachary.tong@elasticsearch.com> * @license http://www.apache.org/licenses/LICENSE-2.0 Apache2 * @link http://elasticsearch.org */ 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 */ public function __construct($retries, $sniffOnStart = false, AbstractConnectionPool $connectionPool, LoggerInterface $log) { $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 array */ 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) { //some kind of real faiure here, like a timeout $this->connectionPool->scheduleCheck(); // log stuff }); return $future; } /** * @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; } } |
#7 | Elasticsearch\Transport->performRequest(GET, /partsit/parts/_search, Array(), Array([query] => Array([query_string] => Array([query] => *, [default_operator] => and)), [filter] => Array([and] => Array([0] => Array(), [1] => Array(), [2] => Array()))), Array()) /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Endpoints/AbstractEndpoint.php (80) <?php namespace Elasticsearch\Endpoints; use Elasticsearch\Common\Exceptions\UnexpectedValueException; use Elasticsearch\Transport; use Exception; use GuzzleHttp\Ring\Future\FutureArrayInterface; /** * Class AbstractEndpoint * * @category Elasticsearch * @package Elasticsearch\Endpoints * @author Zachary Tong <zachary.tong@elasticsearch.com> * @license http://www.apache.org/licenses/LICENSE-2.0 Apache2 * @link http://elasticsearch.org */ abstract class AbstractEndpoint { /** @var array */ protected $params = array(); /** @var string */ protected $index = null; /** @var string */ protected $type = null; /** @var string|int */ protected $id = null; /** @var string */ protected $method = null; /** @var array */ protected $body = null; /** @var \Elasticsearch\Transport */ private $transport = null; /** @var array */ private $options = []; /** * @return string[] */ abstract protected function getParamWhitelist(); /** * @return string */ abstract protected function getURI(); /** * @return string */ abstract protected function getMethod(); /** * @param Transport $transport */ public function __construct($transport) { $this->transport = $transport; } /** * @throws \Exception * @return array */ public function performRequest() { $promise = $this->transport->performRequest( $this->getMethod(), $this->getURI(), $this->params, $this->getBody(), $this->options ); return $promise; } /** * Set the parameters for this endpoint * * @param string[] $params Array of parameters * @return $this */ public function setParams($params) { if (is_object($params) === true) { $params = (array) $params; } $this->checkUserParams($params); $params = $this->convertCustom($params); $this->extractOptions($params); $this->params = $this->convertArraysToStrings($params); return $this; } /** * @param string $index * * @return $this */ public function setIndex($index) { if ($index === null) { return $this; } if (is_array($index) === true) { $index = array_map('trim', $index); $index = implode(",", $index); } $this->index = urlencode($index); return $this; } /** * @param string $type * * @return $this */ public function setType($type) { if ($type === null) { return $this; } if (is_array($type) === true) { $type = array_map('trim', $type); $type = implode(",", $type); } $this->type = urlencode($type); return $this; } /** * @param int|string $docID * * @return $this */ public function setID($docID) { if ($docID === null) { return $this; } $this->id = urlencode($docID); return $this; } /** * @param $result * @return callable|array */ public function resultOrFuture($result) { $response = null; $async = isset($this->options['client']['future']) ? $this->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; } } /** * @return array */ protected function getBody() { return $this->body; } /** * @param string $endpoint * * @return string */ protected function getOptionalURI($endpoint) { $uri = array(); $uri[] = $this->getOptionalIndex(); $uri[] = $this->getOptionalType(); $uri[] = $endpoint; $uri = array_filter($uri); return '/' . implode('/', $uri); } /** * @return string */ private function getOptionalIndex() { if (isset($this->index) === true) { return $this->index; } else { return '_all'; } } /** * @return string */ private function getOptionalType() { if (isset($this->type) === true) { return $this->type; } else { return ''; } } /** * @param array $params * * @throws \Elasticsearch\Common\Exceptions\UnexpectedValueException */ private function checkUserParams($params) { if (isset($params) !== true) { return; //no params, just return. } $whitelist = array_merge($this->getParamWhitelist(), array('client', 'custom', 'filter_path')); foreach ($params as $key => $value) { if (array_search($key, $whitelist) === false) { throw new UnexpectedValueException(sprintf( '"%s" is not a valid parameter. Allowed parameters are: "%s"', $key, implode('", "', $whitelist) )); } } } /** * @param $params Note: this is passed by-reference! */ private function extractOptions(&$params) { // Extract out client options, then start transforming if (isset($params['client']) === true) { $this->options['client'] = $params['client']; unset($params['client']); } $ignore = isset($this->options['client']['ignore']) ? $this->options['client']['ignore'] : null; if (isset($ignore) === true) { if (is_string($ignore)) { $this->options['client']['ignore'] = explode(",", $ignore); } elseif (is_array($ignore)) { $this->options['client']['ignore'] = $ignore; } else { $this->options['client']['ignore'] = [$ignore]; } } } private function convertCustom($params) { if (isset($params['custom']) === true) { foreach ($params['custom'] as $k => $v) { $params[$k] = $v; } unset($params['custom']); } return $params; } private function convertArraysToStrings($params) { foreach ($params as $key => &$value) { if (!($key === 'client' || $key == 'custom') && is_array($value) === true) { if ($this->isNestedArray($value) !== true) { $value = implode(",", $value); } } } return $params; } private function isNestedArray($a) { foreach ($a as $v) { if (is_array($v)) { return true; } } return false; } } |
#8 | Elasticsearch\Endpoints\AbstractEndpoint->performRequest() /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Client.php (930) <?php namespace Elasticsearch; use Elasticsearch\Common\Exceptions\InvalidArgumentException; use Elasticsearch\Common\Exceptions\Missing404Exception; use Elasticsearch\Common\Exceptions\TransportException; use Elasticsearch\Namespaces\CatNamespace; use Elasticsearch\Namespaces\ClusterNamespace; use Elasticsearch\Namespaces\IndicesNamespace; use Elasticsearch\Namespaces\NodesNamespace; use Elasticsearch\Namespaces\SnapshotNamespace; use Elasticsearch\Namespaces\BooleanRequestWrapper; /** * Class Client * * @category Elasticsearch * @package Elasticsearch * @author Zachary Tong <zachary.tong@elasticsearch.com> * @license http://www.apache.org/licenses/LICENSE-2.0 Apache2 * @link http://elasticsearch.org */ 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 callback */ protected $endpoints; /** * Client constructor * * @param Transport $transport * @param callable $endpoint */ public function __construct(Transport $transport, callable $endpoint) { $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); } /** * @param $params * @return array */ public function info($params = []) { /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Info $endpoint */ $endpoint = $endpointBuilder('Info'); $response = $endpoint->setParams($params)->performRequest(); return $endpoint->resultOrFuture($response); } /** * @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'); try { $response = $endpoint->setParams($params)->performRequest(); $endpoint->resultOrFuture($response); } catch (Missing404Exception $exception) { return false; } catch (TransportException $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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * * $params[''] @todo finish the rest of these params * ['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 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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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 */ 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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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 */ 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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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 */ 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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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 termvector($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\TermVector $endpoint */ $endpoint = $endpointBuilder('TermVector'); $endpoint->setIndex($index) ->setType($type) ->setID($id) ->setBody($body); $endpoint->setParams($params); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * Redirect to termvector, this is just a naming difference depending on version */ public function termvectors($params = array()) { return $this->termvector($params); } /** * $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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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); } /** * $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) * ['boost_terms'] = (number) The boost factor * ['max_doc_freq'] = (number) The word occurrence frequency as count: words with higher occurrence in the corpus will be ignored * ['max_query_terms'] = (number) The maximum query terms to be included in the generated query * ['max_word_len'] = (number) The minimum length of the word: longer words will be ignored * ['min_doc_freq'] = (number) The word occurrence frequency as count: words with lower occurrence in the corpus will be ignored * ['min_term_freq'] = (number) The term frequency as percent: terms with lower occurrence in the source document will be ignored * ['min_word_len'] = (number) The minimum length of the word: shorter words will be ignored * ['mlt_fields'] = (list) Specific fields to perform the query against * ['percent_terms_to_match'] = (number) How many terms have to match in order to consider the document a match (default: 0.3) * ['routing'] = (string) Specific routing value * ['search_from'] = (number) The offset from which to return results * ['search_indices'] = (list) A comma-separated list of indices to perform the query against (default: the index containing the document) * ['search_query_hint'] = (string) The search query hint * ['search_scroll'] = (string) A scroll search request definition * ['search_size'] = (number) The number of documents to return (default: 10) * ['search_source'] = (string) A specific search request definition (instead of using the request body) * ['search_type'] = (string) Specific search type (eg. `dfs_then_fetch`, `count`, etc) * ['search_types'] = (list) A comma-separated list of types to perform the query against (default: the same type as the document) * ['stop_words'] = (list) A list of stop words to be ignored * ['body'] = (array) A specific search request definition * * @param $params array Associative array of parameters * * @return array */ public function mlt($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\Mlt $endpoint */ $endpoint = $endpointBuilder('Mlt'); $endpoint->setID($id) ->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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 * ['percolate'] = (string) Percolator queries to execute while indexing the 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\Index $endpoint */ $endpoint = $endpointBuilder('Index'); $endpoint->setID($id) ->setIndex($index) ->setType($type) ->setBody($body) ->createIfAbsent(); $endpoint->setParams($params); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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 * ['body'] = (string) Default document type for items which don't provide one * ['fields'] = (list) Default comma-separated list of fields to return in the response for updates * * @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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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 * ['percolate'] = (string) Percolator queries to execute while indexing the 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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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 * ['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 * ['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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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 * ['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 * ['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 searchExists($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\SearchExists $endpoint */ $endpoint = $endpointBuilder('SearchExists'); $endpoint->setIndex($index) ->setType($type) ->setBody($body); $endpoint->setParams($params); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Scroll $endpoint */ $endpoint = $endpointBuilder('Scroll'); $endpoint->setScrollID($scrollID) ->setBody($body); $endpoint->setParams($params); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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\Scroll $endpoint */ $endpoint = $endpointBuilder('Scroll'); $endpoint->setScrollID($scrollID) ->setBody($body) ->setClearScroll(true); $endpoint->setParams($params); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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 * ['percolate'] = (string) Perform percolation during the operation; use specific registered query name, attribute, or wildcard * ['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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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) ->setLang($lang) ->setBody($body); $endpoint->setParams($params); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $params['id'] = (string) The search template ID (Required) * * @param $params array Associative array of parameters * * @return array */ public function putTemplate($params) { $id = $this->extractArgument($params, 'id'); $body = $this->extractArgument($params, 'body'); /** @var callback $endpointBuilder */ $endpointBuilder = $this->endpoints; /** @var \Elasticsearch\Endpoints\Template\Put $endpoint */ $endpoint = $endpointBuilder('Template\Put'); $endpoint->setID($id) ->setBody($body); $endpoint->setParams($params); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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); $endpoint->setParams($params); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * $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); $response = $endpoint->performRequest(); return $endpoint->resultOrFuture($response); } /** * 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; } /** * @param array $params * @param string $arg * * @return null|mixed */ public function extractArgument(&$params, $arg) { if (is_object($params) === true) { $params = (array) $params; } if (isset($params[$arg]) === 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"); } } } } |
#9 | Elasticsearch\Client->search(Array([index] => partsit, [type] => parts, [body] => Array([query] => Array([query_string] => Array()), [filter] => Array([and] => Array())))) /home/ubuntu/partsit-site/app/models/Parts.php (1356) <?php namespace Models; /** * An encapsulation of a part on PartsIT. * * PHP Version 5 * * @category Models * @package Models * @author Jack Timblin <jacktimblin@gmail.com> * @copyright 2015 PartsIT.com * @license GNU General Public License V3.0 * @version Release: 1 * @see \Models\BaseModel, \Phalcon\Mvc\Model, \Phalcon\Mvc\Model\Behavior\Timestampable * @since Release: 1 */ class Parts extends BaseModel { /* the unique partID of this part @var int */ protected $partID; /* the the manufacturers partNumber for this part. @var string */ protected $partNumber; /* the ID of the manufacturer for this part. @var int */ protected $manufacturerID; /* the short title/description string for this part. @var string */ protected $title; /* the unique url for this part, used to have dynamic product pages. @var string */ protected $partURL; /* the short description for this part. @var string */ protected $shortDescription; /* the category that this part belongs to. @var int */ protected $subCategoryID; /* the date this part was added to the system. @var string */ protected $dateCreated; /* the date this part was last updated to the system. @var string */ protected $dateModified; /* The International Article Number (E(uropean)AN) for this part. Used to uniquely identify this part on Amazon, Icecat etc. @var string */ protected $ean; /** * Called in the models manager, sets up default variables and relationships * for this model. * @return void * @access public * @see \Phalcon\Mvc\Model::initialize() */ public function initialize() { $this->addBehavior( new \Phalcon\Mvc\Model\Behavior\Timestampable( array( 'beforeCreate' => array( 'field' => 'dateCreated', 'format' => 'Y-m-d H:i:s' ), 'beforeUpdate' => array( 'field' => 'dateModified', 'format' => 'Y-m-d H:i:s' ) ) ) ); $this->useDynamicUpdate(true); $this->hasOne( 'partID', '\Models\PromoParts', 'partID', array( 'alias' => 'PromoPart' ) ); $this->hasOne( 'partID', '\Models\CustomPromoParts', 'partID', array( 'alias' => 'CustomPromoParts' ) ); $this->hasMany( 'partID', '\Models\PartFeatureImages', 'partID', array( 'alias' => 'FeatureImages' ) ); $this->hasOne( 'partID', '\Models\IcecatLastUpdated', 'partID', array( 'alias' => 'IcecatLastUpdated' ) ); $this->hasMany( 'partID', '\Models\PartTechSpecs', 'partID', array( 'alias' => 'PartTechSpecs' ) ); $this->hasMany( 'partID', '\Models\PartBundles', 'partID', array( 'alias' => 'PartBundles' ) ); $this->hasMany( 'partID', '\Models\PriceRequests', 'partID', array( 'alias' => 'PriceRequests' ) ); $this->hasMany( 'partID', '\Models\PartVideos', 'partID', array( 'alias' => 'PartVideos' ) ); $this->belongsTo( 'subCategoryID', '\Models\SubCategories', 'subCategoryID', array( 'alias' => 'SubCategories' ) ); $this->hasMany( 'partNumber', '\Models\SAP\DeliveryParts', 'partNumber', array( 'alias' => 'SapDeliveryParts' ) ); $this->hasMany( 'partID', '\Models\RecentlyViewed', 'partID', array( 'alias' => 'RecentlyViewed' ) ); $this->belongsTo( 'manufacturerID', '\Models\Manufacturers', 'manufacturerID', array( 'alias' => 'Manufacturers' ) ); $this->hasOne( 'partID', '\Models\PartDescriptions', 'partID', array( 'foreignKey' => array( 'message' => 'The part has a part description.' ), 'alias' => 'PartDescriptions' ) ); $this->hasMany( 'partID', '\Models\PartFeatures', 'partID', array( 'foreignKey' => array( 'message' => 'The part has a part feature.' ), 'alias' => 'PartFeatures' ) ); $this->hasMany( 'partID', '\Models\Reviews', 'partID', array( 'foreignKey' => array( 'message' => 'The part belongs to a review.' ), 'alias' => 'Reviews' ) ); $this->hasMany( 'partID', '\Models\PartImages', 'partID', array( 'alias' => 'PartImages' ) ); $this->hasOne( 'partID', '\Models\FeaturedReviews', 'partID', array( 'alias' => 'FeaturedReviews' ) ); $this->hasMany( 'partID', '\Models\StockParts', 'partID', array( 'foreignKey' => array( 'message' => 'The part has a stock part.' ), 'alias' => 'StockParts' ) ); $this->hasMany( 'partID', '\Models\CompatibleParts', 'partID', array( 'foreignKey' => array( 'message' => 'The part has a compatible part.' ), 'alias' => 'CompatibleParts' ) ); $this->hasMany( 'partNumber', '\Models\SAP\OrderParts', 'partNumber', array( 'alias' => 'SapOrderParts' ) ); $this->hasMany( 'partNumber', '\Models\SAP\QuoteParts', 'partNumber', array( 'alias' => 'SapQuoteParts' ) ); $this->hasMany( 'partNumber', '\Models\SAP\PurchaseOrderParts', 'partNumber', array( 'alias' => 'SapPurchaseOrderParts' ) ); $this->hasMany( 'partNumber', '\Models\SAP\ArInvoiceParts', 'partNumber', array( 'alias' => 'SapArInvoiceParts' ) ); $this->hasMany( 'partNumber', '\Models\SAP\ApInvoiceParts', 'partNumber', array( 'alias' => 'SapApInvoiceParts' ) ); $this->hasMany( 'partNumber', '\Models\SAP\CustomerRmaParts', 'partNumber', array( 'alias' => 'SapCustomerRmaParts' ) ); $this->hasMany( 'partNumber', '\Models\SAP\SupplierRmaParts', 'partNumber', array( 'alias' => 'SapSupplierRmaParts' ) ); $this->hasMany( 'partID', '\Models\PartKeywords', 'partID', array( 'alias' => 'PartKeywords' ) ); $this->hasOne( 'partID', '\Models\HotProducts', 'partID', array( 'alias' => 'HotProducts' ) ); $this->hasMany( 'partID', '\Models\BundleParts', 'partID', array( 'alias' => 'BundleParts' ) ); $this->hasMany( 'partID', '\Models\Images', 'partID', array( 'alias' => 'Images', 'foreignKey' => array( 'action' => \Phalcon\Mvc\Model\Relation::ACTION_CASCADE ) ) ); } /** * checks to see if this part is part * of a bundle promotion. * @return bool TRUE if this part is part of a * bundle promo, FALSE otherwise. * @access public */ public function isPartOfABundle() { $bpart = $this->getBundleParts(); if (!$bpart) { return false; } $bundles = array(); $now = new \DateTime(); $now = $now->format('Y-m-d'); foreach ($bpart as $bp) { $b = $bp->getBundle(array('validTo > :now:', 'bind' => array('now' => $now))); if($b instanceof \Models\Bundle) { $bundles[] = $b; } } return (count($bundles) > 0); } /** * gets the current promotion that is applied to this part. * @return mixed either the custom promo parts, the promo parts or null if there is * no promotion that has been applied to this part. * @access public */ public function getPromotion() { $c = $this->getCustomPromoParts(); if ($c) { return $c; } return $this->getPromoPart(); } /** * determines the bulk buy promotions for this part. * bulk buy promotions are only applied to stock parts. * @param int $quantityRequired the quantity to work out discount for. * @return string the bulk buy discounted price formatted to a string. * @access public */ public function getBulkRate($quantityRequired) { $price = 0; $discount = 0; $productPrice = $this->getBestPrice(array('vat' => true)); $charterpoint = \Models\Distributors::findFromURL('charterpoint'); $stockPart = \Models\StockParts::findFirst( array( 'partID = :partID: AND distributorID = :charterpoint:', 'bind' => array( 'partID' => $this->getPartID(), 'charterpoint' => $charterpoint->getDistributorID() ), 'order' => 'unitPrice ASC' ) ); if (!$stockPart) { return; } if ($productPrice == 0) { return; } $max = $stockPart->getQuantity(); if (($quantityRequired > 1) && ($max > 1)) { $discount = 8; } if ($max <= $quantityRequired) { $remainder = $quantityRequired - $max; $price = $remainder * $productPrice; $discountable = $quantityRequired - $remainder; } else { $discountable = $quantityRequired; } $discountable = $discountable - 1; $price = $price + $productPrice; $price = $price + ($discountable * ($productPrice - $discount)); return number_format($price, 2, ".", ""); } /** * Gets the EAN for this part. * @return string the EAN for this part, * or null if we do not have one saved. * @access public */ public function getEan() { return $this->ean; } /** * Sets the EAN for this part. * @param string $ean the EAN for this part * @return void * @access public */ public function setEan($ean) { $this->ean = $ean; } /** * checks to see if this parts information needs * updating from icecat. * @return bool TRUE if this part needs updating, FALSE otherwise. * @access public */ public function partNeedsUpdating() { $lastUpdated = $this->getIcecatLastUpdated(); return (!($lastUpdated instanceof \Models\IcecatLastUpdated)); } /** * Finds an existing part entry or generates a new one. * @param string $manufacturer the manufacturer name for this part. * @param string $partNumber the manufacturers part number for this part. * @param string $shortDescription the short description for this part. * @return \Models\Parts the exisiting part entry or the newly generated one. * @static * @access public */ public static function createOrFind( $manufacturer, $partNumber, $shortDescription) { $manufacturer = \Models\Manufacturers::createOrFind($manufacturer); $part = \Models\Parts::findFirst( array( 'partNumber = :partNumber: AND manufacturerID = :manufacturerID:', 'bind' => array( 'partNumber' => $partNumber, 'manufacturerID' => $manufacturer->getManufacturerID() ) ) ); if (!$part) { $filter = new \Phalcon\Filter(); $filter->add('urlSlug', new \PhalconHelpers\Filters\URLSlug()); $filter->add('description', new \PhalconHelpers\Filters\Description()); $partURL = $filter->sanitize($manufacturer->getManufacturerURL() . '-' . $partNumber, 'urlSlug'); $shortDescription = $filter->sanitize($shortDescription, 'description'); while (\Models\Parts::count('partURL = "' . $partURL . '"')) { //TODO $partURL = \Phalcon\Text::increment($partURL, '-'); } $part = new \Models\Parts(); $part->setPartNumber($partNumber); $part->setManufacturerID($manufacturer->getManufacturerID()); $part->setPartURL($partURL); $part->setShortDescription($shortDescription); $part->save(); } return $part; } /** * searches the elasticsearch index for part number matches. * @param string $partNumber the manufacturers part number for this part. * @param bool $onlyExact [optional] whether to only accept an exact match * the default is FALSE. * @return array the parts matching the part number query. * @static * @access public */ public static function searchByPartNumber($partNumber, $onlyExact = false) { $results = array('total' => 0, 'parts' => array()); if (!isset($partNumber) || strlen($partNumber) == 0) { return $results; } //first check the db for an exact match $ex = Parts::findFirst( array( 'partNumber = ?1', 'bind' => array( 1 => $partNumber ) ) ); if ($ex) { return array('total' => 1, 'parts' => array($ex)); } if ($onlyExact) { return array('total' => 0, 'parts' => array()); } $body = array( 'query' => array( 'filtered' => array( 'query' => array( 'query_string' => array( 'default_field' => 'partNumber', 'query' => $partNumber.'*' ) ), 'filter' => array( 'type' => array( 'value' => 'parts' ) ) ) ) ); $res = \Phalcon\DI::getDefault()->get('elasticSearch')->search(array('index' => 'partsit', 'type' => 'parts', 'body' => $body)); $results['total'] = $res['hits']['total']; $e = array(); if ($results['total'] != 0) { foreach ($res['hits']['hits'] as $entry) { if (!in_array($entry['_id'], $e)) { $results['parts'][] = \Models\Parts::findFirst( array( 'partID = ?1', 'bind' => array( 1 => $entry['_id'] ) ) ); $e[] = $entry['_id']; } } } return $results; } /** * searches for a part with the provided URL. * @param string $partURL the url to search for. * @return \Model\Parts|bool the found parts model on success, FALSE otherwise. * @static * @access public */ public static function findFromURL($partURL) { $part = \Models\Parts::findFirst( array( 'partURL = :partURL:', 'bind' => array( 'partURL' => $partURL ) ) ); return $part; } /** * determines the bulk buy options for a particular part. * @return array * @access public */ public function getBulkBuyOptions() { //determine the bulk buy options for this part. $distro = \Models\Distributors::findFromURL('charterpoint'); $opts = array(); if ($distro instanceof \Models\Distributors && $this->countStockParts(array( 'distributorID = ' . $distro->getDistributorID() )) > 0) { $stockParts = $this->getStockParts(array( 'distributorID = ' . $distro->getDistributorID() )); $stockParts->setHydrateMode(\Phalcon\Mvc\Model\Resultset::HYDRATE_ARRAYS); $sp = $stockParts[0]; if ($sp['quantity'] > 20) { $opts = array( 1 => $this->getBulkRate(1), 2 => $this->getBulkRate(2), 5 => $this->getBulkRate(5), 10 => $this->getBulkRate(10), 20 => $this->getBulkRate(20) ); } else { for ($i = 1; $i <= 5; $i++) { $opts[$i] = $this->getBulkRate($i); } } } if(count($opts) == 0) { return; } return $opts; } /** * Returns the parts that have been most ordered according to SAP. * @param int $limit the max amount of parts to return. * @return array an array containing the most ordered parts with a count up to the $limit. * @static * @access public */ public static function findMostOrdered($limit) { $partIDs = \Phalcon\DI::getDefault()->get('modelsManager')->executeQuery( 'SELECT \Models\SAP\Parts.partID, COUNT(\Models\SAP\OrderParts.orderID) FROM \Models\SAP\Parts JOIN \Models\SAP\OrderParts ON \Models\SAP\Parts.partNumber = \Models\SAP\OrderParts.partNumber JOIN \Models\SAP\Orders ON \Models\SAP\OrderParts.orderID = \Models\SAP\Orders.orderID WHERE \Models\SAP\Parts.partID IS NOT NULL AND \Models\SAP\Orders.shortCode LIKE "C-PARTS%" GROUP BY \Models\SAP\Parts.partID ORDER BY COUNT(\Models\SAP\OrderParts.orderID) DESC LIMIT ' . intval($limit) ); $mostOrderedParts = array(); foreach ($partIDs as $partID) { $part = \Models\Parts::findFirst( array( 'partID = :partID:', 'bind' => array( 'partID' => $partID->partID ) ) ); $mostOrderedParts[] = $part; } return $mostOrderedParts; } /** * Returns the parts that have been most recently ordered according to SAP. * @param int $limit the max amount of parts to return. * @return array an array containing the most recently ordered * parts with a count up to the $limit. * @static * @access public */ public static function findRecentlyOrdered($limit) { $partIDs = \Phalcon\DI::getDefault()->get('modelsManager')->executeQuery( 'SELECT DISTINCT \Models\SAP\Parts.partID AS partID FROM \Models\SAP\Parts JOIN \Models\SAP\OrderParts ON \Models\SAP\Parts.partNumber = \Models\SAP\OrderParts.partNumber WHERE \Models\SAP\Parts.partID IS NOT NULL ORDER BY \Models\SAP\OrderParts.orderID DESC LIMIT ' . intval($limit) ); $recentlyOrderedParts = array(); foreach ($partIDs as $partID) { $part = \Models\Parts::findFirst( array( 'partID = :partID:', 'bind' => array( 'partID' => $partID->partID ) ) ); if ($part) { $recentlyOrderedParts[] = $part; } } return $recentlyOrderedParts; } /** * After save event triggered after a model is persisted to the database. * Creates a corresponding elasticsearch index entry for the saved part model. * @return void * @access public */ public function afterSave() { $elasticSearch = \Phalcon\DI::getDefault()->get('elasticSearch'); $quantity = \Models\StockParts::sum( array( 'partID = :partID:', 'bind' => array( 'partID' => $this->getPartID() ), 'column' => 'quantity' ) ); $body = array( 'manufacturer' => $this->getManufacturers()->getManufacturer(), 'partNumber' => $this->getPartNumber(), 'shortDescription' => $this->getShortDescription(), 'partURL' => $this->getPartURL(), 'manufacturerID' => $this->getManufacturers()->getManufacturerID(), 'unitPrice' => $this->getBestPrice(), 'quantity' => $quantity, 'stockParts' => array() ); $title = $this->getTitle(); if ($title != $this->getPartNumber()) { $body['title'] = $title; } $partDescription = $this->getPartDescriptions(); if ($partDescription) { //TODO Strip HTML. $body['longDescription'] = $partDescription->getDescription(); } $subCategory = $this->getSubCategories(); if ($subCategory) { $category = $subCategory->getCategories(); $section = $category->getSections(); $body['category'] = array( 'section' => $section->getSection(), 'category' => $category->getCategory(), 'subCategory' => $subCategory->getSubCategory() ); $body['sectionID'] = $section->getSectionID(); $body['categoryID'] = $category->getCategoryID(); $body['subCategoryID'] = $subCategory->getSubCategoryID(); } $compatibleParts = $this->getCompatibleParts(); if ($compatibleParts && (count($compatibleParts) > 0)) { $body['partFinder'] = array(); foreach ($compatibleParts as $compatiblePart) { $modelNumber = $compatiblePart->getModelNumbers(); $modelFamily = $modelNumber->getModelFamilies(); $systemManufacturer = $modelFamily->getSystemManufacturers(); $body['partFinder'][] = array( 'systemManufacturer' => $systemManufacturer->getSystemManufacturer(), 'modelFamily' => $modelFamily->getModelFamily(), 'modelNumber' => $modelNumber->getModelNumber(), 'systemManufacturerID' => $systemManufacturer->getSystemManufacturerID(), 'modelFamilyID' => $modelFamily->getModelFamilyID(), 'modelNumberID' => $modelNumber->getModelNumberID() ); } } $partFeatures = $this->getPartFeatures(); if ($partFeatures && (count($partFeatures) > 0)) { $body['partFeatures'] = array(); foreach ($partFeatures as $partFeature) { $body['partFeatures'][] = array( $partFeature->getFeature() ); } } $stockParts = $this->getStockParts(); foreach ($stockParts as $stockPart) { $body['stockParts'][] = array( 'distributorID' => $stockPart->getDistributorID(), 'partConditionID' => $stockPart->getPartConditionID(), 'unitPrice' => $stockPart->getUnitPrice(), 'quantity' => $stockPart->getQuantity(), 'estimatedLeadTime' => $stockPart->getEstimatedLeadTime(), 'lastUpdated' => $stockPart->getLastUpdated(), 'validUntil' => $stockPart->getValidUntil(), 'url' => $stockPart->getURL() ); } try { $params = array( 'index' => 'partsit', 'type' => 'parts', 'id' => $this->getPartID(), 'body' => $body, ); if(class_exists('\Elasticsearch\ClientBuilder')) { $params['client'] = array(); $params['client']['ignore'] = array(400, 404); } else { $params['ignore'] = array(400, 404); } $elasticSearch->index( $params ); } catch (\Elasticsearch\Common\Exceptions\Serializer\JsonSerializationError $e) { return; } catch (\Exception $e) { //nothing, just continue to next } } /** * Before delete event triggered before a model is removed from the database. * removes the elasticsearch index entry for this part on part removal. * @return void * @access public */ public function beforeDelete() { $elasticSearch = \Phalcon\DI::getDefault()->get('elasticSearch'); try { $elasticSearch->delete( array( 'index' => 'partsit', 'type' => 'parts', 'id' => $this->getPartID() ) ); } catch (\Elasticsearch\Common\Exceptions\Missing404Exception $e) { } return true; } /** * generates an elastic search query. This function does not execute the query. * @param array $parameters an array of parameters for this query, search term, filters etc. * @return array the constructed elastic search query. * @static * @access private */ private static function generateElasticSearchQuery($parameters) { if (!is_array($parameters)) { $parameters = array($parameters); } $query = '*'; $filters = array(); foreach ($parameters as $key => $parameter) { if (is_int($key) && $parameter) { $query = str_replace('/', '\/', $parameter); } else { switch ($key) { case 'manufacturer': { if ($parameter instanceof \Models\Manufacturers) { $filters['manufacturerID'] = (int) $parameter->getManufacturerID(); } break; } case 'section': { if ($parameter instanceof \Models\Sections) { $filters['sectionID'] = (int) $parameter->getSectionID(); } break; } case 'category': { if ($parameter instanceof \Models\Categories) { $filters['categoryID'] = (int) $parameter->getCategoryID(); } break; } case 'subCategory': { if ($parameter instanceof \Models\SubCategories) { $filters['subCategoryID'] = (int) $parameter->getSubCategoryID(); } break; } case 'systemManfacturer': { if ($parameter instanceof \Models\SystemManfacturers) { $filters['partFinder.systemManufacturerID'] = (int) $parameter->getSystemManufacturerID(); } break; } case 'modelFamily': { if ($parameter instanceof \Models\ModelFamilies) { $filters['partFinder.modelFamilyID'] = (int) $parameter->getModelFamilyID(); } break; } case 'modelNumber': { if ($parameter instanceof \Models\ModelNumbers) { $filters['partFinder.modelNumberID'] = (int) $parameter->getModelNumberID(); } break; } case 'distributor': { if ($parameter instanceof \Models\Distributors) { $filters['stockParts.distributorID'] = (int) $parameter->getDistributorID(); } break; } } } } $body = array( 'query' => array( 'query_string' => array( 'query' => $query, 'default_operator' => 'and' ) ) ); $body['sort'] = array(); if (isset($parameters['sort']) && $parameters['sort']) { foreach ($parameters['sort'] as $field => $order) { $body['sort'][$field] = array( 'order' => $order ); } } else { $body['sort']['_score'] = array( 'order' => 'DESC' ); } if (count($filters) > 0 || (isset($parameters['onlyStock']) && $parameters['onlyStock'])) { $body['filter'] = array( 'and' => array() ); } if (count($filters) > 0) { foreach ($filters as $key => $parameter) { $body['filter']['and'][] = array( 'bool' => array( 'must' => array( 'term' => array( $key => $parameter ) ) ) ); } } if (isset($parameters['onlyStock']) && $parameters['onlyStock']) { $body['filter']['and'][] = array( 'range' => array( 'quantity' => array( 'from' => 1 ) ) ); $body['filter']['and'][] = array( 'range' => array( 'unitPrice' => array( 'from' => 1 ) ) ); } return $body; } public static function search( $parameters, $pageNumber = 1, $itemsPerPage = 20) { //TODO Log search. $body = \Models\Parts::generateElasticSearchQuery($parameters); $startIndex = (($pageNumber - 1) * $itemsPerPage); $body['from'] = $startIndex; $body['size'] = $itemsPerPage; $elasticSearch = \Phalcon\DI::getDefault()->get('elasticSearch'); $params = array( 'index' => 'partsit', 'type' => 'parts', 'body' => $body ); $params['client'] = array(); $params['client']['ignore'] = array(400, 404); $results = $elasticSearch->search( $params ); $partsFromSearch = $results['hits']['hits']; $parts = array(); foreach ($partsFromSearch as $part) { $part = \Models\Parts::findFirst( array( 'partID = :partID:', 'bind' => array( 'partID' => $part['_id'] ), //TODO Cache as partURL or ID? 'cache' => array( 'key' => 'parts:id:' . $part['_id'], 'lifetime' => 86400 // 1 day ) ) ); if (!$part) { \Phalcon\DI::getDefault()->get('queue')->put( array( 'task' => 'mail', 'action' => 'elasticSearchError', 'params' => array( 'parameters' => $parameters, 'pageNumber' => $pageNumber, 'itemsPerPage' => $itemsPerPage ) ) ); continue; } $parts[] = $part; } //sort the part results as some of the results may not have a stock part index entry. //this will be a double check. uasort($parts, function($a, $b){ $as = $a->getBestPrice(array('format' => false)); $bs = $b->getBestPrice(array('format' => false)); $as = (!$as) ? 0 : $as; $bs = (!$bs) ? 0 : $bs; if($as == $bs) { return 0; } return ($as > $bs) ? -1 : 1; }); return array( 'query' => ((isset($parameters[0])) ? $parameters[0] : '*'), 'pageNumber' => $pageNumber, 'itemsPerPage' => $itemsPerPage, 'totalResults' => $results['hits']['total'], 'parts' => $parts ); } public static function searchDistinct($field, $parameters, $limit = 20) { $body = \Models\Parts::generateElasticSearchQuery($parameters); $body['facets'] = array( 'tag' => array( 'terms' => array( 'field' => $field, 'size' => $limit ) ) ); $ignoreArrays = array( 'partFinder' => array( 'systemManufacturerID' => 'partFinder.systemManufacturerID', 'modelFamilyID' => 'partFinder.modelFamilyID', 'modelNumberID' => 'partFinder.modelNumberID' ), 'categories' => array( 'sectionID' => 'sectionID', 'categoryID' => 'categoryID', 'subCategoryID' => 'subCategoryID' ) ); if (isset($body['filter']['and'])) { foreach ($ignoreArrays as $ignoreArray) { if (!array_key_exists($field, $ignoreArray)) { continue; } foreach ($ignoreArray as $ignore) { foreach ($body['filter']['and'] as $i => $filter) { if (array_key_exists($ignore, $filter['bool']['must']['term'])) { unset($body['filter']['and'][$i]); } } } } if (count($body['filter']['and']) == 0) { unset($body['filter']['and']); } if (count($body['filter']) == 0) { unset($body['filter']); } } $body['facets']['tag']['facet_filter'] = $body['filter']; $elasticSearch = \Phalcon\DI::getDefault()->get('elasticSearch'); $results = $elasticSearch->search( array( 'index' => 'partsit', 'type' => 'parts', 'body' => $body, 'client' => array( 'ignore' => array( 404, 400 ) ) ) ); $results = $results['facets']['tag']['terms']; foreach ($results as $i => $result) { $results[$i] = $result['term']; } return $results; } public static function searchTechSpecs($parameters) { $body = \Models\Parts::generateElasticSearchQuery($parameters); unset($body['sort']); $elasticSearch = \Phalcon\DI::getDefault()->get('elasticSearch'); $results = $elasticSearch->search( array( 'index' => 'partsit', 'type' => 'parts', 'body' => $body ) ); $techSpecs = array(); $parts = $results['hits']['hits']; foreach ($parts as $part) { if (!isset($part['_source']['partTechSpecs'])) { continue; } foreach ($part['_source']['partTechSpecs'] as $partTechSpec) { $name = $partTechSpec['name']; $value = $partTechSpec['value']; if (!array_key_exists($name, $techSpecs)) { $techSpecs[$name] = array(); } if (!in_array($value, $techSpecs[$name])) { $techSpecs[$name][] = $value; } } } return $techSpecs; } public static function searchJSON($query) { $elasticSearch = \Phalcon\DI::getDefault()->get('elasticSearch'); $results = $elasticSearch->search( array( 'index' => 'partsit', 'type' => 'parts', 'body' => array( 'query' => array( 'query_string' => array( 'query' => $query ) ), 'facets' => array( 'tag' => array( 'terms' => array( 'field' => 'tag', 'size' => 10, 'order' => 'term' ) ) ), 'from' => 0, 'size' => 10 ), 'ignore' => array( 404, 400 ) ) ); $parts = $results['hits']['hits']; foreach ($parts as $i => $part) { $parts[$i] = array( 'description' => $part['_source']['shortDescription'], 'value' => $part['_source']['manufacturer'] . ' ' . $part['_source']['partNumber'], 'partURL' => $part['_source']['partURL'] ); } return json_encode($parts); } public static function searchAutocomplete($query) { $elasticSearch = \Phalcon\DI::getDefault()->get('elasticSearch'); $results = $elasticSearch->search( array( 'index' => 'partsit', 'type' => 'parts', 'body' => array( 'query' => array( 'query_string' => array( 'query' => $query, 'default_operator' => 'and' ) ), 'from' => 0, 'size' => 10 ), 'client' => array( 'ignore' => array( 404, 400 ) ) ) ); $parts = $results['hits']['hits']; foreach ($parts as $i => $part) { $de = $part['_source']['partNumber'] . ' ' . $part['_source']['shortDescription']; $desc = (strlen($de) > 35) ? substr($de, 0, 35) . '...' : $de; $parts[$i] = array( 'label' => $desc, 'value' => '/product/' . $part['_source']['partURL'] ); } if ($results['hits']['total'] > 10) { $parts[] = array( 'label' => 'more > >', 'value' => '/search?q=' . $query ); } return json_encode($parts); } public function getPartID() { return $this->partID; } public function getPartNumber() { return $this->partNumber; } public function getManufacturerID() { return $this->manufacturerID; } public function getTitle() { return ($this->title ?: $this->getPartNumber()); } public function getPartURL() { return $this->partURL; } public function getShortDescription($force = false) { if($force) { return $this->shortDescription; } if(isset($this->title)) { $t = $this->title; $m = $this->getManufacturers(); $m = ($m) ? $m->getManufacturer() : ''; if(strpos(strtolower($t), strtolower($m)) === false) { return $m . $t; } return $t; } return $this->shortDescription; } public function getSubCategoryID() { return $this->subCategoryID; } public function getDateCreated() { return $this->dateCreated; } public function getDateModified() { return $this->dateModified; } public function getAvailableQuantity() { $availableQuantity = \Models\StockParts::sum( array( 'partID = :partID:', 'bind' => array( 'partID' => $this->getPartID() ), 'column' => 'quantity' ) ); return $availableQuantity; } public function getRefurbishedPrice($update = false, $format = false) { //if update, this function forcefully updates ebay, brokerbin & alibaba. if($update) { $console = \Phalcon\DI::getDefault()->get('console'); //ebay. $console->handle( array( 'task' => 'ebay', 'action' => 'importIndividual', 'params' => array( 0 => $this->getPartID() ) ) ); //brokerbin. $console->handle( array( 'task' => 'brokerbin-parts', 'action' => 'importIndividualForce', 'params' => array( 0 => $this->getPartID() ) ) ); } $ebay = \Models\Distributors::findFromURL('ebay'); $bb = \Models\Distributors::findFromURL('brokerbin'); $ali = \Models\Distributors::findFromURL('alibaba'); //see if there is a price from these three sources and return the cheapest. $stockPart = \Models\StockParts::findFirst( array( 'partID = :partID: AND distributorID IN (:ebay:,:bb:,:ali:)', 'order' => 'unitPrice ASC', 'bind' => array( 'ebay' => $ebay->getDistributorID(), 'bb' => $bb->getDistributorID(), 'ali' => $ali->getDistributorID(), 'partID' => $this->getPartID() ) ) ); if(!$stockPart) { return false; } //times by 1.15. $price = round((floatval($stockPart->getUnitPrice()) * 1.15), 2); if($format) { return number_format($price, 2); } return $price; } public function getBestStockPart($parameters = array()) { $defaultParameters = array( 'minLeadTime' => 0, 'maxLeadTime' => 7 ); $distro = \Models\Distributors::findFromURL('charterpoint'); $stockPart = \Models\StockParts::findFirst(array( 'partID = :partID: AND distributorID = :disID:', 'bind' => array( 'partID' => $this->getPartID(), 'disID' => $distro->getDistributorID() ) )); if(!$stockPart) { $parameters = is_array($parameters) ? array_merge($defaultParameters, $parameters) : $defaultParameters; $ebay = \Models\Distributors::findFromURL('ebay'); $bb = \Models\Distributors::findFromURL('brokerbin'); $ali = \Models\Distributors::findFromURL('alibaba'); /* distributorID NOT IN (:ebay:,:bb:,:ali:) */ $stockPart = \Models\StockParts::findFirst( array( 'partID = :partID: AND (estimatedLeadTime BETWEEN :minLeadTime: AND :maxLeadTime:) AND quantity > 0 AND distributorID IN (1,26,23,28,25,63,12,29,74,21,68,75,76,77,64,11,78) ', 'bind' => array( 'partID' => $this->getPartID(), 'minLeadTime' => $parameters['minLeadTime'], 'maxLeadTime' => $parameters['maxLeadTime'], /**'ebay' => $ebay->getDistributorID(), 'bb' => $bb->getDistributorID(), 'ali' => $ali->getDistributorID()**/ ), 'order' => array( 'unitPrice' ) ) ); if(!$stockPart) { $stockPart = \Models\StockParts::findFirst( array( 'partID = :partID: AND (estimatedLeadTime BETWEEN :minLeadTime: AND :maxLeadTime:) AND distributorID IN (1,26,23,28,25,63,12,29,74,21,68,75,76,77,64,11,78) ', 'bind' => array( 'partID' => $this->getPartID(), 'minLeadTime' => $parameters['minLeadTime'], 'maxLeadTime' => $parameters['maxLeadTime'], /**'ebay' => $ebay->getDistributorID(), 'bb' => $bb->getDistributorID(), 'ali' => $ali->getDistributorID()**/ ), 'order' => array( 'unitPrice' ) ) ); } } return $stockPart; } /** * determines if this part has a valid fixed price. * @return \Models\FixedPrice|bool returns the fixed price on true, false otherwise. * @access public */ public function hasFixedPrice() { $now = new \DateTime(); $now = $now->format('Y-m-d'); $fixedPrice = \Models\FixedPrice::findFirst(array( 'partID = ?1 AND validTo > ?2', 'bind' => array( 1 => $this->getPartID(), 2 => $now ) )); return ($fixedPrice instanceof \Models\FixedPrice) ? $fixedPrice : false; } /** * A new pricing function which utilizes a new markup schema. * valid parameters are: * single : true|false - whether to just return the price for one. * quantity : int - whether to get the price for a specific quantity * vat : true|false - whether to calculate vat for the prices. * format : true|false - whether to format the price. * */ public function getBestPrice($parameters = array()) { $now = new \DateTime(); $now = $now->format('Y-m-d'); $salePrice = 0; $quantity = 1; $single = (isset($parameters['single'])) ? $parameters['single'] : true; $invalidBrokers = \Models\Metadata::get('pricing', 'invalidBrokers'); $invalidBrokers = json_decode($invalidBrokers->getValue(), true); //make sure they every element is an int. array_walk($invalidBrokers, function(&$value){ $value = intval($value); }); $isFromInvalid = false; $hasVat = (isset($parameters['vat']) && is_bool($parameters['vat'])) ? $parameters['vat'] : false; //fixed prices now are cost prices, so then the matrix can work out //quantity based prices based on the formula. $fixedPrice = \Models\FixedPrice::findFirst(array( 'partID = ?1 AND validTo > ?2', 'bind' => array( 1 => $this->getPartID(), 2 => $now ) )); $hasCustomMarkup = false; if(!$fixedPrice) { //if this product is on promotion, always use the //distributor which was used. $promo = $this->getPromotion(); if($promo instanceof \Models\PromoParts) { //if its any promotion type. $stockPart = $promo->getStockParts(); } if(!isset($stockPart) || !$stockPart) { $stockPart = $this->getBestStockPart($parameters); } if (!$stockPart) { return false; } $isFromInvalid = (in_array($stockPart->getDistributorID(), $invalidBrokers)); $salePrice = $stockPart->getUnitPrice(); $quantity = ($stockPart->getQuantity() < 2) ? 10 : $stockPart->getQuantity(); $hasCustomMarkup = (\Models\CustomDistributorMarkup::count( array( 'distributorID = ?1', 'bind' => array( 1 => $stockPart->getDistributorID() ) ) ) > 0); } else { $salePrice = $fixedPrice->getPrice(); $quantity = $fixedPrice->getQuantity(); if(!isset($quantity)) { $quantity = 10; //default a fixed price quantity to 10. } $hasCustomMarkup = $fixedPrice->hasCustomMarkup(); } $salePrice = floatval($salePrice); $quantity = intval($quantity); if($salePrice == 0) { $hasRequired = ($fixedPrice instanceof \Models\FixedPrice && $fixedPrice->getRequiredSalePrice() > 0); if(!$hasRequired) { return false; } } $quantitiesShown = \Models\Metadata::get('pricing', 'quantitiesShown'); $quantitiesShown = json_decode($quantitiesShown->getValue(), true); //make sure they every element is an int. array_walk($quantitiesShown, function(&$value){ $value = intval($value); }); //work out quantity based prices based on the markup. $prices = array(); $quantitiesShown = (isset($parameters['quantity']) && is_numeric($parameters['quantity'])) ? array($parameters['quantity']) : $quantitiesShown; $single = (isset($parameters['quantity']) && is_numeric($parameters['quantity'])) ? true : $single; $markup = \Models\Metadata::findFirst('category = "pricing" and name = "markupRange"'); $markup = json_decode($markup->getValue(), true); //determine if the price was from an un-reliable source. $quantitiesShown = (!$isFromInvalid) ? $quantitiesShown : array(1); $del = \Models\Metadata::get('pricing', 'deliveryCost'); $del = floatval($del->getValue()); $mov = \Models\Metadata::get('pricing', 'minimumOrderValue'); $mov = floatval($mov->getValue()); $minusvat = \Models\Metadata::get('pricing', 'minus-vat'); $minusvat = floatval($minusvat->getValue()); $vat = \Models\Metadata::get('pricing', 'vat'); $vat = floatval($vat->getValue()); foreach($quantitiesShown as $q) { if($q <= $quantity) { //if we have enough data to show this price. //determine if we are a fixed price and if we have a required sale price. if($fixedPrice instanceof \Models\FixedPrice) { $rsp = $fixedPrice->getRequiredSalePrice(); if(isset($rsp) && $rsp > 0 && $rsp > $fixedPrice->getPrice()) { //generate the sale price by reverse engineering the rsp. $rsp -= $del; foreach ($markup as $entry) { if($rsp >= floatval($entry['min']) && ($rsp <= floatval($entry['max']) || intval($entry['max'] == -1))) { //if the price is within the range, apply the markup. switch($entry['type']) { case '+': $rsp -= (floatval($entry['amount'])); break; case '*': $rsp /= (floatval($entry['amount'])); break; } break; } } $salePrice = $rsp; } } //die(var_dump($salePrice)); $up = $salePrice * $q; if($fixedPrice instanceof \Models\FixedPrice && $hasCustomMarkup) { $up = $fixedPrice->generatePrice($up); } elseif(isset($stockPart) && $hasCustomMarkup) { $c = \Models\CustomDistributorMarkup::find( array( 'distributorID = ?1', 'bind' => array( 1 => $stockPart->getDistributorID() ), 'order' => 'distributorID, min' ) ); foreach ($c as $cu) { if($up >= floatval($cu->getMin()) && ($up <= floatval($cu->getMax()) || intval($cu->getMax()) == -1)) { $custom = $cu; } } if ($custom instanceof \Models\CustomDistributorMarkup) { $up = $custom->generatePrice($up); } else { //if there is no valid range for this markup use default price structure. $up = $this->applyMarkup($markup, $up); } } else { $up = $this->applyMarkup($markup, $up); } //add delivery. $up += $del; //determine if the price is below the minimum order value. if($up < $mov) { $up = $mov; //set the minimum order value. } if($hasVat) { //add vat. $up *= $vat; } //apply options. // //ex-vat. // if(isset($parameters['vat']) && !$parameters['vat']) { // $up *= $minusvat; // } //whether to number_format the price. if(isset($parameters['format']) && $parameters['format']) { $up = number_format($up, 2, '.', ''); } //as the basket works in the unit price, we need to make sure //any rounding error is dealt with at this point in order to //stop the risk of the prices being inaccurate when its transfered to the //basket. $s = round($up / $q, 2); $up = $s * $q; $prices[$q] = $up; } } if($single) { //return the price for a single part. $prices = array_values($prices); return $prices[0]; } return $prices; } private function applyMarkup($markup, $up) { foreach ($markup as $entry) { if($up >= floatval($entry['min']) && ($up <= floatval($entry['max']) || intval($entry['max'] == -1))) { //if the price is within the range, apply the markup. switch($entry['type']) { case '+': $up += (floatval($entry['amount'])); break; case '*': $up *= (floatval($entry['amount'])); break; } break; } } return $up; } public function isInStock() { return ($this->countStockParts() > 0); } public function hasPartImage() { $manufacturerURL = $this->getManufacturers()->getManufacturerURL(); $imageFolder = '/img/products/' . $manufacturerURL . '/' . $this->getPartURL(); $images = is_dir('../public' . $imageFolder) ? scandir('../public' . $imageFolder) : array(); sort($images); foreach ($images as $image) { if ($image == '.' || $image == '..') { continue; } return true; } return false; } public function getPartImage() { //determine if this product has any internet images. $images = $this->getImages(); if(count($images) > 0) { $i = $images[0]; return '/resources/image/' . $i->getHash(); } $manufacturerURL = $this->getManufacturers()->getManufacturerURL(); $imageFolder = 'img/products/' . $manufacturerURL . '/' . $this->getPartURL(); $images = is_dir('../public/' . $imageFolder) ? scandir('../public/' . $imageFolder) : array(); sort($images); foreach ($images as $image) { if ($image == '.' || $image == '..') { continue; } $extension = pathinfo('../public/'.$imageFolder.'/'.$image, PATHINFO_EXTENSION); if(!isset($extension) || !in_array($extension, array('jpg', 'jpeg', 'png', 'gif', 'svg'))) { continue; } return rtrim($this->getDI()->get('url')->getBaseUri(), '/') . '/' . $imageFolder . '/' . $image; } $manufacturerImage = $this->getManufacturers()->getManufacturerImage(); return ($manufacturerImage) ? $manufacturerImage : rtrim($this->getDI()->get('url')->getBaseUri(), '/') . '/img/placeholder.png'; } public static function countPartsWithImages() { return PartImages::count(array( 'action = "approve"' )); } public function getSimilarProducts($number = 4) { $query = $this->getManufacturers()->getManufacturer() . ' ' . $this->getPartNumber() . ' ' . $this->getShortDescription(); if ($this->getTitle() != $this->getPartNumber()) { $query .= ' ' . $this->getTitle(); } $query = preg_replace('/[^a-z0-9\-\._]/i', ' ', $query); $body = \Models\Parts::generateElasticSearchQuery( array( $query ) ); $body['facets'] = array( 'tag' => array( 'terms' => array( 'field' => 'tag', 'size' => $number, 'order' => 'term' ) ) ); /* * We need to remove the current part from the search. We're * assuming it'll be one of the first. */ $body['size'] = ($number + 1); $elasticSearch = \Phalcon\DI::getDefault()->get('elasticSearch'); $results = $elasticSearch->search( array( 'index' => 'partsit', 'type' => 'parts', 'body' => $body, 'client' => array( 'ignore' => array(404, 400) ) ) ); $parts = $results['hits']['hits']; foreach ($parts as $i => $part) { if ($part['_source']['partURL'] == $this->getPartURL()) { unset($parts[$i]); continue; } $parts[$i] = \Models\Parts::findFirst( array( 'partID = :partID:', 'bind' => array( 'partID' => $part['_id'] ), 'cache' => array( 'key' => 'parts:id:' . $part['_id'], 'lifetime' => 86400 // 1 day ) ) ); } // Just in case this part wasn't in the search results. $parts = array_splice($parts, 0, $number); return $parts; } public function getOverallRating() { $overallRating = \Models\Reviews::average( array( 'column' => 'starRating', 'partID = :partID: AND isApproved = 1', 'bind' => array( 'partID' => $this->getPartID() ) ) ); return round($overallRating, 2); } public function setPartNumber($partNumber) { $this->partNumber = $partNumber; } public function setManufacturerID($manufacturerID) { $this->manufacturerID = $manufacturerID; } public function setTitle($title) { $this->title = $title; } public function setPartURL($partURL) { $this->partURL = $partURL; } public function setShortDescription($shortDescription) { $filter = $this->getDI()->get('filter'); $shortDescription = $filter->sanitize($shortDescription, 'description'); $this->shortDescription = $shortDescription; } public function setSubCategoryID($subCategoryID) { $this->subCategoryID = $subCategoryID; } public function asArray() { $averagePrice = \Models\StockParts::average( array( 'partID = :partID:', 'bind' => array( 'partID' => $this->getPartID() ), 'column' => 'unitPrice' ) ); $quantity = \Models\StockParts::sum( array( 'partID = :partID:', 'bind' => array( 'partID' => $this->getPartID() ), 'column' => 'quantity' ) ); return array( 'manufacturer' => $this->getManufacturers()->getManufacturer(), 'partNumber' => $this->getPartNumber(), 'shortDescription' => $this->getShortDescription(), 'averagePrice' => number_format($averagePrice, 2, '.', ''), 'quantity' => number_format($quantity, 0, '.', ''), 'url' => 'https://www.partsit.com/product/' . $this->getPartURL() ); } public function changeManufacturer(\Models\Manufacturers $newManufacturer) { //TODO Change part image location, if there is one. $oldManufacturer = $this->getManufacturers(); $oldManufacturerURL = $oldManufacturer->getManufacturerURL(); $oldPartURL = $this->getPartURL(); $newManufacturerURL = $newManufacturer->getManufacturerURL(); if (substr($oldPartURL, 0, strlen($oldManufacturerURL)) != $oldManufacturerURL) { throw new \Exception('Old Part URL is bad: <strong>' . $oldPartURL . '</strong>'); } $newPartURL = $newManufacturerURL . substr($oldPartURL, strlen($oldManufacturerURL)); $tempPart = \Models\Parts::findFirst( array( 'partURL = :partURL:', 'bind' => array( 'partURL' => $newPartURL ) ) ); if ($tempPart) { throw new \Exception('New Part URL already exists: <strong>' . $newPartURL . '</strong>'); } $this->setPartURL( $newPartURL ); $this->setManufacturerID( $newManufacturer->getManufacturerID() ); $this->save(); return $this; } //TODO public function getSapParts() { $sapPart = \Models\SAP\Parts::findFirst( array( 'manufacturer = :manufacturer: AND partNumber = :partNumber:', 'bind' => array( 'manufacturer' => $this->getManufacturers()->getManufacturer(), 'partNumber' => $this->getPartNumber() ) ) ); return $sapPart; } public function getSubCategories($parameters = array()) { if (isset($parameters[0])) { $parameters[0] = '(' . $parameters[0] . ') AND subCategoryID = :subCategoryID:'; } else { $parameters[0] = 'subCategoryID = :subCategoryID:'; } if (!isset($parameters['bind'])) { $parameters['bind'] = array(); } $parameters['bind']['subCategoryID'] = $this->getSubCategoryID(); $parameters['cache'] = array( 'key' => 'subCategories:id:' . $this->getSubCategoryID(), 'lifetime' => 604800 // 1 week ); $subCategory = \Models\SubCategories::findFirst( $parameters ); return $subCategory; } public function getManufacturers($parameters = array()) { if (isset($parameters[0])) { $parameters[0] = '(' . $parameters[0] . ') AND manufacturerID = :manufacturerID:'; } else { $parameters[0] = 'manufacturerID = :manufacturerID:'; } if (!isset($parameters['bind'])) { $parameters['bind'] = array(); } $parameters['bind']['manufacturerID'] = $this->getManufacturerID(); $parameters['cache'] = array( 'key' => 'manufacturers:id:' . $this->getManufacturerID(), 'lifetime' => 604800 // 1 week ); $manufacturer = \Models\Manufacturers::findFirst( $parameters ); return $manufacturer; } public function getAlternateParts() { $alternateParts1 = \Models\AlternateParts::find( array( 'partID = :partID:', 'bind' => array( 'partID' => $this->getPartID() ) ) ); $alternateParts2 = \Models\AlternateParts::find( array( 'alternativePartID = :alternativePartID:', 'bind' => array( 'alternativePartID' => $this->getPartID() ) ) ); $alternateParts = array(); foreach ($alternateParts1 as $alternatePart1) { $alternatePart = $alternatePart1->getAlternativeParts(); $alternateParts[] = $alternatePart; } foreach ($alternateParts2 as $alternatePart2) { $alternatePart = $alternatePart2->getParts(); if (in_array($alternatePart, $alternateParts)) { continue; } $alternateParts[] = $alternatePart; } return $alternateParts; } public function getFeaturesByGroup($columns = 3) { $config = new \Phalcon\Config\Adapter\Ini( 'config/' . ENVIRONMENT . '.ini' ); $connection = new \Phalcon\Db\Adapter\Pdo\Mysql(array( 'host' => $config->dbPartsIT->hostname, 'username' => $config->dbPartsIT->username, 'password' => $config->dbPartsIT->password, 'dbname' => $config->dbPartsIT->database )); $connection->connect(); $query = 'SELECT feature_group.name as name, featureID as id FROM partsit.part_features INNER JOIN feature_group USING (groupId) WHERE part_features.partID = ? ORDER BY feature_group.name ASC'; $result = $connection->query($query, array($this->getPartID())); $result->setFetchMode(\Phalcon\Db::FETCH_ASSOC); $results = $result->fetchAll($result); //return an array of array('feature_name' => array(feature_models)); $data = array(); foreach($results as $entry) { if(!array_key_exists($entry['name'], $data)) { $data[$entry['name']] = array(); } $data[$entry['name']][] = \Models\PartFeatures::findFirst(array('featureID = ?1', 'bind' => array(1 => $entry['id']))); } $data = array_chunk($data, ceil(count($data) / $columns), true); return $data; } } |
#10 | Models\Parts::searchTechSpecs(Array([0] => null, [onlyStock] => , [section] => Object(Models\Sections), [category] => Object(Models\Categories), [subCategory] => Object(Models\SubCategories), [manufacturer] => , [modelNumber] => , [partTechSpecs] => Array())) /home/ubuntu/partsit-site/app/controllers/CategoryController.php (777) <?php namespace Controllers; class CategoryController extends \Controllers\ControllerBase { public function indexAction() { return $this->response->redirect( 'categories' ); } public function sectionAction() { $selectedSectionURL = $this->dispatcher->getParam('sectionURL', 'urlSlug'); $pageNumber = $this->request->getQuery('page') ?: 1; $query = $this->request->getQuery('q', 'trim'); $selectedManufacturerURL = $this->request->getQuery('manufacturer', 'urlSlug'); $selectedModelNumberID = $this->request->getQuery('modelNumber', 'int'); $selectedTechSpecs = $this->request->getQuery('techSpecs'); $showOnlyStock = !!$this->request->getQuery('onlyStock'); $itemsPerPage = $this->request->getQuery('itemsPerPage', 'int', 10); // Force a hard maximum of 100 for the items per page. $itemsPerPage = min($itemsPerPage, 100); $selectedSection = \Models\Sections::findFromURL( $selectedSectionURL ); if (!$selectedSection) { return $this->error404(); } $selectedManufacturer = ($selectedManufacturerURL) ? \Models\Manufacturers::findFromURL($selectedManufacturerURL) : false; $selectedModelNumber = ($selectedModelNumberID) ? \Models\ModelNumbers::findFirstByModelNumberID($selectedModelNumberID) : false; $searchParameters = array( $query, 'onlyStock' => $showOnlyStock, 'section' => $selectedSection, 'manufacturer' => $selectedManufacturer, 'modelNumber' => $selectedModelNumber, 'partTechSpecs' => array(), 'sort' => array( 'manufacturer' => 'ASC', 'partNumber' => 'ASC' ) ); $nonMan = array( $query, 'onlyStock' => $showOnlyStock, 'section' => $selectedSection, 'modelNumber' => $selectedModelNumber, 'partTechSpecs' => array(), 'sort' => array( 'manufacturer' => 'ASC', 'partNumber' => 'ASC' ) ); if ($selectedTechSpecs) { foreach ($selectedTechSpecs as $selectedTechSpecName => $selectedTechSpecValue) { if (!$selectedTechSpecName) { continue; } $selectedTechSpecName = preg_replace('/[^a-z0-9]+/i', '', $selectedTechSpecName); $searchParameters['partTechSpecs'][$selectedTechSpecName] = $selectedTechSpecValue; } } $results = \Models\Parts::search( $searchParameters, $pageNumber, $itemsPerPage ); $parts = $results['parts']; $totalResults = $results['totalResults']; $url = '/category/' . $selectedSectionURL . '/'; $url .= '?' . http_build_query( array( 'q' => $query, 'onlyStock' => $showOnlyStock, 'manufacturer' => $selectedManufacturerURL, 'modelNumber' => $selectedModelNumberID, 'itemsPerPage' => $itemsPerPage, 'page' => '' ), null, '&' ); $sections = \Models\Sections::find( array( 'order' => 'section ASC' ) ); $categories = $selectedSection->getCategories( array( 'order' => 'category ASC' ) ); $filterManufacturers = \Models\Parts::searchDistinct('manufacturerID', $nonMan, 1000); $filterSystemManufacturers = \Models\Parts::searchDistinct('systemManufacturerID', $searchParameters, 1000); $filterModelFamilies = \Models\Parts::searchDistinct('modelFamilyID', $searchParameters, 1000); $filterModelNumbers = \Models\Parts::searchDistinct('modelNumberID', $searchParameters, 1000); $manufacturers = \Models\Manufacturers::find( array( 'order' => 'manufacturer ASC' ) ); $techSpecs = \Models\Parts::searchTechSpecs($searchParameters); $this->view->sections = $sections; $this->view->categories = $categories; $this->view->techSpecs = $techSpecs; $this->view->filterManufacturers = $filterManufacturers; $this->view->filterSystemManufacturers = $filterSystemManufacturers; $this->view->filterModelFamilies = $filterModelFamilies; $this->view->filterModelNumbers = $filterModelNumbers; $this->view->manufacturers = $manufacturers; $this->view->parts = $parts; $this->view->selectedSection = $selectedSection; $this->view->selectedManufacturer = $selectedManufacturer; $this->view->selectedTechSpecs = $selectedTechSpecs; $this->view->selectedModelNumber = $selectedModelNumber; $this->view->itemsPerPage = $itemsPerPage; $this->view->query = $query; $this->view->showOnlyStock = $showOnlyStock; $this->view->totalResults = $totalResults; $this->view->pagination = array( 'pageNumber' => $pageNumber, 'itemsPerPage' => $itemsPerPage, 'totalItems' => $totalResults, 'url' => $url, 'what' => 'product' ); $this->tag->prependTitle( $selectedSection->getSection() . ' parts | ' ); //Show Special offers on the side of search reults. $d = \Models\Metadata::findFirst('category = "promotional" and name = "distributors"'); $distis = json_decode($d->getValue(), true); //get selected SECTION $getSec = $selectedSection->getSection(); $cats = array(); foreach($categories as $cat) { $cats[] = $cat->getCategoryURL(); } $manus = array(); $fs = array( 'distributor_urls' => $distis, 'category_urls' => $cats, 'manufacturer_urls' => $manus ); //get 4 random special offers per page, including a mail shot entry if we need to. $msi = mt_rand(0, 4); $template = new \Template(); $template->setTemplateDir('offer-views'); $offers = \Models\PromoParts::getSitePromotions($fs, 2, 1, false); //render the html for the selected offers. //format the params. $params = array(); if(count($offers > 0)) { for($i = 0; $i < count($offers); $i++) { if($i == $msi) { //enter this first at this index. $params[] = array( 'type' => 'mailshot', 'object' => null ); } $params[] = array('type' => 'promo', 'object' => $offers[$i]); } } $html = $template->renderTemplate('offers', 'home', array('objects' => $params)); $this->view->initialOffers = $html; } public function categoryAction() { $selectedSectionURL = $this->dispatcher->getParam('sectionURL', 'urlSlug'); $selectedCategoryURL = $this->dispatcher->getParam('categoryURL', 'urlSlug'); $pageNumber = $this->request->getQuery('page') ?: 1; $query = $this->request->getQuery('q', 'trim'); $selectedManufacturerURL = $this->request->getQuery('manufacturer', 'urlSlug'); $selectedModelNumberID = $this->request->getQuery('modelNumber', 'int'); $selectedTechSpecs = $this->request->getQuery('techSpecs'); $showOnlyStock = !!$this->request->getQuery('onlyStock'); $itemsPerPage = $this->request->getQuery('itemsPerPage', 'int', 10); // Force a hard maximum of 100 for the items per page. $itemsPerPage = min($itemsPerPage, 100); $selectedCategory = \Models\Categories::findFromURL( $selectedSectionURL, $selectedCategoryURL ); if (!$selectedCategory) { return $this->error404(); } $selectedSection = $selectedCategory->getSections(); $selectedManufacturer = ($selectedManufacturerURL) ? \Models\Manufacturers::findFromURL($selectedManufacturerURL) : false; $selectedModelNumber = ($selectedModelNumberID) ? \Models\ModelNumbers::findFirstByModelNumberID($selectedModelNumberID) : false; $searchParameters = array( $query, 'onlyStock' => $showOnlyStock, 'category' => $selectedCategory, 'manufacturer' => $selectedManufacturer, 'modelNumber' => $selectedModelNumber, 'partTechSpecs' => array(), 'sort' => array( 'manufacturer' => 'ASC', 'partNumber' => 'ASC' ) ); $nonMan = array( $query, 'onlyStock' => $showOnlyStock, 'category' => $selectedCategory, 'modelNumber' => $selectedModelNumber, 'partTechSpecs' => array(), 'sort' => array( 'manufacturer' => 'ASC', 'partNumber' => 'ASC' ) ); if ($selectedTechSpecs) { foreach ($selectedTechSpecs as $selectedTechSpecName => $selectedTechSpecValue) { if (!$selectedTechSpecName) { continue; } $selectedTechSpecName = preg_replace('/[^a-z0-9]+/i', '', $selectedTechSpecName); $searchParameters['partTechSpecs'][$selectedTechSpecName] = $selectedTechSpecValue; } } $results = \Models\Parts::search( $searchParameters, $pageNumber, $itemsPerPage ); $parts = $results['parts']; $totalResults = $results['totalResults']; $url = '/category/' . $selectedSectionURL . '/' . $selectedCategoryURL . '/'; $url .= '?' . http_build_query( array( 'q' => $query, 'onlyStock' => $showOnlyStock, 'manufacturer' => $selectedManufacturerURL, 'modelNumber' => $selectedModelNumberID, 'itemsPerPage' => $itemsPerPage, 'page' => '' ), null, '&' ); $sections = \Models\Sections::find( array( 'order' => 'section ASC' ) ); $categories = $selectedSection->getCategories( array( 'order' => 'category ASC' ) ); $subCategories = $selectedCategory->getSubCategories( array( 'order' => 'subCategory ASC' ) ); //TODO $filterManufacturers = \Models\Parts::searchDistinct('manufacturerID', $nonMan, 1000); $filterSystemManufacturers = \Models\Parts::searchDistinct('systemManufacturerID', $searchParameters, 1000); $filterModelFamilies = \Models\Parts::searchDistinct('modelFamilyID', $searchParameters, 1000); $filterModelNumbers = \Models\Parts::searchDistinct('modelNumberID', $searchParameters, 1000); $manufacturers = \Models\Manufacturers::find( array( 'order' => 'manufacturer ASC' ) ); $techSpecs = \Models\Parts::searchTechSpecs($searchParameters); $this->view->sections = $sections; $this->view->categories = $categories; $this->view->subCategories = $subCategories; $this->view->techSpecs = $techSpecs; $this->view->filterManufacturers = $filterManufacturers; $this->view->filterSystemManufacturers = $filterSystemManufacturers; $this->view->filterModelFamilies = $filterModelFamilies; $this->view->filterModelNumbers = $filterModelNumbers; $this->view->manufacturers = $manufacturers; $this->view->parts = $parts; $this->view->selectedSection = $selectedSection; $this->view->selectedCategory = $selectedCategory; $this->view->selectedManufacturer = $selectedManufacturer; $this->view->selectedTechSpecs = $selectedTechSpecs; $this->view->selectedModelNumber = $selectedModelNumber; $this->view->itemsPerPage = $itemsPerPage; $this->view->query = $query; $this->view->manufacturerURL = @$manufacturerURL; $this->view->showOnlyStock = $showOnlyStock; $this->view->totalResults = $totalResults; $this->view->pagination = array( 'pageNumber' => $pageNumber, 'itemsPerPage' => $itemsPerPage, 'totalItems' => $totalResults, 'url' => $url, 'what' => 'product' ); $this->tag->prependTitle( $selectedCategory->getCategory() . ' parts | ' ); //Show Special offers on the side of search reults. $d = \Models\Metadata::findFirst('category = "promotional" and name = "distributors"'); $distis = json_decode($d->getValue(), true); //get selected category $getCat = $selectedCategory->getCategoryURL(); $cats = /*again get from database, controlled by dashboard. */array($getCat); $manus = array(); $fs = array( 'distributor_urls' => $distis, 'category_urls' => $cats, 'manufacturer_urls' => $manus ); //get 4 random special offers per page, including a mail shot entry if we need to. $msi = mt_rand(0, 4); $template = new \Template(); $template->setTemplateDir('offer-views'); $offers = \Models\PromoParts::getSitePromotions($fs, 2, 1, false); //render the html for the selected offers. //format the params. $params = array(); if(count($offers > 0)) { for($i = 0; $i < count($offers); $i++) { if($i == $msi) { //enter this first at this index. $params[] = array( 'type' => 'mailshot', 'object' => null ); } $params[] = array('type' => 'promo', 'object' => $offers[$i]); } } $html = $template->renderTemplate('offers', 'home', array('objects' => $params)); $this->view->initialOffers = $html; } public function subCategoryAction() { $selectedSectionURL = $this->dispatcher->getParam('sectionURL', 'urlSlug'); $selectedCategoryURL = $this->dispatcher->getParam('categoryURL', 'urlSlug'); $selectedSubCategoryURL = $this->dispatcher->getParam('subCategoryURL', 'urlSlug'); $pageNumber = $this->request->getQuery('page') ?: 1; $query = $this->request->getQuery('q', 'trim'); $selectedManufacturerURL = $this->request->getQuery('manufacturer', 'urlSlug'); $selectedModelNumberID = $this->request->getQuery('modelNumber', 'int'); $selectedTechSpecs = $this->request->getQuery('techSpecs'); $showOnlyStock = !!$this->request->getQuery('onlyStock'); $itemsPerPage = $this->request->getQuery('itemsPerPage', 'int', 10); // Force a hard maximum of 100 for the items per page. $itemsPerPage = min($itemsPerPage, 100); $selectedSubCategory = \Models\SubCategories::findFromURL( $selectedSectionURL, $selectedCategoryURL, $selectedSubCategoryURL ); if (!$selectedSubCategory) { return $this->error404(); } $selectedCategory = $selectedSubCategory->getCategories(); $selectedSection = $selectedCategory->getSections(); $selectedManufacturer = ($selectedManufacturerURL) ? \Models\Manufacturers::findFromURL($selectedManufacturerURL) : false; $selectedModelNumber = ($selectedModelNumberID) ? \Models\ModelNumbers::findFirstByModelNumberID($selectedModelNumberID) : false; $searchParameters = array( $query, 'onlyStock' => $showOnlyStock, 'section' => $selectedSection, 'category' => $selectedCategory, 'subCategory' => $selectedSubCategory, 'manufacturer' => $selectedManufacturer, 'modelNumber' => $selectedModelNumber, 'partTechSpecs' => array() ); $nonMan = array( $query, 'onlyStock' => $showOnlyStock, 'section' => $selectedSection, 'category' => $selectedCategory, 'subCategory' => $selectedSubCategory, 'modelNumber' => $selectedModelNumber, 'partTechSpecs' => array() ); if ($selectedTechSpecs) { foreach ($selectedTechSpecs as $selectedTechSpecName => $selectedTechSpecValue) { if (!$selectedTechSpecName) { continue; } $selectedTechSpecName = preg_replace('/[^a-z0-9]+/i', '', $selectedTechSpecName); $searchParameters['partTechSpecs'][$selectedTechSpecName] = $selectedTechSpecValue; } } $results = \Models\Parts::search( $searchParameters, $pageNumber, $itemsPerPage ); $parts = $results['parts']; $totalResults = $results['totalResults']; $url = '/category/' . $selectedSectionURL . '/' . $selectedCategoryURL . '/' . $selectedSubCategoryURL . '/'; $url .= '?' . http_build_query( array( 'q' => $query, 'onlyStock' => $showOnlyStock, 'manufacturer' => $selectedManufacturerURL, 'modelNumber' => $selectedModelNumberID, 'itemsPerPage' => $itemsPerPage, 'page' => '' ), null, '&' ); $sections = \Models\Sections::find( array( 'order' => 'section ASC' ) ); $categories = $selectedSection->getCategories( array( 'order' => 'category ASC' ) ); $subCategories = $selectedCategory->getSubCategories( array( 'order' => 'subCategory ASC' ) ); //TODO $filterManufacturers = \Models\Parts::searchDistinct('manufacturerID', $nonMan, 1000); $filterSystemManufacturers = \Models\Parts::searchDistinct('systemManufacturerID', $searchParameters, 1000); $filterModelFamilies = \Models\Parts::searchDistinct('modelFamilyID', $searchParameters, 1000); $filterModelNumbers = \Models\Parts::searchDistinct('modelNumberID', $searchParameters, 1000); $manufacturers = \Models\Manufacturers::find( array( 'order' => 'manufacturer ASC' ) ); $techSpecs = \Models\Parts::searchTechSpecs($searchParameters); $this->view->sections = $sections; $this->view->categories = $categories; $this->view->subCategories = $subCategories; $this->view->techSpecs = $techSpecs; $this->view->filterManufacturers = $filterManufacturers; $this->view->filterSystemManufacturers = $filterSystemManufacturers; $this->view->filterModelFamilies = $filterModelFamilies; $this->view->filterModelNumbers = $filterModelNumbers; $this->view->manufacturers = $manufacturers; $this->view->parts = $parts; $this->view->selectedSection = $selectedSection; $this->view->selectedCategory = $selectedCategory; $this->view->selectedSubCategory = $selectedSubCategory; $this->view->selectedManufacturer = $selectedManufacturer; $this->view->selectedTechSpecs = $selectedTechSpecs; $this->view->selectedModelNumber = $selectedModelNumber; $this->view->itemsPerPage = $itemsPerPage; $this->view->query = $query; $this->view->manufacturerURL = $manufacturerURL; $this->view->showOnlyStock = $showOnlyStock; $this->view->totalResults = $totalResults; $this->view->pagination = array( 'pageNumber' => $pageNumber, 'itemsPerPage' => $itemsPerPage, 'totalItems' => $totalResults, 'url' => $url, 'what' => 'product' ); $this->tag->prependTitle( $selectedSubCategory->getSubCategory() . ' parts | ' ); //Show Special offers on the side of search reults. $d = \Models\Metadata::findFirst('category = "promotional" and name = "distributors"'); $distis = json_decode($d->getValue(), true); //get selected category $getCat = $selectedCategory->getCategoryURL(); $cats = /*again get from database, controlled by dashboard. */array($getCat); $manus = array(); $fs = array( 'distributor_urls' => $distis, 'category_urls' => $cats, 'manufacturer_urls' => $manus ); //get 4 random special offers per page, including a mail shot entry if we need to. $msi = mt_rand(0, 4); $template = new \Template(); $template->setTemplateDir('offer-views'); $offers = \Models\PromoParts::getSitePromotions($fs, 2, 1, false); //render the html for the selected offers. //format the params. $params = array(); if(count($offers > 0)) { for($i = 0; $i < count($offers); $i++) { if($i == $msi) { //enter this first at this index. $params[] = array( 'type' => 'mailshot', 'object' => null ); } $params[] = array('type' => 'promo', 'object' => $offers[$i]); } } $html = $template->renderTemplate('offers', 'home', array('objects' => $params)); $this->view->initialOffers = $html; } } |
#11 | Controllers\CategoryController->subCategoryAction(parts-components, motherboards, intel-socket-lga-771) |
#12 | Phalcon\Dispatcher->dispatch() |
#13 | Phalcon\Mvc\Application->handle() /home/ubuntu/partsit-site/app/web.php (424) <?php define('BOOTSTRAP', 'WEB'); if (isset($_SERVER['HTTP_X_VARNISH']) && isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR']; } if(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'http') { header("Location: https://www.partsit.com{$_SERVER['REQUEST_URI']}"); } // if(geoip_country_code_by_name($_SERVER['REMOTE_ADDR']) == 'CN') { // header("HTTP/1.0 404 Not Found"); // return; // } require 'startup.php'; if (ENVIRONMENT == 'development') { $debug = new \Phalcon\Debug(); $debug->listen(); } $di->set('markdown', function($view, $di){ $engine = new \Engine\Markdown($view, $di); return $engine; }); // Setting up the view component. $di->set( 'view', function () use ($config, $di) { $view = new \Phalcon\Mvc\View(); $view->setViewsDir($config->application->viewsDir); // Set the volt templating engine. $view->registerEngines( array( '.volt' => 'volt', '.md' => 'markdown' ) ); return $view; } ); $di->set( 'console', function() { $console = new \Console(); return $console; },true ); $di->set( 'cookies', function () { $cookies = new \Phalcon\Http\Response\Cookies(); $cookies->useEncryption(false); return $cookies; } ); $di->set( 'viewCache', function () use ($config) { $frontCache = new \Phalcon\Cache\Frontend\Output( array( 'lifetime' => $config->cache->viewCache ) ); $cache = new \Phalcon\Cache\Backend\APC( $frontCache, array( 'prefix' => 'viewCache:' ) ); return $cache; } ); $di->set( 'flash', function () { $flash = new \Phalcon\Flash\Direct( array( 'error' => 'alert alert-danger', 'success' => 'alert alert-success', 'notice' => 'alert alert-info', 'warning' => 'alert alert-warning' ) ); return $flash; } ); // Register the flash service with Twitter Bootstrap classes. $di->set( 'flashSession', function () { $flash = new \Phalcon\Flash\Session( array( 'error' => 'alert alert-danger', 'success' => 'alert alert-success', 'notice' => 'alert alert-info', 'warning' => 'alert alert-warning' ) ); return $flash; } ); // Set custom dispatcher to catch events in the dispatch loop. $di->set( 'dispatcher', function () use ($di) { $dispatcher = new \Phalcon\Mvc\Dispatcher(); $dispatcher->setDefaultNamespace('\Controllers'); // Obtain the standard eventsManager from the DI. $eventsManager = $di->getShared('eventsManager'); // Attach a listener for type "dispatch". $eventsManager->attach( 'dispatch:beforeDispatchLoop', function ($event, $dispatcher) { if ($dispatcher->getActionName()) { $actionName = lcfirst(\Phalcon\Text::camelize($dispatcher->getActionName())); $dispatcher->setActionName($actionName); } } ); $eventsManager->attach( 'dispatch:beforeException', function ($event, $dispatcher, $exception) { switch ($exception->getCode()) { case \Phalcon\Mvc\Dispatcher::EXCEPTION_HANDLER_NOT_FOUND: case \Phalcon\Mvc\Dispatcher::EXCEPTION_ACTION_NOT_FOUND: $dispatcher->forward( array( 'controller' => 'error', 'action' => 'route404' ) ); return false; } } ); $dispatcher->setEventsManager($eventsManager); return $dispatcher; }, true ); $di->set( 'url', function () { $url = new \Phalcon\Mvc\Url(); // if (ENVIRONMENT == 'production') { // $url->setBaseUri('http://www.partsit.com/'); // } return $url; } ); /* * Start the session the first time when some component request the session * service. */ $di->setShared( 'session', function () { $session = new \Phalcon\Session\Adapter\Files(); $session->start(); return $session; } ); $di->set( 'logger', function () use ($logger) { return $logger; } ); // Set up custom routes in the application. $di->set( 'router', function () { $router = new \Phalcon\Mvc\Router(false); $router->removeExtraSlashes(true); $router->add( '/:controller', array( 'controller' => 1 ) ); $router->add( '/:controller/([a-zA-Z0-9\-]+)/:params', array( 'controller' => 1, 'action' => 2, 'params' => 3 ) )->convert( 'action', function ($action) { return \Phalcon\Text::camelize($action); } ); $router->add('/applegate.csv', 'applegate::index'); //$router->add('/sitemap.xml', 'sitemap::file'); //add all of the old links, and redirect to new equivilent $router->add('/support/sitemap', 'sitemap::index'); $router->add('/support/partsit-com-rma-returns-request-terms-conditions', 'support::returnsPolicy'); $router->add('/support/cookies-policy', 'support::cookiePolicy'); $router->add('/support/public-sector-credit-account', 'public-sector-credit-account::index'); $router->add('/support/about-partsit-com', 'about::index'); $router->add('/consumers', 'index::consumers'); $router->add('/maintenance', 'index::maintenance'); $router->add('/end-users', 'index::endUsers'); $router->add('/government', 'index::government'); $router->add('/brokers', 'index::brokers'); $router->add('/categories-ajax/{sectionURL:[a-z0-9\-]+}', 'categories-ajax::section'); $router->add('/categories-ajax/{sectionURL:[a-z0-9\-]+}/{categoryURL:[a-z0-9\-]+}', 'categories-ajax::category'); /* chat.chat route */ $router->add('/chat/{chatID:[0-9]+}', 'chat::chat'); /* product route */ $router->add('/product/{partURL:[a-z0-9\-]+}', 'product::product'); $router->add('/product/{partURL:[a-z0-9\-]+}/email', 'product::email'); $router->add('/product/{partURL:[a-z0-9\-]+}/request-price', 'product::requestPrice'); $router->add('/product/{partURL:[a-z0-9\-]+}/review', 'product::review'); $router->add('/product/{partURL:[a-z0-9\-]+}/email-example', 'product::emailExample'); $router->add('/product/{partURL:[a-z0-9\-]+}/refurb', 'product::refurb'); $router->add( '/product/{partURL:[a-z0-9\-]+}/admin/([a-zA-Z0-9\-]+)', array( 'controller' => 'product-admin', 'action' => 2 ) ); /* products route */ $router->add('/products/{partURL:[a-z0-9\-]+}', 'product::product'); $router->add('/products/{partURL:[a-z0-9\-]+}/email', 'product::email'); $router->add('/products/{partURL:[a-z0-9\-]+}/request-price', 'product::requestPrice'); $router->add('/products/{partURL:[a-z0-9\-]+}/review', 'product::review'); $router->add('/products/{partURL:[a-z0-9\-]+}/email-example', 'product::emailExample'); $router->add( '/products/{partURL:[a-z0-9\-]+}/admin/([a-zA-Z0-9\-]+)', array( 'controller' => 'product-admin', 'action' => 2 ) ); $router->add('/resources/image/{hash:[a-zA-Z0-9\-]+}', 'resources::image'); $router->add('/resources/blob/{partID:[0-9]+}', 'resources::blob'); $router->add('/background/alibaba/{partURL:[a-z0-9\-]+}', 'background::alibaba'); $router->add('/reviews/{partURL:[a-z0-9\-]+}', 'reviews::product'); /* part-finder routes */ $router->add('/part-finder/{systemManufacturerURL:[a-z0-9\-]+}', 'part-finder::manufacturer'); $router->add('/part-finder/{systemManufacturerURL:[a-z0-9\-]+}/{modelFamilyURL:[a-z0-9\-]+}', 'part-finder::modelFamily'); $router->add('/part-finder/{systemManufacturerURL:[a-z0-9\-]+}/{modelFamilyURL:[a-z0-9\-]+}/{modelNumberURL:[a-z0-9\-]+}', 'part-finder::modelNumber'); $router->add('/part-finder/{systemManufacturerURL:[a-z0-9\-]+}/{modelFamilyURL:[a-z0-9\-]+}/{modelNumberURL:[a-z0-9\-]+}/{oldCategorySlug:[a-z-]+}', 'part-finder::modelNumber'); $router->add('/part-finder/search', 'part-finder::search'); $router->add('/account/returns/{pageNumber:[0-9]+}', 'account::returns'); $router->add('/account/previous-purchases/{pageNumber:[0-9]+}', 'account::previousPurchases'); $router->add('/account/quotes/{pageNumber:[0-9]+}', 'account::quotes'); $router->add('/account/invoices/{pageNumber:[0-9]+}', 'account::invoices'); /* part-finder admin routes */ $router->add('/dashboard/part-finder/{systemManufacturerURL:[a-z0-9\-]+}', 'dashboard::partFinderManufacturer'); $router->add('/dashboard/part-finder/{systemManufacturerURL:[a-z0-9\-]+}/{modelFamilyURL:[a-z0-9\-]+}', 'dashboard::partFinderModelFamily'); $router->add('/dashboard/part-finder/{systemManufacturerURL:[a-z0-9\-]+}/{modelFamilyURL:[a-z0-9\-]+}/{modelNumberURL:[a-z0-9\-]+}', 'dashboard::partFinderModelNumber'); $router->add('/dashboard/categories/{sectionURL:[a-z0-9\-]+}', 'dashboard::categoriesSection'); $router->add('/dashboard/categories/{sectionURL:[a-z0-9\-]+}/{categoryURL:[a-z0-9\-]+}', 'dashboard::categoriesCategory'); $router->add('/dashboard/promo/{page:[0-9]+}', 'dashboard::promo'); $router->add('/dashboard/pending-orders/{page:[0-9]+}', 'dashboard::pendingOrders'); $router->add('/dashboard/pending-orders/{page:[0-9]+}/{orderDirection:[0-1]{1}}', 'dashboard::pendingOrders'); $router->add('/api/xml/all', 'api::xmlAll'); $router->add('/dashboard/feedback/{pageNumber:[0-9]+}', 'dashboard::feedback'); $router->add('/dashboard/feedback/add', 'dashboard::feedbackAdd'); $router->add('/dashboard/feedback/edit/{feedbackID:[0-9]+}', 'dashboard::feedbackEdit'); //TODO $router->add('/dashboard/email-shots/new', 'dashboard::emailShotsNew'); $router->add('/dashboard/approve-images/{s:[A-Za-z0-9]+}', 'dashboard::approveImages'); $router->add('/dashboard/parts/add', 'dashboard::partsAdd'); $router->add('/dashboard/parts/modify/{partURL:[A-Za-z0-9\-]+}', 'dashboard::partsModify'); $router->add('/dashboard/accounts/{pageNumber:[0-9]+}', 'dashboard::accounts'); $router->add('/dashboard/accounts/orders/{customerID:[0-9]+}', 'dashboard::accountsOrders'); $router->add('/dashboard/accounts/rmas/{customerID:[0-9]+}', 'dashboard::accountsRmas'); $router->add('/dashboard/survey/add', 'dashboard::surveyAdd'); $router->add('/dashboard/newsletter-subscribers/{page:[0-9]+}', 'dashboard::newsletterSubscribers'); $router->add('/dashboard/carousel/add', 'dashboard::carouselAdd'); $router->add('/dashboard/carousel/edit/{carouselID:[0-9]+}', 'dashboard::carouselEdit'); $router->add('/dashboard/carousel/delete/{carouselID:[0-9]+}', 'dashboard::carouselDelete'); $router->add('/dashboard/online-users/{pageNumber:[0-9]+}', 'dashboard::onlineUsers'); $router->add('/dashboard/reviews/{pageNumber:[0-9]+}', 'dashboard::reviews'); $router->add('/dashboard/part-images/{pageNumber:[0-9]+}', 'dashboard::partImages'); $router->add('/dashboard/pending-orders/search/{pendingOrderID:[0-9]+}', 'dashboard::pendingOrdersSingle'); $router->add('/dashboard/showcases/edit/{showcaseURL:[a-z0-9\-]+}', 'dashboard::showcasesEdit'); $router->add('/manufacturers/{letter:[a-z]}', 'manufacturers::letter'); /* manufacturer */ $router->add('/manufacturer/{manufacturerURL:[a-z0-9\-]+}', 'manufacturer::manufacturer'); $router->add('/manufacturer/{manufacturerURL:[a-z0-9\-]+}/{pageNumber:[0-9]+}', 'manufacturer::manufacturer'); /* category routes. */ $router->add('/category/{sectionURL:[a-z0-9\-]+}', 'category::section'); $router->add('/category/{sectionURL:[a-z0-9\-]+}/{categoryURL:[a-z0-9\-]+}', 'category::category'); $router->add('/category/{sectionURL:[a-z0-9\-]+}/{categoryURL:[a-z0-9\-]+}/{subCategoryURL:[a-z0-9\-]+}', 'category::subCategory'); $router->add('/category/{sectionURL:[a-z0-9\-]+}/{categoryURL:[a-z0-9\-]+}/{subCategoryURL:[a-z0-9\-]+}/{pageNumber:[0-9]+}', 'category::subCategory'); /* basket.add routes. */ $router->add('/basket/add/{partURL:[a-z0-9\-]+}', 'basket::add'); $router->add('/basket/add/{partURL:[a-z0-9\-]+}/{quantity:[0-9]+}', 'basket::add'); $router->add('/basket/add-bundle/{partBundleID:[0-9]+}', 'basket::addBundle'); /* basket.remove */ $router->add('/basket/remove/{partURL:[a-z0-9\-]+}', 'basket::remove'); $router->add('/feedback/{pageNumber:[0-9]+}', 'feedback::index'); $router->add('/returns/{orderID:[a-zA-Z0-9\-]+}', 'returns::return'); $router->add('/returns/{orderID:[a-zA-Z0-9\-]+}/submit', 'returns::submit'); $router->add('/res/css/{cssFile:[A-Za-z0-9\-\.]+}', 'res::css'); $router->add('/res/js/{jsFile:[A-Za-z0-9\-\.]+}', 'res::js'); $router->add('/review/{reviewID:[0-9]+}/helpful', 'reviews::helpful'); $router->add('/review/{reviewID:[0-9]+}/unhelpful', 'reviews::unhelpful'); $router->add('/survey/{surveyURL:[A-Za-z0-9-]+}', 'survey::survey'); /* dashboard.staff-ips routes. */ $router->add('/dashboard/staff-ips/add', 'dashboard::staffIpsAdd'); $router->addPost('/background/update-staff-ip-status', 'dashboard::updateIPStatus'); $router->add('/dashboard/staff-ips/edit/{staffIpURL:[A-Za-z0-9-]+}', 'dashboard::staffIpsEdit'); $router->add('/dashboard/staff-ips/delete/{staffIpURL:[A-Za-z0-9-]+}', 'dashboard::staffIpsDelete'); $router->add('/showcase/{showcaseURL:[a-z0-9\-]+}', 'showcase::showcase'); $router->add('/sitemap/xml/pages', 'sitemap::xmlPages'); $router->add('/sitemap/xml/manufacturers', 'sitemap::xmlManufacturers'); $router->add('/sitemap/xml/parts/{pageNumber:[0-9]+}', 'sitemap::xmlParts'); $router->add('/guides/{guideURL:[A-Za-z0-9-]+}', 'guides::guide'); $router->add('/api/xml/{page:[0-9]+}', 'api::xml'); $router->add('/clearance/{manufacturerURL:[A-Za-z0-9-]+}', 'clearance::manufacturer'); $router->add('/clearance/{manufacturerURL:[A-Za-z0-9-]+}/{pageNumber:[0-9]+}', 'clearance::manufacturer'); $router->add('/tracking/{orderID:[0-9]+}', 'tracking::details'); return $router; } ); // Handle the request. $application = new \Phalcon\Mvc\Application($di); $eventsManager = new \Phalcon\Events\Manager(); $application->setEventsManager($eventsManager); $eventsManager->attach("application:boot", new \PhalconHelpers\ServiceProvider\Aws( array( 'region' => 'eu-west-1' ) )); echo $application->handle()->getContent(); // Just in case there's nothing to commit. try { $logger->commit(); } catch (\Exception $e) { } |
#14 | require_once(/home/ubuntu/partsit-site/app/web.php) /home/ubuntu/partsit-site/public/index.php (3) <?php require_once '../app/web.php'; |
Key | Value |
---|---|
_url | /category/parts-components/motherboards/intel-socket-lga-771 |
Key | Value |
---|---|
USER | www-data |
HOME | /var/www |
FCGI_ROLE | RESPONDER |
QUERY_STRING | _url=/category/parts-components/motherboards/intel-socket-lga-771 |
REQUEST_METHOD | GET |
CONTENT_TYPE | |
CONTENT_LENGTH | |
SCRIPT_FILENAME | /home/ubuntu/partsit-site/public/index.php |
SCRIPT_NAME | /index.php |
REQUEST_URI | /category/parts-components/motherboards/intel-socket-lga-771 |
DOCUMENT_URI | /index.php |
DOCUMENT_ROOT | /home/ubuntu/partsit-site/public |
SERVER_PROTOCOL | HTTP/1.1 |
GATEWAY_INTERFACE | CGI/1.1 |
SERVER_SOFTWARE | nginx/1.4.6 |
REMOTE_ADDR | 172.31.32.5 |
REMOTE_PORT | 12322 |
SERVER_ADDR | 172.31.16.243 |
SERVER_PORT | 443 |
SERVER_NAME | |
HTTPS | on |
REDIRECT_STATUS | 200 |
PATH_INFO | |
PATH_TRANSLATED | /home/ubuntu/partsit-site/public |
HTTP_HOST | www.partsit.com |
HTTP_ACCEPT | text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 |
HTTP_ACCEPT_ENCODING | gzip |
HTTP_IF_MODIFIED_SINCE | Tue, 11 Dec 2018 09:44:10 GMT |
HTTP_USER_AGENT | CCBot/2.0 (https://commoncrawl.org/faq/) |
HTTP_X_FORWARDED_FOR | 34.207.152.62 |
HTTP_X_FORWARDED_PORT | 443 |
HTTP_X_FORWARDED_PROTO | https |
HTTP_CONNECTION | keep-alive |
PHP_SELF | /index.php |
REQUEST_TIME_FLOAT | 1550355109.7733 |
REQUEST_TIME | 1550355109 |
# | Path |
---|---|
0 | /home/ubuntu/partsit-site/public/index.php |
1 | /home/ubuntu/partsit-site/app/web.php |
2 | /home/ubuntu/partsit-site/app/startup.php |
3 | /home/ubuntu/partsit-site/vendor/autoload.php |
4 | /home/ubuntu/partsit-site/vendor/composer/autoload_real.php |
5 | /home/ubuntu/partsit-site/vendor/composer/ClassLoader.php |
6 | /home/ubuntu/partsit-site/vendor/composer/include_paths.php |
7 | /home/ubuntu/partsit-site/vendor/composer/autoload_namespaces.php |
8 | /home/ubuntu/partsit-site/vendor/composer/autoload_psr4.php |
9 | /home/ubuntu/partsit-site/vendor/composer/autoload_classmap.php |
10 | /home/ubuntu/partsit-site/vendor/composer/autoload_files.php |
11 | /home/ubuntu/partsit-site/vendor/guzzlehttp/promises/src/functions_include.php |
12 | /home/ubuntu/partsit-site/vendor/guzzlehttp/promises/src/functions.php |
13 | /home/ubuntu/partsit-site/vendor/guzzlehttp/psr7/src/functions_include.php |
14 | /home/ubuntu/partsit-site/vendor/guzzlehttp/psr7/src/functions.php |
15 | /home/ubuntu/partsit-site/vendor/guzzlehttp/guzzle/src/functions_include.php |
16 | /home/ubuntu/partsit-site/vendor/guzzlehttp/guzzle/src/functions.php |
17 | /home/ubuntu/partsit-site/vendor/mtdowling/jmespath.php/src/JmesPath.php |
18 | /home/ubuntu/partsit-site/vendor/aws/aws-sdk-php/src/functions.php |
19 | /home/ubuntu/partsit-site/vendor/swiftmailer/swiftmailer/lib/swift_required.php |
20 | /home/ubuntu/partsit-site/vendor/swiftmailer/swiftmailer/lib/classes/Swift.php |
21 | /home/ubuntu/partsit-site/vendor/ircmaxell/password-compat/lib/password.php |
22 | /home/ubuntu/partsit-site/vendor/symfony/polyfill-php55/bootstrap.php |
23 | /home/ubuntu/partsit-site/vendor/symfony/polyfill-php54/bootstrap.php |
24 | /home/ubuntu/partsit-site/vendor/react/promise/src/functions_include.php |
25 | /home/ubuntu/partsit-site/vendor/react/promise/src/functions.php |
26 | /home/ubuntu/partsit-site/vendor/symfony/polyfill-mbstring/bootstrap.php |
27 | /home/ubuntu/partsit-site/vendor/illuminate/support/Illuminate/Support/helpers.php |
28 | /home/ubuntu/partsit-site/app/library/PhalconHelpers/ServiceProvider/Aws.php |
29 | /home/ubuntu/partsit-site/app/controllers/CategoryController.php |
30 | /home/ubuntu/partsit-site/app/controllers/ControllerBase.php |
31 | /home/ubuntu/partsit-site/app/library/Auth.php |
32 | /home/ubuntu/partsit-site/app/models/StaffIPs.php |
33 | /home/ubuntu/partsit-site/app/models/BaseModel.php |
34 | /home/ubuntu/partsit-site/app/models/Baskets.php |
35 | /home/ubuntu/partsit-site/app/models/ExchangeRates.php |
36 | /home/ubuntu/partsit-site/app/models/Sections.php |
37 | /home/ubuntu/partsit-site/app/models/Metadata.php |
38 | /home/ubuntu/partsit-site/app/models/Manufacturers.php |
39 | /home/ubuntu/partsit-site/app/models/SystemManufacturers.php |
40 | /home/ubuntu/partsit-site/app/library/PhalconHelpers/Filters/MD5.php |
41 | /home/ubuntu/partsit-site/app/library/PhalconHelpers/Filters/IPv4.php |
42 | /home/ubuntu/partsit-site/app/library/PhalconHelpers/Filters/URLSlug.php |
43 | /home/ubuntu/partsit-site/app/library/PhalconHelpers/Filters/Description.php |
44 | /home/ubuntu/partsit-site/app/library/PhalconHelpers/Filters/Month.php |
45 | /home/ubuntu/partsit-site/app/library/PhalconHelpers/Filters/DellServiceTag.php |
46 | /home/ubuntu/partsit-site/app/library/PhalconHelpers/Filters/HPProductNumber.php |
47 | /home/ubuntu/partsit-site/app/library/PhalconHelpers/Filters/LenovoSerialNumber.php |
48 | /home/ubuntu/partsit-site/app/library/PhalconHelpers/Filters/CreditCardNumber.php |
49 | /home/ubuntu/partsit-site/app/library/PhalconHelpers/Filters/Name.php |
50 | /home/ubuntu/partsit-site/app/models/SubCategories.php |
51 | /home/ubuntu/partsit-site/app/models/Categories.php |
52 | /home/ubuntu/partsit-site/app/models/Parts.php |
53 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/ClientBuilder.php |
54 | /home/ubuntu/partsit-site/vendor/psr/log/Psr/Log/NullLogger.php |
55 | /home/ubuntu/partsit-site/vendor/psr/log/Psr/Log/AbstractLogger.php |
56 | /home/ubuntu/partsit-site/vendor/psr/log/Psr/Log/LoggerInterface.php |
57 | /home/ubuntu/partsit-site/vendor/guzzlehttp/ringphp/src/Client/CurlHandler.php |
58 | /home/ubuntu/partsit-site/vendor/guzzlehttp/ringphp/src/Client/CurlFactory.php |
59 | /home/ubuntu/partsit-site/vendor/guzzlehttp/ringphp/src/Client/CurlMultiHandler.php |
60 | /home/ubuntu/partsit-site/vendor/guzzlehttp/ringphp/src/Client/Middleware.php |
61 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Serializers/SmartSerializer.php |
62 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Serializers/SerializerInterface.php |
63 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Connections/ConnectionFactory.php |
64 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Connections/ConnectionFactoryInterface.php |
65 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/ConnectionPool/Selectors/RoundRobinSelector.php |
66 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/ConnectionPool/Selectors/SelectorInterface.php |
67 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Connections/Connection.php |
68 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Connections/ConnectionInterface.php |
69 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/ConnectionPool/StaticNoPingConnectionPool.php |
70 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/ConnectionPool/AbstractConnectionPool.php |
71 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/ConnectionPool/ConnectionPoolInterface.php |
72 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Transport.php |
73 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Client.php |
74 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Namespaces/IndicesNamespace.php |
75 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Namespaces/AbstractNamespace.php |
76 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Namespaces/ClusterNamespace.php |
77 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Namespaces/NodesNamespace.php |
78 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Namespaces/SnapshotNamespace.php |
79 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Namespaces/CatNamespace.php |
80 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Endpoints/Search.php |
81 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Endpoints/AbstractEndpoint.php |
82 | /home/ubuntu/partsit-site/vendor/guzzlehttp/ringphp/src/Core.php |
83 | /home/ubuntu/partsit-site/vendor/guzzlehttp/ringphp/src/Future/CompletedFutureArray.php |
84 | /home/ubuntu/partsit-site/vendor/guzzlehttp/ringphp/src/Future/CompletedFutureValue.php |
85 | /home/ubuntu/partsit-site/vendor/guzzlehttp/ringphp/src/Future/FutureInterface.php |
86 | /home/ubuntu/partsit-site/vendor/react/promise/src/PromiseInterface.php |
87 | /home/ubuntu/partsit-site/vendor/react/promise/src/PromisorInterface.php |
88 | /home/ubuntu/partsit-site/vendor/guzzlehttp/ringphp/src/Future/FutureArrayInterface.php |
89 | /home/ubuntu/partsit-site/vendor/guzzlehttp/ringphp/src/Future/FutureArray.php |
90 | /home/ubuntu/partsit-site/vendor/guzzlehttp/ringphp/src/Future/MagicFutureTrait.php |
91 | /home/ubuntu/partsit-site/vendor/guzzlehttp/ringphp/src/Future/BaseFutureTrait.php |
92 | /home/ubuntu/partsit-site/vendor/react/promise/src/FulfilledPromise.php |
93 | /home/ubuntu/partsit-site/vendor/react/promise/src/ExtendedPromiseInterface.php |
94 | /home/ubuntu/partsit-site/vendor/react/promise/src/CancellablePromiseInterface.php |
95 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Common/Exceptions/BadRequest400Exception.php |
96 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Common/Exceptions/ElasticsearchException.php |
97 | /home/ubuntu/partsit-site/vendor/psr/log/Psr/Log/LogLevel.php |
98 | /home/ubuntu/partsit-site/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Common/Exceptions/Missing404Exception.php |
99 | /home/ubuntu/partsit-site/vendor/react/promise/src/RejectedPromise.php |
Memory | |
---|---|
Usage | 3145728 |