Skip to content

Commit 20fb223

Browse files
authored
Merge pull request #61 from Codencode/category-endpoints
Added category endpoints
2 parents faa6584 + 5d19790 commit 20fb223

File tree

5 files changed

+475
-0
lines changed

5 files changed

+475
-0
lines changed

config/admin/services.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,7 @@ services:
2424
- '@prestashop.core.hook.dispatcher'
2525
- '@prestashop.core.grid.query.doctrine_query_parser'
2626
- 'module'
27+
28+
PrestaShop\Module\APIResources\Validation\IframeValidationGroupsResolver:
29+
arguments:
30+
- '@prestashop.adapter.legacy.configuration'
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
<?php
2+
/**
3+
* Copyright since 2007 PrestaShop SA and Contributors
4+
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
5+
*
6+
* NOTICE OF LICENSE
7+
*
8+
* This source file is subject to the Academic Free License version 3.0
9+
* that is bundled with this package in the file LICENSE.md.
10+
* It is also available through the world-wide-web at this URL:
11+
* https://opensource.org/licenses/AFL-3.0
12+
* If you did not receive a copy of the license and are unable to
13+
* obtain it through the world-wide-web, please send an email
14+
* to license@prestashop.com so we can send you a copy immediately.
15+
*
16+
* @author PrestaShop SA and Contributors <contact@prestashop.com>
17+
* @copyright Since 2007 PrestaShop SA and Contributors
18+
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
19+
*/
20+
21+
namespace PrestaShop\Module\APIResources\ApiPlatform\Resources\Category;
22+
23+
use ApiPlatform\Metadata\ApiProperty;
24+
use ApiPlatform\Metadata\ApiResource;
25+
use PrestaShop\Module\APIResources\Validation\IframeValidationGroupsResolver;
26+
use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\DefaultLanguage;
27+
use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\TypedRegex;
28+
use PrestaShop\PrestaShop\Core\Domain\Category\Command\AddCategoryCommand;
29+
use PrestaShop\PrestaShop\Core\Domain\Category\Command\DeleteCategoryCommand;
30+
use PrestaShop\PrestaShop\Core\Domain\Category\Command\EditCategoryCommand;
31+
use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryConstraintException;
32+
use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryNotFoundException;
33+
use PrestaShop\PrestaShop\Core\Domain\Category\Query\GetCategoryForEditing;
34+
use PrestaShopBundle\ApiPlatform\Metadata\CQRSCreate;
35+
use PrestaShopBundle\ApiPlatform\Metadata\CQRSDelete;
36+
use PrestaShopBundle\ApiPlatform\Metadata\CQRSGet;
37+
use PrestaShopBundle\ApiPlatform\Metadata\CQRSPartialUpdate;
38+
use PrestaShopBundle\ApiPlatform\Metadata\LocalizedValue;
39+
use Symfony\Component\HttpFoundation\Response;
40+
use Symfony\Component\Serializer\Annotation\SerializedName;
41+
use Symfony\Component\Validator\Constraints as Assert;
42+
43+
#[ApiResource(
44+
operations: [
45+
new CQRSGet(
46+
uriTemplate: '/category/{categoryId}',
47+
CQRSQuery: GetCategoryForEditing::class,
48+
scopes: [
49+
'category_read',
50+
],
51+
CQRSQueryMapping: self::QUERY_MAPPING,
52+
),
53+
new CQRSCreate(
54+
uriTemplate: '/category',
55+
validationContext: [IframeValidationGroupsResolver::class, 'create'],
56+
CQRSCommand: AddCategoryCommand::class,
57+
CQRSQuery: GetCategoryForEditing::class,
58+
scopes: [
59+
'category_write',
60+
],
61+
CQRSQueryMapping: self::QUERY_MAPPING,
62+
CQRSCommandMapping: self::COMMAND_MAPPING,
63+
),
64+
new CQRSPartialUpdate(
65+
uriTemplate: '/category/{categoryId}',
66+
validationContext: [IframeValidationGroupsResolver::class, 'update'],
67+
CQRSCommand: EditCategoryCommand::class,
68+
CQRSQuery: GetCategoryForEditing::class,
69+
scopes: [
70+
'category_write',
71+
],
72+
CQRSQueryMapping: self::QUERY_MAPPING,
73+
CQRSCommandMapping: self::COMMAND_MAPPING,
74+
),
75+
new CQRSDelete(
76+
uriTemplate: '/category/{categoryId}',
77+
CQRSCommand: DeleteCategoryCommand::class,
78+
scopes: [
79+
'category_write',
80+
],
81+
),
82+
],
83+
exceptionToStatus: [
84+
CategoryConstraintException::class => Response::HTTP_UNPROCESSABLE_ENTITY,
85+
CategoryNotFoundException::class => Response::HTTP_NOT_FOUND,
86+
],
87+
)]
88+
class Category
89+
{
90+
#[ApiProperty(identifier: true)]
91+
#[SerializedName('id')]
92+
public int $categoryId;
93+
94+
#[LocalizedValue]
95+
#[DefaultLanguage(groups: ['Create'], fieldName: 'names')]
96+
#[DefaultLanguage(groups: ['Update'], fieldName: 'names', allowNull: true)]
97+
#[Assert\All(constraints: [
98+
new TypedRegex([
99+
'type' => TypedRegex::TYPE_CATALOG_NAME,
100+
]),
101+
])]
102+
public array $names;
103+
104+
#[LocalizedValue]
105+
#[DefaultLanguage(groups: ['Create'], fieldName: 'descriptions')]
106+
#[DefaultLanguage(groups: ['Update'], fieldName: 'descriptions', allowNull: true)]
107+
#[Assert\All(constraints: [
108+
new TypedRegex([
109+
'type' => TypedRegex::CLEAN_HTML_NO_IFRAME,
110+
'groups' => ['NoIframe'],
111+
]),
112+
new TypedRegex([
113+
'type' => TypedRegex::CLEAN_HTML_ALLOW_IFRAME,
114+
'groups' => ['AllowIframe'],
115+
]),
116+
])]
117+
public array $descriptions;
118+
119+
#[LocalizedValue]
120+
#[DefaultLanguage(groups: ['Create'], fieldName: 'additionalDescriptions')]
121+
#[DefaultLanguage(groups: ['Update'], fieldName: 'additionalDescriptions', allowNull: true)]
122+
#[Assert\All(constraints: [
123+
new TypedRegex([
124+
'type' => TypedRegex::CLEAN_HTML_NO_IFRAME,
125+
'groups' => ['NoIframe'],
126+
]),
127+
new TypedRegex([
128+
'type' => TypedRegex::CLEAN_HTML_NO_IFRAME,
129+
'groups' => ['AllowIframe'],
130+
]),
131+
])]
132+
public array $additionalDescriptions;
133+
134+
#[LocalizedValue]
135+
#[DefaultLanguage(groups: ['Create'], fieldName: 'linkRewrites')]
136+
#[DefaultLanguage(groups: ['Update'], fieldName: 'linkRewrites', allowNull: false)]
137+
#[Assert\All(constraints: [
138+
new TypedRegex([
139+
'type' => TypedRegex::TYPE_URL,
140+
]),
141+
])]
142+
public array $linkRewrites;
143+
144+
#[LocalizedValue]
145+
#[DefaultLanguage(groups: ['Create'], fieldName: 'metaTitles')]
146+
#[DefaultLanguage(groups: ['Update'], fieldName: 'metaTitles', allowNull: true)]
147+
public array $metaTitles;
148+
149+
#[LocalizedValue]
150+
#[DefaultLanguage(groups: ['Create'], fieldName: 'metaDescriptions')]
151+
#[DefaultLanguage(groups: ['Update'], fieldName: 'metaDescriptions', allowNull: true)]
152+
public array $metaDescriptions;
153+
154+
public int $position;
155+
156+
public int $parentId;
157+
158+
public string $redirectType;
159+
160+
public ?int $redirectTarget = null;
161+
162+
#[ApiProperty(openapiContext: ['type' => 'array', 'items' => ['type' => 'integer'], 'example' => [1, 3]])]
163+
#[Assert\NotBlank(allowNull: true)]
164+
public array $shopIds;
165+
166+
public const QUERY_MAPPING = [
167+
'[id]' => '[categoryId]',
168+
'[name]' => '[names]',
169+
'[description]' => '[descriptions]',
170+
'[additionalDescription]' => '[additionalDescriptions]',
171+
'[associatedShopIds]' => '[shopIds]',
172+
'[metaTitle]' => '[metaTitles]',
173+
'[metaDescription]' => '[metaDescriptions]',
174+
'[linkRewrite]' => '[linkRewrites]',
175+
];
176+
177+
public const COMMAND_MAPPING = [
178+
'[names]' => '[localizedNames]',
179+
'[descriptions]' => '[localizedDescriptions]',
180+
'[additionalDescriptions]' => '[localizedAdditionalDescriptions]',
181+
'[shopIds]' => '[associatedShopIds]',
182+
'[metaTitles]' => '[localizedMetaTitles]',
183+
'[metaDescriptions]' => '[localizedMetaDescriptions]',
184+
'[linkRewrites]' => '[localizedLinkRewrites]',
185+
];
186+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
/**
4+
* Copyright since 2007 PrestaShop SA and Contributors
5+
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
6+
*
7+
* NOTICE OF LICENSE
8+
*
9+
* This source file is subject to the Academic Free License version 3.0
10+
* that is bundled with this package in the file LICENSE.md.
11+
* It is also available through the world-wide-web at this URL:
12+
* https://opensource.org/licenses/AFL-3.0
13+
* If you did not receive a copy of the license and are unable to
14+
* obtain it through the world-wide-web, please send an email
15+
* to license@prestashop.com so we can send you a copy immediately.
16+
*
17+
* @author PrestaShop SA and Contributors <contact@prestashop.com>
18+
* @copyright Since 2007 PrestaShop SA and Contributors
19+
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
20+
*/
21+
22+
declare(strict_types=1);
23+
24+
namespace PrestaShop\Module\APIResources\ApiPlatform\Resources\Category;
25+
26+
use ApiPlatform\Metadata\ApiProperty;
27+
use ApiPlatform\Metadata\ApiResource;
28+
use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryNotFoundException;
29+
use PrestaShop\PrestaShop\Core\Domain\Shop\Exception\ShopAssociationNotFound;
30+
use PrestaShop\PrestaShop\Core\Search\Filters\CategoryFilters;
31+
use PrestaShopBundle\ApiPlatform\Metadata\PaginatedList;
32+
use PrestaShopBundle\ApiPlatform\Provider\QueryListProvider;
33+
use Symfony\Component\HttpFoundation\Response;
34+
35+
#[ApiResource(
36+
operations: [
37+
new PaginatedList(
38+
uriTemplate: '/categories',
39+
provider: QueryListProvider::class,
40+
scopes: ['category_read'],
41+
ApiResourceMapping: [
42+
'[id_category]' => '[categoryId]',
43+
],
44+
gridDataFactory: 'prestashop.core.grid.data.factory.category_decorator',
45+
filtersClass: CategoryFilters::class,
46+
filtersMapping: [
47+
'[categoryId]' => '[id_category]',
48+
],
49+
),
50+
],
51+
exceptionToStatus: [
52+
CategoryNotFoundException::class => Response::HTTP_NOT_FOUND,
53+
ShopAssociationNotFound::class => Response::HTTP_NOT_FOUND,
54+
],
55+
)]
56+
class CategoryList
57+
{
58+
#[ApiProperty(identifier: true)]
59+
public int $categoryId;
60+
61+
public bool $active;
62+
63+
public string $name;
64+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
/**
3+
* Copyright since 2007 PrestaShop SA and Contributors
4+
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
5+
*
6+
* NOTICE OF LICENSE
7+
*
8+
* This source file is subject to the Academic Free License version 3.0
9+
* that is bundled with this package in the file LICENSE.md.
10+
* It is also available through the world-wide-web at this URL:
11+
* https://opensource.org/licenses/AFL-3.0
12+
* If you did not receive a copy of the license and are unable to
13+
* obtain it through the world-wide-web, please send an email
14+
* to license@prestashop.com so we can send you a copy immediately.
15+
*
16+
* @author PrestaShop SA and Contributors <contact@prestashop.com>
17+
* @copyright Since 2007 PrestaShop SA and Contributors
18+
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
19+
*/
20+
21+
namespace PrestaShop\Module\APIResources\Validation;
22+
23+
use PrestaShop\PrestaShop\Adapter\Configuration;
24+
25+
final class IframeValidationGroupsResolver
26+
{
27+
public function __construct(private Configuration $config)
28+
{
29+
}
30+
31+
public function create(): array
32+
{
33+
return ['groups' => array_filter(['Default', 'Create', $this->flagGroup()])];
34+
}
35+
36+
public function update(): array
37+
{
38+
return ['groups' => array_filter(['Default', 'Update', $this->flagGroup()])];
39+
}
40+
41+
private function flagGroup(): string
42+
{
43+
$allowIframe = (bool) ($this->config->get('PS_ALLOW_HTML_IFRAME') ?: false);
44+
45+
return $allowIframe ? 'AllowIframe' : 'NoIframe';
46+
}
47+
}

0 commit comments

Comments
 (0)