Skip to content

Commit 8ba12b3

Browse files
TatevikGrtatevikg1
andauthored
release: dev → main (subscribe page features and configuration updates) (#169)
* Fix: swagger response * Add workflow for updating OpenAPI specs in web frontend and limit client-docs to specific branches * Add endpoint to retrieve all subscribe pages * Developer * Add support for subscribe page data management and validation * Add public page to return list data * After review 0 * Normalize attributes key in SubscribePageData * persist-credentials * Add: getPublicPage endpoint * Enhance SubscribePagePublicNormalizer to resolve attribute IDs using SubscriberAttributeDefinitionRepository * Add PublicSubscriptionRequest class and update subscribe method in SubscriptionController * Add PublicSubscriptionRequest class and update subscribe method in SubscriptionController * Add tests * Add unsubscribe endpoint * Add PublicUnsubscriptionRequest class for unsubscribe functionality in SubscribePagePublicController * Feat: ConfigController * Feat: ConfigController tests * Fix: Unique Validators by adding UpdatingId to requests * Do not check privileges for dashboard analytics * Fix: AccessDeniedHttpException code * Feat: Add EditorUploadController and exception handling for upload-related errors * Feat: Add FileListingController with directory listing functionality and tests * Feat: Add FileListingController get_file * use phplist/core dev-main --------- Co-authored-by: Tatevik <tatevikg1@gmail.com>
1 parent e53430e commit 8ba12b3

88 files changed

Lines changed: 4152 additions & 487 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
name: phpList REST API Build
2-
on: [push, pull_request]
2+
on:
3+
push:
4+
branches:
5+
- main
6+
pull_request:
37
jobs:
48
main:
59
name: phpList Base Dist on PHP ${{ matrix.php-versions }}, with dist ${{ matrix.dependencies }} [Build, Test]

.github/workflows/client-docs.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ name: Update phplist-api-client OpenAPI
33
on:
44
push:
55
branches:
6-
- '**'
6+
- dev
7+
- main
78
pull_request:
9+
branches:
10+
- main
811

912
jobs:
1013
generate-openapi:

.github/workflows/front-docs.yml

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
name: Update phplist-web-frontend OpenAPI
2+
3+
permissions:
4+
contents: write # Required to push to web-frontend repo
5+
actions: read # Required to download artifacts
6+
7+
on:
8+
push:
9+
branches:
10+
- dev
11+
- main
12+
pull_request:
13+
branches:
14+
- main
15+
jobs:
16+
generate-openapi:
17+
runs-on: ubuntu-22.04
18+
outputs:
19+
source_branch: ${{ steps.branch.outputs.source_branch }}
20+
steps:
21+
- name: Determine source branch
22+
env:
23+
EVENT_NAME: ${{ github.event_name }}
24+
HEAD_REF: ${{ github.head_ref }}
25+
REF_NAME: ${{ github.ref_name }}
26+
id: branch
27+
run: |
28+
if [ "$EVENT_NAME" = "pull_request" ]; then
29+
echo "source_branch=$HEAD_REF" >> "$GITHUB_OUTPUT"
30+
else
31+
echo "source_branch=$REF_NAME" >> "$GITHUB_OUTPUT"
32+
fi
33+
34+
- name: Checkout Source Repository
35+
uses: actions/checkout@v4
36+
37+
- name: Setup PHP with Composer and Extensions
38+
uses: shivammathur/setup-php@v2
39+
with:
40+
php-version: 8.1
41+
extensions: mbstring, dom, fileinfo, mysql
42+
43+
- name: Cache Composer Dependencies
44+
uses: actions/cache@v3
45+
with:
46+
path: ~/.composer/cache
47+
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
48+
restore-keys: |
49+
${{ runner.os }}-composer-
50+
51+
- name: Install Composer Dependencies
52+
run: composer install --no-interaction --prefer-dist
53+
54+
- name: Generate OpenAPI Specification JSON
55+
run: vendor/bin/openapi -o docs/latest-restapi.json --format json src
56+
57+
- name: Upload OpenAPI Artifact
58+
uses: actions/upload-artifact@v4
59+
with:
60+
name: openapi-json
61+
path: docs/latest-restapi.json
62+
63+
update-web-frontend:
64+
runs-on: ubuntu-22.04
65+
needs: generate-openapi
66+
env:
67+
TARGET_BRANCH: ${{ needs.generate-openapi.outputs.source_branch }}
68+
steps:
69+
- name: Checkout phpList-web-frontend Repository
70+
uses: actions/checkout@v3
71+
with:
72+
repository: phpList/web-frontend
73+
token: ${{ secrets.PUSH_WEB_FRONTEND }}
74+
fetch-depth: 0
75+
76+
- name: Prepare target branch
77+
run: |
78+
git fetch origin
79+
80+
if git ls-remote --exit-code --heads origin "$TARGET_BRANCH" >/dev/null 2>&1; then
81+
git checkout "$TARGET_BRANCH"
82+
git pull --rebase origin "$TARGET_BRANCH"
83+
else
84+
git checkout -b "$TARGET_BRANCH"
85+
fi
86+
87+
- name: Download Generated OpenAPI JSON
88+
uses: actions/download-artifact@v4
89+
with:
90+
name: openapi-json
91+
path: ./new-openapi
92+
93+
- name: Compare and Check for Differences
94+
id: diff
95+
run: |
96+
# Compare the openapi files if old exists, else always deploy
97+
if [ -f openapi.json ]; then
98+
diff openapi.json new-openapi/latest-restapi.json > openapi-diff.txt || true
99+
if [ -s openapi-diff.txt ]; then
100+
echo "diff=true" >> "$GITHUB_OUTPUT"
101+
else
102+
echo "diff=false" >> "$GITHUB_OUTPUT"
103+
fi
104+
else
105+
echo "No previous openapi.json, will add."
106+
echo "diff=true" >> "$GITHUB_OUTPUT"
107+
fi
108+
109+
- name: Update and Commit OpenAPI File
110+
if: steps.diff.outputs.diff == 'true'
111+
run: |
112+
set -euo pipefail
113+
cp new-openapi/latest-restapi.json openapi.json
114+
git config user.name "github-actions"
115+
git config user.email "github-actions@web-frontend.workflow"
116+
git add openapi.json
117+
if git diff --cached --quiet; then
118+
echo "No changes to commit"
119+
exit 0
120+
fi
121+
git commit -m "Update openapi.json from web frontend workflow $(date -u +"%Y-%m-%dT%H:%M:%SZ")"
122+
git fetch origin "$TARGET_BRANCH"
123+
git rebase "origin/$TARGET_BRANCH"
124+
git push origin HEAD:"$TARGET_BRANCH"
125+
126+
- name: Skip Commit if No Changes
127+
if: steps.diff.outputs.diff == 'false'
128+
run: echo "No changes to openapi.json, skipping commit."

composer.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,11 @@
126126
"type": "attribute",
127127
"prefix": "/api/v2"
128128
},
129+
"rest-api-configuration": {
130+
"resource": "@PhpListRestBundle/Configuration/Controller/",
131+
"type": "attribute",
132+
"prefix": "/api/v2"
133+
},
129134
"rest-api-analitics": {
130135
"resource": "@PhpListRestBundle/Statistics/Controller/",
131136
"type": "attribute",

config/services/controllers.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ services:
2525
autoconfigure: true
2626
public: true
2727

28+
PhpList\RestBundle\Configuration\Controller\:
29+
resource: '../src/Configuration/Controller'
30+
tags: [ 'controller.service_arguments' ]
31+
autowire: true
32+
autoconfigure: true
33+
public: true
34+
2835
PhpList\RestBundle\Statistics\Controller\:
2936
resource: '../src/Statistics/Controller'
3037
tags: [ 'controller.service_arguments' ]

config/services/services.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ services:
33
autowire: true
44
autoconfigure: true
55

6+
PhpList\RestBundle\Subscription\Service\PublicSubscriptionAttributeRuleProvider:
7+
autowire: true
8+
autoconfigure: true
9+
610
PhpList\Core\Domain\Messaging\Service\ForwardingGuard:
711
autowire: true
812
autoconfigure: true
@@ -17,3 +21,14 @@ services:
1721
autowire: true
1822
autoconfigure: true
1923
public: false
24+
25+
PhpList\Core\Domain\Common\Service\UploadService:
26+
autowire: true
27+
autoconfigure: true
28+
public: false
29+
30+
31+
PhpList\Core\Domain\Common\Service\DirectoryListingService:
32+
autowire: true
33+
autoconfigure: true
34+
public: false

config/services/validators.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,26 @@ services:
3737
autoconfigure: true
3838
tags: [ 'validator.constraint_validator' ]
3939

40+
PhpList\RestBundle\Configuration\Validator\Constraint\UniqueConfigKeyValidator:
41+
autowire: true
42+
autoconfigure: true
43+
tags: [ 'validator.constraint_validator' ]
44+
4045
PhpList\RestBundle\Subscription\Validator\Constraint\ListExistsValidator:
4146
autowire: true
4247
autoconfigure: true
4348
tags: [ 'validator.constraint_validator' ]
4449

50+
PhpList\RestBundle\Subscription\Validator\Constraint\ListExistsPublicValidator:
51+
autowire: true
52+
autoconfigure: true
53+
tags: [ 'validator.constraint_validator' ]
54+
55+
PhpList\RestBundle\Subscription\Validator\Constraint\ValidPublicSubscriptionValidator:
56+
autowire: true
57+
autoconfigure: true
58+
tags: [ 'validator.constraint_validator' ]
59+
4560
PhpList\Core\Domain\Identity\Validator\AttributeTypeValidator:
4661
autowire: true
4762
autoconfigure: true

src/Common/EventListener/ExceptionListener.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
use PhpList\Core\Domain\Messaging\Exception\SubscriberNotFoundException;
1212
use PhpList\Core\Domain\Subscription\Exception\AttributeDefinitionCreationException;
1313
use PhpList\Core\Domain\Subscription\Exception\SubscriptionCreationException;
14+
use PhpList\Core\Domain\Common\Exception\InvalidUploadException;
15+
use PhpList\Core\Domain\Common\Exception\MissingUploadException;
16+
use PhpList\Core\Domain\Common\Exception\StorageException;
17+
use PhpList\Core\Domain\Common\Exception\UnsupportedExtensionException;
18+
use PhpList\Core\Domain\Common\Exception\UnsupportedMimeTypeException;
19+
use PhpList\Core\Domain\Common\Exception\UploadTooLargeException;
1420
use Symfony\Component\HttpFoundation\JsonResponse;
1521
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
1622
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
@@ -27,10 +33,16 @@ class ExceptionListener
2733
AttributeDefinitionCreationException::class => null,
2834
AdminAttributeCreationException::class => null,
2935
AccessDeniedException::class => 403,
30-
AccessDeniedHttpException::class => 403,
36+
AccessDeniedHttpException::class => 401,
3137
AttachmentFileNotFoundException::class => 404,
3238
SubscriberNotFoundException::class => 404,
3339
MessageNotReceivedException::class => 422,
40+
MissingUploadException::class => 400,
41+
InvalidUploadException::class => 400,
42+
UnsupportedExtensionException::class => 400,
43+
UnsupportedMimeTypeException::class => 415,
44+
UploadTooLargeException::class => 413,
45+
StorageException::class => 500,
3446
];
3547

3648
public function onKernelException(ExceptionEvent $event): void

src/Common/Validator/RequestValidator.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public function __construct(
2020
) {
2121
}
2222

23-
public function validate(Request $request, string $dtoClass): RequestInterface
23+
public function validate(Request $request, string $dtoClass, ?callable $beforeValidation = null): RequestInterface
2424
{
2525
try {
2626
$content = $request->getContent();
@@ -33,9 +33,6 @@ public function validate(Request $request, string $dtoClass): RequestInterface
3333
if (isset($routeParams['listId'])) {
3434
$routeParams['listId'] = (int) $routeParams['listId'];
3535
}
36-
if (isset($routeParams['templateId'])) {
37-
$routeParams['templateId'] = (int) $routeParams['templateId'];
38-
}
3936

4037
$data = array_merge($routeParams, $request->query->all(), $body ?? []);
4138

@@ -53,6 +50,10 @@ public function validate(Request $request, string $dtoClass): RequestInterface
5350
);
5451
}
5552

53+
if ($beforeValidation !== null) {
54+
$beforeValidation($dto);
55+
}
56+
5657
return $this->validateDto($dto);
5758
}
5859

0 commit comments

Comments
 (0)