diff --git a/server/web_app/src/Controller/ItemController.php b/server/web_app/src/Controller/ItemController.php index c113d3cf5569c681e3dd9499d9e7d581c64862ca..b200cec963f26c3c2e7fa1497cbc3df12cc02e57 100644 --- a/server/web_app/src/Controller/ItemController.php +++ b/server/web_app/src/Controller/ItemController.php @@ -75,7 +75,6 @@ final class ItemController extends AbstractController 'description' =>$item->getDescription(), 'price' =>$item->getPrice(), 'purchaseUrl' =>$item->getPurchaseUrl(), - 'isBought' =>$item->isBought(), 'createdAt' => $item->getCreatedAt() ]; diff --git a/server/web_app/src/DataFixtures/ItemFixtures.php b/server/web_app/src/DataFixtures/ItemFixtures.php index 0afd18eb6e6fba424908201eedd1eec7fec0681b..f383d423be0b9b4d2ccd367eb0bc333dac2c1e7e 100644 --- a/server/web_app/src/DataFixtures/ItemFixtures.php +++ b/server/web_app/src/DataFixtures/ItemFixtures.php @@ -24,7 +24,6 @@ class ItemFixtures extends Fixture implements DependentFixtureInterface 'title' => 'Smartphone', 'description' => 'Latest model with high-end specs', 'price' => 799.99, - 'is_bought' => true, 'purchase_url' => 'https://example.com/smartphone', ], [ @@ -32,7 +31,6 @@ class ItemFixtures extends Fixture implements DependentFixtureInterface 'title' => 'Laptop', 'description' => 'Powerful laptop for work and gaming', 'price' => 1299.49, - 'is_bought' => true, 'purchase_url' => 'https://example.com/laptop', ], [ @@ -40,7 +38,6 @@ class ItemFixtures extends Fixture implements DependentFixtureInterface 'title' => 'Wireless Headphones', 'description' => 'Noise-canceling headphones with long battery life', 'price' => 199.99, - 'is_bought' => false, 'purchase_url' => 'https://example.com/headphones', ], [ @@ -48,7 +45,6 @@ class ItemFixtures extends Fixture implements DependentFixtureInterface 'title' => 'Coffee Maker', 'description' => 'Automatic coffee maker with multiple settings', 'price' => 89.99, - 'is_bought' => false, 'purchase_url' => 'https://example.com/coffee-maker', ], [ @@ -56,7 +52,6 @@ class ItemFixtures extends Fixture implements DependentFixtureInterface 'title' => 'Gaming Chair', 'description' => 'Ergonomic chair for long gaming sessions', 'price' => 249.99, - 'is_bought' => false, 'purchase_url' => 'https://example.com/gaming-chair', ] ]; @@ -67,7 +62,6 @@ class ItemFixtures extends Fixture implements DependentFixtureInterface $item->setTitle($itemData['title']); $item->setDescription($itemData['description']); $item->setPrice($itemData['price']); - $item->setIsBought($itemData['is_bought']); $item->setPurchaseUrl($itemData['purchase_url']); $item->setCreatedAt(new \DateTimeImmutable()); diff --git a/server/web_app/src/DataFixtures/WishListFixtures.php b/server/web_app/src/DataFixtures/WishListFixtures.php index 6fa0ae3ed1a20b91e5f6ce09c0ab20a0b499786b..1a0a557d415ecbc11808770a32e631ed2288a5f2 100644 --- a/server/web_app/src/DataFixtures/WishListFixtures.php +++ b/server/web_app/src/DataFixtures/WishListFixtures.php @@ -26,8 +26,8 @@ class WishListFixtures extends Fixture implements DependentFixtureInterface 'user' => $users[0], // Assuming at least one user exists 'expiration_date' => new \DateTime('+30 days'), 'is_active' => true, - 'url_view_mode' => 'http:://url_view_mode.com', - 'url_edit_mode' => 'http:://url_edit_mode.com', + 'url_view_mode' => 'http://url_view_mode.com', + 'url_edit_mode' => 'http://url_edit_mode.com', ], [ 'name' => 'Tech Gadgets Wishlist', @@ -35,8 +35,8 @@ class WishListFixtures extends Fixture implements DependentFixtureInterface 'user' => $users[1], // Use second user if available, else first user 'expiration_date' => new \DateTime('+60 days'), 'is_active' => true, - 'url_view_mode' => 'http:://url_view_mode.com', - 'url_edit_mode' => 'http:://url_edit_mode.com', + 'url_view_mode' => 'http://url_view_mode.com', + 'url_edit_mode' => 'http://url_edit_mode.com', ], [ 'name' => 'Home Essentials Wishlist', @@ -44,8 +44,8 @@ class WishListFixtures extends Fixture implements DependentFixtureInterface 'user' => $users[2], // Use third user if available, else first user 'expiration_date' => new \DateTime('+90 days'), 'is_active' => false, - 'url_view_mode' => 'http:://url_view_mode.com', - 'url_edit_mode' => 'http:://url_edit_mode.com', + 'url_view_mode' => 'http://url_view_mode.com', + 'url_edit_mode' => 'http://url_edit_mode.com', ], ]; diff --git a/server/web_app/src/Entity/Item.php b/server/web_app/src/Entity/Item.php index e1e13f77a9f633a65c5a09574c5d7fbe2ec1cded..84d0437096d340d7d109ac3a6c77b773e8038791 100644 --- a/server/web_app/src/Entity/Item.php +++ b/server/web_app/src/Entity/Item.php @@ -4,6 +4,7 @@ namespace App\Entity; use App\Repository\ItemRepository; use Doctrine\ORM\Mapping as ORM; +use Symfony\Component\Validator\Constraints as Assert; #[ORM\Entity(repositoryClass: ItemRepository::class)] class Item @@ -15,24 +16,29 @@ class Item #[ORM\ManyToOne(targetEntity: WishList::class)] #[ORM\JoinColumn(nullable: false)] + #[Assert\NotNull(message: "WishList must be selected.")] private ?WishList $wishList = null; #[ORM\Column(length: 255)] + #[Assert\NotBlank(message: "Title cannot be empty.")] + #[Assert\Length(max: 255, maxMessage: "Title cannot be longer than 255 characters.")] private ?string $title = null; #[ORM\Column(length: 255, nullable: true)] + #[Assert\Length(max: 255, maxMessage: "Description cannot be longer than 255 characters.")] private ?string $description = null; #[ORM\Column] + #[Assert\NotNull(message: "Price cannot be null.")] + #[Assert\Positive(message: "Price must be a positive number.")] private ?float $price = null; #[ORM\Column(length: 255, nullable: true)] private ?string $purchaseUrl = null; - #[ORM\Column(length: 255, nullable: true)] - private ?bool $isBought = null; - #[ORM\Column] + #[Assert\NotNull(message: "CreatedAt must be set.")] + #[Assert\Type(type: \DateTimeImmutable::class, message: "CreatedAt must be a valid DateTimeImmutable instance.")] private ?\DateTimeImmutable $createdAt = null; public function getId(): ?int diff --git a/server/web_app/src/Entity/Purchase.php b/server/web_app/src/Entity/Purchase.php index 7f5df9582b2592f45171ddc5bc1054587c0bd018..edb95c7c14e3f8f5fb51f9ee54c829f4618a4535 100644 --- a/server/web_app/src/Entity/Purchase.php +++ b/server/web_app/src/Entity/Purchase.php @@ -4,30 +4,33 @@ namespace App\Entity; use App\Repository\PurchaseRepository; use Doctrine\ORM\Mapping as ORM; +use Symfony\Component\Validator\Constraints as Assert; #[ORM\Entity(repositoryClass: PurchaseRepository::class)] class Purchase { #[ORM\Id] - #[ORM\GeneratedValue] - #[ORM\Column] - private ?int $id = null; - #[ORM\ManyToOne(targetEntity: User::class)] #[ORM\JoinColumn(nullable: false)] private ?User $user = null; + #[ORM\id] #[ORM\ManyToOne(targetEntity: Item::class)] #[ORM\JoinColumn(nullable: false)] private ?Item $item = null; #[ORM\Column(length: 255, nullable: true)] + #[Assert\Length(max: 255, maxMessage: "URL proof cannot exceed 255 characters.")] + #[Assert\Url(message: "URL proof must be a valid URL.")] private ?string $urlProof = null; #[ORM\Column(length: 255, nullable: true)] + #[Assert\Length(max: 255, maxMessage: "Message cannot exceed 255 characters.")] private ?string $message = null; #[ORM\Column] + #[Assert\NotNull(message: "CreatedAt must be set.")] + #[Assert\Type(type: \DateTimeImmutable::class, message: "CreatedAt must be a valid DateTimeImmutable instance.")] private ?\DateTimeImmutable $createdAt = null; public function getId(): ?int diff --git a/server/web_app/src/Entity/User.php b/server/web_app/src/Entity/User.php index 3e312859b3f7095fec27fa84434102d7555ca2d0..532b2fd9d4d8bcb241c1db72ebe1e1cf27fcb670 100644 --- a/server/web_app/src/Entity/User.php +++ b/server/web_app/src/Entity/User.php @@ -17,17 +17,17 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface #[ORM\Column] private ?int $id = null; - #[ORM\Column(length: 255, nullable: true)] + #[ORM\Column(length: 255, unique: true)] #[Assert\NotBlank(message: "Username cannot be empty.")] #[Assert\Length(min: 3, max: 50, minMessage: "Username must be at least {{ limit }} characters long.")] private ?string $userName = null; - #[ORM\Column(length: 255, nullable: true)] + #[ORM\Column(length: 255)] #[Assert\NotBlank(message: "Name cannot be empty.")] #[Assert\Length(min: 2, max: 100, minMessage: "Name must be at least {{ limit }} characters long.")] private ?string $name = null; - #[ORM\Column(length: 255, nullable: true)] + #[ORM\Column(length: 255)] #[Assert\NotBlank(message: "Surname cannot be empty.")] #[Assert\Length(min: 2, max: 100, minMessage: "Surname must be at least {{ limit }} characters long.")] private ?string $surname = null; @@ -42,17 +42,22 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface #[Assert\Length(min: 8, minMessage: "Password must be at least {{ limit }} characters long.")] private ?string $password = null; - #[ORM\Column(nullable: true)] - private ?bool $isBlocked = null; + #[ORM\Column] + #[ORM\Column(type: 'boolean', options: ['default' => false])] + #[Assert\NotNull(message: "Blocked status cannot be null.")] + private ?bool $isBlocked = false; - #[ORM\Column(enumType: UserRole::class)] + #[ORM\Column(enumType: UserRole::class, options: ['default' => 'user'])] #[Assert\Choice( - callback: [UserRole::class, 'cases'], + callback: [UserRole::class, 'getValues'], message: "Invalid role value. Allowed values: {{ choices }}." )] - private ?UserRole $role = null; + private UserRole $role = UserRole::USER; + #[ORM\Column] + #[Assert\NotNull(message: "CreatedAt must be set.")] + #[Assert\Type(type: \DateTimeImmutable::class, message: "CreatedAt must be a valid DateTimeImmutable instance.")] private ?\DateTimeImmutable $createdAt = null; public function getId(): ?int diff --git a/server/web_app/src/Entity/WishList.php b/server/web_app/src/Entity/WishList.php index 5bb2b14aa2cf32ab4ce64814fe84d2c0100a9213..8849ca9b43b3bce5f2ef5bb33057fce6ef77a19c 100644 --- a/server/web_app/src/Entity/WishList.php +++ b/server/web_app/src/Entity/WishList.php @@ -7,6 +7,7 @@ use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; +use Symfony\Component\Validator\Constraints as Assert; #[ORM\Entity(repositoryClass: WishListRepository::class)] class WishList @@ -18,28 +19,43 @@ class WishList #[ORM\ManyToOne(targetEntity: User::class)] #[ORM\JoinColumn(nullable: false)] + #[Assert\NotNull(message: "User must be provided.")] private ?User $user = null; #[ORM\Column(length: 255)] + #[Assert\NotBlank(message: "Name cannot be empty.")] + #[Assert\Length(max: 255, maxMessage: "Name cannot be longer than 255 characters.")] private ?string $name = null; - #[ORM\Column(length: 255)] + #[ORM\Column(length: 255, nullable: true)] + #[Assert\Length(max: 255, maxMessage: "Description cannot be longer than 255 characters.")] private ?string $description = null; #[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)] + #[Assert\Type(type: \DateTimeInterface::class, message: "Expiration date must be a valid date.")] + #[Assert\GreaterThan("today", message: "Expiration date must be in the future.")] private ?\DateTimeInterface $expirationDate = null; - #[ORM\Column] - private ?bool $isActive = null; + #[ORM\Column(options: ['default' => true])] + #[Assert\NotNull(message: "isActive status must be set.")] + #[Assert\Type(type: 'bool', message: "isActive must be a boolean value.")] + private ?bool $isActive = true; - //add getters and setters #[ORM\Column(length: 255)] + #[Assert\NotBlank(message: "View mode URL cannot be empty.")] + #[Assert\Length(max: 255, maxMessage: "View mode URL cannot be longer than 255 characters.")] + #[Assert\Url(message: "View mode URL must be a valid URL.")] private ?string $urlViewMode = null; + #[Assert\NotBlank(message: "Edit mode URL cannot be empty.")] + #[Assert\Length(max: 255, maxMessage: "Edit mode URL cannot be longer than 255 characters.")] + #[Assert\Url(message: "Edit mode URL must be a valid URL.")] #[ORM\Column(length: 255)] private ?string $urlEditMode = null; #[ORM\Column] + #[Assert\NotNull(message: "CreatedAt must be set.")] + #[Assert\Type(type: \DateTimeImmutable::class, message: "CreatedAt must be a valid DateTimeImmutable instance.")] private ?\DateTimeImmutable $createdAt = null; public function __construct() diff --git a/server/web_app/src/Entity/WishListMember.php b/server/web_app/src/Entity/WishListMember.php index cc617a249d35fb42dd26c442171be154860418cf..07e32759a3881b232d96a174f0c35aac2d0a0143 100644 --- a/server/web_app/src/Entity/WishListMember.php +++ b/server/web_app/src/Entity/WishListMember.php @@ -4,6 +4,7 @@ namespace App\Entity; use App\Repository\WishListMemberRepository; use Doctrine\ORM\Mapping as ORM; +use Symfony\Component\Validator\Constraints as Assert; #[ORM\Entity(repositoryClass: WishListMemberRepository::class)] class WishListMember @@ -15,19 +16,26 @@ class WishListMember #[ORM\ManyToOne(targetEntity: WishList::class)] #[ORM\JoinColumn(nullable: false)] + #[Assert\NotNull(message: "WishList must be provided.")] private ?WishList $wishList = null; #[ORM\ManyToOne(targetEntity: User::class)] #[ORM\JoinColumn(nullable: false)] + #[Assert\NotNull(message: "User must be provided.")] private ?User $user = null; #[ORM\Column] - private ?bool $canEdit = null; + #[Assert\NotNull(message: "Edit permission (canEdit) must be set.")] + #[Assert\Type(type: 'bool', message: "canEdit must be a boolean value.")] + private ?bool $canEdit = false; - #[ORM\Column(nullable: true)] - private ?bool $isAccepted = null; + #[ORM\Column(nullable: true, options: ['default' => false])] + #[Assert\Type(type: 'bool', message: "isAccepted must be a boolean value.")] + private ?bool $isAccepted = false; #[ORM\Column] + #[Assert\NotNull(message: "CreatedAt must be set.")] + #[Assert\Type(type: \DateTimeImmutable::class, message: "CreatedAt must be a valid DateTimeImmutable instance.")] private ?\DateTimeImmutable $createdAt = null; public function getId(): ?int diff --git a/server/web_app/src/Enum/UserRole.php b/server/web_app/src/Enum/UserRole.php index 4b040563c164cbd5def4c6c336cd5118aacda1dc..f348d5a846fd2310693453e389c0be848232da78 100644 --- a/server/web_app/src/Enum/UserRole.php +++ b/server/web_app/src/Enum/UserRole.php @@ -14,6 +14,11 @@ enum UserRole: string self::USER => 'Regular User' }; } + + public static function getValues(): array + { + return array_column(self::cases(), 'value'); + } } ?> \ No newline at end of file diff --git a/server/web_app/src/Repository/ItemRepository.php b/server/web_app/src/Repository/ItemRepository.php index e148efaa59c7ec831866bc6718fbac9f53672c68..48e7dca15a9807de8561f9318696c0391cb429ae 100644 --- a/server/web_app/src/Repository/ItemRepository.php +++ b/server/web_app/src/Repository/ItemRepository.php @@ -20,16 +20,6 @@ class ItemRepository extends ServiceEntityRepository return $this->findAll(); } - // Custom query method to find active users - public function findByStatus($isBought): array - { - return $this->createQueryBuilder('u') - ->andWhere('u.isBought = :isBought') - ->setParameter('isBought', $isBought) - ->getQuery() - ->getResult(); - } - // Custom query method to find a user by id public function findOneById(int $id): ?Item {