Skip to content

Commit

Permalink
Organize code.
Browse files Browse the repository at this point in the history
  • Loading branch information
lujewwy committed Aug 30, 2023
1 parent 128a298 commit bb8f285
Show file tree
Hide file tree
Showing 6 changed files with 222 additions and 145 deletions.
5 changes: 5 additions & 0 deletions hw11/src/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ELASTIC_HOST=es:9200
ELASTIC_USERNAME=elastic
ELASTIC_PASSWORD=elastic_password
ELASTIC_INDEX=books-shop
ELASTIC_MAX_OUTPUT_SIZE=100
5 changes: 5 additions & 0 deletions hw11/src/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ELASTIC_HOST=
ELASTIC_USERNAME=
ELASTIC_PASSWORD=
ELASTIC_INDEX=
ELASTIC_MAX_OUTPUT_SIZE=
167 changes: 22 additions & 145 deletions hw11/src/app/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,48 @@

namespace App;

use App\Services\PrepareOutputService;
use App\Services\PrepareSearchService;
use Elastic\Elasticsearch\Client;
use Elastic\Elasticsearch\ClientBuilder;
use Elastic\Elasticsearch\Exception\ClientResponseException;
use Elastic\Elasticsearch\Exception\ServerResponseException;

class App
{
private const ELASTIC_HOST = 'es:9200';
private const ELASTIC_USERNAME = 'elastic';
private const ELASTIC_PASSWORD = 'elastic_password';
private const ELASTIC_INDEX = 'books-shop';
private const ELASTIC_MAX_OUTPUT_SIZE = 100;
use Helpers;

private array $operators = [
'>' => 'gt',
'>=' => 'gte',
'<' => 'lt',
'<=' => 'lte',
];
private string $elasticHost;
private string $elasticUsername;
private string $elasticPassword;
private string $elasticIndex;
private string $elasticMaxOutputSize;

private Client $client;

public function __construct()
{
$this->elasticHost = $this->env('ELASTIC_HOST');
$this->elasticUsername = $this->env('ELASTIC_USERNAME');
$this->elasticPassword = $this->env('ELASTIC_PASSWORD');
$this->elasticIndex = $this->env('ELASTIC_INDEX');
$this->elasticMaxOutputSize = $this->env('ELASTIC_MAX_OUTPUT_SIZE');

$client = ClientBuilder::create()
->setHosts([self::ELASTIC_HOST])
->setBasicAuthentication(self::ELASTIC_USERNAME, self::ELASTIC_PASSWORD)
->setHosts([$this->elasticHost])
->setBasicAuthentication($this->elasticUsername, $this->elasticPassword)
->build();

$this->client = $client;
}

public function get(): void
{
$searchParams = $this->getSearchParams();
$searchParams = PrepareSearchService::getSearchParams();

$params = [
'index' => self::ELASTIC_INDEX,
'size' => self::ELASTIC_MAX_OUTPUT_SIZE,
'index' => $this->elasticIndex,
'size' => $this->elasticMaxOutputSize,
'body' => [
'sort' => [
"_score" => "desc"
Expand All @@ -56,148 +59,22 @@ public function get(): void
try {
$result = $this->client->search($params);
} catch (ClientResponseException | ServerResponseException $e) {
echo $e->getResponse() . PHP_EOL;
echo $e->getMessage() . PHP_EOL;
}

if (isset($result) && isset($result['hits']) && isset($result['hits']['hits'])) {
$items = array_map(function ($item) {
return $item['_source'];
}, $result['hits']['hits']);

$this->outputResult($items);
}
}

private function outputResult(array $items): void
{
foreach ($items as $i => $lines) {
foreach ($lines as $key => $value) {
if (!is_array($value)) {
$columns[$key][0] = $key;
$columns[$key][] = $value;

$rows[$i][] = $value;
} else {
foreach ($value as $subKey => $subValue) {
$complexKey = $key . ' (' . $subValue['shop'] . ')';
$columns[$complexKey][0] = $complexKey;
$columns[$complexKey][] = $subValue['stock'];

$rows[$i][] = $subValue['stock'];
}
}
}
}

$rows = [[...array_keys($columns)], ...$rows];
$lengths = array_values(array_map(fn($x) => max(array_map('mb_strlen', $x)), $columns));

foreach ($rows as $row) {
foreach ($row as $key => $data) {
$string = (is_bool($data)) ? (($data) ? 'true' : 'false') : (string)$data;

$lengthDelta = $lengths[$key] - mb_strlen($string, 'UTF-8');
for ($i = 0; $i < $lengthDelta; $i++) {
$string .= ' ';
}
$string .= ' | ';

echo $string;
}
echo PHP_EOL;
}
}

private function getSearchParams(): array|bool
{
$params = $_SERVER['argv'];

if (count($params) > 1) {
unset($params[0]);

$searchParams = [];

foreach ($params as $param) {
[$paramKey, $paramValue] = explode(':', $param);

if ($paramKey === 'title') {
$value = [
'query' => $paramValue,
'fuzziness' => 'auto',
];
} elseif ($paramKey === 'category') {
$value = $paramValue;
} else {
$value = $this->getValue($paramValue);
}

if (($paramKey === 'price' || $paramKey === 'stock') && is_array($value)) {
$key = 'range';
$filter = 'filter';

if ($paramKey === 'stock') {
$paramKey = 'stock.stock';
}
} elseif ($paramKey === 'category') {
$key = 'term';
$filter = 'must';
$paramKey = 'category';
} else {
$key = 'match';
$filter = 'must';
}

if (!array_key_exists($filter, $searchParams)) {
$searchParams[$filter] = [];
}

if (count($searchParams[$filter]) === 0) {
$searchParams[$filter][] = [$key => [$paramKey => $value]];
} else {
foreach ($searchParams[$filter] as $existKey => $existFilter) {
if (!array_key_exists($key, $existFilter)) {
$searchParams[$filter][] = [$key => [$paramKey => $value]];
} else {
if (!array_key_exists($paramKey, $existFilter[$key])) {
$searchParams[$filter][][$key] = [$paramKey => $value];
} else {
if (is_array($searchParams[$filter][$existKey][$key][$paramKey])) {
$searchParams[$filter][$existKey][$key][$paramKey] = array_merge(
$searchParams[$filter][$existKey][$key][$paramKey],
$value
);
} else {
$searchParams[$filter][$existKey][$key][$paramKey] = $value;
}
}
}
}
}
}

return $searchParams;
}

return false;
}

private function getValue(string $value): array|string
{
$array = explode(' ', $value);

if (count($array) > 1) {
$array[0] = array_key_exists($array[0], $this->operators) ? $this->operators[$array[0]] : $array[0];

return [$array[0] => $array[1]];
PrepareOutputService::outputResult($items);
}

return $array[0];
}

public function create(): void
{
$params = [
'index' => self::ELASTIC_INDEX,
'index' => $this->elasticIndex,
'body' => [
'mappings' => [
'properties' => [
Expand Down
37 changes: 37 additions & 0 deletions hw11/src/app/Helpers.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace App;

trait Helpers
{
public function env(string $key = null): bool|string
{
$filePath = __DIR__ . '/../.env';

if (!file_exists($filePath)) {
echo 'Copy .env.example to .env file and fill in required values.' . PHP_EOL;
exit;
}

if ($key) {
$handle = fopen($filePath, 'r');
if ($handle) {
while (($line = fgets($handle)) !== false) {
if (strpos($line, '=')) {
[$param, $value] = explode('=', $line);

if (trim($param) === $key) {
return trim($value);
}
}
}

fclose($handle);
}
}

return false;
}
}
52 changes: 52 additions & 0 deletions hw11/src/app/Services/PrepareOutputService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);

namespace App\Services;

class PrepareOutputService
{
public static function outputResult(array $items): void
{
$columns = [];
$rows = [];

foreach ($items as $i => $lines) {
foreach ($lines as $key => $value) {
if (!is_array($value)) {
$columns[$key][0] = $key;
$columns[$key][] = $value;

$rows[$i][] = $value;
} else {
foreach ($value as $subKey => $subValue) {
$complexKey = $key . ' (' . $subValue['shop'] . ')';
$columns[$complexKey][0] = $complexKey;
$columns[$complexKey][] = $subValue['stock'];

$rows[$i][] = $subValue['stock'];
}
}
}
}

$rows = [[...array_keys($columns)], ...$rows];
$lengths = array_values(array_map(fn($x) => max(array_map('mb_strlen', $x)), $columns));

foreach ($rows as $row) {
echo '| ';
foreach ($row as $key => $data) {
$string = (is_bool($data)) ? (($data) ? 'true' : 'false') : (string)$data;

$lengthDelta = $lengths[$key] - mb_strlen($string, 'UTF-8');
for ($i = 0; $i < $lengthDelta; $i++) {
$string .= ' ';
}
$string .= ' | ';

echo $string;
}
echo PHP_EOL;
}
}
}
Loading

0 comments on commit bb8f285

Please sign in to comment.