src/Submarine/PagesBundle/Entity/Page.php line 46

Open in your IDE?
  1. <?php
  2. /**
  3.  * (c) itmedia.by <info@itmedia.by>
  4.  */
  5. namespace Submarine\PagesBundle\Entity;
  6. use CatalogBundle\Entity\ProductVariation;
  7. use Doctrine\Common\Collections\ArrayCollection;
  8. use Doctrine\Common\Collections\Collection;
  9. use Doctrine\ORM\Event\LifecycleEventArgs;
  10. use Doctrine\ORM\Event\PostPersistEventArgs;
  11. use Doctrine\ORM\Event\PreFlushEventArgs;
  12. use Doctrine\ORM\Event\PrePersistEventArgs;
  13. use Doctrine\ORM\Mapping as ORM;
  14. use Postroyka\AppBundle\Entity\CronUpdate;
  15. use Postroyka\AppBundle\Entity\PageDefected;
  16. use Postroyka\AppBundle\Redis\RedisBaseProvider;
  17. use Submarine\CoreBundle\Entity\CommentsAwareInterface;
  18. use Submarine\CoreBundle\Entity\OrderAwareInterface;
  19. use Submarine\CoreBundle\Entity\SubmarineEntityInterface;
  20. use Submarine\CoreBundle\Exception\InvalidArgumentException;
  21. use Submarine\CoreBundle\Uploader\AbstractUploadEntity;
  22. use Submarine\FilesBundle\Provider\FilesProvider;
  23. use Submarine\PagesBundle\Entity\Type\PageType;
  24. use Submarine\PagesBundle\Entity\Type\PageValue;
  25. use Symfony\Component\HttpFoundation\File\File;
  26. use Symfony\Component\Validator\Constraints as Assert;
  27. /**
  28.  * Class Page
  29.  * @package Submarine\PagesBundle
  30.  *
  31.  * @ORM\Entity(repositoryClass="Submarine\PagesBundle\Repository\PageRepository")
  32.  *
  33.  * @ORM\Table(
  34.  *      name="submarine_pages",
  35.  *      indexes={
  36.  *          @ORM\Index(name="published", columns={"is_enabled", "is_deleted"}),
  37.  *          @ORM\Index(name="published_at", columns={"published_at"}),
  38.  *          @ORM\Index(name="url", columns={"url"}),
  39.  *          @ORM\Index(name="tag", columns={"tag"})
  40.  *      })
  41.  * @ORM\HasLifecycleCallbacks()
  42.  */
  43. class Page extends AbstractUploadEntity implements
  44.     SubmarineEntityInterface,
  45.     CommentsAwareInterface,
  46.     OrderAwareInterface
  47. {
  48.     const STOCK_VALUE "stock";
  49.     const IN_STOCK "in_stock";
  50.     const NOT_IN_STOCK "not_in_stock";
  51.     const OUT_PRODUCTION "out_production";
  52.     /**
  53.      * ID
  54.      * @var int
  55.      *
  56.      * @ORM\Id()
  57.      * @ORM\Column(name="id", type="integer", nullable=false, unique=true)
  58.      * @ORM\GeneratedValue(strategy="AUTO")
  59.      */
  60.     private $id;
  61.     /**
  62.      * URL
  63.      * @var string
  64.      *
  65.      * @ORM\Column(name="url", type="string", nullable=true)
  66.      */
  67.     private $url;
  68.     /**
  69.      * Имя/ключ документа
  70.      *
  71.      * @var string
  72.      * @ORM\Column(name="tag", type="string", nullable=true)
  73.      */
  74.     private $tag;
  75.     /**
  76.      * Является папкой страница?
  77.      * @var bool
  78.      *
  79.      * @ORM\Column(name="is_directory", type="boolean", nullable=true)
  80.      */
  81.     private $directory false;
  82.     /**
  83.      * @var string
  84.      *
  85.      * @ORM\Column(name="title", type="string", nullable=false)
  86.      * @Assert\NotBlank()
  87.      */
  88.     private $title;
  89.     /**
  90.      * Описание
  91.      * @var string
  92.      *
  93.      * @ORM\Column(name="description", type="string", nullable=true, length=2048)
  94.      */
  95.     private $description;
  96.     // --------------- Активность ----------------
  97.     /**
  98.      * Страница удалена
  99.      *
  100.      * @var bool
  101.      * @ORM\Column(name="is_deleted", type="boolean", nullable=true)
  102.      */
  103.     private $deleted false;
  104.     /**
  105.      * Страница включена
  106.      *
  107.      * @var bool
  108.      * @ORM\Column(name="is_enabled", type="boolean", nullable=true)
  109.      */
  110.     private $enabled true;
  111.     // ------------ Tags ----------------
  112.     /**
  113.      *
  114.      * @var string
  115.      *
  116.      * @ORM\Column(name="html_title", type="string", nullable=true)
  117.      */
  118.     private $metaTitle;
  119.     /**
  120.      * @var string
  121.      *
  122.      * @ORM\Column(name="html_meta_description", type="text", nullable=true)
  123.      */
  124.     private $metaDescription;
  125.     /**
  126.      * @var string
  127.      *
  128.      * @ORM\Column(name="html_meta_keywords", type="string", nullable=true, length=1024)
  129.      */
  130.     private $metaKeywords;
  131.     // -------------- Связи -----------
  132.     /**
  133.      * Тип страницы
  134.      * @var PageType
  135.      *
  136.      * @ORM\ManyToOne(targetEntity="Submarine\PagesBundle\Entity\Type\PageType")
  137.      * @ORM\JoinColumn(name="type_id", referencedColumnName="id")
  138.      */
  139.     private $type;
  140.     /**
  141.      * Родительские связи страницы
  142.      * @var ArrayCollection|Relations[]
  143.      *
  144.      * @ORM\OneToMany(targetEntity="Submarine\PagesBundle\Entity\Relations", mappedBy="page", cascade={"REMOVE"})
  145.      */
  146.     private $parents;
  147.     /**
  148.      * Дочернмие связи
  149.      * @var ArrayCollection|Relations[]
  150.      *
  151.      * @ORM\OneToMany(targetEntity="Submarine\PagesBundle\Entity\Relations", mappedBy="parent")
  152.      */
  153.     private $child;
  154.     /**
  155.      * Дополнительные поля
  156.      * @var ArrayCollection|PageValue[]
  157.      *
  158.      * @ORM\OneToMany(
  159.      *     targetEntity="Submarine\PagesBundle\Entity\Type\PageValue",
  160.      *     mappedBy="page",
  161.      *     cascade={"ALL"},
  162.      *     indexBy="field_id",
  163.      * )
  164.      */
  165.     private $fields;
  166.     /**
  167.      * Кэширование доп.значения страницы
  168.      *
  169.      * @var array
  170.      * @ORM\Column(name="cached_values", type="array", nullable=true)
  171.      */
  172.     private $values = [];
  173.     /**
  174.      * Тело документа
  175.      * @var PageBody
  176.      *
  177.      * @ORM\ManyToOne(targetEntity="Submarine\PagesBundle\Entity\PageBody", cascade={"ALL"}, inversedBy="pages")
  178.      * @ORM\JoinColumn(name="body_id", referencedColumnName="id", nullable=true)
  179.      */
  180.     private $pageBody;
  181.     /**
  182.      * Связанные страницы
  183.      * @var Link[]|ArrayCollection
  184.      * @ORM\OneToMany(
  185.      *     targetEntity="Submarine\PagesBundle\Entity\Link",
  186.      *     mappedBy="parent",
  187.      *     orphanRemoval=true,
  188.      * )
  189.      * @ORM\OrderBy({"position"="ASC"})
  190.      * @Assert\Valid()
  191.      */
  192.     private $linkedPages;
  193.     /**
  194.      * Связанные страницы в корзине
  195.      *
  196.      * @var LinkInCart[]|ArrayCollection
  197.      *
  198.      * @ORM\OneToMany(
  199.      *     targetEntity="Submarine\PagesBundle\Entity\LinkInCart",
  200.      *     mappedBy="parent",
  201.      *     orphanRemoval=true,
  202.      * )
  203.      * @ORM\OrderBy({"position"="ASC"})
  204.      * @Assert\Valid()
  205.      */
  206.     private $linkedPagesInCart;
  207.     /**
  208.      * Сопутствующие товары
  209.      *
  210.      * @var AccompanyPage[]|ArrayCollection
  211.      *
  212.      * @ORM\OneToMany(
  213.      *     targetEntity="Submarine\PagesBundle\Entity\AccompanyPage",
  214.      *     mappedBy="parent",
  215.      *     orphanRemoval=true,
  216.      * )
  217.      * @ORM\OrderBy({"position"="ASC"})
  218.      * @Assert\Valid()
  219.      */
  220.     private $accompanyPages;
  221.     /**
  222.      * @ORM\OneToMany(targetEntity="Submarine\PagesBundle\Entity\TitleUrlRelations", mappedBy="page", cascade={"remove", "persist"})
  223.      * @var TitleUrlRelations[]|ArrayCollection
  224.      */
  225.     private $titleUrlRelations;
  226.     // ---------------- Dates ------------
  227.     /**
  228.      * @var \DateTime
  229.      *
  230.      * @ORM\Column(name="created_at", type="datetime")
  231.      */
  232.     private $createdAt;
  233.     /**
  234.      * @var \DateTime
  235.      *
  236.      * @ORM\Column(name="updated_at", type="datetime")
  237.      */
  238.     private $updatedAt;
  239.     /**
  240.      * @var \DateTime
  241.      *
  242.      * @ORM\Column(name="published_at", type="datetime")
  243.      */
  244.     private $publishedAt;
  245.     // ---------------- Upload ---------------
  246.     /**
  247.      * @var File
  248.      */
  249.     private $file;
  250.     /**
  251.      * @var File
  252.      */
  253.     private $fileFid;
  254.     /**
  255.      * @var File|null
  256.      */
  257.     private $fileMobileMenu;
  258.     /**
  259.      * Картинка (путь)
  260.      * @var string
  261.      *
  262.      * @ORM\Column(name="image_path", type="string", nullable=true)
  263.      */
  264.     private $image;
  265.     /**
  266.      * Картинка для фида(путь)
  267.      * @var string
  268.      *
  269.      * @ORM\Column(name="image_path_fid", type="string", nullable=true)
  270.      */
  271.     private $imageFid;
  272.     // ---------------- Comments ------------
  273.     /**
  274.      * Количество комментариев
  275.      * @ORM\Column(type="integer", unique=false, nullable=true)
  276.      * @var integer
  277.      */
  278.     private $countComments 0;
  279.     /**
  280.      * Количество комментариев
  281.      * @ORM\Column(type="boolean", unique=false, nullable=true)
  282.      * @var bool
  283.      */
  284.     private $allowedComments false;
  285.     /**
  286.      * Модерирация кооментариев комментариев
  287.      * @ORM\Column(type="boolean", unique=false, nullable=true)
  288.      * @var bool
  289.      */
  290.     private $moderatedComments false;
  291.     // ---------------- Product --------------
  292.     /**
  293.      * Стоимость товара
  294.      *
  295.      * @var float
  296.      * @ORM\Column(name="price", type="decimal", precision=15, scale=2, nullable=true)
  297.      */
  298.     private $price;
  299.     /**
  300.      * @var string|null
  301.      *
  302.      * @Assert\Regex(
  303.      *     pattern="/^\d+\.?\d*(\;\d+\.?\d*)*$/",
  304.      *     match=true,
  305.      *     message="Данные должны быть через ';' (пример: 2.975;3;6)"
  306.      * )
  307.      *
  308.      * @ORM\Column(type="string", nullable=true)
  309.      */
  310.     private $multipleDimensions;
  311.     /**
  312.      * Артикул товара
  313.      *
  314.      * @var string
  315.      * @ORM\Column(name="product_id", type="string", nullable=true, unique=false)
  316.      */
  317.     private $productId;
  318.     /**
  319.      * @ORM\Column(type="string", nullable=true, unique=true)
  320.      */
  321.     private ?int $b24Id;
  322.     /**
  323.      * Количество товаров у категории
  324.      *
  325.      * @var integer
  326.      * @ORM\Column(name="count_products", type="integer", nullable=true, unique=false)
  327.      */
  328.     private $countProducts;
  329.     /**
  330.      * Наличие товара
  331.      *
  332.      * @var bool
  333.      * @ORM\Column(name="is_available", type="boolean", nullable=true)
  334.      */
  335.     private $available;
  336.     /**
  337.      * Распростряняется скидка на товар?
  338.      *
  339.      * @var bool
  340.      * @ORM\Column(name="is_discount", type="boolean", nullable=true)
  341.      */
  342.     private $discount;
  343.     // ---------------- Virtual ----------------
  344.     /**
  345.      * @var FilesProvider
  346.      */
  347.     private $filesProvider;
  348.     /**
  349.      * @var bool
  350.      */
  351.     private $selected;
  352.     /**
  353.      * @var Collection
  354.      * @ORM\OneToMany(targetEntity="Postroyka\AppBundle\Entity\CronUpdate", mappedBy="page")
  355.      */
  356.     private $cronUpdates;
  357.     /**
  358.      * @ORM\OneToOne(targetEntity="Postroyka\AppBundle\Entity\PageDefected", mappedBy="parent", cascade={"remove", "persist"})
  359.      */
  360.     private ?PageDefected $pageDefected;
  361.     /**
  362.      * Статус товара
  363.      *
  364.      * @var string
  365.      *
  366.      * @ORM\Column(name="product_status", type="string", nullable=false, options={"default" : Submarine\PagesBundle\Entity\Page::NOT_IN_STOCK})
  367.      */
  368.      private $productStatus;
  369.     /**
  370.      * @ORM\OneToOne(targetEntity="Submarine\PagesBundle\Entity\PageB24UpdateTime", mappedBy="page", cascade={"remove", "persist"})
  371.      */
  372.     private ?PageB24UpdateTime $pageB24UpdateTime;
  373.     /**
  374.      * Связи с данными по складам
  375.      * @var ArrayCollection
  376.      *
  377.      * @ORM\OneToMany(targetEntity="Submarine\PagesBundle\Entity\PageB24Warehouse", mappedBy="page", cascade={"REMOVE"})
  378.      */
  379.     private Collection $pageB24Warehouses;
  380.     /**
  381.      * Картинка для мобильного меню(путь)
  382.      * @var string|null
  383.      *
  384.      * @ORM\Column(name="image_mobile_menu", type="string", nullable=true)
  385.      */
  386.     private $imageMobileMenu;
  387.     /**
  388.      * Арктикул товара
  389.      *
  390.      * @var string
  391.      *
  392.      * @ORM\Column(type="string", nullable=false, unique=true)
  393.      */
  394.     private $vendorCode;
  395.     // ------------------ Methods ---------------
  396.     /**
  397.      * Имя сущности
  398.      * @return string
  399.      */
  400.     public static function entityName()
  401.     {
  402.         return __CLASS__;
  403.     }
  404.     public function __construct()
  405.     {
  406.         $this->createdAt = new \DateTime();
  407.         $this->updatedAt = new \DateTime();
  408.         $this->publishedAt = new \DateTime();
  409.         $this->pageBody = new PageBody();
  410.         $this->fields = new ArrayCollection();
  411.         $this->parents = new ArrayCollection();
  412.         $this->linkedPages = new ArrayCollection();
  413.         $this->accompanyPages = new ArrayCollection();
  414.         $this->linkedPagesInCart = new ArrayCollection();
  415.         $this->titleUrlRelations = new ArrayCollection();
  416.         $this->cronUpdates = new ArrayCollection();
  417.         $this->pageB24Warehouses = new ArrayCollection();
  418.         $this->productStatus self::NOT_IN_STOCK;
  419.         $this->pageB24UpdateTime = new PageB24UpdateTime($this);
  420.     }
  421.     public function __clone()
  422.     {
  423.         $this->id null;
  424.     }
  425.     /**
  426.      * @ORM\PreUpdate()
  427.      */
  428.     public function preUpdate()
  429.     {
  430.         $this->updatedAt = new \DateTime();
  431.         RedisBaseProvider::clearKeysByPattern('*' RedisBaseProvider::REDIS_HOMEPAGE_KEY);
  432.         RedisBaseProvider::clearKeysByPattern('*' RedisBaseProvider::CATALOG_PAGE_REDIS_KEY '*');
  433.         RedisBaseProvider::setKey(RedisBaseProvider::REDIS_PRODUCT_UPDATE);
  434.     }
  435.     /**
  436.      * @ORM\PreFlush()
  437.      */
  438.     public function preFlush(PreFlushEventArgs $args)
  439.     {
  440.         if(!$this->vendorCode || !$this->id || strpos($this->vendorCode, (string)$this->id3) === false){
  441.             $this->vendorCode rand(100999) . str_pad($this->id5"0"STR_PAD_LEFT);
  442.         }
  443.     }
  444.     /**
  445.      * ID сущности
  446.      * @return mixed
  447.      */
  448.     public function getId()
  449.     {
  450.         return $this->id;
  451.     }
  452.     /**
  453.      * @return PageType
  454.      */
  455.     public function getType()
  456.     {
  457.         return $this->type;
  458.     }
  459.     /**
  460.      * @param PageType $type
  461.      */
  462.     public function setType(PageType $type)
  463.     {
  464.         $this->type $type;
  465.         $this->directory $type->isDirectory();
  466.         $this->allowedComments $type->isAllowComments();
  467.     }
  468.     /**
  469.      * @return ArrayCollection|Relations[]
  470.      */
  471.     public function getParents()
  472.     {
  473.         return $this->parents;
  474.     }
  475.     /**
  476.      * Родительские страницы
  477.      * ВАЖНО!!! Зансение в массиве может быть и null - значит родитель корневая папка
  478.      * Page[]
  479.      */
  480.     public function getParentPages()
  481.     {
  482.         $parent = [];
  483.         foreach ($this->parents as $rel) {
  484.             $parent[] = $rel->getParent();
  485.         }
  486.         return $parent;
  487.     }
  488.     // -------------- Состояние страницы ---------------
  489.     /**
  490.      * @return boolean
  491.      */
  492.     public function isDirectory()
  493.     {
  494.         return $this->directory;
  495.     }
  496.     /**
  497.      * @param boolean $directory
  498.      */
  499.     public function setDirectory($directory)
  500.     {
  501.         $this->directory $directory;
  502.     }
  503.     /**
  504.      * @return boolean
  505.      */
  506.     public function isEnabled()
  507.     {
  508.         return $this->enabled;
  509.     }
  510.     /**
  511.      * @param boolean $enabled
  512.      */
  513.     public function setEnabled($enabled)
  514.     {
  515.         $this->enabled $enabled;
  516.     }
  517.     /**
  518.      * @return boolean
  519.      */
  520.     public function isDeleted()
  521.     {
  522.         return $this->deleted;
  523.     }
  524.     /**
  525.      * @param boolean $deleted
  526.      */
  527.     public function setDeleted($deleted)
  528.     {
  529.         $this->deleted $deleted;
  530.     }
  531.     // ------------ Идентификация страницы -----------
  532.     /**
  533.      * @return string
  534.      */
  535.     public function getUrl()
  536.     {
  537.         return $this->url;
  538.     }
  539.     /**
  540.      * @param string $url
  541.      */
  542.     public function setUrl($url)
  543.     {
  544.         if (!== strpos($url'/')) {
  545.             $url '/' $url;
  546.         }
  547.         $this->url $url;
  548.     }
  549.     /**
  550.      * @return string
  551.      */
  552.     public function getTag()
  553.     {
  554.         return $this->tag;
  555.     }
  556.     /**
  557.      * @param string $key
  558.      */
  559.     public function setTag($key)
  560.     {
  561.         $this->tag $key;
  562.     }
  563.     // --------------- Content ---------------
  564.     /**
  565.      * @return string
  566.      */
  567.     public function getTitle()
  568.     {
  569.         return $this->title;
  570.     }
  571.     /**
  572.      * @param string $title
  573.      */
  574.     public function setTitle($title)
  575.     {
  576.         $this->title $title;
  577.     }
  578.     /**
  579.      * @return string
  580.      */
  581.     public function getDescription()
  582.     {
  583.         return $this->description;
  584.     }
  585.     /**
  586.      * @param string $description
  587.      */
  588.     public function setDescription($description)
  589.     {
  590.         $this->description $description;
  591.     }
  592.     /**
  593.      * @return string
  594.      */
  595.     public function getImage()
  596.     {
  597.         return $this->image;
  598.     }
  599.     /**
  600.      * @return string
  601.      */
  602.     public function getImageFid()
  603.     {
  604.         return $this->imageFid;
  605.     }
  606.     /**
  607.      * @return string|null
  608.      */
  609.     public function getImageMobileMenu(): ?string
  610.     {
  611.         return $this->imageMobileMenu;
  612.     }
  613.     /**
  614.      * @param string|null $imageMobileMenu
  615.      */
  616.     public function setImageMobileMenu(?string $imageMobileMenu): void
  617.     {
  618.         $this->imageMobileMenu $imageMobileMenu;
  619.     }
  620.     /**
  621.      * @return PageBody
  622.      */
  623.     public function getPageBody()
  624.     {
  625.         return $this->pageBody;
  626.     }
  627.     /**
  628.      * @param PageBody $body
  629.      */
  630.     public function setPageBody(PageBody $body)
  631.     {
  632.         $this->pageBody $body;
  633.     }
  634.     /**
  635.      * Тело документа
  636.      * @return string
  637.      */
  638.     public function getBody()
  639.     {
  640.         return $this->pageBody->getBody();
  641.     }
  642.     /**
  643.      * Тело документа
  644.      *
  645.      * @param $pageBody
  646.      */
  647.     public function setBody($pageBody)
  648.     {
  649.         $this->pageBody->setBody($pageBody);
  650.     }
  651.     /**
  652.      * @return ArrayCollection|PageValue[]
  653.      */
  654.     public function getFields()
  655.     {
  656.         return $this->fields;
  657.     }
  658.     /**
  659.      * @param $name
  660.      *
  661.      * @return PageValue|null
  662.      */
  663.     public function getField($name)
  664.     {
  665.         return $this->fields->get($name);
  666.     }
  667.     /**
  668.      * @param array $values
  669.      */
  670.     public function setValues($values)
  671.     {
  672.         $this->values = [];
  673.         foreach ($values as $key => $value) {
  674.             $this->setValue($key$value);
  675.         }
  676.     }
  677.     /**
  678.      * Обновление кэша значений
  679.      */
  680.     public function updateCacheValues()
  681.     {
  682.         $values = [];
  683.         foreach ($this->fields as $field) {
  684.             $values[$field->getField()->getId()] = $field->getValue();
  685.         }
  686.         $this->values $values;
  687.     }
  688.     /**
  689.      * @return array
  690.      */
  691.     public function getValues()
  692.     {
  693.         $this->updateCacheValues();
  694.         return $this->values;
  695.     }
  696.     /**
  697.      * Установка значения
  698.      *
  699.      * @param string $name
  700.      * @param string $value
  701.      * @param bool $strict Если true - будет выдано исключение при попытке сохранить значение для не найденого поля
  702.      *
  703.      * @throws InvalidArgumentException
  704.      */
  705.     public function setValue($name$value$strict false)
  706.     {
  707.         if ($this->getType()->hasField($name)) {
  708.             $field $this->getField($name);
  709.             if (!$field) {
  710.                 if ($strict) {
  711.                     throw new InvalidArgumentException(sprintf('Field %s not found'$name));
  712.                 }
  713.                 $field = new PageValue($this->getType()->getField($name), $this$value);
  714.                 $this->fields->set($name$field);
  715.             } else {
  716.                 $field->setValue($value);
  717.             }
  718.             $this->values[$name] = $value;
  719.         }
  720.     }
  721.     /**
  722.      * Значение (из кэша)
  723.      *
  724.      * @param $name
  725.      * @param null|string $default
  726.      *
  727.      * @return mixed
  728.      */
  729.     public function getValue($name$default null)
  730.     {
  731.         return isset($this->values[$name]) ? $this->values[$name] : $default;
  732.     }
  733.     /**
  734.      * @return ArrayCollection|Relations[]
  735.      */
  736.     public function getChild()
  737.     {
  738.         return $this->child;
  739.     }
  740.     /**
  741.      * @return ArrayCollection|Link[]
  742.      */
  743.     public function getLinkedPages()
  744.     {
  745.         return $this->linkedPages;
  746.     }
  747.     /**
  748.      * @param ArrayCollection|Link[] $linkedPages
  749.      */
  750.     public function setLinkedPages($linkedPages)
  751.     {
  752.         $this->linkedPages $linkedPages;
  753.     }
  754.     /**
  755.      * @param Link $linkedPage
  756.      */
  757.     public function addLinkedPage(Link $linkedPage)
  758.     {
  759.         $this->linkedPages->add($linkedPage);
  760.         $linkedPage->setParent($this);
  761.     }
  762.     /**
  763.      * @param Link $linkedPage
  764.      */
  765.     public function removeLinkedPage(Link $linkedPage)
  766.     {
  767.         $this->linkedPages->removeElement($linkedPage);
  768.     }
  769.     /**
  770.      * @return ArrayCollection|LinkInCart[]
  771.      */
  772.     public function getLinkedPagesInCart()
  773.     {
  774.         return $this->linkedPagesInCart;
  775.     }
  776.     /**
  777.      * @param ArrayCollection|LinkInCart[] $linkedPagesInCart
  778.      */
  779.     public function setLinkedPagesInCart($linkedPagesInCart)
  780.     {
  781.         $this->linkedPagesInCart $linkedPagesInCart;
  782.     }
  783.     /**
  784.      * @param LinkInCart $linkedPageInCart
  785.      */
  786.     public function addLinkedPageInCart(LinkInCart $linkedPageInCart)
  787.     {
  788.         $this->linkedPagesInCart->add($linkedPageInCart);
  789.         $linkedPageInCart->setParent($this);
  790.     }
  791.     /**
  792.      * @param LinkInCart $linkedPageInCart
  793.      */
  794.     public function removeLinkedPageInCart(Link $linkedPageInCart)
  795.     {
  796.         $this->linkedPagesInCart->removeElement($linkedPageInCart);
  797.     }
  798.     /**
  799.      * @return ArrayCollection|AccompanyPage[]
  800.      */
  801.     public function getAccompanyPages()
  802.     {
  803.         return $this->accompanyPages;
  804.     }
  805.     /**
  806.      * @param ArrayCollection|AccompanyPage[] $accompanyPages
  807.      */
  808.     public function setAccompanyPages($accompanyPages): void
  809.     {
  810.         $this->accompanyPages $accompanyPages;
  811.     }
  812.     /**
  813.      * @param AccompanyPage $accompanyPage
  814.      */
  815.     public function addAccompanyPage(AccompanyPage $accompanyPage)
  816.     {
  817.         $this->accompanyPages->add($accompanyPage);
  818.         $accompanyPage->setParent($this);
  819.     }
  820.     /**
  821.      * @param AccompanyPage $accompanyPage
  822.      */
  823.     public function removeAccompanyPage(AccompanyPage $accompanyPage)
  824.     {
  825.         $this->accompanyPages->removeElement($accompanyPage);
  826.     }
  827.     /**
  828.      * @return TitleUrlRelations[]|ArrayCollection
  829.      */
  830.     public function getTitleUrlRelation()
  831.     {
  832.         return $this->titleUrlRelations;
  833.     }
  834.     /**
  835.      * @param TitleUrlRelations[]|ArrayCollection $titleUrlRelations
  836.      */
  837.     public function setTitleUrlRelations($titleUrlRelations): void
  838.     {
  839.         $this->titleUrlRelations $titleUrlRelations;
  840.     }
  841.     /**
  842.      * @param TitleUrlRelations $titleUrlRelation
  843.      */
  844.     public function addTitleUrlRelation(TitleUrlRelations $titleUrlRelation)
  845.     {
  846.         $titleUrlRelation->setPage($this);
  847.         $this->titleUrlRelations->add($titleUrlRelation);
  848.     }
  849.     /**
  850.      * @param TitleUrlRelations $titleUrlRelation
  851.      */
  852.     public function removeTitleUrlRelation(TitleUrlRelations $titleUrlRelation)
  853.     {
  854.         $this->titleUrlRelations->removeElement($titleUrlRelation);
  855.     }
  856.     public function getTitleUrlRelationByTitle(string $title): ?TitleUrlRelations
  857.     {
  858.         foreach ($this->titleUrlRelations as $titleUrlRelation) {
  859.             if ($titleUrlRelation->getTitle() == $title) {
  860.                 return $titleUrlRelation;
  861.             }
  862.         }
  863.         return null;
  864.     }
  865.     public function getLinkedPagesProducts()
  866.     {
  867.         return $this->getLinkedProducts($this->getLinkedPages());
  868.     }
  869.     public function getLinkedPagesInCartProducts()
  870.     {
  871.         return $this->getLinkedProducts($this->getLinkedPagesInCart());
  872.     }
  873.     public function getLinkedProducts($links)
  874.     {
  875.         $linkedProducts = new ArrayCollection();
  876.         /** @var SubmarineEntityInterface $link */
  877.         foreach ($links as $link){
  878.             $linkedProducts->add($link->getPage());
  879.         }
  880.         return $linkedProducts;
  881.     }
  882.     // ---------------- Dates -----------------
  883.     /**
  884.      * @return \DateTime
  885.      */
  886.     public function getPublishedAt()
  887.     {
  888.         return $this->publishedAt;
  889.     }
  890.     /**
  891.      * @param \DateTime $publishedAt
  892.      */
  893.     public function setPublishedAt($publishedAt)
  894.     {
  895.         $this->publishedAt $publishedAt;
  896.     }
  897.     /**
  898.      * @return \DateTime
  899.      */
  900.     public function getCreatedAt()
  901.     {
  902.         return $this->createdAt;
  903.     }
  904.     /**
  905.      * @param \DateTime $createdAt
  906.      */
  907.     public function setCreatedAt($createdAt)
  908.     {
  909.         $this->createdAt $createdAt;
  910.     }
  911.     /**
  912.      * @return \DateTime
  913.      */
  914.     public function getUpdatedAt()
  915.     {
  916.         return $this->updatedAt;
  917.     }
  918.     /**
  919.      * @param \DateTime $updatedAt
  920.      */
  921.     public function setUpdatedAt($updatedAt)
  922.     {
  923.         $this->updatedAt $updatedAt;
  924.     }
  925.     // ---------------- Tags ------------------
  926.     /**
  927.      * @return string
  928.      */
  929.     public function getMetaTitle()
  930.     {
  931.         return $this->metaTitle;
  932.     }
  933.     /**
  934.      * @param string $tagTitle
  935.      */
  936.     public function setMetaTitle($tagTitle)
  937.     {
  938.         $this->metaTitle $tagTitle;
  939.     }
  940.     /**
  941.      * @return string
  942.      */
  943.     public function getMetaDescription()
  944.     {
  945.         return $this->metaDescription;
  946.     }
  947.     /**
  948.      * @param string $tagMetaDescription
  949.      */
  950.     public function setMetaDescription($tagMetaDescription)
  951.     {
  952.         $this->metaDescription $tagMetaDescription;
  953.     }
  954.     /**
  955.      * @return string
  956.      */
  957.     public function getMetaKeywords()
  958.     {
  959.         return $this->metaKeywords;
  960.     }
  961.     /**
  962.      * @param string $tagMetaKeywords
  963.      */
  964.     public function setMetaKeywords($tagMetaKeywords)
  965.     {
  966.         $this->metaKeywords $tagMetaKeywords;
  967.     }
  968.     // -------------------- Comments --------------
  969.     /**
  970.      * Количество коментариев
  971.      * @return integer
  972.      */
  973.     public function getCountComments()
  974.     {
  975.         return $this->countComments;
  976.     }
  977.     /**
  978.      * Установить кол-во комментарием
  979.      *
  980.      * @param $count
  981.      */
  982.     public function setCountComments($count)
  983.     {
  984.         $this->countComments $count;
  985.     }
  986.     /**
  987.      * Разрешено комментировать сущность?
  988.      * @return bool
  989.      */
  990.     public function isAllowedComments()
  991.     {
  992.         return $this->allowedComments;
  993.     }
  994.     /**
  995.      * @param boolean $allowedComments
  996.      */
  997.     public function setAllowedComments($allowedComments)
  998.     {
  999.         $this->allowedComments $allowedComments;
  1000.     }
  1001.     /**
  1002.      * Включена премодерация комментариев к сущности?
  1003.      * @return bool
  1004.      */
  1005.     public function isModeratedComments()
  1006.     {
  1007.         return $this->moderatedComments;
  1008.     }
  1009.     /**
  1010.      * @param boolean $moderatedComments
  1011.      */
  1012.     public function setModeratedComments($moderatedComments)
  1013.     {
  1014.         $this->moderatedComments $moderatedComments;
  1015.     }
  1016.     /**
  1017.      * Имя route для просмотра сущности в администраторской части
  1018.      * Route должен иметь парамер {id}
  1019.      * @return string|null
  1020.      */
  1021.     public function getRouteNameBackend()
  1022.     {
  1023.         return null;
  1024.     }
  1025.     // ---------------- Virtual -------------
  1026.     /**
  1027.      * @param FilesProvider $filesProvider
  1028.      */
  1029.     public function setFilesProvider($filesProvider)
  1030.     {
  1031.         $this->filesProvider $filesProvider;
  1032.     }
  1033.     /**
  1034.      * Фотогалерея
  1035.      * @return \Submarine\FilesBundle\Entity\Image[]
  1036.      */
  1037.     public function getImages()
  1038.     {
  1039.         return $this->filesProvider->getEntityImages($this);
  1040.     }
  1041.     public function getFiles()
  1042.     {
  1043.         return $this->filesProvider->getEntityFiles($this);
  1044.     }
  1045.     /**
  1046.      * @return boolean
  1047.      */
  1048.     public function isSelected()
  1049.     {
  1050.         return $this->selected;
  1051.     }
  1052.     /**
  1053.      * @param boolean $selected
  1054.      */
  1055.     public function setSelected($selected)
  1056.     {
  1057.         $this->selected $selected;
  1058.     }
  1059.     // ------------------ Files ----------------
  1060.     public function getPathPublic()
  1061.     {
  1062.         return 'media/pages/';
  1063.     }
  1064.     /**
  1065.      * Установка файла
  1066.      *
  1067.      * @param File $file
  1068.      */
  1069.     public function setFile(File $file null)
  1070.     {
  1071.         $this->file $file;
  1072.     }
  1073.     /**
  1074.      * Получение файла
  1075.      * @return File
  1076.      */
  1077.     public function getFile()
  1078.     {
  1079.         return $this->file;
  1080.     }
  1081.     /**
  1082.      * Установка файла
  1083.      *
  1084.      * @param File $file
  1085.      */
  1086.     public function setFileFid(File $file null)
  1087.     {
  1088.         $this->fileFid $file;
  1089.     }
  1090.     /**
  1091.      * Получение файла
  1092.      * @return File
  1093.      */
  1094.     public function getFileFid()
  1095.     {
  1096.         return $this->fileFid;
  1097.     }
  1098.     /**
  1099.      * @return File|null
  1100.      */
  1101.     public function getFileMobileMenu(): ?File
  1102.     {
  1103.         return $this->fileMobileMenu;
  1104.     }
  1105.     /**
  1106.      * @param File|null $fileMobileMenu
  1107.      */
  1108.     public function setFileMobileMenu(?File $fileMobileMenu): void
  1109.     {
  1110.         $this->fileMobileMenu $fileMobileMenu;
  1111.     }
  1112.     /**
  1113.      * Путь к файлу
  1114.      *
  1115.      * @param string $filePath
  1116.      */
  1117.     public function setFilePath($filePath)
  1118.     {
  1119.         $this->image $filePath;
  1120.     }
  1121.     /**
  1122.      * Путь к файлу
  1123.      * @return string
  1124.      */
  1125.     public function getFilePath()
  1126.     {
  1127.         return $this->image;
  1128.     }
  1129.     /**
  1130.      * Путь к файлу фида
  1131.      *
  1132.      * @param string $filePath
  1133.      */
  1134.     public function setFilePathFid($filePath)
  1135.     {
  1136.         $this->imageFid $filePath;
  1137.     }
  1138.     /**
  1139.      * Путь к файлу фида
  1140.      * @return string
  1141.      */
  1142.     public function getFilePathFid()
  1143.     {
  1144.         return $this->imageFid;
  1145.     }
  1146.     // -------------------- E-commerce ------------------
  1147.     /**
  1148.      * Стоимость товара
  1149.      * @return float
  1150.      */
  1151.     public function getPrice()
  1152.     {
  1153.         return $this->price;
  1154.     }
  1155.     /**
  1156.      * @param float|string $price
  1157.      */
  1158.     public function setPrice($price)
  1159.     {
  1160.         if (is_string($price)) {
  1161.             $price str_replace([','' '], ['.'''], $price);
  1162.         }
  1163.         $this->price = (float)$price;
  1164.     }
  1165.     /**
  1166.      * @return null|string
  1167.      */
  1168.     public function getMultipleDimensions(): ?string
  1169.     {
  1170.         return $this->multipleDimensions;
  1171.     }
  1172.     /**
  1173.      * @param null|string $multipleDimensions
  1174.      */
  1175.     public function setMultipleDimensions(?string $multipleDimensions): void
  1176.     {
  1177.         $this->multipleDimensions trim($multipleDimensions);
  1178.     }
  1179.     /**
  1180.      * @return array
  1181.      */
  1182.     public function getArrayMultipleDimensions(): array
  1183.     {
  1184.         if(!$this->multipleDimensions){
  1185.             return [];
  1186.         }
  1187.         $parsedValues = [];
  1188.         foreach (explode(';'$this->multipleDimensions) as $item){
  1189.             $parsedValues[] = (float)trim($item);
  1190.         }
  1191.         return $parsedValues;
  1192.     }
  1193.     /**
  1194.      * Наличие товара
  1195.      * @return boolean
  1196.      */
  1197.     public function isAvailable()
  1198.     {
  1199.         return $this->available;
  1200.     }
  1201.     /**
  1202.      * @param boolean $available
  1203.      */
  1204.     public function setAvailable($available)
  1205.     {
  1206.         $this->available $available;
  1207.     }
  1208.     /**
  1209.      * Распространяется скидка на товар?
  1210.      * @return bool
  1211.      */
  1212.     public function isDiscount()
  1213.     {
  1214.         return $this->discount;
  1215.     }
  1216.     /**
  1217.      * @param boolean $discount
  1218.      */
  1219.     public function setDiscount($discount)
  1220.     {
  1221.         $this->discount $discount;
  1222.     }
  1223.     /**
  1224.      * @return null|int
  1225.      */
  1226.     public function getCountProducts(): ?int
  1227.     {
  1228.         return $this->countProducts;
  1229.     }
  1230.     /**
  1231.      * @return bool
  1232.      */
  1233.     public function isHaveProducts(): bool
  1234.     {
  1235.         return $this->countProducts !== 0;
  1236.     }
  1237.     /**
  1238.      * @param int $countProducts
  1239.      */
  1240.     public function setCountProducts(int $countProducts): void
  1241.     {
  1242.         $this->countProducts $countProducts;
  1243.     }
  1244.     /**
  1245.      * Артикул товара
  1246.      * @return string
  1247.      */
  1248.     public function getProductId()
  1249.     {
  1250.         return $this->productId;
  1251.     }
  1252.     /**
  1253.      * @return string
  1254.      */
  1255.     public function getProductStatus(): string
  1256.     {
  1257.         return $this->productStatus;
  1258.     }
  1259.     /**
  1260.      * @param string $productStatus
  1261.      */
  1262.     public function setProductStatus(string $productStatus): void
  1263.     {
  1264.         $this->productStatus $productStatus;
  1265.     }
  1266.     public function inStock()
  1267.     {
  1268.         return $this->productStatus === self::IN_STOCK;
  1269.     }
  1270.     /**
  1271.      * @param string $productId
  1272.      */
  1273.     public function setProductId($productId)
  1274.     {
  1275.         $this->productId $productId;
  1276.     }
  1277.     /**
  1278.      * @return Collection
  1279.      */
  1280.     public function getCronUpdates()
  1281.     {
  1282.         return $this->cronUpdates;
  1283.     }
  1284.     /**
  1285.      * @param Collection $cronUpdates
  1286.      */
  1287.     public function setCronUpdates($cronUpdates): void
  1288.     {
  1289.         $this->cronUpdates $cronUpdates;
  1290.     }
  1291.     /**
  1292.      * @return PageDefected|null
  1293.      */
  1294.     public function getPageDefected(): ?PageDefected
  1295.     {
  1296.         return $this->pageDefected;
  1297.     }
  1298.     /**
  1299.      * @param PageDefected|null $pageDefected
  1300.      */
  1301.     public function setPageDefected(?PageDefected $pageDefected): void
  1302.     {
  1303.         $this->pageDefected $pageDefected;
  1304.     }
  1305.     public function hasActivePageDefected() : bool
  1306.     {
  1307.         return $this->pageDefected && $this->pageDefected->isActive();
  1308.     }
  1309.     /**
  1310.      * @return PageB24UpdateTime|null
  1311.      */
  1312.     public function getPageB24UpdateTime(): ?PageB24UpdateTime
  1313.     {
  1314.         return $this->pageB24UpdateTime;
  1315.     }
  1316.     /**
  1317.      * @param PageB24UpdateTime|null $pageB24UpdateTime
  1318.      */
  1319.     public function setPageB24UpdateTime(?PageB24UpdateTime $pageB24UpdateTime): void
  1320.     {
  1321.         $this->pageB24UpdateTime $pageB24UpdateTime;
  1322.     }
  1323.     /**
  1324.      * @return int|null
  1325.      */
  1326.     public function getB24Id(): ?int
  1327.     {
  1328.         return $this->b24Id;
  1329.     }
  1330.     /**
  1331.      * @param int|null $b24Id
  1332.      */
  1333.     public function setB24Id(?int $b24Id): void
  1334.     {
  1335.         $this->b24Id $b24Id;
  1336.     }
  1337.     /**
  1338.      * @return string
  1339.      */
  1340.     public function getVendorCode(): string
  1341.     {
  1342.         return $this->vendorCode;
  1343.     }
  1344.     /**
  1345.      * @param string $vendorCode
  1346.      */
  1347.     public function setVendorCode(string $vendorCode): void
  1348.     {
  1349.         $this->vendorCode $vendorCode;
  1350.     }
  1351.     public function getPageB24Warehouses(int $WHId null): ArrayCollection|Collection|null
  1352.     {
  1353.         if($WHId){
  1354.             $wh $this->getPageB24Warehouses()->filter(function (PageB24Warehouse $pageB24Warehouse) use ($WHId){
  1355.                 return (int)$pageB24Warehouse->getB24WHId() === $WHId;
  1356.             });
  1357.             return $wh->count() ? $wh null;
  1358.         }
  1359.         return $this->pageB24Warehouses;
  1360.     }
  1361.     public function setPageB24Warehouses(ArrayCollection|Collection $pageB24Warehouses): void
  1362.     {
  1363.         $this->pageB24Warehouses $pageB24Warehouses;
  1364.     }
  1365.     public function getNotEmptyPageB24Warehouses(): ArrayCollection|Collection
  1366.     {
  1367.         $WHsNotEmpty = new ArrayCollection();
  1368.         //to fix issue with double WH
  1369.         /** @var PageB24Warehouse $pageB24Warehouse */
  1370.         foreach ($this->getPageB24Warehouses() as $pageB24Warehouse){
  1371.             if($pageB24Warehouse->getCountInStock() > 0) {
  1372.                 $WHsNotEmpty->set($pageB24Warehouse->getB24WHId(), $pageB24Warehouse);
  1373.             }
  1374.         }
  1375.         return $WHsNotEmpty;
  1376.     }
  1377.     public function getCronUpdateByType(string $type)
  1378.     {
  1379.         /** @var CronUpdate $cronUpdate */
  1380.         foreach ($this->cronUpdates as $cronUpdate){
  1381.             if($cronUpdate->getTypeAction() === $type){
  1382.                 return $cronUpdate;
  1383.             }
  1384.         }
  1385.         return new CronUpdate();
  1386.     }
  1387.     public function getCatalogLevel($level 0)
  1388.     {
  1389.         if(!$this->parents->first()->getParent()){
  1390.             return $level;
  1391.         }
  1392.         return $this->parents->first()->getParent()->getCatalogLevel($level 1);
  1393.     }
  1394.     public function getMainCatalogPage()
  1395.     {
  1396.         $level $this->getCatalogLevel();
  1397.         if($level 2){
  1398.             return $this;
  1399.         }
  1400.         $page $this;
  1401.         foreach (range(2$level) as $index){
  1402.             $page $page->parents->first()->getParent();
  1403.         }
  1404.         return $page;
  1405.     }
  1406. }