<?php
namespace App\Manager;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\Category;
class CategoryManager {
private $em;
private $languageMgr;
private $projectDir;
public function __construct(EntityManagerInterface $em, \App\Manager\LanguageManager $languageMgr, \Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface $parameter)
{
$this->projectDir = $parameter->get('kernel.project_dir').'/';
$this->em = $em;
$this->languageMgr = $languageMgr;
}
public function sortCategory(Category $category, $position, $flush=true)
{
$category->setSortOrder($position);
$this->em->persist($category);
if($flush){
$this->em->flush();
}
}
public function export(?Category $category=null, $filename = null)
{
if(empty($category)){
$categories = $this->em->getRepository('App:Category')->getAll();
}else{
$categories = $this->em->getRepository('App:Category')->getCategorysByCategory($category);
}
if(empty($filename)) {
$filename = 'var/exports/categories'.date('YmdHis').'.csv';
}
$fp = fopen($this->projectDir.$filename,'w');
\App\Helpers\Encoder::fputcsvEol($fp, $this->getCsvHeader(),";");
foreach($categories as $category){
\App\Helpers\Encoder::fputcsvEol($fp, $this->categoryToCsv($category),";");
}
fclose($fp);
return $filename;
}
public function categoryToCsv(Category $category) : array {
$descriptionEn = $category->getCategoryDescription('en');
if(is_null($descriptionEn))
$descriptionEn = $this->createCategoryDescription($category,'en');
$descriptionFr = $category->getCategoryDescription('fr');
if(is_null($descriptionFr))
$descriptionFr = $this->createCategoryDescription($category,'fr');
$tab = [
/*1 ID categorie */ $category->getId(),
/*2 ID parent */ $category->getParent()?$category->getParent()->getId():0,
/*3 Active */ $category->getAffichage(),
/*4 Position */ $category->getSortOrder(),
/*5 Désignation FR */ $descriptionFr->getName(),
/*6 H1 FR */ $descriptionFr->getHeadingTitle(),
/*7 Description longue FR */ $descriptionFr->getDescription(),
/*8 URL FR */ $descriptionFr->getUrl(),
/*9 Meta Title FR */ $descriptionFr->getHeadTitleTag(),
/*10 Meta Description FR */ $descriptionFr->getHeadDescTag(),
/*11 Meta Keywords FR */ $descriptionFr->getHeadKeywordsTag(),
/*12 Tags FR */ $descriptionFr->getTags(),
/*13 Bannière FR */ $descriptionFr->getMenuBanner(),
/*14 Désignation EN */ $descriptionEn->getName(),
/*15 H1 EN */ $descriptionEn->getHeadingTitle(),
/*16 Description longue EN */ $descriptionEn->getDescription(),
/*17 URL EN */ $descriptionEn->getUrl(),
/*18 Meta Title EN */ $descriptionEn->getHeadTitleTag(),
/*19 Meta Description EN */ $descriptionEn->getHeadDescTag(),
/*20 Meta Keywords EN */ $descriptionEn->getHeadKeywordsTag(),
/*21 Tags EN */ $descriptionEn->getTags(),
/*22 Bannière EN */ $descriptionEn->getMenuBanner(),
/*23 Date de création */ $category->getDateAdded()?$category->getDateAdded()->format('YmdHis'):'',
/*24 Date de modification */ ''
];
return $tab;
}
protected function getCsvHeader() {
return [
'ID categorie',
'ID parent',
'Active',
'Position',
'Désignation FR',
'H1 FR',
'Description longue FR',
'URL FR',
'Meta Title FR',
'Meta Description FR',
'Meta Keywords FR',
'Tags FR',
'Bannière FR',
'Désignation EN',
'H1 EN',
'Description longue EN',
'URL EN ',
'Meta Title EN',
'Meta Description EN',
'Meta Keywords EN ',
'Tags FR',
'Bannière FR',
'Date de création ',
'Date de modification'
];
}
/**
* Builds the filter facets available for a category from Attribute values (Akeneo import),
* restricted to attributes flagged "show in filter". The array key is the attribute code,
* matching the format expected by getProducts()/getProductsCount().
*/
public function getFilters(Category $category, $lang = 'fr') {
$language = $this->languageMgr->getByCode($lang);
$sql = 'select
a.attributes_code,
ad.attributes_title,
a.attributes_order,
pa.attributes_value
from attributes a
inner join attributes_description ad on ad.attributes_id = a.attributes_id and ad.language_id = :languageId
inner join products_attributes pa on pa.attributes_id = a.attributes_id
inner join products_to_categories ptc on ptc.products_id = pa.products_id
inner join products p on p.products_id = pa.products_id
where
a.attributes_filter = 1 and
a.attributes_status = 1 and
p.products_status = 1 and
ptc.categories_id in (:categoryIds) and
pa.attributes_value is not null and pa.attributes_value <> \'\'
group by a.attributes_code, pa.attributes_value
order by a.attributes_order, pa.attributes_value';
$conn = $this->em->getConnection();
$st = $conn->executeQuery($sql, [
'languageId' => $language->getId(),
'categoryIds' => $this->getCategoryTreeIds($category)
], [
'categoryIds' => \Doctrine\DBAL\Connection::PARAM_INT_ARRAY
]);
$filters = array();
while ($result = $st->fetchAssociative()) {
$code = $result['attributes_code'];
if(!isset($filters[$code])){
$filters[$code] = array(
'name' => $result['attributes_title'],
'attributes' => array()
);
}
$filters[$code]['attributes'][] = array(
'id' => htmlentities($result['attributes_value']),
'name' => htmlentities($result['attributes_value'])
);
}
return $filters;
}
/**
* Lists a category's products, page by page. Variants sharing the same ProductModel are
* grouped and returned as a single entry (see CategoryProductRepository::getProductsByCategory).
* $filters maps an Attribute code to a value (or array of values) to filter by, e.g. ['main_color' => 'RED'].
*
* Products assigned to any descendant category are included as well, not only those
* assigned directly to $category.
*/
public function getProducts(Category $category, $filters = [], $sorts = [], $page = 1, $limit = 20, $locale = 'fr') {
return $this->em->getRepository(\App\Entity\CategoryProduct::class)->getProductsByCategory($this->getCategoryTreeIds($category), true, $limit, $page, is_array($sorts) ? $sorts : [], $filters ?: []);
}
public function getProductsCount(Category $category, $filters = []) {
return $this->em->getRepository(\App\Entity\CategoryProduct::class)->getProductCountByCategory($this->getCategoryTreeIds($category), true, $filters ?: []);
}
/**
* Returns the id of $category plus the ids of all its descendant categories (recursively).
*/
private function getCategoryTreeIds(Category $category) : array {
return $this->em->getRepository(Category::class)->getChildrenIds($category);
}
public function createCategoryDescription(Category $category, $code = 'fr'){
$description = new \App\Entity\CategoryDescription();
$description->setLanguage($this->languageMgr->getByCode($code));
$description->setCategory($category);
$this->em->persist($description);
$this->em->flush();
return $description;
}
public function getPathTags(Category $category, $code = 'fr') {
$tags = $category->getTags();
if(empty($tags)){
$path = $this->em->getRepository('App:Category')->getPath($category);
$rpath = array_reverse($path);
foreach($rpath as $p){
$cDescription = $p->getCategoryDescription($code);
$tags = $cDescription->getTags();
if(!empty($tags))
return $tags;
}
}
return $tags;
}
public function orderChildrenByPathIds(Category &$category, $path = null) {
if(is_null($path)){
$path = [];
$p_tmp = $this->em->getRepository('App:Category')->getPath($category);
if($path){
foreach($pids as $p){
$pids[] = $p->getId();
}
}
}
if(!empty($path)){
print_r($path);
$children = [];
foreach($category->getChildren() as $child){
$this->orderChildrenByPathIds($child,$path);
$child->setCurrentPath($path);
$children[] = $child;
}
usort($children, function($a, $b)
{
if(in_array($a->getId(), $a->getCurrentPath())){
return -1;
}
return $a->getSortOrder()<$b->getSortOrder()?-1:1;
});
$category->setChildren($children);
}
}
}