/src/Command/CacheGenerateCommand.php
PHP | 289 lines | 227 code | 56 blank | 6 comment | 3 complexity | d1892e916629858b19486b9aaf787971 MD5 | raw file
- <?php
- namespace App\Command;
- use App\Domain\Category\Repository\CategoryRepository;
- use App\Domain\City\Entity\City;
- use App\Domain\City\Repository\CityRepository;
- use App\Domain\Product\Entity\Offer;
- use App\Domain\Product\Repository\ProductRepository;
- use App\Domain\Property\Entity\Property;
- use Doctrine\ORM\EntityManagerInterface;
- use Symfony\Component\Console\Command\Command;
- use Symfony\Component\Console\Helper\ProgressBar;
- use Symfony\Component\Console\Input\InputInterface;
- use Symfony\Component\Console\Output\ConsoleSectionOutput;
- use Symfony\Component\Console\Output\OutputInterface;
- use Symfony\Component\Console\Style\SymfonyStyle;
- class CacheGenerateCommand extends Command
- {
- protected static $defaultName = 'cache:generate';
- private EntityManagerInterface $entityManager;
- private CityRepository $cityRepository;
- private CategoryRepository $categoryRepository;
- private ProductRepository $productRepository;
- private string $path;
- private SymfonyStyle $io;
- private ProgressBar $memoryBar;
- public function __construct(
- EntityManagerInterface $entityManager,
- CityRepository $cityRepository,
- CategoryRepository $categoryRepository,
- ProductRepository $productRepository
- ) {
- parent::__construct();
- $this->entityManager = $entityManager;
- $this->cityRepository = $cityRepository;
- $this->categoryRepository = $categoryRepository;
- $this->productRepository = $productRepository;
- $this->path = implode('/', [__DIR__, '../..', 'var/cache/json/']);
- $this->makeDir($this->path);
- chdir($this->path);
- }
- private function makeDir($path): bool
- {
- return is_dir($path) || mkdir($path, 0775, true);
- }
- protected function configure()
- {
- $this
- ->setAliases(['c:g'])
- ->setDescription('Generate *.json files');
- }
- protected function execute(InputInterface $input, OutputInterface $output): int
- {
- ini_set('memory_limit', '1024M');
- $this->io = new SymfonyStyle($input, $output);
- /** @var OutputInterface $section */
- $section = $output->section('* Memory Usage');
- $section->writeln('<info>* Memory Usage</info>');
- $this->memoryBar = new ProgressBar($section, 1024);
- $this->memoryBar->setEmptyBarCharacter('░');
- $this->memoryBar->setProgressCharacter('');
- $this->memoryBar->setBarCharacter('▓');
- $this->jsonInit($output);
- $this->jsonCategoryProducts($output);
- $this->jsonCategoryFilters($output);
- return Command::SUCCESS;
- }
- private function jsonInit(OutputInterface $output): self
- {
- $section = $output->section('Menu');
- $section->writeln('<comment>* Menu & Cities</comment>');
- $cities = $this->entityManager->getRepository(City::class)->findAll();
- $categories = $this->categoryRepository->findBy(['active' => true]);
- $progressbar = $this->createProgressBar($section, count($cities));
- foreach ($cities as $city) {
- $this->trackMemory();
- $fileName = implode(
- '/',
- [
- $city->getDomain(),
- 'init.json',
- ]
- );
- $this->saveData(
- $fileName,
- [
- 'data' => [
- 'cities' => $cities,
- 'categories' => $categories
- ],
- ]
- );
- $progressbar->advance();
- }
- $this->entityManager->clear();
- $progressbar->finish();
- $this->trackMemory();
- return $this;
- }
- private function saveData(string $name, array $data): void
- {
- $e = explode('/', $name);
- if (count($e) > 1) {
- array_pop($e);
- array_unshift($e, $this->path);
- $path = implode('/', $e);
- if (!is_dir($path)) {
- mkdir($path, 0775, true);
- }
- }
- file_put_contents(
- $name,
- json_encode(
- $data,
- (JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT | JSON_UNESCAPED_UNICODE)
- )
- );
- // $this->print(new \SplFileInfo($name));
- }
- private function jsonCategoryProducts(OutputInterface $output): self
- {
- $section = $output->section('Categories');
- $section->writeln('');
- $section->writeln('<comment>* Category Products</comment>');
- $categories = $this->categoryRepository->findBy(['active' => true]);
- $this->trackMemory();
- $this->entityManager->clear();
- $this->trackMemory();
- $cities = $this->entityManager->getRepository(City::class)->findAll();
- $progressbar = $this->createProgressBar($section, (count($categories) * count($cities)));
- $offerRepository = $this->entityManager->getRepository(Offer::class);
- /** @var City $city */
- foreach ($cities as $city) {
- foreach ($categories as $category) {
- $fileName = implode(
- '/',
- [
- $city->getDomain(),
- 'category',
- $category->getId(),
- 'products.json',
- ]
- );
- $products = $offerRepository->getProductsWithOffersByCityAndCategory($city, $category);
- $this->saveData(
- $fileName,
- [
- 'total' => count($products),
- 'data' => $products,
- //'prices' => $products->getMinMaxPrices(),
- ]
- );
- $progressbar->advance();
- $this->trackMemory();
- }//end foreach
- }//end foreach
- $progressbar->finish();
- return $this;
- }
- private function jsonCategoryFilters(OutputInterface $output): self
- {
- $section = $output->section('Filters');
- $section->writeln('');
- $section->writeln('<comment>* Category Filters</comment>');
- $categories = $this->categoryRepository->findBy(['active' => true]);
- $cities = $this->cityRepository->findAll();
- $offerRepository = $this->entityManager->getRepository(Property::class);
- $total = (count($categories) * count($cities));
- $progressbar = $this->createProgressBar($section, $total);
- foreach ($cities as $city) {
- foreach ($categories as $category) {
- $fileName = implode('/', [$city->getDomain(), 'category', $category->getId(), 'filters.json']);
- $filters = $offerRepository->getFiltersBy($city, $category);
- $this->saveData($fileName, ['data' => $filters]);
- $this->trackMemory();
- $progressbar->advance();
- }
- }
- $progressbar->finish();
- return $this;
- }
- private function jsonCategorySorting(OutputInterface $output): self
- {
- $section = $output->section('Sorting');
- $section->writeln('');
- $section->writeln('<comment>* Category Sorting</comment>');
- $categories = $this->categoryRepository->findBy(['active' => true]);
- $this->trackMemory();
- $this->entityManager->clear();
- $this->trackMemory();
- $cities = $this->entityManager->getRepository(City::class)->findAll();
- $progressbar = $this->createProgressBar($section, (count($categories) * count($cities)));
- $offerRepository = $this->entityManager->getRepository(Offer::class);
- /** @var City $city */
- foreach ($cities as $city) {
- foreach ($categories as $category) {
- $fileName = implode(
- '/',
- [
- $city->getDomain(),
- 'category',
- $category->getId(),
- 'sorting.json',
- ]
- );
- $products = $offerRepository->getProductsWithOffersByCityAndCategory($city, $category);
- $this->saveData(
- $fileName,
- [
- 'total' => count($products),
- 'data' => $products,
- //'prices' => $products->getMinMaxPrices(),
- ]
- );
- $progressbar->advance();
- $this->trackMemory();
- }//end foreach
- }//end foreach
- $progressbar->finish();
- return $this;
- }
- private function trackMemory(): void
- {
- $this->memoryBar->setProgress(((int) memory_get_peak_usage(true) / 1024 / 1024));
- }
- private function createProgressBar(ConsoleSectionOutput $sectionOutput, $max = 0)
- {
- $progressBar = new ProgressBar($sectionOutput, $max);
- $progressBar->setEmptyBarCharacter('░');
- $progressBar->setProgressCharacter('');
- $progressBar->setBarCharacter('▓');
- return $progressBar;
- }
- }