<?php
namespace App\Service\Filter;
use App\Env;
use App\Service\Auth\Auth;
use App\Service\Search\SearchProd;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Contracts\Cache\TagAwareCacheInterface;
class Prods
{
private $prods = [];
private $pc = [];
private $prod_count = 0;
public function __construct(
private RequestStack $rs,
private Auth $Auth,
private EntityManagerInterface $em,
private TagAwareCacheInterface $appCache,
private Env $Env,
private Security $security,
private SearchProd $searchProd,
private CatTree $catTree,
)
{
$this->Auth->setUser($security->getUser());
}
public function getFromDb(int $cat = 0, string $spec = '', string $q = '', int $id = 0)
{
$request = $this->rs->getCurrentRequest();
$test = $request->get('test');
$q = $q ? $q : $request->get('q');
$prods_temp_q = $prods_temp = [];
$opt = $this->Auth->isOpt() ? 'opt' : '';
$where = "visible = 1 and (num > 0 or num2 > 0 or num3 > 0)";
if ($cat) {
$where .= " and ".$this->catTree->getCatTreeWhere($cat);
}
switch($spec) {
case 'new':
$where .= " and `new` = 1";
break;
case 'pop':
$where .= " and `pop` = 1";
break;
case 'onsale':
$where .= " and `onsale` = 1";
break;
case 'mix':
$where .= " and `mix` = 1";
break;
case 'action':
if($this->Auth->isOpt()) $where .= " and `skidkaopt` > 0";
else $where .= " and `skidka` > 0";
break;
case 'search':
$lang = $this->rs->getCurrentRequest()->getLocale();
$ids = $this->searchProd->search($lang, $q);
if (count($ids)) {
$where .= " and (id in (".implode(",", $ids).") or art like '%$q%')";
} else {
$where .= " and (id = -1 or art like '%$q%')";
}
break;
}
$select = "id, cat, intname, name, art, price, price2, price3, priceopt, priceopt2, priceopt3, skidka, skidka2, skidka3, skidkaopt, skidkaopt2, skidkaopt3, numdiscount, numdiscount2, numdiscount3, chars, numdiscountopt, numdiscountopt2, numdiscountopt3, num, num2, num3, weight, weight2, weight3, inpack, inpack2, inpack3, pop, new, mix, action, onsale, prior, ordered, changed, colors";
if ($id) {
$q = "SELECT $select FROM prod WHERE id = $id";
$prods_temp = $this->em->getConnection()->prepare($q)->executeQuery()->fetchAllAssociative();
} elseif ($q) {
$q = "SELECT $select FROM prod WHERE $where";
$prods_temp_q = $this->em->getConnection()->prepare($q)->executeQuery()->fetchAllAssociative();
} else {
$q = "SELECT $select FROM prod WHERE $where";
$prods_temp = $this->em->getConnection()->prepare($q)->executeQuery()->fetchAllAssociative();
}
$this->pc = [];
$this->prods = [];
if (is_array($prods_temp) && count($prods_temp)) {
foreach ($prods_temp as $kc => $p) {
$p['colors'] = json_decode($p['colors'], true);
$this->prods[$p['id']] = $p;
$chars = explode(";", $p['chars']);
foreach ($chars as $char) {
$cv = explode(":", $char);
if ($cv[0] != 'onsale' && $cv[0] != 'pop' && $cv[0] != 'action' && $cv[0] != 'new' && $cv[0] != 'mix' && isset($cv[1]) && $cv[1] > 0) {
$this->pc[$cv[0]][] = $cv[1];
}
}
}
unset($prods_temp);
}
if (is_array($prods_temp_q) && count($prods_temp_q)) {
foreach ($prods_temp_q as $kc => $p) {
$p['colors'] = json_decode($p['colors'], true);
$this->prods[$p['id']] = $p;
$chars = explode(";", $p['chars']);
foreach ($chars as $char) {
$cv = explode(":", $char);
if ($cv[0] != 'onsale' && $cv[0] != 'pop' && $cv[0] != 'action' && $cv[0] != 'new' && $cv[0] != 'mix' && isset($cv[1]) && $cv[1] > 0) {
$this->pc[$cv[0]][] = $cv[1];
}
}
}
unset($prods_temp_q);
}
// $prod_ids = [];
// foreach ($this->prods as $k => $v) {
// $prod_ids[] = $v['id'];
// }
// //TODO Alex
// $this->prods = $this->em->createQuery('SELECT p from App\Entity\Prod p WHERE p.id in (:ids)')
// ->setParameter('ids', $prod_ids)
// //->setMaxResults(50)
// ->getResult();
return $this->prods;
}
public function getProd($id = 0)
{
$prods = $this->getFromDb(0, '', '', $id);
if ($prods) {
return reset($prods);
} else {
return [];
}
}
public function getProds(int $cat = 0, string $spec = '', string $search = ''): array
{
if (empty($this->prods)) {
return $this->getFromDb($cat, $spec, $search);
}
return $this->prods;
}
public function getPC(int $cat = 0, string $spec = ''): array
{
if (empty($this->pc)) {
$this->getFromDb($cat, $spec);
}
return $this->pc;
}
public function getchars(array $get_params)
{
$filter = [];
foreach ($get_params as $k => $v) {
if ($k == 'getnum' || $k == 'filter' || $k == 'q') {
continue;
}
if (isset($get_params[$k]) && is_array($get_params[$k])) {
$filter[str_replace('char', '', $k)] = [];
foreach ($get_params[$k] as $vvv) {
array_push($filter[str_replace('char', '', $k)], $vvv);
}
} else {
$filter[str_replace('char', '', $k)] = $v;
}
}
return $filter;
}
/**
*
* @param array $get_params
* @param \App\Entity\Prod[] $prods
* @param array $chars
* @return array
*/
public function filter (array $get_params, array $prods, array $chars = array()) {
$qwe = '';
if (empty($chars)) {
$filter = $this->getchars($get_params);
} else {
$filter = $chars;
}
foreach($filter as $k => $char) {
if($char == 'action' && $this->Auth->isOpt()) {
$filter[$k] = 'actionopt';
}
}
if (isset($filter['sale']) && $filter['sale'] == 1) {
$filter[$filter['sale']] = "1";
unset($filter['sale']);
}
$ids = array();
if (empty($filter)) {
return $prods;
}
$fc = count($filter);
foreach ($prods as $k => $prod) {
if (empty($prod->getChars())) {
continue;
}
$filter_vals_founded = 0;
foreach ($filter as $c => $cv) {
if (is_array($cv) && count($cv) > 1) { // Выбрано нескольно значений одной характеристики
foreach ($cv as $ccv) {
if (strstr($prod->getChars(), $c.":".$ccv.";")) { // Если хотя бы одно значение найдено, то значение считается найдено
$qwe .= $c.":".$ccv.";";
$filter_vals_founded++;
break;
}
}
} else { // Выбрано ОДНО значение одной характеристики
if (is_array($cv)) {
$cv = $cv[0];
}
if (strstr($prod->getChars(), $c.":".$cv.";")) {
$filter_vals_founded++;
}
}
}
if ($filter_vals_founded >= $fc) { // Если найдены все значения характеристик, помещаем товар в массив
$ids[] = $prod;
}
}
return $ids;
}
/**
*
* @param \App\Entity\Prod[] $prods
* @param array $chars
* @param mixed $char
* @param mixed $charval
* @return int
*/
public function prodcount (array $prods, array $chars, $char, $charval)
{
$filter = $chars;
$fc = count($filter);
$cnt = 0;
$qwe = '';
if ($char == 'action' && $this->Auth->isOpt()) {
$char = 'actionopt';
}
if (isset($filter['sale'])) {
$filter[$filter['sale']] = "1";
unset($filter['sale']);
}
foreach ($prods as $k => $prod) {
if (empty($prod['chars'])) {
continue;
}
if (!empty($filter)) {
$filter_vals_founded = 0;
foreach ($filter as $c => $cv) {
if (is_array($cv) && count($cv) > 1) { // Выбрано нескольно значений одной характеристики
foreach ($cv as $ccv) {
if (strstr($prod['chars'], $c.":".$ccv.";") || $c == $char) { // Если хотя бы одно значение найдено, то значение считается найдено
$qwe .= $c.":".$ccv.";";
$filter_vals_founded++;
break;
}
}
} else { // Выбрано ОДНО значение одной характеристики
if (is_array($cv)) {
$cv = $cv[0];
}
if (strstr($prod['chars'], $c.":".$cv.";") || $c == $char) {
$filter_vals_founded++;
}
}
}
if (strstr($prod['chars'], $char.":".$charval.";") && $filter_vals_founded >= $fc) { // Прибавляем 1 к значению характеристики в фильтре с учетом того, что она соответствуюе всем остальным условиям
$cnt++;
}
} else { // фильтр не задан
if (strstr($prod['chars'], $char.":".$charval.";")) {
$cnt++;
}
}
}
return $cnt;
}
}