classes/XLite/Model/Category.php line 128

Open in your IDE?
  1. <?php
  2. /**
  3.  * Copyright (c) 2011-present Qualiteam software Ltd. All rights reserved.
  4.  * See https://www.x-cart.com/license-agreement.html for license details.
  5.  */
  6. namespace XLite\Model;
  7. use ApiPlatform\Core\Annotation as ApiPlatform;
  8. use Doctrine\ORM\Mapping as ORM;
  9. use XLite\API\Endpoint\Category\DTO\CategoryMoveInput;
  10. use XLite\API\Endpoint\Category\DTO\CategoryProductInput;
  11. use XLite\API\Endpoint\Category\DTO\CategoryProductOutput;
  12. use XLite\API\Endpoint\Category\DTO\CategoryStatsOutput;
  13. use XLite\API\Endpoint\Category\DTO\CategoryInput;
  14. use XLite\API\Endpoint\Category\DTO\CategoryOutput;
  15. use XLite\API\Endpoint\Category\Filter\ParentFilter;
  16. use XLite\API\Filter\TranslationAwareOrderFilter;
  17. use XLite\Controller\API\Category\DeleteCategoryProduct;
  18. use XLite\Core\Database;
  19. /**
  20.  * Category
  21.  *
  22.  * @ORM\Entity
  23.  * @ORM\Table  (name="categories",
  24.  *      indexes={
  25.  *          @ORM\Index (name="lpos", columns={"lpos"}),
  26.  *          @ORM\Index (name="rpos", columns={"rpos"}),
  27.  *          @ORM\Index (name="enabled", columns={"enabled"})
  28.  *      }
  29.  * )
  30.  * @ApiPlatform\ApiResource(
  31.  *     input=CategoryInput::class,
  32.  *     output=CategoryOutput::class,
  33.  *     itemOperations={
  34.  *         "get"={
  35.  *             "method"="GET",
  36.  *             "path"="/categories/{category_id}",
  37.  *             "identifiers"={"category_id"},
  38.  *         },
  39.  *         "put"={
  40.  *             "method"="PUT",
  41.  *             "path"="/categories/{category_id}",
  42.  *             "identifiers"={"category_id"},
  43.  *         },
  44.  *         "delete"={
  45.  *             "method"="DELETE",
  46.  *             "path"="/categories/{category_id}",
  47.  *             "identifiers"={"category_id"},
  48.  *         },
  49.  *         "move"={
  50.  *             "method"="PUT",
  51.  *             "input"=CategoryMoveInput::class,
  52.  *             "path"="/categories/{category_id}/move",
  53.  *             "identifiers"={"category_id"},
  54.  *             "openapi_context"={
  55.  *                  "summary"="Update a category position in the categories tree",
  56.  *                  "parameters"={
  57.  *                      {"name"="category_id", "in"="path", "required"=true, "schema"={"type"="integer"}}
  58.  *                  }
  59.  *             },
  60.  *         },
  61.  *         "stats"={
  62.  *             "method"="GET",
  63.  *             "output"=CategoryStatsOutput::class,
  64.  *             "path"="/categories/{category_id}/stats",
  65.  *             "identifiers"={"category_id"},
  66.  *             "openapi_context"={
  67.  *                  "summary"="Retrieve category statistics",
  68.  *                  "parameters"={
  69.  *                      {"name"="category_id", "in"="path", "required"=true, "schema"={"type"="integer"}}
  70.  *                  }
  71.  *             },
  72.  *         },
  73.  *         "delete_category_product"={
  74.  *             "method"="DELETE",
  75.  *             "path"="/categories/{category_id}/products/{product_id}",
  76.  *             "identifiers"={"category_id"},
  77.  *             "requirements"={"category_id"="\d+", "product_id"="\d+"},
  78.  *             "controller"=DeleteCategoryProduct::class,
  79.  *             "read"=false,
  80.  *             "openapi_context"={
  81.  *                  "summary"="Delete a product from a category",
  82.  *                  "parameters"={
  83.  *                      {"name"="category_id", "in"="path", "required"=true, "schema"={"type"="integer"}},
  84.  *                      {"name"="product_id", "in"="path", "required"=true, "schema"={"type"="integer"}},
  85.  *                  }
  86.  *             },
  87.  *         },
  88.  *     },
  89.  *     collectionOperations={
  90.  *         "get"={
  91.  *             "method"="GET",
  92.  *             "path"="/categories",
  93.  *             "identifiers"={"category_id"},
  94.  *         },
  95.  *         "post"={
  96.  *             "method"="POST",
  97.  *             "path"="/categories",
  98.  *             "identifiers"={"category_id"},
  99.  *         },
  100.  *         "add_category_product"={
  101.  *             "method"="POST",
  102.  *             "input"=CategoryProductInput::class,
  103.  *             "path"="/categories/{category_id}/products",
  104.  *             "identifiers"={"category_id"},
  105.  *             "requirements"={"category_id"="\d+"},
  106.  *             "openapi_context"={
  107.  *                 "summary"="Add a product to a category",
  108.  *                 "parameters"={
  109.  *                     {"name"="category_id", "in"="path", "required"=true, "schema"={"type"="integer"}}
  110.  *                 }
  111.  *             },
  112.  *         },
  113.  *         "get_category_products"={
  114.  *             "method"="GET",
  115.  *             "path"="/categories/{category_id}/products",
  116.  *             "identifiers"={"category_id"},
  117.  *             "output"=CategoryProductOutput::class,
  118.  *             "requirements"={"category_id"="\d+"},
  119.  *             "openapi_context"={
  120.  *                 "summary"="Retrieve a list of products from a category",
  121.  *                 "parameters"={
  122.  *                     {"name"="category_id", "in"="path", "required"=true, "schema"={"type"="integer"}}
  123.  *                 }
  124.  *             },
  125.  *         },
  126.  *     }
  127.  * )
  128.  * @ApiPlatform\ApiFilter(ParentFilter::class, properties={"parent"})
  129.  * @ApiPlatform\ApiFilter(TranslationAwareOrderFilter::class, properties={"position"="ASC"})
  130.  */
  131. class Category extends \XLite\Model\Base\Catalog
  132. {
  133.     /**
  134.      * Node unique ID
  135.      *
  136.      * @var integer
  137.      *
  138.      * @ORM\Id
  139.      * @ORM\GeneratedValue (strategy="AUTO")
  140.      * @ORM\Column         (type="integer", options={ "unsigned": true })
  141.      */
  142.     protected $category_id;
  143.     /**
  144.      * Node left value
  145.      *
  146.      * @var integer
  147.      *
  148.      * @ORM\Column (type="integer")
  149.      */
  150.     protected $lpos;
  151.     /**
  152.      * Node right value
  153.      *
  154.      * @var integer
  155.      *
  156.      * @ORM\Column (type="integer")
  157.      */
  158.     protected $rpos;
  159.     /**
  160.      * Node status
  161.      *
  162.      * @var boolean
  163.      *
  164.      * @ORM\Column (type="boolean")
  165.      */
  166.     protected $enabled true;
  167.     /**
  168.      * Whether to display the category title, or not
  169.      *
  170.      * @var boolean
  171.      *
  172.      * @ORM\Column (type="boolean")
  173.      */
  174.     protected $show_title true;
  175.     /**
  176.      * Category "depth" in the tree
  177.      *
  178.      * @var integer
  179.      *
  180.      * @ORM\Column (type="integer")
  181.      */
  182.     protected $depth = -1;
  183.     /**
  184.      * Category position parameter. Sort inside the parent category
  185.      *
  186.      * @var integer
  187.      *
  188.      * @ORM\Column (type="integer")
  189.      */
  190.     protected $pos 0;
  191.     /**
  192.      * Whether to display the category title, or not
  193.      *
  194.      * @var string
  195.      *
  196.      * @ORM\Column (type="string", length=32, nullable=true)
  197.      */
  198.     protected $root_category_look;
  199.     /**
  200.      * Some cached flags
  201.      *
  202.      * @var \XLite\Model\Category\QuickFlags
  203.      *
  204.      * @ORM\OneToOne (targetEntity="XLite\Model\Category\QuickFlags", mappedBy="category", cascade={"all"})
  205.      */
  206.     protected $quickFlags;
  207.     /**
  208.      * Memberships
  209.      *
  210.      * @var \Doctrine\Common\Collections\ArrayCollection
  211.      *
  212.      * @ORM\ManyToMany (targetEntity="XLite\Model\Membership", inversedBy="categories")
  213.      * @ORM\JoinTable (name="category_membership_links",
  214.      *      joinColumns={@ORM\JoinColumn (name="category_id", referencedColumnName="category_id", onDelete="CASCADE")},
  215.      *      inverseJoinColumns={@ORM\JoinColumn (name="membership_id", referencedColumnName="membership_id", onDelete="CASCADE")}
  216.      * )
  217.      */
  218.     protected $memberships;
  219.     /**
  220.      * One-to-one relation with category_images table
  221.      *
  222.      * @var \XLite\Model\Image\Category\Image
  223.      *
  224.      * @ORM\OneToOne  (targetEntity="XLite\Model\Image\Category\Image", mappedBy="category", cascade={"all"})
  225.      */
  226.     protected $image;
  227.     /**
  228.      * One-to-one relation with category_images table
  229.      *
  230.      * @var \XLite\Model\Image\Category\Banner
  231.      *
  232.      * @ORM\OneToOne  (targetEntity="XLite\Model\Image\Category\Banner", mappedBy="category", cascade={"all"})
  233.      */
  234.     protected $banner;
  235.     /**
  236.      * Relation to a CategoryProducts entities
  237.      *
  238.      * @var \Doctrine\Common\Collections\ArrayCollection
  239.      *
  240.      * @ORM\OneToMany (targetEntity="XLite\Model\CategoryProducts", mappedBy="category", cascade={"all"})
  241.      * @ORM\OrderBy   ({"orderby" = "ASC"})
  242.      */
  243.     protected $categoryProducts;
  244.     /**
  245.      * Child categories
  246.      *
  247.      * @var \Doctrine\Common\Collections\ArrayCollection
  248.      *
  249.      * @ORM\OneToMany (targetEntity="XLite\Model\Category", mappedBy="parent", cascade={"all"})
  250.      * @ORM\OrderBy({"pos" = "ASC","category_id"="ASC","lpos" = "ASC"})
  251.      */
  252.     protected $children;
  253.     /**
  254.      * Parent category
  255.      *
  256.      * @var \XLite\Model\Category
  257.      *
  258.      * @ORM\ManyToOne  (targetEntity="XLite\Model\Category", inversedBy="children")
  259.      * @ORM\JoinColumn (name="parent_id", referencedColumnName="category_id", onDelete="SET NULL")
  260.      */
  261.     protected $parent;
  262.     /**
  263.      * Caching flag to check if the category is visible in the parents branch.
  264.      *
  265.      * @var boolean
  266.      */
  267.     protected $flagVisible;
  268.     /**
  269.      * Clean URLs
  270.      *
  271.      * @var \Doctrine\Common\Collections\Collection
  272.      *
  273.      * @ORM\OneToMany (targetEntity="XLite\Model\CleanURL", mappedBy="category", cascade={"all"})
  274.      * @ORM\OrderBy   ({"id" = "ASC"})
  275.      */
  276.     protected $cleanURLs;
  277.     /**
  278.      * Meta description type
  279.      *
  280.      * @var string
  281.      *
  282.      * @ORM\Column (type="string", length=1)
  283.      */
  284.     protected $metaDescType 'A';
  285.     /**
  286.      * Flag to exporting entities
  287.      *
  288.      * @var boolean
  289.      *
  290.      * @ORM\Column (type="boolean")
  291.      */
  292.     protected $xcPendingExport false;
  293.     /**
  294.      * @var \Doctrine\Common\Collections\Collection
  295.      *
  296.      * @ORM\OneToMany (targetEntity="XLite\Model\CategoryTranslation", mappedBy="owner", cascade={"all"})
  297.      */
  298.     protected $translations;
  299.     /**
  300.      * Get object unique id
  301.      *
  302.      * @return integer
  303.      */
  304.     public function getId()
  305.     {
  306.         return $this->getCategoryId();
  307.     }
  308.     /**
  309.      * Set parent
  310.      *
  311.      * @param \XLite\Model\Category $parent Parent category OPTIONAL
  312.      *
  313.      * @return void
  314.      */
  315.     public function setParent(\XLite\Model\Category $parent null)
  316.     {
  317.         $this->parent $parent;
  318.     }
  319.     /**
  320.      * Set image
  321.      *
  322.      * @param \XLite\Model\Image\Category\Image $image Image OPTIONAL
  323.      *
  324.      * @return void
  325.      */
  326.     public function setImage(\XLite\Model\Image\Category\Image $image null)
  327.     {
  328.         $this->image $image;
  329.     }
  330.     /**
  331.      * Check if category has image
  332.      *
  333.      * @return boolean
  334.      */
  335.     public function hasImage()
  336.     {
  337.         return $this->getImage() !== null;
  338.     }
  339.     /**
  340.      * Set banner image
  341.      *
  342.      * @param \XLite\Model\Image\Category\Banner $image Image OPTIONAL
  343.      *
  344.      * @return void
  345.      */
  346.     public function setBanner(\XLite\Model\Image\Category\Banner $image null)
  347.     {
  348.         $this->banner $image;
  349.     }
  350.     /**
  351.      * Check if category has image
  352.      *
  353.      * @return boolean
  354.      */
  355.     public function hasBanner()
  356.     {
  357.         return $this->getBanner() !== null;
  358.     }
  359.     /**
  360.      * Check every parent of category to be enabled.
  361.      *
  362.      * @return boolean
  363.      */
  364.     public function isVisible()
  365.     {
  366.         if ($this->flagVisible === null) {
  367.             $current $this;
  368.             $hidden false;
  369.             $rootCategoryId Database::getRepo('XLite\Model\Category')->getRootCategoryId();
  370.             while ($rootCategoryId != $current->getCategoryId()) {
  371.                 if (!$this->checkStorefrontVisibility($current)) {
  372.                     $hidden true;
  373.                     break;
  374.                 }
  375.                 $current $current->getParent();
  376.             }
  377.             $this->flagVisible = !$hidden;
  378.         }
  379.         return $this->flagVisible;
  380.     }
  381.     /**
  382.      * @return bool
  383.      */
  384.     public function isRootCategory()
  385.     {
  386.         return $this->getCategoryId() == Database::getRepo('XLite\Model\Category')->getRootCategoryId();
  387.     }
  388.     /**
  389.      * Check if the category is visible on the storefront for the current customer
  390.      *
  391.      * @param \XLite\Model\Category $current Current category
  392.      *
  393.      * @return boolean
  394.      */
  395.     protected function checkStorefrontVisibility($current)
  396.     {
  397.         return $current->getEnabled()
  398.             && (
  399.                 $current->getMemberships()->count() === 0
  400.                 || in_array(\XLite\Core\Auth::getInstance()->getMembershipId(), $current->getMembershipIds())
  401.             );
  402.     }
  403.     /**
  404.      * Get the number of subcategories
  405.      *
  406.      * @return integer
  407.      */
  408.     public function getSubcategoriesCount()
  409.     {
  410.         $result 0;
  411.         $enabledCondition $this->getRepository()->getEnabledCondition();
  412.         $quickFlags $this->getQuickFlags();
  413.         if ($quickFlags) {
  414.             $result $enabledCondition
  415.                 $quickFlags->getSubcategoriesCountEnabled()
  416.                 : $quickFlags->getSubcategoriesCountAll();
  417.         }
  418.         return $result;
  419.     }
  420.     /**
  421.      * Check if category has subcategories
  422.      *
  423.      * @return boolean
  424.      */
  425.     public function hasSubcategories()
  426.     {
  427.         return $this->getSubcategoriesCount();
  428.     }
  429.     /**
  430.      * Return subcategories list
  431.      *
  432.      * @return \Doctrine\Common\Collections\Collection
  433.      */
  434.     public function getSubcategories()
  435.     {
  436.         return $this->getChildren()->filter(
  437.             static function (\XLite\Model\Category $category) {
  438.                 return $category->getEnabled();
  439.             }
  440.         );
  441.     }
  442.     /**
  443.      * Return siblings list.
  444.      * You are able to include itself into this list. (Customer area)
  445.      *
  446.      * @param boolean $hasSelf Flag to include itself
  447.      *
  448.      * @return array
  449.      */
  450.     public function getSiblings($hasSelf false)
  451.     {
  452.         return $this->getRepository()->getSiblings($this$hasSelf);
  453.     }
  454.     /**
  455.      * Return siblings list.
  456.      * You are able to include itself into this list. (Customer area)
  457.      *
  458.      * @param integer $maxResults   Max results
  459.      * @param boolean $hasSelf      Flag to include itself
  460.      *
  461.      * @return array
  462.      */
  463.     public function getSiblingsFramed($maxResults$hasSelf false)
  464.     {
  465.         return $this->getRepository()->getSiblingsFramed($this$maxResults$hasSelf);
  466.     }
  467.     /**
  468.      * Get category path
  469.      *
  470.      * @return Category[]
  471.      */
  472.     public function getPath()
  473.     {
  474.         return $this->getRepository()->getCategoryPath($this->getCategoryId());
  475.     }
  476.     /**
  477.      * Gets full path to the category as a string: <parent category>/.../<category name>
  478.      *
  479.      * @return string
  480.      */
  481.     public function getStringPath()
  482.     {
  483.         $path = [];
  484.         foreach ($this->getPath() as $category) {
  485.             $path[] = $category->getName();
  486.         }
  487.         return implode('/'$path);
  488.     }
  489.     /**
  490.      * Return parent category ID
  491.      *
  492.      * @return integer
  493.      */
  494.     public function getParentId()
  495.     {
  496.         return $this->getParent() ? $this->getParent()->getCategoryId() : 0;
  497.     }
  498.     /**
  499.      * Set parent category ID
  500.      *
  501.      * @param integer $parentID Value to set
  502.      *
  503.      * @return void
  504.      */
  505.     public function setParentId($parentID)
  506.     {
  507.         $this->parent $this->getRepository()->find($parentID);
  508.     }
  509.     /**
  510.      * Get membership Ids
  511.      *
  512.      * @return array
  513.      */
  514.     public function getMembershipIds()
  515.     {
  516.         $result = [];
  517.         foreach ($this->getMemberships() as $membership) {
  518.             $result[] = $membership->getMembershipId();
  519.         }
  520.         return $result;
  521.     }
  522.     /**
  523.      * Flag if the category and active profile have the same memberships. (when category is displayed or hidden)
  524.      *
  525.      * @return boolean
  526.      */
  527.     public function hasAvailableMembership()
  528.     {
  529.         return $this->getMemberships()->count() === 0
  530.             || in_array(\XLite\Core\Auth::getInstance()->getMembershipId(), $this->getMembershipIds());
  531.     }
  532.     /**
  533.      * Return number of products associated with the category
  534.      *
  535.      * @return integer
  536.      */
  537.     public function getProductsCount()
  538.     {
  539.         return $this->getProducts(nulltrue);
  540.     }
  541.     /**
  542.      * Return products list
  543.      *
  544.      * @param \XLite\Core\CommonCell $cnd       Search condition OPTIONAL
  545.      * @param boolean                $countOnly Return items list or only its size OPTIONAL
  546.      *
  547.      * @return array|integer
  548.      */
  549.     public function getProducts(\XLite\Core\CommonCell $cnd null$countOnly false)
  550.     {
  551.         if ($cnd === null) {
  552.             $cnd = new \XLite\Core\CommonCell();
  553.         }
  554.         // Main condition for this search
  555.         $cnd->{\XLite\Model\Repo\Product::P_CATEGORY_ID} = $this->getCategoryId();
  556.         if (
  557.             \XLite\Core\Config::getInstance()->General->show_out_of_stock_products !== 'directLink'
  558.             && !'searchOnly' !== \XLite\Core\Config::getInstance()->General->show_out_of_stock_products
  559.             && !\XLite::isAdminZone()
  560.         ) {
  561.             $cnd->{\XLite\Model\Repo\Product::P_INVENTORY} = false;
  562.         }
  563.         return Database::getRepo('XLite\Model\Product')->search($cnd$countOnly);
  564.     }
  565.     /**
  566.      * Check if product present in category
  567.      *
  568.      * @param \XLite\Model\Product|integer $product  Product
  569.      *
  570.      * @return boolean
  571.      */
  572.     public function hasProduct($product)
  573.     {
  574.         return $this->getRepository()->hasProduct($this$product);
  575.     }
  576.     /**
  577.      * Return category description
  578.      *
  579.      * @return string
  580.      */
  581.     public function getViewDescription()
  582.     {
  583.         return static::getPreprocessedValue($this->getDescription())
  584.             ?: $this->getDescription();
  585.     }
  586.     /**
  587.      * Get position
  588.      *
  589.      * @return integer
  590.      */
  591.     public function getPosition()
  592.     {
  593.         return $this->getPos();
  594.     }
  595.     /**
  596.      * Set position
  597.      *
  598.      * @param integer $position Product position
  599.      *
  600.      * @return self
  601.      */
  602.     public function setPosition($position)
  603.     {
  604.         return $this->setPos($position);
  605.     }
  606.     /**
  607.      * Returns meta description
  608.      *
  609.      * @return string
  610.      */
  611.     public function getMetaDesc()
  612.     {
  613.         return $this->getMetaDescType() === 'A'
  614.             ? static::postprocessMetaDescription($this->getDescription())
  615.             : $this->getSoftTranslation()->getMetaDesc();
  616.     }
  617.     /**
  618.      * Returns meta description type
  619.      *
  620.      * @return string
  621.      */
  622.     public function getMetaDescType()
  623.     {
  624.         $result $this->metaDescType;
  625.         if (!$result) {
  626.             $metaDescPresent array_reduce($this->getTranslations()->toArray(), static function ($carry$item) {
  627.                 return $carry ?: (bool) $item->getMetaDesc();
  628.             }, false);
  629.             $result $metaDescPresent 'C' 'A';
  630.         }
  631.         return $result;
  632.     }
  633.     /**
  634.      * Constructor
  635.      *
  636.      * @param array $data Entity properties OPTIONAL
  637.      */
  638.     public function __construct(array $data = [])
  639.     {
  640.         $this->categoryProducts = new \Doctrine\Common\Collections\ArrayCollection();
  641.         $this->children         = new \Doctrine\Common\Collections\ArrayCollection();
  642.         $this->memberships      = new \Doctrine\Common\Collections\ArrayCollection();
  643.         parent::__construct($data);
  644.     }
  645.     /**
  646.      * Get category_id
  647.      *
  648.      * @return integer
  649.      */
  650.     public function getCategoryId()
  651.     {
  652.         return (int) $this->category_id;
  653.     }
  654.     /**
  655.      * Set lpos
  656.      *
  657.      * @param integer $lpos
  658.      * @return Category
  659.      */
  660.     public function setLpos($lpos)
  661.     {
  662.         $this->lpos $lpos;
  663.         return $this;
  664.     }
  665.     /**
  666.      * Get lpos
  667.      *
  668.      * @return integer
  669.      */
  670.     public function getLpos()
  671.     {
  672.         return $this->lpos;
  673.     }
  674.     /**
  675.      * Set rpos
  676.      *
  677.      * @param integer $rpos
  678.      * @return Category
  679.      */
  680.     public function setRpos($rpos)
  681.     {
  682.         $this->rpos $rpos;
  683.         return $this;
  684.     }
  685.     /**
  686.      * Get rpos
  687.      *
  688.      * @return integer
  689.      */
  690.     public function getRpos()
  691.     {
  692.         return $this->rpos;
  693.     }
  694.     /**
  695.      * Set enabled
  696.      *
  697.      * @param boolean $enabled
  698.      * @return Category
  699.      */
  700.     public function setEnabled($enabled)
  701.     {
  702.         $this->getPreviousState()->enabled $this->enabled;
  703.         $this->enabled                     = (bool)$enabled;
  704.         return $this;
  705.     }
  706.     /**
  707.      * Get enabled
  708.      *
  709.      * @return boolean
  710.      */
  711.     public function getEnabled()
  712.     {
  713.         return $this->enabled;
  714.     }
  715.     /**
  716.      * Set show_title
  717.      *
  718.      * @param boolean $showTitle
  719.      * @return Category
  720.      */
  721.     public function setShowTitle($showTitle)
  722.     {
  723.         $this->show_title $showTitle;
  724.         return $this;
  725.     }
  726.     /**
  727.      * Get show_title
  728.      *
  729.      * @return boolean
  730.      */
  731.     public function getShowTitle()
  732.     {
  733.         return $this->show_title;
  734.     }
  735.     /**
  736.      * Set depth
  737.      *
  738.      * @param integer $depth
  739.      * @return Category
  740.      */
  741.     public function setDepth($depth)
  742.     {
  743.         $this->depth $depth;
  744.         return $this;
  745.     }
  746.     /**
  747.      * Get depth
  748.      *
  749.      * @return integer
  750.      */
  751.     public function getDepth()
  752.     {
  753.         return $this->depth;
  754.     }
  755.     /**
  756.      * Set pos
  757.      *
  758.      * @param integer $pos
  759.      * @return Category
  760.      */
  761.     public function setPos($pos)
  762.     {
  763.         $this->pos $pos;
  764.         return $this;
  765.     }
  766.     /**
  767.      * Get pos
  768.      *
  769.      * @return integer
  770.      */
  771.     public function getPos()
  772.     {
  773.         return $this->pos;
  774.     }
  775.     /**
  776.      * Set root_category_look
  777.      *
  778.      * @param string $rootCategoryLook
  779.      * @return Category
  780.      */
  781.     public function setRootCategoryLook($rootCategoryLook)
  782.     {
  783.         $this->root_category_look $rootCategoryLook;
  784.         return $this;
  785.     }
  786.     /**
  787.      * Get root_category_look
  788.      *
  789.      * @return string
  790.      */
  791.     public function getRootCategoryLook()
  792.     {
  793.         return $this->root_category_look;
  794.     }
  795.     /**
  796.      * Set metaDescType
  797.      *
  798.      * @param string $metaDescType
  799.      * @return Category
  800.      */
  801.     public function setMetaDescType($metaDescType)
  802.     {
  803.         $this->metaDescType $metaDescType;
  804.         return $this;
  805.     }
  806.     /**
  807.      * Set xcPendingExport
  808.      *
  809.      * @param boolean $xcPendingExport
  810.      * @return Category
  811.      */
  812.     public function setXcPendingExport($xcPendingExport)
  813.     {
  814.         $this->xcPendingExport $xcPendingExport;
  815.         return $this;
  816.     }
  817.     /**
  818.      * Get xcPendingExport
  819.      *
  820.      * @return boolean
  821.      */
  822.     public function getXcPendingExport()
  823.     {
  824.         return $this->xcPendingExport;
  825.     }
  826.     /**
  827.      * Set quickFlags
  828.      *
  829.      * @param \XLite\Model\Category\QuickFlags $quickFlags
  830.      * @return Category
  831.      */
  832.     public function setQuickFlags(\XLite\Model\Category\QuickFlags $quickFlags null)
  833.     {
  834.         $this->quickFlags $quickFlags;
  835.         return $this;
  836.     }
  837.     /**
  838.      * Get quickFlags
  839.      *
  840.      * @return \XLite\Model\Category\QuickFlags
  841.      */
  842.     public function getQuickFlags()
  843.     {
  844.         return $this->quickFlags;
  845.     }
  846.     /**
  847.      * Add memberships
  848.      *
  849.      * @param \XLite\Model\Membership $memberships
  850.      * @return Category
  851.      */
  852.     public function addMemberships(\XLite\Model\Membership $memberships)
  853.     {
  854.         $this->memberships[] = $memberships;
  855.         return $this;
  856.     }
  857.     /**
  858.      * Get memberships
  859.      *
  860.      * @return \Doctrine\Common\Collections\Collection
  861.      */
  862.     public function getMemberships()
  863.     {
  864.         return $this->memberships;
  865.     }
  866.     /**
  867.      * Get image
  868.      *
  869.      * @return \XLite\Model\Image\Category\Image
  870.      */
  871.     public function getImage()
  872.     {
  873.         return $this->image;
  874.     }
  875.     /**
  876.      * Get banner image
  877.      *
  878.      * @return \XLite\Model\Image\Category\Banner
  879.      */
  880.     public function getBanner()
  881.     {
  882.         return $this->banner;
  883.     }
  884.     /**
  885.      * Add categoryProducts
  886.      *
  887.      * @param \XLite\Model\CategoryProducts $categoryProducts
  888.      * @return Category
  889.      */
  890.     public function addCategoryProducts(\XLite\Model\CategoryProducts $categoryProducts)
  891.     {
  892.         $this->categoryProducts[] = $categoryProducts;
  893.         return $this;
  894.     }
  895.     /**
  896.      * Get categoryProducts
  897.      *
  898.      * @return \Doctrine\Common\Collections\Collection
  899.      */
  900.     public function getCategoryProducts()
  901.     {
  902.         return $this->categoryProducts;
  903.     }
  904.     /**
  905.      * Add children
  906.      *
  907.      * @param \XLite\Model\Category $children
  908.      * @return Category
  909.      */
  910.     public function addChildren(\XLite\Model\Category $children)
  911.     {
  912.         $this->children[] = $children;
  913.         return $this;
  914.     }
  915.     /**
  916.      * Get children
  917.      *
  918.      * @return \Doctrine\Common\Collections\Collection
  919.      */
  920.     public function getChildren()
  921.     {
  922.         return $this->children;
  923.     }
  924.     /**
  925.      * Get parent
  926.      *
  927.      * @return \XLite\Model\Category
  928.      */
  929.     public function getParent()
  930.     {
  931.         return $this->parent;
  932.     }
  933.     /**
  934.      * Add cleanURLs
  935.      *
  936.      * @param \XLite\Model\CleanURL $cleanURLs
  937.      * @return Category
  938.      */
  939.     public function addCleanURLs(\XLite\Model\CleanURL $cleanURLs)
  940.     {
  941.         $this->cleanURLs[] = $cleanURLs;
  942.         return $this;
  943.     }
  944.     /**
  945.      * Get cleanURLs
  946.      *
  947.      * @return \Doctrine\Common\Collections\Collection
  948.      */
  949.     public function getCleanURLs()
  950.     {
  951.         return $this->cleanURLs;
  952.     }
  953.     /**
  954.      * Get front URL
  955.      *
  956.      * @return string
  957.      */
  958.     public function getFrontURL($buildCuInAdminZone false)
  959.     {
  960.         return $this->getCategoryId()
  961.             ? \XLite\Core\Converter::makeURLValid(
  962.                 \XLite::getInstance()->getShopURL(
  963.                     \XLite\Core\Converter::buildURL(
  964.                         'category',
  965.                         '',
  966.                         ['category_id' => $this->getCategoryId()],
  967.                         \XLite::getCustomerScript(),
  968.                         $buildCuInAdminZone
  969.                     )
  970.                 )
  971.             )
  972.             : null;
  973.     }
  974.     // {{{ Translation Getters / setters
  975.     /**
  976.      * @return string
  977.      */
  978.     public function getDescription()
  979.     {
  980.         return $this->getTranslationField(__FUNCTION__);
  981.     }
  982.     /**
  983.      * @param string $description
  984.      *
  985.      * @return \XLite\Model\Base\Translation
  986.      */
  987.     public function setDescription($description)
  988.     {
  989.         return $this->setTranslationField(__FUNCTION__$description);
  990.     }
  991.     /**
  992.      * @return string
  993.      */
  994.     public function getMetaTags()
  995.     {
  996.         return $this->getTranslationField(__FUNCTION__);
  997.     }
  998.     /**
  999.      * @param string $metaTags
  1000.      *
  1001.      * @return \XLite\Model\Base\Translation
  1002.      */
  1003.     public function setMetaTags($metaTags)
  1004.     {
  1005.         return $this->setTranslationField(__FUNCTION__$metaTags);
  1006.     }
  1007.     /**
  1008.      * @param string $metaDesc
  1009.      *
  1010.      * @return \XLite\Model\Base\Translation
  1011.      */
  1012.     public function setMetaDesc($metaDesc)
  1013.     {
  1014.         return $this->setTranslationField(__FUNCTION__$metaDesc);
  1015.     }
  1016.     /**
  1017.      * @return string
  1018.      */
  1019.     public function getMetaTitle()
  1020.     {
  1021.         return $this->getTranslationField(__FUNCTION__);
  1022.     }
  1023.     /**
  1024.      * @param string $metaTitle
  1025.      *
  1026.      * @return \XLite\Model\Base\Translation
  1027.      */
  1028.     public function setMetaTitle($metaTitle)
  1029.     {
  1030.         return $this->setTranslationField(__FUNCTION__$metaTitle);
  1031.     }
  1032.     // }}}
  1033. }