src/Entity/Shop.php line 13

Open in your IDE?
  1. <?php
  2. namespace App\Entity;
  3. use App\Repository\ShopRepository;
  4. use DateTimeImmutable;
  5. use Doctrine\Common\Collections\ArrayCollection;
  6. use Doctrine\Common\Collections\Collection;
  7. use Doctrine\DBAL\Types\Types;
  8. use Doctrine\ORM\Mapping as ORM;
  9. #[ORM\Entity(repositoryClassShopRepository::class)]
  10. class Shop
  11. {
  12.     #[ORM\Id]
  13.     #[ORM\GeneratedValue]
  14.     #[ORM\Column]
  15.     private ?int $id null;
  16.     #[ORM\OneToMany(targetEntityNotification::class, mappedBy'shop')]
  17.     private Collection $notifications;
  18.     #[ORM\Column(length100unique:true)]
  19.     private ?string $name null;
  20.     #[ORM\Column(length120unique:true)]
  21.     private ?string $slug null;
  22.     #[ORM\Column(typeTypes::TEXTnullabletrue)]
  23.     private ?string $description null;
  24.     #[ORM\Column(length255nullabletrue)]
  25.     private ?string $logo null;
  26.     #[ORM\ManyToOne(inversedBy'shops')]
  27.     #[ORM\JoinColumn(nullablefalse)]
  28.     private ?ShopCategory $shopCategory null;
  29.     #[ORM\Column(length255nullabletrue)]
  30.     private ?string $address null;
  31.     #[ORM\OneToMany(targetEntityProduct::class, mappedBy'shop')]
  32.     private Collection $products;
  33.     #[ORM\OneToMany(targetEntityShopFollow::class, mappedBy'shop')]
  34.     private Collection $follows;
  35.     #[ORM\OneToMany(targetEntityShopReview::class, mappedBy'shop')]
  36.     private Collection $reviews;
  37.     #[ORM\Column(length50nullabletrue)]
  38.     private ?string $phoneNumber null;
  39.     #[ORM\Column(length255nullabletrue)]
  40.     private ?string $email null;
  41.     #[ORM\Column]
  42.     private ?bool $isActive null;
  43.     #[ORM\Column]
  44.     private ?DateTimeImmutable $createdAt null;
  45.     #[ORM\Column(nullabletrue)]
  46.     private ?DateTimeImmutable $updatedAt null;
  47.     #[ORM\ManyToMany(targetEntityUser::class, inversedBy'shops')]
  48.     private Collection $manager;
  49.     #[ORM\Column]
  50.     private ?int $currentProducts null;
  51.     #[ORM\Column]
  52.     private ?int $currentEmployees null;
  53.     #[ORM\Column]
  54.     private ?int $currentOrders null;
  55.     #[ORM\Column(typeTypes::DECIMALprecision15scale3)]
  56.     private ?string $currentRevenue null;
  57.     #[ORM\Column]
  58.     private ?int $currentStorage null;
  59.     #[ORM\ManyToOne(inversedBy'shops')]
  60.     private ?ShopPlan $plan null;
  61.     #[ORM\Column]
  62.     private ?int $currentCaLimit null;
  63.     #[ORM\Column(length255nullabletrue)]
  64.     private ?string $siretNif null;
  65.     #[ORM\Column(length255nullabletrue)]
  66.     private ?string $iban null;
  67.     // Nouveaux champs pour améliorer la boutique
  68.     #[ORM\Column(length255nullabletrue)]
  69.     private ?string $website null;
  70.     #[ORM\Column(length255nullabletrue)]
  71.     private ?string $facebook null;
  72.     #[ORM\Column(length255nullabletrue)]
  73.     private ?string $instagram null;
  74.     #[ORM\Column(length255nullabletrue)]
  75.     private ?string $twitter null;
  76.     #[ORM\Column(length255nullabletrue)]
  77.     private ?string $youtube null;
  78.     #[ORM\Column(length255nullabletrue)]
  79.     private ?string $tiktok null;
  80.     #[ORM\Column(length255nullabletrue)]
  81.     private ?string $whatsapp null;
  82.     #[ORM\Column(length255nullabletrue)]
  83.     private ?string $telegram null;
  84.     #[ORM\Column(typeTypes::JSONnullabletrue)]
  85.     private ?array $bannerImages null;
  86.     #[ORM\Column]
  87.     private ?int $viewCount 0;
  88.     #[ORM\Column]
  89.     private ?int $followerCount 0;
  90.     #[ORM\Column]
  91.     private ?float $averageRating 0.0;
  92.     #[ORM\Column]
  93.     private ?int $reviewCount 0;
  94.     #[ORM\Column(length50nullabletrue)]
  95.     private ?string $status 'pending'// pending, active, suspended, closed
  96.     #[ORM\Column(length255nullabletrue)]
  97.     private ?string $verificationStatus 'unverified'// unverified, pending, verified, rejected
  98.     #[ORM\Column(nullabletrue)]
  99.     private ?DateTimeImmutable $verifiedAt null;
  100.     #[ORM\Column(length255nullabletrue)]
  101.     private ?string $businessHours null;
  102.     #[ORM\Column(length255nullabletrue)]
  103.     private ?string $deliveryAreas null;
  104.     #[ORM\Column(length255nullabletrue)]
  105.     private ?string $paymentMethods null;
  106.     #[ORM\Column(typeTypes::TEXTnullabletrue)]
  107.     private ?string $returnPolicy null;
  108.     #[ORM\Column(typeTypes::TEXTnullabletrue)]
  109.     private ?string $shippingPolicy null;
  110.     #[ORM\Column(typeTypes::TEXTnullabletrue)]
  111.     private ?string $privacyPolicy null;
  112.     #[ORM\Column]
  113.     private ?bool $isVerified false;
  114.     #[ORM\Column]
  115.     private ?bool $isPremium false;
  116.     #[ORM\Column]
  117.     private ?bool $allowReviews true;
  118.     #[ORM\Column]
  119.     private ?bool $allowMessages true;
  120.     #[ORM\Column]
  121.     private ?bool $showContactInfo true;
  122.     #[ORM\Column]
  123.     private ?bool $showSocialLinks true;
  124.     public function __construct()
  125.     {
  126.         $this->notifications = new ArrayCollection();
  127.         $this->products = new ArrayCollection();
  128.         $this->follows = new ArrayCollection();
  129.         $this->reviews = new ArrayCollection();
  130.         $this->manager = new ArrayCollection();
  131.         $this->createdAt = new DateTimeImmutable();
  132.         $this->isActive true;
  133.         $this->currentProducts 0;
  134.         $this->currentEmployees 0;
  135.         $this->currentOrders 0;
  136.         $this->currentRevenue '0.000';
  137.         $this->currentStorage 0;
  138.         $this->currentCaLimit 0;
  139.         $this->viewCount 0;
  140.         $this->followerCount 0;
  141.         $this->averageRating 0.0;
  142.         $this->reviewCount 0;
  143.         $this->isVerified false;
  144.         $this->isPremium false;
  145.         $this->allowReviews true;
  146.         $this->allowMessages true;
  147.         $this->showContactInfo true;
  148.         $this->showSocialLinks true;
  149.     }
  150.     public function getId(): ?int
  151.     {
  152.         return $this->id;
  153.     }
  154.     /**
  155.      * @return Collection<int, Notification>
  156.      */
  157.     public function getNotifications(): Collection
  158.     {
  159.         return $this->notifications;
  160.     }
  161.     public function addNotification(Notification $notification): static
  162.     {
  163.         if (!$this->notifications->contains($notification)) {
  164.             $this->notifications->add($notification);
  165.             $notification->setShop($this);
  166.         }
  167.         return $this;
  168.     }
  169.     public function removeNotification(Notification $notification): static
  170.     {
  171.         if ($this->notifications->removeElement($notification)) {
  172.             // set the owning side to null (unless already changed)
  173.             if ($notification->getShop() === $this) {
  174.                 $notification->setShop(null);
  175.             }
  176.         }
  177.         return $this;
  178.     }
  179.     public function getName(): ?string
  180.     {
  181.         return $this->name;
  182.     }
  183.     public function setName(string $name): static
  184.     {
  185.         $this->name $name;
  186.         return $this;
  187.     }
  188.     public function getSlug(): ?string
  189.     {
  190.         return $this->slug;
  191.     }
  192.     public function setSlug(string $slug): static
  193.     {
  194.         $this->slug $slug;
  195.         return $this;
  196.     }
  197.     public function getDescription(): ?string
  198.     {
  199.         return $this->description;
  200.     }
  201.     public function setDescription(?string $description): static
  202.     {
  203.         $this->description $description;
  204.         return $this;
  205.     }
  206.     public function getLogo(): ?string
  207.     {
  208.         return $this->logo;
  209.     }
  210.     public function setLogo(?string $logo): static
  211.     {
  212.         $this->logo $logo;
  213.         return $this;
  214.     }
  215.     public function getShopCategory(): ?ShopCategory
  216.     {
  217.         return $this->shopCategory;
  218.     }
  219.     public function setShopCategory(?ShopCategory $shopCategory): static
  220.     {
  221.         $this->shopCategory $shopCategory;
  222.         return $this;
  223.     }
  224.     public function getAddress(): ?string
  225.     {
  226.         return $this->address;
  227.     }
  228.     public function setAddress(?string $address): static
  229.     {
  230.         $this->address $address;
  231.         return $this;
  232.     }
  233.     /**
  234.      * @return Collection<int, Product>
  235.      */
  236.     public function getProducts(): Collection
  237.     {
  238.         return $this->products;
  239.     }
  240.     public function addProduct(Product $product): static
  241.     {
  242.         if (!$this->products->contains($product)) {
  243.             $this->products->add($product);
  244.             $product->setShop($this);
  245.         }
  246.         return $this;
  247.     }
  248.     public function removeProduct(Product $product): static
  249.     {
  250.         if ($this->products->removeElement($product)) {
  251.             // set the owning side to null (unless already changed)
  252.             if ($product->getShop() === $this) {
  253.                 $product->setShop(null);
  254.             }
  255.         }
  256.         return $this;
  257.     }
  258.     public function getPhoneNumber(): ?string
  259.     {
  260.         return $this->phoneNumber;
  261.     }
  262.     public function setPhoneNumber(?string $phoneNumber): static
  263.     {
  264.         $this->phoneNumber $phoneNumber;
  265.         return $this;
  266.     }
  267.     public function getEmail(): ?string
  268.     {
  269.         return $this->email;
  270.     }
  271.     public function setEmail(?string $email): static
  272.     {
  273.         $this->email $email;
  274.         return $this;
  275.     }
  276.     public function isIsActive(): ?bool
  277.     {
  278.         return $this->isActive;
  279.     }
  280.     public function setIsActive(bool $isActive): static
  281.     {
  282.         $this->isActive $isActive;
  283.         return $this;
  284.     }
  285.     public function getCreatedAt(): ?DateTimeImmutable
  286.     {
  287.         return $this->createdAt;
  288.     }
  289.     public function setCreatedAt(DateTimeImmutable $createdAt): static
  290.     {
  291.         $this->createdAt $createdAt;
  292.         return $this;
  293.     }
  294.     public function getUpdatedAt(): ?DateTimeImmutable
  295.     {
  296.         return $this->updatedAt;
  297.     }
  298.     public function setUpdatedAt(?DateTimeImmutable $updatedAt): static
  299.     {
  300.         $this->updatedAt $updatedAt;
  301.         return $this;
  302.     }
  303.     /**
  304.      * @return Collection<int, User>
  305.      */
  306.     public function getManager(): Collection
  307.     {
  308.         return $this->manager;
  309.     }
  310.     public function addManager(User $manager): static
  311.     {
  312.         if (!$this->manager->contains($manager)) {
  313.             $this->manager->add($manager);
  314.         }
  315.         return $this;
  316.     }
  317.     public function removeManager(User $manager): static
  318.     {
  319.         $this->manager->removeElement($manager);
  320.         return $this;
  321.     }
  322.     public function getCurrentProducts(): ?int
  323.     {
  324.         return $this->currentProducts;
  325.     }
  326.     public function setCurrentProducts(int $currentProducts): static
  327.     {
  328.         $this->currentProducts $currentProducts;
  329.         return $this;
  330.     }
  331.     public function getCurrentEmployees(): ?int
  332.     {
  333.         return $this->currentEmployees;
  334.     }
  335.     public function setCurrentEmployees(int $currentEmployees): static
  336.     {
  337.         $this->currentEmployees $currentEmployees;
  338.         return $this;
  339.     }
  340.     public function getCurrentOrders(): ?int
  341.     {
  342.         return $this->currentOrders;
  343.     }
  344.     public function setCurrentOrders(int $currentOrders): static
  345.     {
  346.         $this->currentOrders $currentOrders;
  347.         return $this;
  348.     }
  349.     public function getCurrentRevenue(): ?string
  350.     {
  351.         return $this->currentRevenue;
  352.     }
  353.     public function setCurrentRevenue(string $currentRevenue): static
  354.     {
  355.         $this->currentRevenue $currentRevenue;
  356.         return $this;
  357.     }
  358.     public function getCurrentStorage(): ?int
  359.     {
  360.         return $this->currentStorage;
  361.     }
  362.     public function setCurrentStorage(int $currentStorage): static
  363.     {
  364.         $this->currentStorage $currentStorage;
  365.         return $this;
  366.     }
  367.     public function getPlan(): ?ShopPlan
  368.     {
  369.         return $this->plan;
  370.     }
  371.     public function setPlan(?ShopPlan $plan): static
  372.     {
  373.         $this->plan $plan;
  374.         return $this;
  375.     }
  376.     public function getCurrentCaLimit(): ?int
  377.     {
  378.         return $this->currentCaLimit;
  379.     }
  380.     public function setCurrentCaLimit(int $currentCaLimit): static
  381.     {
  382.         $this->currentCaLimit $currentCaLimit;
  383.         return $this;
  384.     }
  385.     public function getSiretNif(): ?string
  386.     {
  387.         return $this->siretNif;
  388.     }
  389.     public function setSiretNif(?string $siretNif): static
  390.     {
  391.         $this->siretNif $siretNif;
  392.         return $this;
  393.     }
  394.     public function getIban(): ?string
  395.     {
  396.         return $this->iban;
  397.     }
  398.     public function setIban(?string $iban): static
  399.     {
  400.         $this->iban $iban;
  401.         return $this;
  402.     }
  403.     // Getters et setters pour les nouveaux champs
  404.     public function getWebsite(): ?string
  405.     {
  406.         return $this->website;
  407.     }
  408.     public function setWebsite(?string $website): static
  409.     {
  410.         $this->website $website;
  411.         return $this;
  412.     }
  413.     public function getFacebook(): ?string
  414.     {
  415.         return $this->facebook;
  416.     }
  417.     public function setFacebook(?string $facebook): static
  418.     {
  419.         $this->facebook $facebook;
  420.         return $this;
  421.     }
  422.     public function getInstagram(): ?string
  423.     {
  424.         return $this->instagram;
  425.     }
  426.     public function setInstagram(?string $instagram): static
  427.     {
  428.         $this->instagram $instagram;
  429.         return $this;
  430.     }
  431.     public function getTwitter(): ?string
  432.     {
  433.         return $this->twitter;
  434.     }
  435.     public function setTwitter(?string $twitter): static
  436.     {
  437.         $this->twitter $twitter;
  438.         return $this;
  439.     }
  440.     public function getYoutube(): ?string
  441.     {
  442.         return $this->youtube;
  443.     }
  444.     public function setYoutube(?string $youtube): static
  445.     {
  446.         $this->youtube $youtube;
  447.         return $this;
  448.     }
  449.     public function getTiktok(): ?string
  450.     {
  451.         return $this->tiktok;
  452.     }
  453.     public function setTiktok(?string $tiktok): static
  454.     {
  455.         $this->tiktok $tiktok;
  456.         return $this;
  457.     }
  458.     public function getWhatsapp(): ?string
  459.     {
  460.         return $this->whatsapp;
  461.     }
  462.     public function setWhatsapp(?string $whatsapp): static
  463.     {
  464.         $this->whatsapp $whatsapp;
  465.         return $this;
  466.     }
  467.     public function getTelegram(): ?string
  468.     {
  469.         return $this->telegram;
  470.     }
  471.     public function setTelegram(?string $telegram): static
  472.     {
  473.         $this->telegram $telegram;
  474.         return $this;
  475.     }
  476.     public function getBannerImages(): ?array
  477.     {
  478.         return $this->bannerImages;
  479.     }
  480.     public function setBannerImages(?array $bannerImages): static
  481.     {
  482.         $this->bannerImages $bannerImages;
  483.         return $this;
  484.     }
  485.     public function addBannerImage(string $imagePath): static
  486.     {
  487.         if ($this->bannerImages === null) {
  488.             $this->bannerImages = [];
  489.         }
  490.         
  491.         if (!in_array($imagePath$this->bannerImages)) {
  492.             $this->bannerImages[] = $imagePath;
  493.         }
  494.         
  495.         return $this;
  496.     }
  497.     public function removeBannerImage(string $imagePath): static
  498.     {
  499.         if ($this->bannerImages !== null) {
  500.             $this->bannerImages array_values(array_filter($this->bannerImages, function($img) use ($imagePath) {
  501.                 return $img !== $imagePath;
  502.             }));
  503.         }
  504.         
  505.         return $this;
  506.     }
  507.     public function getAllBannerImages(): array
  508.     {
  509.         return $this->bannerImages ?? [];
  510.     }
  511.     public function getFirstBannerImage(): ?string
  512.     {
  513.         return !empty($this->bannerImages) ? $this->bannerImages[0] : null;
  514.     }
  515.     public function getViewCount(): ?int
  516.     {
  517.         return $this->viewCount;
  518.     }
  519.     public function setViewCount(int $viewCount): static
  520.     {
  521.         $this->viewCount $viewCount;
  522.         return $this;
  523.     }
  524.     public function incrementViewCount(): static
  525.     {
  526.         $this->viewCount = ($this->viewCount ?? 0) + 1;
  527.         return $this;
  528.     }
  529.     public function getFollowerCount(): ?int
  530.     {
  531.         return $this->followerCount;
  532.     }
  533.     public function setFollowerCount(int $followerCount): static
  534.     {
  535.         $this->followerCount $followerCount;
  536.         return $this;
  537.     }
  538.     public function setAverageRating(float $averageRating): static
  539.     {
  540.         $this->averageRating $averageRating;
  541.         return $this;
  542.     }
  543.     public function getReviewCount(): ?int
  544.     {
  545.         return $this->reviewCount;
  546.     }
  547.     public function setReviewCount(int $reviewCount): static
  548.     {
  549.         $this->reviewCount $reviewCount;
  550.         return $this;
  551.     }
  552.     public function getStatus(): ?string
  553.     {
  554.         return $this->status;
  555.     }
  556.     public function setStatus(string $status): static
  557.     {
  558.         $this->status $status;
  559.         return $this;
  560.     }
  561.     public function getVerificationStatus(): ?string
  562.     {
  563.         return $this->verificationStatus;
  564.     }
  565.     public function setVerificationStatus(string $verificationStatus): static
  566.     {
  567.         $this->verificationStatus $verificationStatus;
  568.         return $this;
  569.     }
  570.     public function getVerifiedAt(): ?DateTimeImmutable
  571.     {
  572.         return $this->verifiedAt;
  573.     }
  574.     public function setVerifiedAt(?DateTimeImmutable $verifiedAt): static
  575.     {
  576.         $this->verifiedAt $verifiedAt;
  577.         return $this;
  578.     }
  579.     public function getBusinessHours(): ?string
  580.     {
  581.         return $this->businessHours;
  582.     }
  583.     public function setBusinessHours(?string $businessHours): static
  584.     {
  585.         $this->businessHours $businessHours;
  586.         return $this;
  587.     }
  588.     public function getDeliveryAreas(): ?string
  589.     {
  590.         return $this->deliveryAreas;
  591.     }
  592.     public function setDeliveryAreas(?string $deliveryAreas): static
  593.     {
  594.         $this->deliveryAreas $deliveryAreas;
  595.         return $this;
  596.     }
  597.     public function getPaymentMethods(): ?string
  598.     {
  599.         return $this->paymentMethods;
  600.     }
  601.     public function setPaymentMethods(?string $paymentMethods): static
  602.     {
  603.         $this->paymentMethods $paymentMethods;
  604.         return $this;
  605.     }
  606.     public function getReturnPolicy(): ?string
  607.     {
  608.         return $this->returnPolicy;
  609.     }
  610.     public function setReturnPolicy(?string $returnPolicy): static
  611.     {
  612.         $this->returnPolicy $returnPolicy;
  613.         return $this;
  614.     }
  615.     public function getShippingPolicy(): ?string
  616.     {
  617.         return $this->shippingPolicy;
  618.     }
  619.     public function setShippingPolicy(?string $shippingPolicy): static
  620.     {
  621.         $this->shippingPolicy $shippingPolicy;
  622.         return $this;
  623.     }
  624.     public function getPrivacyPolicy(): ?string
  625.     {
  626.         return $this->privacyPolicy;
  627.     }
  628.     public function setPrivacyPolicy(?string $privacyPolicy): static
  629.     {
  630.         $this->privacyPolicy $privacyPolicy;
  631.         return $this;
  632.     }
  633.     public function isIsVerified(): ?bool
  634.     {
  635.         return $this->isVerified;
  636.     }
  637.     public function setIsVerified(bool $isVerified): static
  638.     {
  639.         $this->isVerified $isVerified;
  640.         return $this;
  641.     }
  642.     public function isIsPremium(): ?bool
  643.     {
  644.         return $this->isPremium;
  645.     }
  646.     public function setIsPremium(bool $isPremium): static
  647.     {
  648.         $this->isPremium $isPremium;
  649.         return $this;
  650.     }
  651.     public function isAllowReviews(): ?bool
  652.     {
  653.         return $this->allowReviews;
  654.     }
  655.     public function setAllowReviews(bool $allowReviews): static
  656.     {
  657.         $this->allowReviews $allowReviews;
  658.         return $this;
  659.     }
  660.     public function isAllowMessages(): ?bool
  661.     {
  662.         return $this->allowMessages;
  663.     }
  664.     public function setAllowMessages(bool $allowMessages): static
  665.     {
  666.         $this->allowMessages $allowMessages;
  667.         return $this;
  668.     }
  669.     public function isShowContactInfo(): ?bool
  670.     {
  671.         return $this->showContactInfo;
  672.     }
  673.     public function setShowContactInfo(bool $showContactInfo): static
  674.     {
  675.         $this->showContactInfo $showContactInfo;
  676.         return $this;
  677.     }
  678.     public function isShowSocialLinks(): ?bool
  679.     {
  680.         return $this->showSocialLinks;
  681.     }
  682.     public function setShowSocialLinks(bool $showSocialLinks): static
  683.     {
  684.         $this->showSocialLinks $showSocialLinks;
  685.         return $this;
  686.     }
  687.     // Méthodes utilitaires
  688.     public function getSocialLinks(): array
  689.     {
  690.         $links = [];
  691.         if ($this->website$links['website'] = $this->website;
  692.         if ($this->facebook$links['facebook'] = $this->facebook;
  693.         if ($this->instagram$links['instagram'] = $this->instagram;
  694.         if ($this->twitter$links['twitter'] = $this->twitter;
  695.         if ($this->youtube$links['youtube'] = $this->youtube;
  696.         if ($this->tiktok$links['tiktok'] = $this->tiktok;
  697.         if ($this->whatsapp$links['whatsapp'] = $this->whatsapp;
  698.         if ($this->telegram$links['telegram'] = $this->telegram;
  699.         return $links;
  700.     }
  701.     public function getActiveProductsCount(): int
  702.     {
  703.         return $this->products->filter(fn($product) => $product->isIsActive())->count();
  704.     }
  705.     public function getTotalRevenue(): float
  706.     {
  707.         return (float) $this->currentRevenue;
  708.     }
  709.     public function getFormattedRevenue(): string
  710.     {
  711.         return number_format($this->getTotalRevenue(), 2'.'' ') . ' HTG';
  712.     }
  713.     public function isActive(): bool
  714.     {
  715.         return $this->isActive && $this->status === 'active';
  716.     }
  717.     public function isVerified(): bool
  718.     {
  719.         return $this->isVerified && $this->verificationStatus === 'verified';
  720.     }
  721.     public function canReceiveOrders(): bool
  722.     {
  723.         return $this->isActive() && $this->getActiveProductsCount() > 0;
  724.     }
  725.     /**
  726.      * @return Collection<int, ShopFollow>
  727.      */
  728.     public function getFollows(): Collection
  729.     {
  730.         return $this->follows;
  731.     }
  732.     public function addFollow(ShopFollow $follow): static
  733.     {
  734.         if (!$this->follows->contains($follow)) {
  735.             $this->follows->add($follow);
  736.             $follow->setShop($this);
  737.         }
  738.         return $this;
  739.     }
  740.     public function removeFollow(ShopFollow $follow): static
  741.     {
  742.         if ($this->follows->removeElement($follow)) {
  743.             // set the owning side to null (unless already changed)
  744.             if ($follow->getShop() === $this) {
  745.                 $follow->setShop(null);
  746.             }
  747.         }
  748.         return $this;
  749.     }
  750.     /**
  751.      * Compte le nombre de followers actifs
  752.      */
  753.     public function getActiveFollowersCount(): int
  754.     {
  755.         return $this->follows->filter(function(ShopFollow $follow) {
  756.             return $follow->isActive();
  757.         })->count();
  758.     }
  759.     /**
  760.      * Vérifie si un utilisateur suit cette boutique
  761.      */
  762.     public function isFollowedBy(User $user): bool
  763.     {
  764.         return $this->follows->exists(function($keyShopFollow $follow) use ($user) {
  765.             return $follow->getUser() === $user && $follow->isActive();
  766.         });
  767.     }
  768.     /**
  769.      * Récupère le follow d'un utilisateur pour cette boutique
  770.      */
  771.     public function getFollowByUser(User $user): ?ShopFollow
  772.     {
  773.         foreach ($this->follows as $follow) {
  774.             if ($follow->getUser() === $user && $follow->isActive()) {
  775.                 return $follow;
  776.             }
  777.         }
  778.         return null;
  779.     }
  780.     /**
  781.      * @return Collection<int, ShopReview>
  782.      */
  783.     public function getReviews(): Collection
  784.     {
  785.         return $this->reviews;
  786.     }
  787.     public function addReview(ShopReview $review): static
  788.     {
  789.         if (!$this->reviews->contains($review)) {
  790.             $this->reviews->add($review);
  791.             $review->setShop($this);
  792.         }
  793.         return $this;
  794.     }
  795.     public function removeReview(ShopReview $review): static
  796.     {
  797.         if ($this->reviews->removeElement($review)) {
  798.             // set the owning side to null (unless already changed)
  799.             if ($review->getShop() === $this) {
  800.                 $review->setShop(null);
  801.             }
  802.         }
  803.         return $this;
  804.     }
  805.     /**
  806.      * Obtenir la note moyenne des avis
  807.      */
  808.     public function getAverageRating(): float
  809.     {
  810.         $totalRating 0;
  811.         $reviewCount 0;
  812.         foreach ($this->reviews as $review) {
  813.             if ($review->isVisible()) {
  814.                 $totalRating += $review->getRating();
  815.                 $reviewCount++;
  816.             }
  817.         }
  818.         return $reviewCount round($totalRating $reviewCount1) : 0;
  819.     }
  820.     /**
  821.      * Obtenir le nombre d'avis visibles
  822.      */
  823.     public function getVisibleReviewsCount(): int
  824.     {
  825.         $count 0;
  826.         foreach ($this->reviews as $review) {
  827.             if ($review->isVisible()) {
  828.                 $count++;
  829.             }
  830.         }
  831.         return $count;
  832.     }
  833.     public function __toString(): string
  834.     {
  835.         return $this->name ?? 'Boutique sans nom';
  836.     }
  837. }