<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="App\Repository\ProductRepository")
*/
class Product implements \Serializable
{
const PRODUCT_TYPE_DIRECTORY = 1;
const PRODUCT_TYPE_CLASSIFIED = 2;
const PRODUCT_TYPE_MEMBERSHIP = 3;
const PRODUCT_TYPE_SHOP = 4;
const RENEW_YEARLY = "annual";
const RENEW_MONTHLY = "month";
const RENEW_BIMONTHLY = "bimonthly";
const RENEW_TRIMONTHLY = "trimonthly";
const RENEW_NOT_SET = "none";
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="bigint")
*/
private $id;
/**
* @ORM\Version @ORM\Column(type="integer")
*/
private $version;
/**
* @ORM\Column(type="string", length=255)
*/
private $title;
/**
* @ORM\Column(type="text")
*/
private $description;
/**
* @ORM\Column(type="string", length=255)
*/
private $slug;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Media", cascade={"persist"})
* @ORM\JoinColumn(nullable=true)
*/
private $media;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Media", cascade={"persist"})
* @ORM\JoinColumn(nullable=true)
*/
private $dummy_media; //same as in the content admin
/**
* @ O R M\Column(type="decimal", precision=10, scale=2)
* @ORM\Column(type="integer")
*
* Store as pennies
*/
private $price;
/**
* @ORM\Column(type="string", length=32)
*
* YEARLY, MONTHLY, ETC ...
*
*/
private $payment_rate;
/**
* @ORM\Column(type="integer")
*/
private $type;
/**
* @ORM\Column(type="integer")
*/
private $status;
/**
* @ORM\Column(type="datetime")
*/
private $published;
/**
* @ORM\Column(type="datetime")
*/
private $modified_at;
/**
* @ORM\Column(type="datetime")
*/
private $created_at;
/**
* @ORM\OneToMany(targetEntity="App\Entity\PurchaseItem", mappedBy="product")
*/
private $purchase_items;
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Coupon", mappedBy="products")
*/
private $coupons;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Category", inversedBy="products")
*/
private $category;
/**
* The secondary categories should contain ALL the categories assigned to the product object.
* @ORM\ManyToMany(targetEntity="App\Entity\Category", inversedBy="secondary_products")
*/
private $secondary_categories;
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Customer", mappedBy="products", cascade={"persist"})
*/
private $customers;
/**
* @ORM\OneToMany(targetEntity="App\Entity\ProductOption", mappedBy="product", orphanRemoval=true, cascade={"persist", "remove"}, fetch="EAGER")
*/
private $productOptions;
public function __construct()
{
$this->price = 0;
$this->payment_rate = "";
$this->description = "";
$this->purchase_items = new ArrayCollection();
$this->coupons = new ArrayCollection();
$this->published = new \DateTime();
$this->modified_at = new \DateTime();
$this->created_at = new \DateTime ();
$this->customers = new ArrayCollection();
$this->secondary_categories = new ArrayCollection();
$this->productOptions = new ArrayCollection();
}
public function getId()
{
return $this->id;
}
public function getVersion() {
return $this->version;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title = null): self
{
$this->title = $title ? $title : "";
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(string $description = null): self
{
$this->description = $description ? $description : "";
return $this;
}
public function getIntroText($words = 50): ?string
{
$description = strip_tags($this->description);
$description = trim($description);
$description = explode(" ", $description);
if ($words < count($description)) {
$description = array_slice($description, 0, $words);
$description[] = "...";
}
$description = implode(" ", $description);
$description = htmlspecialchars_decode($description, ENT_QUOTES);
$description = html_entity_decode($description);
return $description;
}
public function getSlug(): ?string
{
return $this->slug;
}
public function setSlug(string $slug = null): self
{
$this->slug = $slug ? $slug : "";
return $this;
}
public function getFeaturedImageURL ()
{
if($this->media) {
return $this->media->getURL();
}
return "";
}
public function getFeaturedImageTag ($class = "", $style = "")
{
if($this->media) {
return $this->media->getImageTag($class, $style);
}
return "";
}
public function getMedia (): ?Media
{
return $this->media;
}
public function setMedia (Media $media = null): self
{
$this->media = $media;
return $this;
}
public function getDummyMedia (): ?Media
{
return $this->dummy_media;
}
public function setDummyMedia (Media $dummy_media = null): self
{
$this->dummy_media = $dummy_media;
return $this;
}
public function getPrice()
{
return $this->price;
}
public function getPriceUsd ()
{
return "$" . number_format(($this->price / 100), 2);
}
public function setPrice($price = null): self
{
/*
if (strpos($price, ".") == false) {
$price = preg_replace("/[^0-9]/", "", $price);
$price .= "00"; // add pennies
} else {
$price = preg_replace("/[^0-9]/", "", $price);
}
*/
$price = (int) $price;
$this->price = $price ? $price : 0;
return $this;
}
public function getPaymentRate(): ?string
{
return $this->payment_rate;
}
public function setPaymentRate(string $payment_rate): self
{
$this->payment_rate = $payment_rate;
return $this;
}
public function getPaymentRateNice(): ?string
{
switch($this->payment_rate) {
case SELF::RENEW_YEARLY:
return "Annually";
case SELF::RENEW_MONTHLY:
return "Monthly";
case SELF::RENEW_BIMONTHLY:
return "Bimonthly";
case SELF::RENEW_TRIMONTHLY:
return "Trimonthly";
default:
return "One Time";
}
}
public function getType(): ?int
{
return $this->type;
}
public function setType(int $type): self
{
$this->type = $type;
return $this;
}
public function getTypeString(): ?string
{
switch ($this->type) {
case self::PRODUCT_TYPE_DIRECTORY:
return "Directory Listing";
case self::PRODUCT_TYPE_CLASSIFIED:
return "Classified Listing";
case self::PRODUCT_TYPE_MEMBERSHIP:
return "R-Club Membership";
case self::PRODUCT_TYPE_SHOP:
return "RCS Shop Item";
}
return "Product";
}
public function getStatus(): ?int
{
return $this->status;
}
public function setStatus(int $status): self
{
$this->status = $status;
return $this;
}
public function getPublished(): ?\DateTimeInterface
{
return $this->published;
}
public function setPublished(\DateTimeInterface $published): self
{
$this->published = $published;
return $this;
}
public function getModifiedAt(): ?\DateTimeInterface
{
return $this->modified_at;
}
public function setModifiedAt(\DateTimeInterface $modified_at): self
{
$this->modified_at = $modified_at;
return $this;
}
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->created_at;
}
public function setCreatedAt(\DateTimeInterface $created_at): self
{
$this->created_at = $created_at;
return $this;
}
/**
* @return Collection|Order[]
*/
public function getpurchase_items(): Collection
{
return $this->purchase_items;
}
public function addPurchase(Purchase $order): self
{
if (!$this->purchase_items->contains($order)) {
$this->purchase_items[] = $order;
$order->setProduct($this);
}
return $this;
}
public function removePurchase(Purchase $order): self
{
if ($this->purchase_items->contains($order)) {
$this->purchase_items->removeElement($order);
// set the owning side to null (unless already changed)
if ($order->getProduct() === $this) {
$order->setProduct(null);
}
}
return $this;
}
public function getFullPrice ()
{
return "$" . number_format(($this->price / 100), 2);
}
public function __toString ()
{
return $this->title ? $this->title : "";
}
/**
* @return Collection|Coupon[]
*/
public function getCoupons(): Collection
{
return $this->coupons;
}
public function addCoupon(Coupon $coupon): self
{
if (!$this->coupons->contains($coupon)) {
$this->coupons[] = $coupon;
$coupon->addProduct($this);
}
return $this;
}
public function removeCoupon(Coupon $coupon): self
{
if ($this->coupons->contains($coupon)) {
$this->coupons->removeElement($coupon);
$coupon->removeProduct($this);
}
return $this;
}
public function getCategory(): ?Category
{
return $this->category;
}
public function setCategory(?Category $category): self
{
//remove the previous primary category from the list of all categories
//(is there a better way to do this?
if($this->category) {
$this->removeSecondaryCategory($this->category);
}
// also make sure category is set in the secondary categories too.
if($category) {
$this->addSecondaryCategory($category);
}
$this->category = $category;
return $this;
}
/**
* @return Collection|Category[]
*/
public function getSecondaryCategories(): Collection
{
return $this->secondary_categories;
}
public function addSecondaryCategory(Category $secondaryCategory): self
{
if (!$this->secondary_categories->contains($secondaryCategory)) {
$this->secondary_categories[] = $secondaryCategory;
$secondaryCategory->addSecondaryProduct($this);
}
return $this;
}
public function resetSecondaryCategories(): self
{
$this->secondary_categories = new ArrayCollection();
// retain the primary category if it exists
if ($this->category) {
$this->addSecondaryCategory($this->category);
}
return $this;
}
public function removeSecondaryCategory(Category $secondaryCategory): self
{
if ($this->secondary_categories->contains($secondaryCategory)) {
$this->secondary_categories->removeElement($secondaryCategory);
$secondaryCategory->removeSecondaryProduct($this);
}
return $this;
}
/**
* @return Collection|Customer[]
*/
public function getCustomers(): Collection
{
return $this->customers;
}
//don't think Sonata is using this
public function addCustomers($customers): self
{
if(is_array($customers)) {
foreach($customers as $customer) {
$this->addCustomer($customer);
}
}
else {
$this->customers->clear();
$this->addCustomer($customers);
}
return $this;
}
public function addCustomer(Customer $customer): self
{
if (!$this->customers->contains($customer)) {
$this->customers[] = $customer;
$customer->addProduct($this);
}
return $this;
}
public function removeCustomer(Customer $customer): self
{
if ($this->customers->contains($customer)) {
$this->customers->removeElement($customer);
$customer->removeProduct($this);
}
return $this;
}
public function resetCustomers(): self
{
foreach($this->customers as $customer) {
$this->removeCustomer($customer);
}
return $this;
}
/**
* @return Collection|ProductOption[]
*/
public function getProductOptions(): Collection
{
return $this->productOptions;
}
public function addProductOption(ProductOption $productOption): self
{
if (!$this->productOptions->contains($productOption)) {
$this->productOptions[] = $productOption;
$productOption->setProduct($this);
}
return $this;
}
public function removeProductOption(ProductOption $productOption): self
{
if ($this->productOptions->contains($productOption)) {
$this->productOptions->removeElement($productOption);
// set the owning side to null (unless already changed)
if ($productOption->getProduct() === $this) {
$productOption->setProduct(null);
}
}
return $this;
}
public function getURL ()
{
return "/product/{$this->slug}";
}
public function serialize ()
{
return serialize(array(
$this->id,
$this->title,
$this->description,
$this->price,
$this->payment_rate,
$this->type,
$this->status,
));
}
public function unserialize ($serialized)
{
list (
$this->id,
$this->title,
$this->description,
$this->price,
$this->payment_rate,
$this->type,
$this->status
) = unserialize($serialized, array ("allowed_classes" => false));
}
public function toJSON ()
{
return json_encode([
"id" => $this->id,
"title" => $this->title,
"description" => $this->description,
"price" => $this->price,
"payment_rate" => $this->payment_rate,
"type" => $this->type,
"status" => $this->status,
]);
}
}