Compare commits

...
Sign in to create a new pull request.

212 commits

Author SHA1 Message Date
Noah Lancien
162b4a6451 ci: 👷 Replaced user 33 with 82 2026-10-26 14:10:56 +01:00
de5ef8d70e
build: fix docker image tag 2026-09-09 17:56:44 +02:00
Jérémy
41a8a032af Merge branch '62-sentry-error' into 'develop'
fix: 🐛 allow null concept in concept trail

See merge request ldc-web/projets/nature-and-respect!81
2026-09-09 17:25:52 +02:00
Corentin Huet
eef38c02d5 fix: 🐛 hide breadcrumb on the 404 page 2026-09-02 18:01:10 +02:00
Noix
da89d39521 Merge branch 'issue-61' into 'develop'
Issue 61

See merge request ldc-web/projets/nature-and-respect!80
2026-08-07 07:33:58 +00:00
Alexis Gousseau
92cd02fd27
feat: ✨ add commit lint from husky configuration 2026-08-06 11:13:31 +02:00
Alexis Gousseau
965e4867aa
fix: 🐛 check if route name exist before getting his name 2026-08-06 11:09:44 +02:00
Alexis Gousseau
08f592e141
chore: ⬆️ bump laravel-common to v4.1.6 2026-08-06 11:05:53 +02:00
Noix
3b58f67701 Merge branch 'issue-59-fix' into 'develop'
fix: 🐛 dimension img and add wrap for handle click

See merge request ldc-web/projets/nature-and-respect!78
2026-07-29 15:12:31 +00:00
Abdel LAMRANI
7bcd3feb02 fix: 🐛 dimension img and add wrap for handle click 2026-07-29 16:31:38 +02:00
Karl M'muller
ef45646bf3 Merge branch 'issue-59' into 'develop'
feat: ✨ add logo when lang= DE

See merge request ldc-web/projets/nature-and-respect!76
2026-07-29 12:36:10 +00:00
Abdel LAMRANI
2e8d3ce15d feat: ✨ add logo when lang= DE 2026-07-27 10:31:24 +02:00
Noah Lancien
5fb7c29d70 revert: ⏪ 6dd1c429d4 2026-04-21 10:24:27 +02:00
Noah Lancien
1fc0dddc30 Merge branch 'migrate-mysql-and-bump-php' into develop 2026-04-21 10:09:49 +02:00
Noah Lancien
6dd1c429d4 chore: ⬆️ npm update 2026-04-21 10:09:24 +02:00
Noah Lancien
df97c19d5e chore: ⬆️ bump php8.5 2026-04-21 10:09:03 +02:00
Noah Lancien
503a8f1efd fix: 🐛 Updated htaccess to redirect index.php 2026-04-21 10:05:38 +02:00
Noah Lancien
58af5b7922 ci: 👷 Limit cron jobs to 1 2026-04-21 10:05:05 +02:00
Noah Lancien
86727e4d3c ci: 👷 Added variable for db host 2026-04-21 10:04:41 +02:00
Noah Lancien
7a001ab811 feat: updated admin-secure 2026-01-14 11:17:09 +01:00
Noah Lancien
f3db8cf28f ci: added staging-resources.yaml 2026-01-09 10:17:49 +01:00
Noah Lancien
bb5e56e172 ci: added ci variables to define pod resources 2026-01-09 10:17:16 +01:00
karl.muller
303ac8cab4 Merge branch 'remove-old-steps' into 'develop'
fix: 🔥 remove old recipes steps

See merge request ldc-web/projets/nature-and-respect!74
2025-07-24 08:37:19 +00:00
Alexis Gousseau
23164bd6c8
fix: 🔥 remove old recipes steps 2025-07-22 10:33:21 +02:00
karl.muller
ef72b9c99a Merge branch 'issue-52' into 'develop'
fix: 🐛 slugify and decode binded url

See merge request ldc-web/projets/nature-and-respect!73
2025-07-21 09:06:18 +00:00
Karl
98a84c1dd9 fix: 🐛 slugify and decode binded url 2025-07-21 10:10:21 +02:00
noah.lancien
86e8662dbc Merge branch 'hreflang' into 'develop'
chore: 📦 bump laravel-common to v3.4.2

See merge request ldc-web/projets/nature-and-respect!72
2025-07-18 15:37:22 +00:00
Alexis Gousseau
4d193061fa
chore: 📦 bump laravel-common to v3.4.2 2025-07-18 17:32:46 +02:00
Vincent BRIDIER
0f8b79d77c Merge branch 'sitemap' into 'develop'
fix: 🐛 repair sitemap generator #51

See merge request ldc-web/projets/nature-and-respect!71
2025-07-18 15:27:35 +00:00
Alexis Gousseau
40d1e7f04b
fix: 🐛 repair sitemap generator #51 2025-07-18 17:18:56 +02:00
noah.lancien
b32f19fdb9 Merge branch 'breadcrumb' into 'develop'
fix: 🐛 add a condition for nullable models when laravel does not resolve them

See merge request ldc-web/projets/nature-and-respect!70
2025-07-18 15:05:23 +00:00
Alexis Gousseau
72e16d1715
fix: 🐛 add a condition for nullable models when laravel does not resolve them 2025-07-18 16:54:44 +02:00
noah.lancien
6068573793 Merge branch 'head-attributes' into 'develop'
feat: ✨ update head attributes #50

See merge request ldc-web/projets/nature-and-respect!66
2025-07-18 14:16:59 +00:00
Alexis Gousseau
8193aaa597
feat: ✨ update head attributes #50 2025-07-18 14:45:46 +02:00
noah.lancien
801b876df5 Merge branch 'schema-org' into 'develop'
fix: 🔍 improve recipes schema org

See merge request ldc-web/projets/nature-and-respect!69
2025-07-18 10:52:44 +00:00
Alexis Gousseau
0327175fc5
fix: 🔍 improve recipes schema org 2025-07-18 12:23:18 +02:00
noah.lancien
80ae4d966b Merge branch 'errors-pages' into 'develop'
fix: 🐛 repair model display error pages

See merge request ldc-web/projets/nature-and-respect!68
2025-07-18 08:22:34 +00:00
Alexis Gousseau
312ca41b9c
fix: 🐛 repair model display error pages 2025-07-18 10:04:12 +02:00
noah.lancien
5195c59687 Merge branch 'duration' into 'develop'
fix: 🐛 update recipe duration type

See merge request ldc-web/projets/nature-and-respect!67
2025-07-17 15:08:38 +00:00
Alexis Gousseau
fe2379e302
fix: 🐛 update recipe duration type 2025-07-17 16:38:23 +02:00
noah.lancien
a5312f3a5a Merge branch 'validation' into 'develop'
fix: 🐛 validate recipe duration as a number

See merge request ldc-web/projets/nature-and-respect!65
2025-07-17 10:46:36 +00:00
Alexis Gousseau
18d8ce80b5
fix: 🐛 repair seo functionnalty in the back office 2025-07-17 11:58:12 +02:00
Alexis Gousseau
7599240975
fix: 🐛 validate recipe duration as a number 2025-07-17 11:57:57 +02:00
Noah Lancien
2c0456c735 ci: update image version + replace 443 port by 80 in manifest 2025-07-16 16:45:59 +02:00
noah.lancien
3092c16b2f Merge branch 'add-spatie-schema' into 'develop'
add spatie schema org plugin and uwil schema org laravel plugin and add jsonld...

See merge request ldc-web/projets/nature-and-respect!33
2025-07-16 14:26:52 +00:00
Alexis Gousseau
3df66b6874
feat: ✨ add schema org on needed models 2025-07-16 16:19:37 +02:00
Alexis Gousseau
385a408d83
fix: 🎨 format & clean code (models translations, methods' prototype, linters errors) 2025-07-10 16:56:33 +02:00
Alexis Gousseau
3b1d071943
chore: ⬆️ bump project to laravel 11 with php 8.3 2025-07-10 15:18:47 +02:00
noah.lancien
623fb37d39 Merge branch 'issue-47-feedback' into 'develop'
fix: replace haltungsform3 icon #47

See merge request ldc-web/projets/nature-and-respect!64
2025-04-08 15:27:33 +00:00
Corentin Huet
35f395bb58 fix: replace haltungsform3 icon 2025-04-08 16:46:30 +02:00
karl.muller
d636dcfaf6 Merge branch 'issue-47-logo' into 'develop'
feat: replace haltungsform 3 logo

See merge request ldc-web/projets/nature-and-respect!63
2025-04-02 14:39:00 +00:00
Corentin Huet
12d2545e9b feat: replace haltungsform 3 logo 2025-04-02 16:03:36 +02:00
noah.lancien
e4a7c9533f Merge branch 'issue-45-news-date' into 'develop'
fix: Updated publication date system

See merge request ldc-web/projets/nature-and-respect!62
2025-02-26 14:24:21 +00:00
Noah Lancien
2f87a92bfa fix: Updated publication date system 2025-02-26 13:02:02 +01:00
noah.lancien
240d6257a7 Merge branch 'issue-46-object-cover-on-news-images' into 'develop'
Issue 46 object cover on news images

See merge request ldc-web/projets/nature-and-respect!61
2025-02-25 14:21:45 +00:00
Noah Lancien
806262e8b7 fix: added object-fit cover on news index images 2025-02-25 10:42:16 +01:00
Karl Muller
bea39f3132 fix: change manifest for cron issue 2025-01-14 10:25:55 +00:00
noah.lancien
df019d230b Merge branch 'issues-43-44' into 'develop'
Issues 43 44

See merge request ldc-web/projets/nature-and-respect!60
2024-11-14 08:15:54 +00:00
Sebastien Hattry
91bab690d7 feat: 🍱 Add certification logos 2024-11-13 16:07:05 +01:00
Sebastien Hattry
69bebfc92a chore: auto formatting 2024-11-13 16:05:02 +01:00
Thibault Raquet
75469508a6 Update production-resources.yaml 2024-08-23 13:29:14 +00:00
Noah Lancien
390b38e43a Updated manifest.yaml 2024-08-01 08:51:55 +02:00
Noah Lancien
95e0efe6ff Merge branch 'bump-cn-6.0.3' into develop 2024-07-16 18:47:08 +02:00
Noah Lancien
7af694a6af Bumped cookie-notice to 6.0.3 2024-07-16 18:46:13 +02:00
Noah Lancien
9c22e8d16c Merge branch 'compsoer-update' into develop 2024-07-16 18:27:22 +02:00
Noah Lancien
2e59cc915b phpcs + phpstan 2024-07-16 18:21:29 +02:00
Noah Lancien
edb7206a1e chore: composer update 2024-07-16 18:10:06 +02:00
Louis Rossignol
31a19fc846 Merge branch 'trunk' into 'develop'
# Conflicts:
#   manifest.yaml
2024-07-04 08:42:22 +00:00
Thibault Raquet
c54ffd1e01 Add new file 2024-07-02 12:27:32 +00:00
Thibault Raquet
0fcf0b9ba4 Update manifest.yaml 2024-07-02 12:27:14 +00:00
Louis Rossignol
f76a855707 Add new file 2024-07-02 08:33:23 +00:00
Louis Rossignol
fc538f9668 Update manifest.yaml 2024-07-02 08:32:55 +00:00
Vincent BRIDIER
a040e1f31d Merge branch 'cn' into 'develop'
chore: ⬆️ bump @ldc-web/cookie-notice to 6.0.1

See merge request ldc-web/projets/nature-and-respect!48
2024-06-19 17:04:01 +00:00
Vincent BRIDIER
b4ecf09d1f Merge branch 'news-fix' into 'develop'
fix news

See merge request ldc-web/projets/nature-and-respect!50
2024-06-17 13:30:09 +00:00
Jérémy Munsch
21165b29e7
chore: ⬆️ bump @ldc-web/cookie-notice to 6.0.1 2024-06-17 15:25:26 +02:00
Jérémy Munsch
0b4e410e9d
fix news 2024-06-17 15:21:29 +02:00
Vincent BRIDIER
7bae433a1a
Merge branch 'develop' into trunk 2024-06-17 14:54:56 +02:00
Vincent BRIDIER
212b41a451 Merge branch 'fix-40-percent-issue' into 'develop'
Fix: #40 - Base64decode crashed when there was a '%' in a string

See merge request ldc-web/projets/nature-and-respect!49
2024-06-17 12:54:39 +00:00
Noah Lancien
23dc6307cd Fix: #40 - Base64decode crashed when there was a '%' in a string 2024-06-17 14:48:46 +02:00
Vincent BRIDIER
08b2d56f82
Merge branch 'develop' into trunk 2024-06-13 14:52:26 +02:00
Vincent BRIDIER
ac197b3827
Fix contact page 2024-06-13 14:52:17 +02:00
Vincent BRIDIER
a6ec394ade
Merge branch 'develop' into trunk 2024-06-12 16:01:33 +02:00
Vincent BRIDIER
edcfc912c5
Fix cookie translations 2024-06-12 16:01:21 +02:00
Vincent BRIDIER
3335cf8634
Merge branch 'develop' into trunk 2024-06-10 15:53:20 +02:00
Vincent BRIDIER
d205e51337 Merge branch 'cn' into 'develop'
contact link

See merge request ldc-web/projets/nature-and-respect!47
2024-06-10 13:53:08 +00:00
Jérémy Munsch
388ab64000 contact link 2024-06-10 13:53:08 +00:00
Vincent BRIDIER
6dd90e283d
Merge branch 'develop' into trunk 2024-06-10 15:01:06 +02:00
Vincent BRIDIER
5365906e27 Merge branch 'cn' into 'develop'
Cn

See merge request ldc-web/projets/nature-and-respect!46
2024-06-10 13:00:41 +00:00
Jérémy Munsch
e1c971ef13
add missing i18n string 2024-06-10 14:57:50 +02:00
Jérémy Munsch
a77ace0615
Closes #38 2024-06-10 14:00:19 +02:00
Jérémy Munsch
0ba88f51eb
Closes #37 2024-06-10 13:58:45 +02:00
Jérémy Munsch
c08266d81b
Closes #39 2024-06-10 13:46:46 +02:00
Vincent BRIDIER
af65a8d458
Merge branch 'develop' into trunk 2024-06-10 12:37:40 +02:00
Vincent BRIDIER
f5d1a8d215 Merge branch 'cn' into 'develop'
Cn

See merge request ldc-web/projets/nature-and-respect!45
2024-06-10 10:36:23 +00:00
Jérémy Munsch
d6f82c9df1
Closes #39 2024-06-10 11:03:04 +02:00
Jérémy Munsch
c081208cd3
feat: Bump cn to 5.x and inline Closes #38,#37 2024-06-10 11:02:59 +02:00
Jérémy Munsch
01463b185e
Merge remote-tracking branch 'origin/phpstan+rgpd2k24' into cn 2024-06-10 09:52:06 +02:00
Jérémy Munsch
7b659d3120
Merge remote-tracking branch 'origin/issue-35-rgpd' into cn 2024-06-10 09:51:27 +02:00
Noah Lancien
222347d890 phpstan 2024-01-29 16:20:14 +01:00
Noah Lancien
2104c27427 Updated CN to 4.0.0 + Added Static pages CRUD 2024-01-03 15:30:10 +01:00
Vincent BRIDIER
bdb2f9c149
Merge branch 'develop' into trunk 2023-12-12 12:16:26 +01:00
Vincent BRIDIER
4a145cd8f4 Merge branch 'ts-1857' into 'develop'
added language management for sliders

See merge request ldc-web/projets/nature-and-respect!42
2023-12-12 11:15:57 +00:00
nicolas.demangeat
252e067cbb added language management for sliders 2023-12-12 11:15:57 +00:00
Vincent BRIDIER
4f8975e4ed Update manifest 2023-12-11 11:15:14 +00:00
Vincent BRIDIER
072ceae5b2
Merge branch 'develop' into trunk 2023-09-13 08:55:21 +02:00
Vincent BRIDIER
1a516842c3
Tmp remove admin-secure middleware for bo 2023-09-13 08:55:03 +02:00
Vincent BRIDIER
c8947adc5b
Add NewsStatusUpdate to kernel 2023-09-13 08:54:41 +02:00
Vincent BRIDIER
0beacf4846
Merge branch 'develop' into trunk 2023-09-11 18:08:03 +02:00
Vincent BRIDIER
25ad0e6f1d
Update Nature & Respect 2023-09-11 18:07:50 +02:00
Vincent BRIDIER
a0581cb398
Merge branch 'develop' into trunk 2023-09-11 17:18:35 +02:00
Vincent BRIDIER
b8956d5653 Merge branch 'issue-33-news-index' into 'develop'
Issue 33 - news.index wording and first picture is now required

See merge request ldc-web/projets/nature-and-respect!41
2023-09-11 15:17:18 +00:00
Noah Lancien
b882a81053 News first picture is now required 2023-09-11 15:18:20 +02:00
Noah Lancien
9916a0f348 Replaced lorem ipsum with given text in news.index 2023-09-11 15:16:56 +02:00
Vincent BRIDIER
a7469de5c6
Merge branch 'develop' into trunk 2023-09-06 14:36:52 +02:00
Vincent BRIDIER
9e846933d7
Update for UWIL 2023-09-06 14:35:50 +02:00
Vincent BRIDIER
e155a26d2a
Fix SEO Laravel 2023-09-06 14:35:33 +02:00
Vincent BRIDIER
b5de55f31f
Composer update 2023-09-06 13:14:34 +02:00
Vincent BRIDIER
cfb74382a9 Merge branch 'admin-secure' into 'develop'
Add ldc/web-admin-secure-laravel

See merge request ldc-web/projets/nature-and-respect!20
2023-09-06 11:09:42 +00:00
Jérémy Munsch
6c9e430566 Add ldc/web-admin-secure-laravel 2023-09-06 11:09:42 +00:00
Vincent BRIDIER
c43c1559cd Merge branch 'issue-32' into 'develop'
add news status column on index page - issue #32

See merge request ldc-web/projets/nature-and-respect!37
2023-09-06 11:04:37 +00:00
Vincent BRIDIER
18d7357219 Merge branch 'issue-31' into 'develop'
update navigation - issue #31

See merge request ldc-web/projets/nature-and-respect!38
2023-09-06 10:56:29 +00:00
Vincent BRIDIER
8454328693 Merge branch 'issue-29' into 'develop'
update images in different languages - issue #29

See merge request ldc-web/projets/nature-and-respect!36
2023-09-06 10:53:44 +00:00
Alexis Gousseau
59ea6fcb23 update images in different languages - issue #29 2023-09-06 10:53:44 +00:00
Vincent BRIDIER
0559b21b89 Merge branch 'issue-27' into 'develop'
update news header banner - issue #27

See merge request ldc-web/projets/nature-and-respect!35
2023-09-06 10:46:22 +00:00
Vincent BRIDIER
66ccd487ce Merge branch 'issue-28' into 'develop'
update images in different languages - issue #28

See merge request ldc-web/projets/nature-and-respect!39
2023-09-06 10:44:07 +00:00
Alexis Gousseau
7fbddaca24 update images in different languages - issue #28 2023-09-06 10:44:07 +00:00
Vincent BRIDIER
e5efdb32fc Merge branch 'issue-30' into 'develop'
fix translation - issue #30

See merge request ldc-web/projets/nature-and-respect!40
2023-09-06 10:23:59 +00:00
Alexis Gousseau
071a3e05c2 fix translation - issue #30 2023-09-06 10:23:59 +00:00
Vincent BRIDIER
62571fcec6 Merge branch 'update-lang-switch-redirection' into 'develop'
Lang switchs now redirect to the same page with the selected lang

See merge request ldc-web/projets/nature-and-respect!29
2023-09-06 10:18:25 +00:00
noah.lancien
831698f44b Lang switchs now redirect to the same page with the selected lang 2023-09-06 10:18:25 +00:00
Vincent BRIDIER
7cc2acc252
Merge branch 'develop' into trunk 2023-09-05 18:06:58 +02:00
Vincent BRIDIER
4299a7834f
Bump codezero/laravel-localized-routes 2023-09-05 18:05:44 +02:00
Alexis Gousseau
950e1f1b47 update navigation - issue #31 2023-08-30 13:01:14 +02:00
Alexis Gousseau
af56adc577 add news status column on index page - issue #32 2023-08-30 12:25:37 +02:00
Alexis Gousseau
b76dd6e9f9 update news header banner - issue #27 2023-08-30 11:41:41 +02:00
Vincent BRIDIER
61efed1f74
Merge branch 'develop' into trunk 2023-08-14 10:22:01 +02:00
Vincent BRIDIER
295e4eb2e1 Merge branch '26-fix-concept-toseoitem' into 'develop'
Resolve "Fix Concept toSeoItem"

Closes #26

See merge request ldc-web/projets/nature-and-respect!32
2023-08-14 08:20:49 +00:00
Nicolas Demangeat
feaf9fd9d4 add toSeoItem in concept model 2023-08-14 10:07:57 +02:00
Vincent BRIDIER
bdba7bb889 Merge branch 'bugfix-nav' into 'develop'
add href link to home link

See merge request ldc-web/projets/nature-and-respect!31
2023-08-11 07:59:41 +00:00
Nicolas Demangeat
e4cdc7c652 add href link to home link 2023-08-10 16:53:40 +02:00
Vincent BRIDIER
b4578d1f75
Merge branch 'develop' into trunk 2023-08-10 14:51:33 +02:00
Vincent BRIDIER
601a5e967b Merge branch 'issue-24' into 'develop'
Issue 24

Closes #24

See merge request ldc-web/projets/nature-and-respect!30
2023-07-28 14:29:01 +00:00
Sebastien Hattry
436bdb40ab Have the right labels in the right places 2023-07-28 13:29:54 +00:00
Sebastien Hattry
7aee1fd616 npm audit fix 2023-07-28 13:11:35 +00:00
Vincent BRIDIER
9ccbfb41f6 Merge branch 'seo' into 'develop'
See merge request ldc-web/projets/nature-and-respect!28
2023-07-11 09:57:55 +00:00
nicolas.demangeat
87142052e9 Add SEO Package 2023-07-11 09:57:55 +00:00
Vincent BRIDIER
47bc061878 Merge branch 'bump_laravel_k8s' into 'develop'
bump laravel k8s

See merge request ldc-web/projets/nature-and-respect!27
2023-07-04 11:01:03 +00:00
Nicolas Demangeat
0ec9228a43 bump laravel k8s 2023-07-04 12:35:23 +02:00
Vincent BRIDIER
d4360b486f
Merge branch 'develop' into trunk 2023-07-03 18:58:31 +02:00
Vincent BRIDIER
cbf82481ce
Update HTACCESS 2023-07-03 18:58:21 +02:00
Vincent BRIDIER
086a5c8461
Merge branch 'develop' into trunk 2023-07-03 15:24:00 +02:00
Vincent BRIDIER
ac5164ab29
Update manifest 2023-07-03 15:12:09 +02:00
Vincent BRIDIER
ea8541209a Merge branch 'issue-23' into 'develop'
fix home route with parameters - issue #23

Closes #23

See merge request ldc-web/projets/nature-and-respect!26
2023-06-29 09:12:41 +00:00
Alexis Gousseau
8988559c68 fix home route with parameters - issue #23 2023-06-29 11:06:57 +02:00
Vincent BRIDIER
09803e015c
Merge branch 'develop' into trunk 2023-06-23 12:32:22 +02:00
Vincent BRIDIER
1420bb52e6 Merge branch 'news' into 'develop'
Fix error 500 in News

Closes #22

See merge request ldc-web/projets/nature-and-respect!24
2023-06-23 10:22:12 +00:00
Vincent BRIDIER
1039d91f18 Merge branch 'fix-list-item-component' into 'develop'
Replaced code in template by computed values (like lionor)

See merge request ldc-web/projets/nature-and-respect!25
2023-06-23 10:18:51 +00:00
Noah Lancien
28f4baa8e3 Replaced code in template by computed values (like lionor) 2023-06-23 11:36:16 +02:00
Noah Lancien
ce62ad8020 Fixed publish/unpublish_date for news and in the input 2023-06-15 16:45:00 +02:00
Vincent BRIDIER
53a77e8a0e fix translations 2023-06-15 14:26:33 +00:00
Jérémy Munsch
7f1cf742a7
Add missing planificated_status virtual fields on News 2023-06-15 15:51:48 +02:00
Vincent BRIDIER
f5f2f511fe
Merge branch 'develop' into trunk 2023-06-14 08:45:51 +02:00
Vincent BRIDIER
6043f7c8cc
Fixe #21 - News deletion 2023-06-14 08:45:09 +02:00
Vincent BRIDIER
0b3e487636
Merge branch 'develop' into trunk 2023-06-13 18:31:18 +02:00
Vincent BRIDIER
6fbad46d90
some fixes 2023-06-13 18:29:23 +02:00
Jérémy Munsch
5cfbb17f7b
Concept + News Fix 2023-06-13 13:13:56 +02:00
Jérémy Munsch
c9ca0b17bf
Minicrud fix 2023-06-13 13:12:51 +02:00
Vincent BRIDIER
8d83cd3b4d
some fixes 2023-06-13 11:51:00 +02:00
Jérémy Munsch
d58d0e5f2a
phpcs remove comment 2023-06-09 11:00:40 +02:00
Jérémy Munsch
0417c73d4a
Implements #19 News show 2023-06-09 11:00:40 +02:00
Jérémy Munsch
c1369ea508
Implements #18 News.index
- Add toastify css to front
- Bump kwaadpepper/image-resizer with fit option
- Enhance news picture size to 770x770
2023-06-09 11:00:40 +02:00
Jérémy Munsch
9ce41966bc
Implements #17 Add News Model BO 2023-06-09 10:57:28 +02:00
Jérémy Munsch
67e1273128 Merge branch 'issue-20' into 'develop'
Fixed lang selector : now responsive

Closes #20

See merge request ldc-web/projets/nature-and-respect!23
2023-06-09 08:55:28 +00:00
Noah Lancien
3857f1ab79 Closes #20 lang selector : now responsive 2023-06-09 10:47:09 +02:00
Vincent BRIDIER
61c00d0bb0
Merge branch 'develop' into trunk 2023-06-05 11:01:34 +02:00
Vincent BRIDIER
998f7e0a8a Merge branch 'fixes' into 'develop'
404 PAGE

See merge request ldc-web/projets/nature-and-respect!19
2023-06-05 09:00:45 +00:00
Jérémy Munsch
568ebb9f2d
404 PAGE
- Add second layout as minimal for front (we have 2 to maintain)
- set links as optional  (Do not throw 404 from layout)
- Keep 404 as standard as possible
2023-06-05 09:38:33 +02:00
Jérémy Munsch
0468e10854
refresh sitemap config set only published elements 2023-06-05 09:17:38 +02:00
Vincent BRIDIER
29b9351a9a
Merge branch 'develop' into trunk 2023-06-02 13:22:22 +02:00
Vincent BRIDIER
6e51fe7bda
Merge branch 'develop' into trunk 2023-06-02 13:06:56 +02:00
Vincent BRIDIER
1092009f1b
Merge branch 'develop' into trunk 2023-06-02 12:26:13 +02:00
Vincent BRIDIER
3ecd7c8d08
Merge branch 'develop' into trunk 2023-06-01 17:12:11 +02:00
Vincent BRIDIER
f5d46c4983
Merge branch 'develop' into trunk 2023-06-01 16:36:58 +02:00
Vincent BRIDIER
1a6be8daa5
Merge branch 'develop' into trunk 2023-06-01 15:32:17 +02:00
Jérémy Munsch
17963e0adb
Merge branch 'develop' into trunk 2023-06-01 09:36:24 +02:00
Jérémy Munsch
33d43d773d
Merge branch 'develop' into trunk 2023-05-31 17:37:40 +02:00
Jérémy Munsch
dd8be91b33
Merge branch 'develop' into trunk 2023-05-31 17:28:38 +02:00
Jérémy Munsch
c62fb96b58
Merge branch 'develop' into trunk 2023-05-31 15:16:39 +02:00
Vincent BRIDIER
93356592e8
Merge branch 'develop' into trunk 2023-05-31 15:06:44 +02:00
Jérémy Munsch
488daea476
Merge branch 'develop' into trunk 2023-05-31 13:38:51 +02:00
Jérémy Munsch
0196d9ed6a
Revert useless patch 2023-05-31 13:38:40 +02:00
Jérémy Munsch
8c449dce0e
Merge branch 'develop' into trunk 2023-05-31 11:04:52 +02:00
Jérémy Munsch
a3f3355359
concept fix display 2023-05-31 11:04:21 +02:00
Jérémy Munsch
f7fbd63f7e
Merge branch 'develop' into trunk 2023-05-31 10:02:25 +02:00
Jérémy Munsch
cfb4b54763
Merge branch 'develop' into trunk 2023-05-30 22:13:01 +02:00
Vincent BRIDIER
4cd9204c19
Merge branch 'develop' into trunk 2023-05-30 21:41:26 +02:00
Vincent BRIDIER
a12d617e69
Merge branch 'develop' into trunk 2023-05-30 18:00:00 +02:00
Vincent BRIDIER
058675f072
Merge branch 'develop' into trunk 2023-05-30 13:51:41 +02:00
Vincent BRIDIER
416c1638a9
Merge branch 'develop' into trunk 2023-05-30 12:42:25 +02:00
Vincent BRIDIER
214f8379bf
Merge branch 'develop' into trunk 2023-05-30 11:23:20 +02:00
Vincent BRIDIER
24a2e32339
Merge branch 'develop' into trunk 2023-05-30 10:59:19 +02:00
Vincent BRIDIER
2057e53ee2
Merge branch 'develop' into trunk 2023-05-26 18:35:20 +02:00
Vincent BRIDIER
2b1ef6ea31
Merge branch 'develop' into trunk 2023-05-26 18:02:01 +02:00
Jérémy Munsch
b171f3a68a
Merge branch 'develop' into trunk 2023-05-15 14:24:19 +02:00
Jérémy Munsch
052b73713e
Merge branch 'develop' into trunk 2023-05-15 12:56:04 +02:00
Jérémy Munsch
82710ddf17
Merge branch 'develop' into trunk 2023-05-15 10:54:45 +02:00
Vincent BRIDIER
74b8899be7
Merge branch 'develop' into trunk 2023-05-10 15:32:29 +02:00
Vincent BRIDIER
2cf5dcd6fd
Merge branch 'develop' into trunk 2023-05-10 14:48:46 +02:00
Vincent BRIDIER
453c4e2895
Merge branch 'develop' into trunk 2023-05-10 14:27:51 +02:00
Vincent BRIDIER
79ddb51a74
Merge branch 'develop' into trunk 2023-05-10 12:37:21 +02:00
Vincent BRIDIER
df72fd8622
Merge branch 'develop' into trunk 2023-05-10 12:23:34 +02:00
Olivier Legat
cb1461704b Merge branch 'develop' into trunk 2021-11-24 12:06:15 +01:00
284 changed files with 17008 additions and 9540 deletions

View file

@ -46,3 +46,10 @@ GOOGLE_RECAPTCHA_PRIVATE=6LeQxHoUAAAAAOudkLY90DerM_ZtlaFfzTlJJvIo
GOOGLE_RECAPTCHA_VERSION=2
# - MAPS
GOOGLE_MAPS_KEY=
# UWIL ADMIN SECURE
# - LIST SEPARATED WITH ',' (Required)
UWIL_ADMIN_SECURE_CIDR_LIST=""
# - LIST SEPARATED WITH ',' (Optional)
UWIL_ADMIN_SECURE_CIDR_PROJECT_ALLOWED_LIST=""

2
.husky/commit-msg Normal file
View file

@ -0,0 +1,2 @@
#!/bin/sh
npx commitlint --config node_modules/@uwil/husky-config/commitlint.config.js --edit $1

View file

@ -1,4 +1,4 @@
FROM registry.s-web.fr/ldc-web/projets/ldc-web-images-docker/ldcweb-production-8.2:latest
FROM registry.s-web.fr/ldc-web/projets/ldc-web-images-docker/uwil-production-8.5:${PHP_8_5_TAG}
COPY --chown=www-data:www-data . /app/srcs
COPY --chown=www-data:www-data ./public/build /app/srcs/public/build
COPY --chown=www-data:www-data ./vendor /app/srcs/vendor

View file

@ -26,28 +26,28 @@ class CreateAdmin extends Command
/**
* The firstname of the new user.
*
* @var string
* @var string|null
*/
protected $firstname;
/**
* The lastname of the new user.
*
* @var string
* @var string|null
*/
protected $lastname;
/**
* The email of the new user.
*
* @var string
* @var string|null
*/
protected $email;
/**
* The password of the new user.
*
* @var string
* @var string|null
*/
protected $password;

View file

@ -2,6 +2,7 @@
namespace App\Console;
use App\Jobs\NewsStatusUpdate;
use App\Jobs\SlidersStatusUpdate;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
@ -17,6 +18,7 @@ class Kernel extends ConsoleKernel
protected function schedule(Schedule $schedule)
{
$schedule->job(SlidersStatusUpdate::class)->everyMinute();
$schedule->job(NewsStatusUpdate::class)->everyMinute();
}
/**

View file

@ -21,10 +21,7 @@ enum InputType: int
case string = 11;
case text = 12;
case url = 13;
/** Vimeo only */
case videoVimeo = 14;
/** Youtube only */
case videoYoutube = 15;
/** Youtube or Vimeo. */
case video = 16;
}

View file

@ -4,19 +4,31 @@ namespace App\Enums\Products;
use App\Traits\Enums\BaseEnum;
enum CertificationsEnum : int
enum CertificationsEnum: int
{
use BaseEnum;
case haltungsform3 = 3;
case haltungsform4 = 4;
case ecc = 5;
case nutriscoreA = 6;
case nutriscoreB = 7;
case nutriscoreC = 8;
case nutriscoreD = 9;
case nutriscoreE = 10;
/**
* Custom added images definition
*/
private const IMAGES = [
self::haltungsform3->name => "haltungsform3.png",
self::haltungsform4->name => "haltungsform4.png",
self::ecc->name => "ECC-Logo-green.svg",
self::nutriscoreA->name => "nutriscore-a.png",
self::nutriscoreB->name => "nutriscore-b.png",
self::nutriscoreC->name => "nutriscore-c.png",
self::nutriscoreD->name => "nutriscore-d.png",
self::nutriscoreE->name => "nutriscore-e.png",
];
/**

View file

@ -0,0 +1,56 @@
<?php
namespace App\Enums;
use App\Traits\Enums\BaseEnum;
enum StaticPageType: int
{
use BaseEnum;
case contact = 1;
case legals = 2;
case confidentiality = 3;
case home = 4;
case products = 5;
case product = 6;
case recipes = 7;
case recipe = 8;
case newsPlural = 9;
case newsSingular = 10;
case concept = 11;
case store = 12;
/**
* Optionnal labels definition.
*
* @phpstan-ignore-next-line
*/
private const LABELS = [
self::contact->name => 'enums.static_page_type.contact',
self::legals->name => 'enums.static_page_type.legals',
self::confidentiality->name => 'enums.static_page_type.confidentiality',
self::home->name => 'enums.static_page_type.home',
self::products->name => 'enums.static_page_type.products',
self::product->name => 'enums.static_page_type.product',
self::recipes->name => 'enums.static_page_type.recipes',
self::recipe->name => 'enums.static_page_type.recipe',
self::newsPlural->name => 'enums.static_page_type.newsPlural',
self::newsSingular->name => 'enums.static_page_type.newsSingular',
self::concept->name => 'enums.static_page_type.concept',
self::store->name => 'enums.static_page_type.store',
];
/**
* Get all editable pages.
*
* @return array
*/
public static function getEditableContentPages(): array
{
return [
self::legals,
self::confidentiality,
];
}
}

View file

@ -21,9 +21,9 @@ class ConceptController extends Controller
* Display a listing of the resource.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View
*/
public function index(Request $request)
public function index(Request $request): \Illuminate\Contracts\View\View
{
/** @var \Illuminate\Database\Eloquent\Builder $concepts */
$concepts = Concept::query();
@ -51,9 +51,9 @@ class ConceptController extends Controller
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
*/
public function create()
public function create(): \Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
{
if (Concept::count() === 8) {
return back()
@ -61,7 +61,7 @@ class ConceptController extends Controller
'error',
trans(
'You already created 8 :models. Please delete or edit an existing one.',
['models' => trans('models.classes.concepts')]
['models' => Str::of(trans('models.classes.concept'))->plural()]
)
);
}
@ -73,9 +73,9 @@ class ConceptController extends Controller
* Store a newly created resource in storage.
*
* @param \App\Http\Requests\Bo\Concepts\StoreConceptRequest $request
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function store(StoreConceptRequest $request)
public function store(StoreConceptRequest $request): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request) {
$concept = new Concept();
@ -90,14 +90,14 @@ class ConceptController extends Controller
->route('bo.concepts.edit', $concept)
->with('success', trans(
'crud.messages.has_been_created',
['model' => Str::singular(trans('models.classes.concepts'))]
['model' => trans('models.classes.concept')]
));
}
return redirect()
->back()
->with('error', trans(
'crud.messages.cannot_be_created',
['model' => Str::singular(trans('models.classes.concepts'))]
['model' => trans('models.classes.concept')]
));
});
}
@ -106,9 +106,9 @@ class ConceptController extends Controller
* Show the form for editing the specified resource.
*
* @param \App\Models\Concept $concept
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View
*/
public function edit(Concept $concept)
public function edit(Concept $concept): \Illuminate\Contracts\View\View
{
return view('bo.pages.concepts.edit', [
'conceptModel' => $concept
@ -120,9 +120,9 @@ class ConceptController extends Controller
*
* @param \App\Http\Requests\Bo\Concepts\UpdateConceptRequest $request
* @param \App\Models\Concept $concept
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function update(UpdateConceptRequest $request, Concept $concept)
public function update(UpdateConceptRequest $request, Concept $concept): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request, $concept) {
$concept->fill(array_replace_recursive(
@ -135,14 +135,14 @@ class ConceptController extends Controller
->route('bo.concepts.edit', $concept)
->with('success', trans(
'crud.messages.has_been_updated',
['model' => Str::singular(trans('models.classes.concepts'))]
['model' => trans('models.classes.concept')]
));
}
return redirect()
->back()
->with('error', trans(
'crud.messages.cannot_be_updated',
['model' => Str::singular(trans('models.classes.concepts'))]
['model' => trans('models.classes.concept')]
));
});
}
@ -151,23 +151,23 @@ class ConceptController extends Controller
* Remove the specified resource from storage.
*
* @param \App\Models\Concept $concept
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy(Concept $concept)
public function destroy(Concept $concept): \Illuminate\Http\RedirectResponse
{
if ($concept->deleteOrFail()) {
return redirect()
->route('bo.concepts.index')
->with('success', trans(
'crud.messages.has_been_deleted',
['model' => Str::singular(trans('models.classes.concepts'))]
['model' => trans('models.classes.concept')]
));
}
return redirect()
->back()
->with('error', trans(
':crud.messages.cannot_be_deleted',
['model' => Str::singular(trans('models.classes.concepts'))]
['model' => trans('models.classes.concept')]
));
}
}

View file

@ -6,20 +6,16 @@ use App\Http\Controllers\Controller;
use App\Http\Requests\Bo\Homes\UpdateHomeRequest;
use App\Models\Home;
use App\Models\Product;
use App\Traits\Requests\HasPicture;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
class HomeController extends Controller
{
use HasPicture;
/**
* Display a listing of the resource.
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
* @return \Illuminate\Contracts\View\View
*/
public function edit()
public function edit(): \Illuminate\Contracts\View\View
{
$homeModel = Home::query()->firstOrFail();
$products = Product::query()->where('status', true)->orderBy('label', 'ASC')->get();
@ -32,9 +28,9 @@ class HomeController extends Controller
*
* @param \App\Http\Requests\Bo\Homes\UpdateHomeRequest $request
* @param \App\Models\Home $home
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function update(UpdateHomeRequest $request, Home $home)
public function update(UpdateHomeRequest $request, Home $home): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request, $home) {
$data = $request->validated();
@ -44,12 +40,12 @@ class HomeController extends Controller
->route('bo.homes.edit', $home)
->with('success', trans(
'crud.messages.has_been_updated',
['model' => Str::singular(trans('models.classes.homes'))]
['model' => trans('models.classes.home')]
));
} //end if
return back()->with('success', trans(
'crud.messages.cannot_be_updated',
['model' => Str::singular(trans('models.classes.homes'))]
['model' => trans('models.classes.home')]
));
});
}

View file

@ -0,0 +1,163 @@
<?php
namespace App\Http\Controllers\Bo;
use App\Http\Controllers\Controller;
use App\Http\Requests\Bo\News\StoreNewsRequest;
use App\Http\Requests\Bo\News\UpdateNewsRequest;
use App\Models\News;
use App\Traits\Controllers\ChangesModelOrder;
use App\Traits\Controllers\UpdateModelStatus;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
class NewsController extends Controller
{
use ChangesModelOrder;
use UpdateModelStatus;
/**
* Display a listing of the resource.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Contracts\View\View
*/
public function index(Request $request): \Illuminate\Contracts\View\View
{
/** @var \Illuminate\Database\Eloquent\Builder $news */
$news = News::query();
if ($request->search) {
$this->searchQuery(
$news,
$request->search,
null,
'seo_title',
'title',
'subtitle',
);
}
$this->sortQuery($news);
$searchFields = trans('SEO title, Title, subtitle');
$newsListModels = $news->paginate(10);
return view('bo.pages.news.index', compact('newsListModels', 'searchFields'));
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Contracts\View\View
*/
public function create(): \Illuminate\Contracts\View\View
{
return view('bo.pages.news.create');
}
/**
* Store a newly created resource in storage.
*
* @param \App\Http\Requests\Bo\News\StoreNewsRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
public function store(StoreNewsRequest $request): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request) {
$news = new News();
$news->data = News::getEmptyData();
$news->fill(array_replace_recursive(
\json_decode(\json_encode($news->toArray()), true),
$request->validated()
));
if ($news->saveOrFail()) {
return redirect()
->route('bo.news.edit', $news)
->with('success', trans(
'crud.messages.has_been_created',
['model' => Str::singular(trans('models.classes.news'))]
));
}
return redirect()
->back()
->with('error', trans(
'crud.messages.cannot_be_created',
['model' => Str::singular(trans('models.classes.news'))]
));
});
}
/**
* Show the form for editing the specified resource.
*
* @param \App\Models\News $news
* @return \Illuminate\Contracts\View\View
*/
public function edit(News $news): \Illuminate\Contracts\View\View
{
return view('bo.pages.news.edit', [
'newsModel' => $news
]);
}
/**
* Update the specified resource in storage.
*
* @param \App\Http\Requests\Bo\News\UpdateNewsRequest $request
* @param \App\Models\News $news
* @return \Illuminate\Http\RedirectResponse
*/
public function update(UpdateNewsRequest $request, News $news): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request, $news) {
$news->fill(array_replace_recursive(
\json_decode(\json_encode($news->toArray()), true),
$request->validated()
));
$news->locales = $request->locales;
if ($news->saveOrFail()) {
return redirect()
->route('bo.news.edit', $news)
->with('success', trans(
'crud.messages.has_been_updated',
['model' => Str::singular(trans('models.classes.news'))]
));
}
return redirect()
->back()
->with('error', trans(
'crud.messages.cannot_be_updated',
['model' => Str::singular(trans('models.classes.news'))]
));
});
}
/**
* Remove the specified resource from storage.
*
* @param \App\Models\News $news
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy(News $news): \Illuminate\Http\RedirectResponse
{
if ($news->deleteOrFail()) {
return redirect()
->route('bo.news.index')
->with('success', trans(
'crud.messages.has_been_deleted',
['model' => Str::singular(trans('models.classes.news'))]
));
}
return redirect()
->back()
->with('error', trans(
':crud.messages.cannot_be_deleted',
['model' => Str::singular(trans('models.classes.news'))]
));
}
}

View file

@ -10,24 +10,21 @@ use App\Models\Product;
use App\Models\Range;
use App\Traits\Controllers\ChangesModelOrder;
use App\Traits\Controllers\UpdateModelStatus;
use App\Traits\Requests\HasPicture;
use Illuminate\Contracts\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
class ProductController extends Controller
{
use ChangesModelOrder;
use HasPicture;
use UpdateModelStatus;
/**
* Display a listing of the resource.
*
* @param \App\Http\Requests\ProductIndexFilterRequest $request
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View
*/
public function index(ProductIndexFilterRequest $request)
public function index(ProductIndexFilterRequest $request): \Illuminate\Contracts\View\View
{
/** @var \Illuminate\Database\Eloquent\Builder $product */
$product = Product::query();
@ -60,9 +57,9 @@ class ProductController extends Controller
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View
*/
public function create()
public function create(): \Illuminate\Contracts\View\View
{
$rangeModels = Range::orderBy('label', 'ASC')->get();
@ -73,14 +70,14 @@ class ProductController extends Controller
* Store a newly created resource in storage.
*
* @param \App\Http\Requests\Bo\Products\StoreProductRequest $request
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function store(StoreProductRequest $request)
public function store(StoreProductRequest $request): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request) {
$product = new Product();
$tmpNutrionnalValues = \collect($request->validated()['nutritionnal_values']);
$tmpList = \collect($request->validated()['list']);
$tmpNutrionnalValues = $request->validated()['nutritionnal_values'];
$tmpList = $request->validated()['list'];
$product->fill($request->validated());
$product->nutritionnal_values = $tmpNutrionnalValues;
$product->list = $tmpList;
@ -90,14 +87,14 @@ class ProductController extends Controller
->route('bo.products.edit', $product)
->with('success', trans(
'crud.messages.has_been_created',
['model' => Str::singular(trans('models.classes.products'))]
['model' => trans('models.classes.product')]
));
}
return redirect()
->back()
->with('error', trans(
'crud.messages.cannot_be_created',
['model' => Str::singular(trans('models.classes.products'))]
['model' => trans('models.classes.product')]
));
});
}
@ -106,9 +103,9 @@ class ProductController extends Controller
* Display a listing of the resource.
*
* @param \App\Models\Product $product
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
* @return \Illuminate\Contracts\View\View
*/
public function edit(Product $product)
public function edit(Product $product): \Illuminate\Contracts\View\View
{
$rangeModels = Range::orderBy('label', 'ASC')->get();
@ -123,13 +120,13 @@ class ProductController extends Controller
*
* @param \App\Http\Requests\Bo\Products\UpdateProductRequest $request
* @param \App\Models\Product $product
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function update(UpdateProductRequest $request, Product $product)
public function update(UpdateProductRequest $request, Product $product): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request, $product) {
$tmpNutrionnalValues = \collect($request->validated()['nutritionnal_values']);
$tmpList = \collect($request->validated()['list']);
$tmpNutrionnalValues = $request->validated()['nutritionnal_values'];
$tmpList = $request->validated()['list'];
$product->fill($request->validated());
$product->nutritionnal_values = $tmpNutrionnalValues;
$product->list = $tmpList;
@ -138,14 +135,14 @@ class ProductController extends Controller
->route('bo.products.edit', $product)
->with('success', trans(
'crud.messages.has_been_updated',
['model' => Str::singular(trans('models.classes.products'))]
['model' => trans('models.classes.product')]
));
} //end if
return redirect()
->back()
->with('error', trans(
'crud.messages.cannot_be_updated',
['model' => Str::singular(trans('models.classes.products'))]
['model' => trans('models.classes.product')]
));
});
}
@ -154,9 +151,9 @@ class ProductController extends Controller
* Remove the specified resource from storage.
*
* @param \App\Models\Product $product
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy(Product $product)
public function destroy(Product $product): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($product) {
$product->recipes()->detach();
@ -165,14 +162,14 @@ class ProductController extends Controller
->route('bo.products.index')
->with('success', trans(
'crud.messages.has_been_deleted',
['model' => Str::singular(trans('models.classes.products'))]
['model' => trans('models.classes.product')]
));
}
return redirect()
->back()
->with('error', trans(
':crud.messages.cannot_be_deleted',
['model' => Str::singular(trans('models.classes.products'))]
['model' => trans('models.classes.product')]
));
});
}

View file

@ -8,24 +8,21 @@ use App\Http\Requests\Bo\Ranges\UpdateRangeRequest;
use App\Models\Range;
use App\Traits\Controllers\UpdateModelStatus;
use App\Traits\Controllers\ChangesModelOrder;
use App\Traits\Requests\HasPicture;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
class RangeController extends Controller
{
use ChangesModelOrder;
use HasPicture;
use UpdateModelStatus;
/**
* Display a listing of the resource.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View
*/
public function index(Request $request)
public function index(Request $request): \Illuminate\Contracts\View\View
{
/** @var \Illuminate\Database\Eloquent\Builder $range */
$range = Range::query();
@ -50,9 +47,9 @@ class RangeController extends Controller
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View
*/
public function create()
public function create(): \Illuminate\Contracts\View\View
{
return view('bo.pages.ranges.create');
}
@ -61,9 +58,9 @@ class RangeController extends Controller
* Store a newly created resource in storage.
*
* @param \App\Http\Requests\Bo\Ranges\StoreRangeRequest $request
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function store(StoreRangeRequest $request)
public function store(StoreRangeRequest $request): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request) {
$range = new Range();
@ -74,14 +71,14 @@ class RangeController extends Controller
->route('bo.ranges.edit', $range)
->with('success', trans(
'crud.messages.has_been_created',
['model' => Str::singular(trans('models.classes.ranges'))]
['model' => trans('models.classes.range')]
));
}
return redirect()
->back()
->with('error', trans(
'crud.messages.cannot_be_created',
['model' => Str::singular(trans('models.classes.ranges'))]
['model' => trans('models.classes.range')]
));
});
}
@ -90,9 +87,9 @@ class RangeController extends Controller
* Display a listing of the resource.
*
* @param \App\Models\Range $range
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
* @return \Illuminate\Contracts\View\View
*/
public function edit(Range $range)
public function edit(Range $range): \Illuminate\Contracts\View\View
{
return view('bo.pages.ranges.edit', ['rangeModel' => $range]);
}
@ -102,9 +99,9 @@ class RangeController extends Controller
*
* @param \App\Http\Requests\Bo\Ranges\UpdateRangeRequest $request
* @param \App\Models\Range $range
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function update(UpdateRangeRequest $request, Range $range)
public function update(UpdateRangeRequest $request, Range $range): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request, $range) {
$range->fill($request->validated());
@ -113,7 +110,7 @@ class RangeController extends Controller
->route('bo.ranges.edit', $range)
->with('success', trans(
'crud.messages.has_been_updated',
['model' => Str::singular(trans('models.classes.ranges'))]
['model' => trans('models.classes.range')]
));
} //end if
return back();
@ -124,23 +121,23 @@ class RangeController extends Controller
* Remove the specified resource from storage.
*
* @param \App\Models\Range $range
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy(Range $range)
public function destroy(Range $range): \Illuminate\Http\RedirectResponse
{
if ($range->deleteOrFail()) {
return redirect()
->route('bo.ranges.index')
->with('success', trans(
'crud.messages.has_been_deleted',
['model' => Str::singular(trans('models.classes.ranges'))]
['model' => trans('models.classes.range')]
));
}
return redirect()
->back()
->with('error', trans(
':crud.messages.cannot_be_deleted',
['model' => Str::singular(trans('models.classes.ranges'))]
['model' => trans('models.classes.range')]
));
}
}

View file

@ -9,24 +9,21 @@ use App\Models\Range;
use App\Models\Recipe;
use App\Traits\Controllers\UpdateModelStatus;
use App\Traits\Controllers\ChangesModelOrder;
use App\Traits\Requests\HasPicture;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
class RecipeController extends Controller
{
use ChangesModelOrder;
use HasPicture;
use UpdateModelStatus;
/**
* Display a listing of the resource.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View
*/
public function index(Request $request)
public function index(Request $request): \Illuminate\Contracts\View\View
{
/** @var \Illuminate\Database\Eloquent\Builder $recipe */
$recipe = Recipe::query();
@ -51,9 +48,9 @@ class RecipeController extends Controller
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View
*/
public function create()
public function create(): \Illuminate\Contracts\View\View
{
$rangeModels = Range::orderBy('order', 'ASC')->get();
@ -64,13 +61,13 @@ class RecipeController extends Controller
* Store a newly created resource in storage.
*
* @param \App\Http\Requests\Bo\Recipes\StoreRecipeRequest $request
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function store(StoreRecipeRequest $request)
public function store(StoreRecipeRequest $request): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request) {
$recipe = new Recipe();
$tmpIngredients = \collect($request->validated()['ingredients'])->sortKeys();
$tmpIngredients = \collect($request->validated()['ingredients'])->sortKeys()->toArray();
$recipe->fill($request->validated());
$recipe->ingredients = $tmpIngredients;
@ -79,14 +76,14 @@ class RecipeController extends Controller
->route('bo.recipes.edit', $recipe)
->with('success', trans(
'crud.messages.has_been_created',
['model' => Str::singular(trans('models.classes.recipes'))]
['model' => trans('models.classes.recipe')]
));
}
return redirect()
->back()
->with('error', trans(
'crud.messages.cannot_be_created',
['model' => Str::singular(trans('models.classes.recipes'))]
['model' => trans('models.classes.recipe')]
));
});
}
@ -95,9 +92,9 @@ class RecipeController extends Controller
* Show the form for editing the specified resource.
*
* @param \App\Models\Recipe $recipe
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View
*/
public function edit(Recipe $recipe)
public function edit(Recipe $recipe): \Illuminate\Contracts\View\View
{
$rangeModels = Range::orderBy('order', 'ASC')->get();
@ -112,12 +109,12 @@ class RecipeController extends Controller
*
* @param \App\Http\Requests\Bo\Recipes\UpdateRecipeRequest $request
* @param \App\Models\Recipe $recipe
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function update(UpdateRecipeRequest $request, Recipe $recipe)
public function update(UpdateRecipeRequest $request, Recipe $recipe): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request, $recipe) {
$tmpIngredients = \collect($request->validated()['ingredients'])->sortKeys();
$tmpIngredients = \collect($request->validated()['ingredients'])->sortKeys()->toArray();
$recipe->fill($request->validated());
$recipe->ingredients = $tmpIngredients;
@ -126,14 +123,14 @@ class RecipeController extends Controller
->route('bo.recipes.edit', $recipe)
->with('success', trans(
'crud.messages.has_been_updated',
['model' => Str::singular(trans('models.classes.recipes'))]
['model' => trans('models.classes.recipe')]
));
} //end if
return redirect()
->back()
->with('error', trans(
'crud.messages.cannot_be_updated',
['model' => Str::singular(trans('models.classes.recipes'))]
['model' => trans('models.classes.recipe')]
));
});
}
@ -142,9 +139,9 @@ class RecipeController extends Controller
* Remove the specified resource from storage.
*
* @param \App\Models\Recipe $recipe
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy(Recipe $recipe)
public function destroy(Recipe $recipe): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($recipe) {
$recipe->products()->detach();
@ -153,14 +150,14 @@ class RecipeController extends Controller
->route('bo.recipes.index')
->with('success', trans(
'crud.messages.has_been_deleted',
['model' => Str::singular(trans('models.classes.recipes'))]
['model' => trans('models.classes.recipe')]
));
}
return redirect()
->back()
->with('error', trans(
':crud.messages.cannot_be_deleted',
['model' => Str::singular(trans('models.classes.recipes'))]
['model' => trans('models.classes.recipe')]
));
});
}

View file

@ -10,7 +10,6 @@ use App\Traits\Controllers\UpdateModelStatus;
use App\Traits\Controllers\ChangesModelOrder;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
class SliderController extends Controller
{
@ -21,9 +20,9 @@ class SliderController extends Controller
* Display a listing of the resource.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View
*/
public function index(Request $request)
public function index(Request $request): \Illuminate\Contracts\View\View
{
/** @var \Illuminate\Database\Eloquent\Builder $sliders */
$sliders = Slider::query();
@ -49,9 +48,9 @@ class SliderController extends Controller
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View
*/
public function create()
public function create(): \Illuminate\Contracts\View\View
{
return view('bo.pages.sliders.create');
}
@ -60,9 +59,9 @@ class SliderController extends Controller
* Store a newly created resource in storage.
*
* @param \App\Http\Requests\Bo\Sliders\StoreSliderRequest $request
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function store(StoreSliderRequest $request)
public function store(StoreSliderRequest $request): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request) {
$slider = new Slider();
@ -73,14 +72,14 @@ class SliderController extends Controller
->route('bo.sliders.edit', $slider)
->with('success', trans(
'crud.messages.has_been_created',
['model' => Str::singular(trans('models.classes.sliders'))]
['model' => trans('models.classes.slider')]
));
}
return redirect()
->back()
->with('error', trans(
'crud.messages.cannot_be_created',
['model' => Str::singular(trans('models.classes.sliders'))]
['model' => trans('models.classes.slider')]
));
});
}
@ -89,9 +88,9 @@ class SliderController extends Controller
* Show the form for editing the specified resource.
*
* @param \App\Models\Slider $slider
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View
*/
public function edit(Slider $slider)
public function edit(Slider $slider): \Illuminate\Contracts\View\View
{
return view('bo.pages.sliders.edit', [
'sliderModel' => $slider
@ -103,9 +102,9 @@ class SliderController extends Controller
*
* @param \App\Http\Requests\Bo\Sliders\UpdateSliderRequest $request
* @param \App\Models\Slider $slider
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function update(UpdateSliderRequest $request, Slider $slider)
public function update(UpdateSliderRequest $request, Slider $slider): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request, $slider) {
$slider->fill($request->validated());
@ -115,14 +114,14 @@ class SliderController extends Controller
->route('bo.sliders.edit', $slider)
->with('success', trans(
'crud.messages.has_been_updated',
['model' => Str::singular(trans('models.classes.sliders'))]
['model' => trans('models.classes.slider')]
));
}
return redirect()
->back()
->with('error', trans(
'crud.messages.cannot_be_updated',
['model' => Str::singular(trans('models.classes.sliders'))]
['model' => trans('models.classes.slider')]
));
});
}
@ -131,23 +130,23 @@ class SliderController extends Controller
* Remove the specified resource from storage.
*
* @param \App\Models\Slider $slider
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy(Slider $slider)
public function destroy(Slider $slider): \Illuminate\Http\RedirectResponse
{
if ($slider->deleteOrFail()) {
return redirect()
->route('bo.sliders.index')
->with('success', trans(
'crud.messages.has_been_deleted',
['model' => Str::singular(trans('models.classes.sliders'))]
['model' => trans('models.classes.slider')]
));
}
return redirect()
->back()
->with('error', trans(
':crud.messages.cannot_be_deleted',
['model' => Str::singular(trans('models.classes.sliders'))]
['model' => trans('models.classes.slider')]
));
}
}

View file

@ -0,0 +1,90 @@
<?php
namespace App\Http\Controllers\Bo;
use App\Http\Controllers\Controller;
use App\Http\Requests\Bo\StaticPages\UpdateStaticPageRequest;
use App\Models\StaticPage;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class StaticPageController extends Controller
{
/**
* Create the controller instance.
*/
public function __construct()
{
$this->authorizeResource(StaticPage::class);
}
/**
* Display a listing of the resource.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Contracts\View\View
*/
public function index(Request $request): \Illuminate\Contracts\View\View
{
/** @var \Illuminate\Database\Eloquent\Builder $query */
$query = StaticPage::query();
/** @var string $search Search field */
$search = $request->search;
if ($search) {
$this->searchQuery(
$query,
$search,
null,
'title',
);
}
$searchFields = \implode(', ', [
trans('validation.attributes.title'),
]);
/** Sort columns with a query */
$this->sortQuery($query);
/** Custom pagination */
$staticPageModels = $query->paginate(10);
return view('bo.pages.static_pages.index', compact('staticPageModels', 'search', 'searchFields'));
}
/**
* Show the form for editing the specified resource.
*
* @param \App\Models\StaticPage $static_page
* @return \Illuminate\Contracts\View\View
*/
public function edit(StaticPage $static_page): \Illuminate\Contracts\View\View
{
return view('bo.pages.static_pages.edit', ['staticPageModel' => $static_page]);
}
/**
* Update the specified resource in storage.
*
* @param \App\Http\Requests\Bo\StaticPages\UpdateStaticPageRequest $request
* @param \App\Models\StaticPage $static_page
* @return \Illuminate\Http\RedirectResponse
*/
public function update(UpdateStaticPageRequest $request, StaticPage $static_page): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request, $static_page) {
$static_page->fill($request->validated());
if ($static_page->saveOrFail()) {
return redirect()->route('bo.static_pages.edit', $static_page)
->with('success', __('crud.messages.has_been_updated', [
'model' => trans('models.classes.static_page')
]));
}
return redirect()->route('bo.static_pages.edit', $static_page)
->with('error', __('crud.messages.cannot_be_updated', [
'model' => trans('models.classes.static_page')
]));
});
}
}

View file

@ -10,24 +10,21 @@ use App\Models\StoreType;
use App\Models\StoreRegion;
use App\Traits\Controllers\UpdateModelStatus;
use App\Traits\Controllers\ChangesModelOrder;
use App\Traits\Requests\HasPicture;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
class StoreController extends Controller
{
use ChangesModelOrder;
use HasPicture;
use UpdateModelStatus;
/**
* Display a listing of the resource.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View
*/
public function index(Request $request)
public function index(Request $request): \Illuminate\Contracts\View\View
{
/** @var \Illuminate\Database\Eloquent\Builder $store */
$store = Store::query();
@ -52,9 +49,9 @@ class StoreController extends Controller
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View
*/
public function create()
public function create(): \Illuminate\Contracts\View\View
{
$typeModels = StoreType::orderBy('name', 'ASC')->get();
$regionModels = StoreRegion::orderBy('name', 'ASC')->get();
@ -66,9 +63,9 @@ class StoreController extends Controller
* Store a newly created resource in storage.
*
* @param \App\Http\Requests\Bo\Stores\StoreStoreRequest $request
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function store(StoreStoreRequest $request)
public function store(StoreStoreRequest $request): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request) {
$store = new Store();
@ -79,14 +76,14 @@ class StoreController extends Controller
->route('bo.stores.edit', $store)
->with('success', trans(
'crud.messages.has_been_created',
['model' => Str::singular(trans('models.classes.stores'))]
['model' => trans('models.classes.store')]
));
}
return redirect()
->back()
->with('error', trans(
'crud.messages.cannot_be_created',
['model' => Str::singular(trans('models.classes.stores'))]
['model' => trans('models.classes.store')]
));
});
}
@ -95,9 +92,9 @@ class StoreController extends Controller
* Display a listing of the resource.
*
* @param \App\Models\Store $store
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
* @return \Illuminate\Contracts\View\View
*/
public function edit(Store $store)
public function edit(Store $store): \Illuminate\Contracts\View\View
{
$typeModels = StoreType::orderBy('name', 'ASC')->get();
$regionModels = StoreRegion::orderBy('name', 'ASC')->get();
@ -113,9 +110,9 @@ class StoreController extends Controller
*
* @param \App\Http\Requests\Bo\Stores\UpdateStoreRequest $request
* @param \App\Models\Store $store
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function update(UpdateStoreRequest $request, Store $store)
public function update(UpdateStoreRequest $request, Store $store): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request, $store) {
$store->fill($request->validated());
@ -124,14 +121,14 @@ class StoreController extends Controller
->route('bo.stores.edit', $store)
->with('success', trans(
'crud.messages.has_been_updated',
['model' => Str::singular(trans('models.classes.stores'))]
['model' => trans('models.classes.store')]
));
} //end if
return redirect()
->back()
->with('error', trans(
'crud.messages.cannot_be_updated',
['model' => Str::singular(trans('models.classes.stores'))]
['model' => trans('models.classes.store')]
));
});
}
@ -140,23 +137,23 @@ class StoreController extends Controller
* Remove the specified resource from storage.
*
* @param \App\Models\Store $store
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy(Store $store)
public function destroy(Store $store): \Illuminate\Http\RedirectResponse
{
if ($store->deleteOrFail()) {
return redirect()
->route('bo.stores.index')
->with('success', trans(
'crud.messages.has_been_deleted',
['model' => Str::singular(trans('models.classes.stores'))]
['model' => trans('models.classes.store')]
));
}
return redirect()
->back()
->with('error', trans(
':crud.messages.cannot_be_deleted',
['model' => Str::singular(trans('models.classes.stores'))]
['model' => trans('models.classes.store')]
));
}
}

View file

@ -8,24 +8,21 @@ use App\Http\Requests\Bo\StoreGroups\UpdateStoreGroupRequest;
use App\Models\StoreGroup;
use App\Traits\Controllers\UpdateModelStatus;
use App\Traits\Controllers\ChangesModelOrder;
use App\Traits\Requests\HasPicture;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
class StoreGroupController extends Controller
{
use ChangesModelOrder;
use HasPicture;
use UpdateModelStatus;
/**
* Display a listing of the resource.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View
*/
public function index(Request $request)
public function index(Request $request): \Illuminate\Contracts\View\View
{
/** @var \Illuminate\Database\Eloquent\Builder $storeGroup */
$storeGroup = StoreGroup::query();
@ -50,9 +47,9 @@ class StoreGroupController extends Controller
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View
*/
public function create()
public function create(): \Illuminate\Contracts\View\View
{
return view('bo.pages.storegroups.create');
}
@ -61,9 +58,9 @@ class StoreGroupController extends Controller
* Store a newly created resource in storage.
*
* @param \App\Http\Requests\Bo\StoreGroups\StoreStoreGroupRequest $request
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function store(StoreStoreGroupRequest $request)
public function store(StoreStoreGroupRequest $request): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request) {
$storeGroup = new StoreGroup();
@ -74,14 +71,14 @@ class StoreGroupController extends Controller
->route('bo.storegroups.edit', $storeGroup)
->with('success', trans(
'crud.messages.has_been_created',
['model' => Str::singular(trans('models.classes.storegroups'))]
['model' => trans('models.classes.storegroup')]
));
}
return redirect()
->back()
->with('error', trans(
'crud.messages.cannot_be_created',
['model' => Str::singular(trans('models.classes.storegroups'))]
['model' => trans('models.classes.storegroup')]
));
});
}
@ -90,9 +87,9 @@ class StoreGroupController extends Controller
* Display a listing of the resource.
*
* @param \App\Models\StoreGroup $storegroup
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
* @return \Illuminate\Contracts\View\View
*/
public function edit(StoreGroup $storegroup)
public function edit(StoreGroup $storegroup): \Illuminate\Contracts\View\View
{
return view('bo.pages.storegroups.edit', ['storegroupModel' => $storegroup]);
}
@ -102,9 +99,9 @@ class StoreGroupController extends Controller
*
* @param \App\Http\Requests\Bo\StoreGroups\UpdateStoreGroupRequest $request
* @param \App\Models\StoreGroup $storegroup
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function update(UpdateStoreGroupRequest $request, StoreGroup $storegroup)
public function update(UpdateStoreGroupRequest $request, StoreGroup $storegroup): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request, $storegroup) {
$storegroup->fill($request->validated());
@ -113,14 +110,14 @@ class StoreGroupController extends Controller
->route('bo.storegroups.edit', $storegroup)
->with('success', trans(
'crud.messages.has_been_updated',
['model' => Str::singular(trans('models.classes.storegroups'))]
['model' => trans('models.classes.storegroup')]
));
} //end if
return redirect()
->back()
->with('error', trans(
'crud.messages.cannot_be_updated',
['model' => Str::singular(trans('models.classes.storegroups'))]
['model' => trans('models.classes.storegroup')]
));
});
}
@ -129,9 +126,9 @@ class StoreGroupController extends Controller
* Remove the specified resource from storage.
*
* @param \App\Models\StoreGroup $storegroup
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy(StoreGroup $storegroup)
public function destroy(StoreGroup $storegroup): \Illuminate\Http\RedirectResponse
{
foreach ($storegroup->storeRegions as $region) {
foreach ($region->stores as $store) {
@ -145,14 +142,14 @@ class StoreGroupController extends Controller
->route('bo.storegroups.index')
->with('success', trans(
'crud.messages.has_been_deleted',
['model' => Str::singular(trans('models.classes.storegroups'))]
['model' => trans('models.classes.storegroup')]
));
}
return redirect()
->back()
->with('error', trans(
':crud.messages.cannot_be_deleted',
['model' => Str::singular(trans('models.classes.storegroups'))]
['model' => trans('models.classes.storegroup')]
));
}
}

View file

@ -9,24 +9,21 @@ use App\Models\StoreRegion;
use App\Models\StoreGroup;
use App\Traits\Controllers\UpdateModelStatus;
use App\Traits\Controllers\ChangesModelOrder;
use App\Traits\Requests\HasPicture;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
class StoreRegionController extends Controller
{
use ChangesModelOrder;
use HasPicture;
use UpdateModelStatus;
/**
* Display a listing of the resource.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View
*/
public function index(Request $request)
public function index(Request $request): \Illuminate\Contracts\View\View
{
/** @var \Illuminate\Database\Eloquent\Builder $storeregion */
$storeregion = StoreRegion::query();
@ -51,9 +48,9 @@ class StoreRegionController extends Controller
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View
*/
public function create()
public function create(): \Illuminate\Contracts\View\View
{
$storegroupModels = StoreGroup::orderBy('order', 'ASC')->get();
@ -64,9 +61,9 @@ class StoreRegionController extends Controller
* Store a newly created resource in storage.
*
* @param \App\Http\Requests\Bo\StoreRegions\StoreStoreRegionRequest $request
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function store(StoreStoreRegionRequest $request)
public function store(StoreStoreRegionRequest $request): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request) {
$storeregion = new StoreRegion();
@ -77,14 +74,14 @@ class StoreRegionController extends Controller
->route('bo.storeregions.edit', $storeregion)
->with('success', trans(
'crud.messages.has_been_created',
['model' => Str::singular(trans('models.classes.storeregions'))]
['model' => trans('models.classes.storeregion')]
));
}
return redirect()
->back()
->with('error', trans(
'crud.messages.cannot_be_created',
['model' => Str::singular(trans('models.classes.storeregions'))]
['model' => trans('models.classes.storeregion')]
));
});
}
@ -93,9 +90,9 @@ class StoreRegionController extends Controller
* Show the form for editing the specified resource.
*
* @param \App\Models\StoreRegion $storeregion
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View
*/
public function edit(StoreRegion $storeregion)
public function edit(StoreRegion $storeregion): \Illuminate\Contracts\View\View
{
$storegroupModels = StoreGroup::orderBy('order', 'ASC')->get();
@ -110,10 +107,12 @@ class StoreRegionController extends Controller
*
* @param \App\Http\Requests\Bo\StoreRegions\UpdateStoreRegionRequest $request
* @param \App\Models\StoreRegion $storeregion
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function update(UpdateStoreRegionRequest $request, StoreRegion $storeregion)
{
public function update(
UpdateStoreRegionRequest $request,
StoreRegion $storeregion
): \Illuminate\Http\RedirectResponse {
return DB::transaction(function () use ($request, $storeregion) {
$storeregion->fill($request->validated());
@ -122,14 +121,14 @@ class StoreRegionController extends Controller
->route('bo.storeregions.edit', $storeregion)
->with('success', trans(
'crud.messages.has_been_updated',
['model' => Str::singular(trans('models.classes.storeregions'))]
['model' => trans('models.classes.storeregion')]
));
} //end if
return redirect()
->back()
->with('error', trans(
'crud.messages.cannot_be_updated',
['model' => Str::singular(trans('models.classes.storeregions'))]
['model' => trans('models.classes.storeregion')]
));
});
}
@ -138,9 +137,9 @@ class StoreRegionController extends Controller
* Remove the specified resource from storage.
*
* @param \App\Models\StoreRegion $storeregion
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy(StoreRegion $storeregion)
public function destroy(StoreRegion $storeregion): \Illuminate\Http\RedirectResponse
{
foreach ($storeregion->stores as $store) {
$store->deleteOrFail();
@ -150,14 +149,14 @@ class StoreRegionController extends Controller
->route('bo.storeregions.index')
->with('success', trans(
'crud.messages.has_been_deleted',
['model' => Str::singular(trans('models.classes.storeregions'))]
['model' => trans('models.classes.storeregion')]
));
}
return redirect()
->back()
->with('error', trans(
':crud.messages.cannot_be_deleted',
['model' => Str::singular(trans('models.classes.storeregions'))]
['model' => trans('models.classes.storeregion')]
));
}
}

View file

@ -8,24 +8,21 @@ use App\Http\Requests\Bo\StoreTypes\UpdateStoreTypeRequest;
use App\Models\StoreType;
use App\Traits\Controllers\UpdateModelStatus;
use App\Traits\Controllers\ChangesModelOrder;
use App\Traits\Requests\HasPicture;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
class StoreTypeController extends Controller
{
use ChangesModelOrder;
use HasPicture;
use UpdateModelStatus;
/**
* Display a listing of the resource.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View
*/
public function index(Request $request)
public function index(Request $request): \Illuminate\Contracts\View\View
{
/** @var \Illuminate\Database\Eloquent\Builder $storetype */
$storetype = StoreType::query();
@ -50,9 +47,9 @@ class StoreTypeController extends Controller
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View
*/
public function create()
public function create(): \Illuminate\Contracts\View\View
{
return view('bo.pages.storetypes.create');
}
@ -61,9 +58,9 @@ class StoreTypeController extends Controller
* Store a newly created resource in storage.
*
* @param \App\Http\Requests\Bo\StoreTypes\StoreStoreTypeRequest $request
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function store(StoreStoreTypeRequest $request)
public function store(StoreStoreTypeRequest $request): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request) {
$storetype = new StoreType();
@ -74,14 +71,14 @@ class StoreTypeController extends Controller
->route('bo.storetypes.edit', $storetype)
->with('success', trans(
'crud.messages.has_been_created',
['model' => Str::singular(trans('models.classes.storetypes'))]
['model' => trans('models.classes.storetype')]
));
}
return redirect()
->back()
->with('error', trans(
'crud.messages.cannot_be_created',
['model' => Str::singular(trans('models.classes.storetypes'))]
['model' => trans('models.classes.storetype')]
));
});
}
@ -90,9 +87,9 @@ class StoreTypeController extends Controller
* Show the form for editing the specified resource.
*
* @param \App\Models\StoreType $storetype
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\View
*/
public function edit(StoreType $storetype)
public function edit(StoreType $storetype): \Illuminate\Contracts\View\View
{
return view('bo.pages.storetypes.edit', [
'storetypeModel' => $storetype,
@ -104,9 +101,9 @@ class StoreTypeController extends Controller
*
* @param \App\Http\Requests\Bo\StoreTypes\UpdateStoreTypeRequest $request
* @param \App\Models\StoreType $storetype
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function update(UpdateStoreTypeRequest $request, StoreType $storetype)
public function update(UpdateStoreTypeRequest $request, StoreType $storetype): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request, $storetype) {
$storetype->fill($request->validated());
@ -116,14 +113,14 @@ class StoreTypeController extends Controller
->route('bo.storetypes.edit', $storetype)
->with('success', trans(
'crud.messages.has_been_updated',
['model' => Str::singular(trans('models.classes.storetypes'))]
['model' => trans('models.classes.storetype')]
));
} //end if
return redirect()
->back()
->with('error', trans(
'crud.messages.cannot_be_updated',
['model' => Str::singular(trans('models.classes.storetypes'))]
['model' => trans('models.classes.storetype')]
));
});
}
@ -132,9 +129,9 @@ class StoreTypeController extends Controller
* Remove the specified resource from storage.
*
* @param \App\Models\StoreType $storetype
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy(StoreType $storetype)
public function destroy(StoreType $storetype): \Illuminate\Http\RedirectResponse
{
foreach ($storetype->stores as $store) {
$store->deleteOrFail();
@ -144,14 +141,14 @@ class StoreTypeController extends Controller
->route('bo.storetypes.index')
->with('success', trans(
'crud.messages.has_been_deleted',
['model' => Str::singular(trans('models.classes.storetypes'))]
['model' => trans('models.classes.storetype')]
));
}
return redirect()
->back()
->with('error', trans(
':crud.messages.cannot_be_deleted',
['model' => Str::singular(trans('models.classes.storetypes'))]
['model' => trans('models.classes.storetype')]
));
}
}

View file

@ -109,10 +109,7 @@ class Controller extends BaseController
Session::remove("$rName.sort_way");
}
if (request()->sort_col and request()->sort_way and Schema::hasColumn($table, request()->sort_col)) {
if (
!isset($ignore) or
(isset($ignore) and !in_array(request()->sort_col, $ignore))
) {
if (!in_array(request()->input('sort_col'), $ignore)) {
$query = $query->orderBy(\sprintf("$table.%s", request()->sort_col), request()->sort_way);
}
} elseif (Schema::hasColumn($table, 'order')) {

View file

@ -2,8 +2,10 @@
namespace App\Http\Controllers\Fo;
use App\Enums\StaticPageType;
use App\Http\Controllers\Controller;
use App\Models\Concept;
use App\Models\StaticPage;
class ConceptController extends Controller
{
@ -13,8 +15,9 @@ class ConceptController extends Controller
* @param \App\Models\Concept $concept
* @return \Illuminate\Contracts\View\View
*/
public function show(Concept $concept)
public function show(Concept $concept): \Illuminate\Contracts\View\View
{
return view('fo.pages.concepts.concept', ['conceptModel' => $concept]);
$staticPageModel = StaticPage::query()->where('type', StaticPageType::concept)->firstOrFail();
return view('fo.pages.concepts.concept', ['staticPageModel' => $staticPageModel, 'conceptModel' => $concept]);
}
}

View file

@ -2,30 +2,33 @@
namespace App\Http\Controllers\Fo;
use App\Enums\StaticPageType;
use App\Http\Controllers\Controller;
use App\Http\Requests\Fo\ContactRequest;
use App\Mail\ContactMessageReceived;
use App\Models\StaticPage;
use Illuminate\Support\Facades\Mail;
class ContactController extends Controller
{
/**
* Show contact page
* Show contact page.
*
* @return \Illuminate\Contracts\View\View
*/
public function contactForm()
public function contactForm(): \Illuminate\Contracts\View\View
{
return view('fo.pages.contact');
$staticPageModel = StaticPage::query()->where('type', StaticPageType::contact)->firstOrFail();
return view('fo.pages.contact', \compact('staticPageModel'));
}
/**
* Submit contact form
* Submit contact form.
*
* @param \App\Http\Requests\Fo\ContactRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
public function sendContactForm(ContactRequest $request)
public function sendContactForm(ContactRequest $request): \Illuminate\Http\RedirectResponse
{
Mail::queue(new ContactMessageReceived(
first_name: $request->first_name,

View file

@ -13,7 +13,7 @@ class GroupController extends Controller
* @param integer $id
* @return \App\Models\StoreGroup
*/
public function show(int $id)
public function show(int $id): \App\Models\StoreGroup
{
return StoreGroup::query()->find($id);
}

View file

@ -2,9 +2,11 @@
namespace App\Http\Controllers\Fo;
use App\Enums\StaticPageType;
use App\Http\Controllers\Controller;
use App\Models\Home;
use App\Models\Slider;
use App\Models\StaticPage;
class HomeController extends Controller
{
@ -13,10 +15,16 @@ class HomeController extends Controller
*
* @return \Illuminate\Contracts\View\View
*/
public function index()
public function index(): \Illuminate\Contracts\View\View
{
$staticPageModel = StaticPage::query()->where('type', StaticPageType::home)->firstOrFail();
$currentLocale = app()->currentLocale();
$home = Home::query()->firstOrFail();
$sliders = Slider::query()->where('status', true)->orderBy('order')->get();
return view('fo.pages.home', compact('home', 'sliders'));
$sliders = Slider::query()
->where('status', true)
->orderBy('order')
->whereJsonContains('locales', $currentLocale)
->get();
return view('fo.pages.home', compact('staticPageModel', 'home', 'sliders'));
}
}

View file

@ -0,0 +1,81 @@
<?php
namespace App\Http\Controllers\Fo;
use App\Enums\StaticPageType;
use App\Http\Controllers\Controller;
use App\Models\News;
use App\Models\StaticPage;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
class NewsController extends Controller
{
/**
* News index
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
*/
public function index(Request $request): \Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
{
$staticPageModel = StaticPage::query()->where('type', StaticPageType::newsPlural)->firstOrFail();
if ($request->wantsJson()) {
$currentLocale = app()->currentLocale();
$newsList = News::query()
->where('status', true)
->whereJsonContains('locales', $currentLocale)
->orderBy('order')
->paginate();
return \response()->json(\collect($newsList->items())
->map(fn ($newsModel) => str($this->renderNews($newsModel))->toBase64()));
}
return view('fo.pages.news.index', compact('staticPageModel'));
}
/**
* Product show
*
* @param \App\Models\News $publishedNews
* @return \Illuminate\Contracts\View\View
*/
public function show(News $publishedNews): \Illuminate\Contracts\View\View
{
$staticPageModel = StaticPage::query()->where('type', StaticPageType::newsPlural)->firstOrFail();
$currentLocale = app()->currentLocale();
$relatedNewsList = News::query()
->where('id', '!=', $publishedNews->id)
->where('status', true)
->whereJsonContains('locales', $currentLocale)
->orderBy('order', 'DESC')
->limit(2)->get();
return view('fo.pages.news.show', [
'staticPageModel' => $staticPageModel,
'newsModel' => $publishedNews,
'relatedNewsList' => $relatedNewsList
]);
}
/**
* Render a news for JS usage (ajax)
*
* @param \App\Models\News $newsModel
* @return string Base64 rendered view.
*/
private function renderNews(News $newsModel): string
{
$locale = \app()->currentLocale();
$pictures = $newsModel->picture_list;
return Cache::remember(
"NewsRendered_{$locale}_{$newsModel->id}_{$newsModel->updated_at}",
60,
fn () => \view(
'fo.pages.news.bloc',
[
'newsModel' => $newsModel,
'pictures' => $pictures
]
)->render()
);
}
}

View file

@ -2,36 +2,44 @@
namespace App\Http\Controllers\Fo;
use App\Enums\StaticPageType;
use App\Http\Controllers\Controller;
use App\Models\Product;
use App\Models\Range;
use App\Models\StaticPage;
use Illuminate\Contracts\Database\Eloquent\Builder;
class ProductController extends Controller
{
/**
* Products index
* Products index.
*
* @return \Illuminate\Contracts\View\View
*/
public function index()
public function index(): \Illuminate\Contracts\View\View
{
$ranges = Range::query()->where('status', true)
->whereHas('products', fn (Builder $q) => $q->where('status', true))
->with('products', fn (Builder $q) => $q->where('status', true)->orderBy('order'))
$staticPageModel = StaticPage::query()->where('type', StaticPageType::products)->firstOrFail();
$rangeModels = Range::query()
->where('status', true)
->whereHas('products', fn(Builder $q) => $q->where('status', true))
->with('products', fn(Builder $q) => $q->where('status', true)->orderBy('order'))
->orderBy('order')
->get();
return view('fo.pages.products.index', compact(['ranges']));
return view('fo.pages.products.index', compact('staticPageModel', 'rangeModels'));
}
/**
* Product show
* Product show.
*
* @param \App\Models\Product $publishedProduct
* @return \Illuminate\Contracts\View\View
*/
public function show(Product $publishedProduct)
public function show(Product $publishedProduct): \Illuminate\Contracts\View\View
{
return view('fo.pages.products.show', ['productModel' => $publishedProduct]);
$staticPageModel = StaticPage::query()->where('type', StaticPageType::product)->firstOrFail();
return view('fo.pages.products.show', [
'staticPageModel' => $staticPageModel,
'productModel' => $publishedProduct,
]);
}
}

View file

@ -2,8 +2,10 @@
namespace App\Http\Controllers\Fo;
use App\Enums\StaticPageType;
use App\Http\Controllers\Controller;
use App\Models\Recipe;
use App\Models\StaticPage;
use Illuminate\Contracts\Database\Eloquent\Builder;
class RecipeController extends Controller
@ -13,13 +15,14 @@ class RecipeController extends Controller
*
* @return \Illuminate\Contracts\View\View
*/
public function index()
public function index(): \Illuminate\Contracts\View\View
{
$recipes = Recipe::query()->where('status', true)
$staticPageModel = StaticPage::query()->where('type', StaticPageType::recipes)->firstOrFail();
$recipeModels = Recipe::query()->where('status', true)
->whereHas('range', fn (Builder $q) => $q->where('status', true))
->orderBy('order')
->get();
return view('fo.pages.recipes.index', compact('recipes'));
return view('fo.pages.recipes.index', compact('staticPageModel', 'recipeModels'));
}
/**
@ -28,8 +31,12 @@ class RecipeController extends Controller
* @param \App\Models\Recipe $publishedRecipe
* @return \Illuminate\Contracts\View\View
*/
public function show(Recipe $publishedRecipe)
public function show(Recipe $publishedRecipe): \Illuminate\Contracts\View\View
{
return view('fo.pages.recipes.show', ['recipeModel' => $publishedRecipe]);
$staticPageModel = StaticPage::query()->where('type', StaticPageType::recipe)->firstOrFail();
return view('fo.pages.recipes.show', [
'staticPageModel' => $staticPageModel,
'recipeModel' => $publishedRecipe,
]);
}
}

View file

@ -13,7 +13,7 @@ class RegionController extends Controller
* @param integer $id
* @return \App\Models\StoreRegion;
*/
public function show(int $id)
public function show(int $id): \App\Models\StoreRegion
{
return StoreRegion::find($id);
}

View file

@ -0,0 +1,34 @@
<?php
namespace App\Http\Controllers\Fo;
use App\Enums\StaticPageType;
use App\Http\Controllers\Controller;
use App\Models\StaticPage;
class StaticPageController extends Controller
{
/**
* Legal show
*
* @param \App\Models\StaticPage $legalPage
* @return \Illuminate\Contracts\View\View
*/
public function legals(StaticPage $legalPage)
{
$legalPage = StaticPage::query()->where('type', StaticPageType::legals)->firstOrFail();
return view('fo.pages.legals', ['staticPageModel' => $legalPage]);
}
/**
* Policies show
*
* @param \App\Models\StaticPage $policiesPage
* @return \Illuminate\Contracts\View\View
*/
public function policies(StaticPage $policiesPage)
{
$policiesPage = StaticPage::query()->where('type', StaticPageType::confidentiality)->firstOrFail();
return view('fo.pages.privacy', ['staticPageModel' => $policiesPage]);
}
}

View file

@ -2,21 +2,33 @@
namespace App\Http\Controllers\Fo;
use App\Enums\StaticPageType;
use App\Http\Controllers\Controller;
use App\Http\Requests\Api\StoreFinderRequest;
use App\Http\Resources\StoreFinderResource;
use App\Models\StaticPage;
use App\Models\Store;
use Illuminate\Http\JsonResponse;
class StoreController extends Controller
{
/**
* Store by city
* Store page.
*
* @return \Illuminate\Contracts\View\View
*/
public function index(): \Illuminate\Contracts\View\View
{
$staticPageModel = StaticPage::query()->where('type', StaticPageType::store)->firstOrFail();
return view('fo.pages.storefinder', compact('staticPageModel'));
}
/**
* Store by city.
*
* @param \App\Http\Requests\Api\StoreFinderRequest $request
* @return \Illuminate\Http\JsonResponse;
* @return \Illuminate\Http\JsonResponse
*/
public function city(StoreFinderRequest $request): JsonResponse
public function city(StoreFinderRequest $request): \Illuminate\Http\JsonResponse
{
return \response()->json(new StoreFinderResource(Store::query()
->where('city', 'LIKE', '%' . $request->input('city') . '%')

View file

@ -38,6 +38,7 @@ class Kernel extends HttpKernel
\App\Http\Middleware\VerifyCsrfToken::class,
\CodeZero\LocalizedRoutes\Middleware\SetLocale::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\Lang::class,
\App\Http\Middleware\SecureHeaders::class,
],

View file

@ -33,7 +33,6 @@ class Authenticate extends Middleware
}
return route('login');
}
abort(401);
return null;
}

View file

@ -25,6 +25,9 @@ class Lang
app()->setLocale(session()->get('lang', config('app.locale')));
return $next($request);
}
if (Route::current()->getName() == null && count($request->all()) > 0) {
return redirect()->route('home', $request->all());
}
return $next($request);
}
}

View file

@ -84,7 +84,9 @@ class SecureHeaders
]) . ';',
// ! If you dont use ckeditor use this
// "style-src 'self' 'nonce-$nonce';",
// phpcs:disable Generic.Commenting.Fixme.TaskFound
// FIXME: use Alpine CSP compliant.
// phpcs:enable
// ! unsave Eval needed for Alpine JS de merde.
// phpcs:ignore Generic.Files.LineLength.TooLong
"script-src 'self' 'unsafe-eval' {$jsDev} " . \implode(' ', [

View file

@ -11,7 +11,7 @@ class ChangeOrderRequest extends FormRequest
*
* @return boolean
*/
public function authorize()
public function authorize(): bool
{
return auth('backend')->check();
}
@ -21,10 +21,10 @@ class ChangeOrderRequest extends FormRequest
*
* @return void
*/
protected function prepareForValidation()
protected function prepareForValidation(): void
{
$this->merge([
'direction' => $this->action === 'up' ? true : false
'direction' => $this->direction === 'up' ? true : false
]);
}
@ -33,10 +33,9 @@ class ChangeOrderRequest extends FormRequest
*
* @return array
*/
public function rules()
public function rules(): array
{
return [
'action' => 'required|string|in:up,down',
'direction' => 'required|boolean',
];
}

View file

@ -25,7 +25,7 @@ class StoreConceptRequest extends UpdateMiniCrudRequest
*
* @return boolean
*/
public function authorize()
public function authorize(): bool
{
return (auth('backend')->check() && Concept::count() < 9);
}
@ -35,10 +35,10 @@ class StoreConceptRequest extends UpdateMiniCrudRequest
*
* @return void
*/
protected function prepareForValidation()
protected function prepareForValidation(): void
{
$this->merge([
'slug' => Str::slug(strip_tags($this->name))
'slug' => Str::slug(strip_tags($this->input('name')))
]);
$this->mergePicture('picture');
}
@ -48,23 +48,19 @@ class StoreConceptRequest extends UpdateMiniCrudRequest
*
* @return array
*/
public function rules()
public function rules(): array
{
$rules = [
'seo_title' => 'required|min:3|max:70',
'seo_description' => 'required|min:50|max:160',
'name' => 'required|min:3|max:70',
'slug' => 'unique_translation:concepts',
'title' => 'required|min:3|max:70',
'title_background_color' => [
'required', new Enum(ColorsEnum::class)
],
'title_background_color' => ['required', new Enum(ColorsEnum::class)],
'subtitle' => 'required|min:3|max:70',
'description' => 'required|string|min:15',
'data' => 'present|array',
'data.*' => 'required|array',
'picture_alt' => 'required|min:3|max:255',
'picture_title' => 'required|min:3|max:255',
];
@ -85,7 +81,6 @@ class StoreConceptRequest extends UpdateMiniCrudRequest
return [
'seo_title' => trans('titre') . ' seo',
'seo_description' => trans('description') . ' seo',
'name' => trans('name of the concept'),
'slug' => trans('slug of the concept'),
'title' => trans('title of the concept'),
@ -93,7 +88,6 @@ class StoreConceptRequest extends UpdateMiniCrudRequest
'description' => trans('description of the concept'),
'data' => trans('values of the data'),
'data.*.value' => trans('value of the data'),
'picture' => trans('illustration'),
'picture_alt' => trans('alt attribute of the image'),
'picture_title' => trans('title attribute of the image'),

View file

@ -12,7 +12,7 @@ class UpdateConceptRequest extends StoreConceptRequest
*
* @return array
*/
public function rules()
public function rules(): array
{
$rules = [
'slug' => UniqueTranslationRule::for('concepts')->ignore($this->concept->id),

View file

@ -14,7 +14,7 @@ class UpdateHomeRequest extends FormRequest
*
* @return boolean
*/
public function authorize()
public function authorize(): bool
{
return auth('backend')->check();
}
@ -24,7 +24,7 @@ class UpdateHomeRequest extends FormRequest
*
* @return void
*/
protected function prepareForValidation()
protected function prepareForValidation(): void
{
$this->mergePicture('part3_picture');
}
@ -34,18 +34,14 @@ class UpdateHomeRequest extends FormRequest
*
* @return array
*/
public function rules()
public function rules(): array
{
$rules = [
'seo_title' => 'required|min:3|max:70',
'seo_description' => 'required|min:50|max:160',
'part1_title' => 'required|min:3|max:70',
'part1_subtitle' => 'required|min:3|max:70',
'part1_text_1' => 'required|string|min:15',
'part1_text_2' => 'required|string|min:15',
'part1_text_3' => 'required|string|min:15',
'part2_title' => 'required|min:3|max:70',
'part2_subtitle' => 'required|min:3|max:70',
'part2_text' => 'required|string|min:15',
@ -54,7 +50,6 @@ class UpdateHomeRequest extends FormRequest
'part2_list.*.value' => 'required|string|min:3|max:255',
'part2_product1_id' => 'required|exists:products,id',
'part2_product2_id' => 'required|exists:products,id',
'part3_picture_alt' => 'required|min:3|max:255',
'part3_picture_title' => 'required|min:3|max:255',
];
@ -69,18 +64,14 @@ class UpdateHomeRequest extends FormRequest
*
* @return array
*/
public function attributes()
public function attributes(): array
{
return [
'seo_title' => trans('titre') . ' seo',
'seo_description' => trans('description') . ' seo',
'part1_title' => trans('title part.1'),
'part1_subtitle' => trans('subtitle part.1'),
'part1_text_1' => trans('text 1 part.1'),
'part1_text_2' => trans('text 2 part.1'),
'part1_text_3' => trans('text 3 part.1'),
'part2_title' => trans('title part.2'),
'part2_subtitle' => trans('subtitle part.2'),
'part2_text' => trans('text part.2'),
@ -88,7 +79,6 @@ class UpdateHomeRequest extends FormRequest
'part2_list.*.value' => trans('value of the list part.2'),
'part2_product1_id' => trans('value of the first product part.2'),
'part2_product2_id' => trans('value of the second product part.2'),
'part3_picture' => trans('illustration'),
'part3_picture_alt' => trans('alt attribute of the image'),
'part3_picture_title' => trans('title attribute of the image'),

View file

@ -0,0 +1,94 @@
<?php
namespace App\Http\Requests\Bo\News;
use App\Http\Requests\Bo\UpdateMiniCrudRequest;
use Illuminate\Support\Str;
class StoreNewsRequest extends UpdateMiniCrudRequest
{
/**
* The model parameter name
*
* @var string
*/
protected $modelName = 'news';
/**
* Determine if the user is authorized to make this request.
*
* @return boolean
*/
public function authorize(): bool
{
return auth('backend')->check();
}
/**
* Prepare the data for validation.
*
* @return void
*/
protected function prepareForValidation(): void
{
$this->merge([
'slug' => Str::slug(strip_tags($this->input('name'))),
'status' => $this->boolean('status'),
'publish_at' => $this->date('publish_at'),
'unpublish_at' => $this->date('unpublish_at'),
'locales' => \collect($this->input('locales'))->filter()->unique()->all()
]);
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules(): array
{
$rules = [
'seo_title' => 'required|min:3|max:70',
'seo_description' => 'required|min:50|max:160',
'slug' => 'unique_translation:news',
'title' => 'required|min:3|max:70',
'subtitle' => 'required|min:3|max:70',
'content' => 'required|string|min:15',
'locales' => 'required|array',
'locales.*' => [
'required',
\sprintf('in:%s', \implode(',', \config('app.locales')))
],
'data' => 'present|array',
'data.*' => 'required|array',
'data.bloc_1_display_picture.value' => 'required|accepted',
'status' => 'required|boolean',
'publish_at' => 'required|date',
'unpublish_at' => 'sometimes|nullable|date'
];
return \array_merge(
parent::rules(),
$rules
);
}
/**
* Get custom attributes for validator errors.
*
* @return array
*/
public function attributes(): array
{
return [
'seo_title' => trans('titre') . ' seo',
'seo_description' => trans('description') . ' seo',
'slug' => trans('slug of the news'),
'title' => trans('title of the news'),
'subtitle' => trans('subtitle of the news'),
'content' => trans('content of the news'),
'data' => trans('values of the data'),
'data.*.value' => trans('value of the data'),
'data.bloc_1_display_picture.value' => trans('visibility of the first picture')
];
}
}

View file

@ -0,0 +1,25 @@
<?php
namespace App\Http\Requests\Bo\News;
use App\Http\Requests\Bo\News\StoreNewsRequest;
use CodeZero\UniqueTranslation\UniqueTranslationRule;
class UpdateNewsRequest extends StoreNewsRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules(): array
{
$rules = [
'slug' => UniqueTranslationRule::for('news')->ignore($this->news->id),
];
return \array_merge(
parent::rules(),
$rules,
);
}
}

View file

@ -15,7 +15,7 @@ class StoreProductRequest extends FormRequest
*
* @return boolean
*/
public function authorize()
public function authorize(): bool
{
return auth('backend')->check();
}
@ -25,14 +25,14 @@ class StoreProductRequest extends FormRequest
*
* @return void
*/
protected function prepareForValidation()
protected function prepareForValidation(): void
{
$this->merge([
'slug' => Str::slug(strip_tags($this->label)),
'status' => $this->status ? true : false,
'list' => $this->list ?? [],
'nutritionnal_values' => $this->nutritionnal_values ?? [],
'certifications' => \collect($this->certifications)->all(),
'slug' => Str::slug(strip_tags($this->input('label'))),
'status' => $this->boolean('status'),
'list' => $this->input('list') ?? [],
'nutritionnal_values' => $this->input('nutritionnal_values') ?? [],
'certifications' => \collect($this->input('certifications'))->all(),
]);
$this->mergePicture('picture');
}
@ -42,7 +42,7 @@ class StoreProductRequest extends FormRequest
*
* @return array
*/
public function rules()
public function rules(): array
{
$rules = [
'seo_title' => 'required|min:3|max:70',
@ -58,7 +58,7 @@ class StoreProductRequest extends FormRequest
'certifications' => 'present|array',
'certifications.*' => 'required|integer',
'list' => [
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
'present', 'array', function ($attribute, array $value, $fail) {
if (1 > count($value)) {
$fail(\trans('You must fill in at least 2 lines in the list.'));
@ -68,7 +68,7 @@ class StoreProductRequest extends FormRequest
'list.*' => 'required|array',
'list.*.value' => 'nullable|string|min:3|max:255',
'nutritionnal_values' => [
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
'present', 'array', function ($attribute, array $value, $fail) {
if (1 > count($value)) {
$fail(\trans('You must fill in at least 2 lines of nutritional values.'));

View file

@ -11,7 +11,7 @@ class UpdateProductRequest extends StoreProductRequest
*
* @return array
*/
public function rules()
public function rules(): array
{
$rules = [
'seo_title' => 'required|min:3|max:70',
@ -27,7 +27,7 @@ class UpdateProductRequest extends StoreProductRequest
'certifications' => 'present|array',
'certifications.*' => 'required|integer',
'list' => [
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
'present', 'array', function ($attribute, array $value, $fail) {
if (1 > count($value)) {
$fail(\trans('You must fill in at least 2 lines in the list.'));
@ -37,7 +37,7 @@ class UpdateProductRequest extends StoreProductRequest
'list.*' => 'required|array',
'list.*.value' => 'nullable|string|min:3|max:255',
'nutritionnal_values' => [
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
'present', 'array', function ($attribute, array $value, $fail) {
if (1 > count($value)) {
$fail(\trans('You must fill in at least 2 lines of nutritional values.'));

View file

@ -17,7 +17,7 @@ class StoreRangeRequest extends FormRequest
*
* @return boolean
*/
public function authorize()
public function authorize(): bool
{
return auth('backend')->check();
}
@ -27,11 +27,11 @@ class StoreRangeRequest extends FormRequest
*
* @return void
*/
protected function prepareForValidation()
protected function prepareForValidation(): void
{
$this->merge([
'slug' => Str::slug(strip_tags($this->label)),
'status' => $this->status ? true : false,
'slug' => Str::slug(strip_tags($this->input('label'))),
'status' => $this->boolean('status'),
]);
}
@ -40,7 +40,7 @@ class StoreRangeRequest extends FormRequest
*
* @return array
*/
public function rules()
public function rules(): array
{
return [
'seo_title' => 'required|min:3|max:70',

View file

@ -2,9 +2,7 @@
namespace App\Http\Requests\Bo\Ranges;
use App\Enums\Ranges\PictoEnum;
use CodeZero\UniqueTranslation\UniqueTranslationRule;
use Illuminate\Validation\Rules\Enum;
class UpdateRangeRequest extends StoreRangeRequest
{
@ -13,15 +11,14 @@ class UpdateRangeRequest extends StoreRangeRequest
*
* @return array
*/
public function rules()
public function rules(): array
{
return [
'seo_title' => 'required|min:3|max:70',
'seo_description' => 'required|min:50|max:160',
'label' => 'required|min:3|max:255',
$rules = [
'slug' => UniqueTranslationRule::for('ranges')->ignore($this->range->id),
'picto' => [new Enum(PictoEnum::class)],
'status' => 'required|boolean'
];
return \array_merge(
parent::rules(),
$rules,
);
}
}

View file

@ -17,7 +17,7 @@ class StoreRecipeRequest extends FormRequest
*
* @return boolean
*/
public function authorize()
public function authorize(): bool
{
return auth('backend')->check();
}
@ -27,11 +27,11 @@ class StoreRecipeRequest extends FormRequest
*
* @return void
*/
protected function prepareForValidation()
protected function prepareForValidation(): void
{
$this->merge([
'slug' => Str::slug(strip_tags($this->name)),
'status' => $this->status ? true : false,
'slug' => Str::slug(strip_tags($this->input('name'))),
'status' => $this->boolean('status'),
]);
$this->mergePicture('picture');
$this->mergePicture('picture_thumbnail');
@ -42,7 +42,7 @@ class StoreRecipeRequest extends FormRequest
*
* @return array
*/
public function rules()
public function rules(): array
{
$rules = [
'seo_title' => 'required|min:3|max:70',
@ -54,7 +54,7 @@ class StoreRecipeRequest extends FormRequest
'picture_thumbnail_alt' => 'required|min:3|max:255',
'picture_thumbnail_title' => 'required|min:3|max:255',
'ingredients' => [
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
'present', 'array', function ($attribute, array $value, $fail) {
if (1 > count($value)) {
$fail(\trans('You must fill in at least 1 line of ingredients.'));
@ -67,8 +67,8 @@ class StoreRecipeRequest extends FormRequest
'teaser' => 'required|min:50|max:160',
'steps' => 'required|string|min:15',
'difficulty' => [new Enum(DifficultyEnum::class)],
'duration' => 'required|string|min:1|max:150',
'tips' => 'nullable|string|min:15',
'duration' => 'required|numeric|between:1,1440',
'tips' => 'required|string|min:15',
'range_id' => 'required|exists:ranges,id',
'status' => 'required|boolean'
];

View file

@ -11,7 +11,7 @@ class UpdateRecipeRequest extends StoreRecipeRequest
*
* @return array
*/
public function rules()
public function rules(): array
{
$rules = [
'slug' => UniqueTranslationRule::for('recipes')->ignore($this->recipe->id)
@ -19,8 +19,6 @@ class UpdateRecipeRequest extends StoreRecipeRequest
return \array_merge(
parent::rules(),
$rules,
$this->pictureRules('picture', 1600, 900, 1600, 900, true),
$this->pictureRules('picture_thumbnail', 430, 242, 430, 242, true),
);
}
}

View file

@ -23,7 +23,7 @@ class StoreSliderRequest extends FormRequest
*
* @return boolean
*/
public function authorize()
public function authorize(): bool
{
return auth('backend')->check();
}
@ -33,13 +33,16 @@ class StoreSliderRequest extends FormRequest
*
* @return void
*/
protected function prepareForValidation()
protected function prepareForValidation(): void
{
$this->merge([
'link_new_tab' => $this->link_new_tab ? true : false,
'status' => $this->status ? true : false,
'publish_at' => $this->publish_at ? \str_replace('T', ' ', $this->publish_at) : null,
'unpublish_at' => $this->unpublish_at ? \str_replace('T', ' ', $this->unpublish_at) : null,
'link_new_tab' => $this->boolean('link_new_tab'),
'status' => $this->boolean('status'),
'publish_at' => $this->input('publish_at') ? \str_replace('T', ' ', $this->input('publish_at')) : null,
'unpublish_at' => $this->input('unpublish_at') ?
\str_replace('T', ' ', $this->input('unpublish_at')) :
null,
'locales' => \collect($this->input('locales'))->filter()->unique()->all()
]);
$this->mergePicture('picture');
}
@ -49,7 +52,7 @@ class StoreSliderRequest extends FormRequest
*
* @return array
*/
public function rules()
public function rules(): array
{
$rules = [
'type' => [new Enum(TypeEnum::class)],
@ -62,6 +65,8 @@ class StoreSliderRequest extends FormRequest
'picture_alt' => 'required|min:3|max:255',
'picture_title' => 'required|min:3|max:255',
'status' => 'required|boolean',
'locales' => 'required|array',
'locales.*' => ['required', \sprintf('in:%s', \implode(',', \config('app.locales')))],
'publish_at' => 'sometimes|nullable|date',
'unpublish_at' => 'sometimes|nullable|date'
];
@ -76,7 +81,7 @@ class StoreSliderRequest extends FormRequest
*
* @return array
*/
public function attributes()
public function attributes(): array
{
return [
'type' => trans('type of slider'),

View file

@ -0,0 +1,66 @@
<?php
namespace App\Http\Requests\Bo\StaticPages;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Str;
class UpdateStaticPageRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return boolean
*/
public function authorize(): bool
{
return Gate::check('update', $this->route('static_page'));
}
/**
* Prepare the data for validation.
*
* @return void
*/
public function prepareForValidation(): void
{
/** @var \App\Models\StaticPage $staticPageModel */
$staticPageModel = request()->route()->parameter('static_page');
$this->merge([
'content' => (in_array($staticPageModel->type, \App\Enums\StaticPageType::getEditableContentPages()))
? Str::of($this->input('content'))->value()
: null
]);
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'seo_title' => 'required|min:45|max:70',
'seo_description' => 'required|min:50|max:160',
'title' => 'required|min:3|max:255',
'content' => 'present|string|nullable'
];
}
/**
* Get custom attributes for validator errors.
*
* @return array
*/
public function attributes(): array
{
return [
'seo_title' => trans('validation.custom.seo_title'),
'seo_description' => trans('validation.custom.seo_description'),
'title' => trans('validation.attributes.title'),
'content' => trans('validation.attributes.content'),
];
}
}

View file

@ -14,7 +14,7 @@ class StoreStoreGroupRequest extends FormRequest
*
* @return boolean
*/
public function authorize()
public function authorize(): bool
{
return auth('backend')->check();
}
@ -24,7 +24,7 @@ class StoreStoreGroupRequest extends FormRequest
*
* @return void
*/
protected function prepareForValidation()
protected function prepareForValidation(): void
{
$this->mergePicture('picture');
}
@ -34,7 +34,7 @@ class StoreStoreGroupRequest extends FormRequest
*
* @return array
*/
public function rules()
public function rules(): array
{
$rules = [
'name' => 'required|min:3|max:255',
@ -50,7 +50,7 @@ class StoreStoreGroupRequest extends FormRequest
*
* @return array
*/
public function attributes()
public function attributes(): array
{
return [
'name' => trans('name'),

View file

@ -12,7 +12,7 @@ class UpdateStoreGroupRequest extends StoreStoreGroupRequest
*
* @return array
*/
public function rules()
public function rules(): array
{
$rules = [
'name' => [

View file

@ -14,7 +14,7 @@ class StoreStoreRegionRequest extends FormRequest
*
* @return boolean
*/
public function authorize()
public function authorize(): bool
{
return auth('backend')->check();
}
@ -24,7 +24,7 @@ class StoreStoreRegionRequest extends FormRequest
*
* @return void
*/
protected function prepareForValidation()
protected function prepareForValidation(): void
{
$this->mergePicture('picture');
}
@ -34,7 +34,7 @@ class StoreStoreRegionRequest extends FormRequest
*
* @return array
*/
public function rules()
public function rules(): array
{
$rules = [
'name' => 'required|min:3|max:255',
@ -51,7 +51,7 @@ class StoreStoreRegionRequest extends FormRequest
*
* @return array
*/
public function attributes()
public function attributes(): array
{
return [
'name' => trans('name'),

View file

@ -12,7 +12,7 @@ class UpdateStoreRegionRequest extends StoreStoreRegionRequest
*
* @return array
*/
public function rules()
public function rules(): array
{
$rules = [
'name' => [

View file

@ -11,7 +11,7 @@ class StoreStoreTypeRequest extends FormRequest
*
* @return boolean
*/
public function authorize()
public function authorize(): bool
{
return auth('backend')->check();
}
@ -21,7 +21,7 @@ class StoreStoreTypeRequest extends FormRequest
*
* @return array
*/
public function rules()
public function rules(): array
{
$rules = [
'name' => 'required|min:3|max:255',
@ -36,7 +36,7 @@ class StoreStoreTypeRequest extends FormRequest
*
* @return array
*/
public function attributes()
public function attributes(): array
{
return [
'name' => trans('name'),

View file

@ -12,7 +12,7 @@ class UpdateStoreTypeRequest extends StoreStoreTypeRequest
*
* @return array
*/
public function rules()
public function rules(): array
{
$rules = [
'name' => [

View file

@ -14,7 +14,7 @@ class StoreStoreRequest extends FormRequest
*
* @return boolean
*/
public function authorize()
public function authorize(): bool
{
return auth('backend')->check();
}
@ -24,7 +24,7 @@ class StoreStoreRequest extends FormRequest
*
* @return array
*/
public function rules()
public function rules(): array
{
$rules = [
'state' => 'required|min:3|max:255',
@ -46,7 +46,7 @@ class StoreStoreRequest extends FormRequest
*
* @return array
*/
public function attributes()
public function attributes(): array
{
return [
'state' => trans('State'),

View file

@ -4,6 +4,8 @@ namespace App\Http\Requests\Bo;
use App\Enums\InputType;
use App\Lib\Helpers\ToolboxHelper;
use App\Models\Concept;
use App\Models\News;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\ValidationException;
@ -21,7 +23,7 @@ abstract class UpdateMiniCrudRequest extends FormRequest
*
* @return boolean
*/
public function authorize()
public function authorize(): bool
{
return auth('backend')->check();
}
@ -30,14 +32,24 @@ abstract class UpdateMiniCrudRequest extends FormRequest
* Get the validation rules that apply to the request.
*
* @return array
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.MaxExceeded
* @phpcs:disable Generic.Metrics.NestingLevel.TooHigh
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.MaxExceeded
*/
public function rules()
public function rules(): array
{
// phpcs:enable
$rules = [];
foreach ($this->{$this->modelName}->data as $iptName => $input) {
$data = $this->{$this->modelName}->data ?? null;
if (!$data and $this->route()->getName() === 'bo.concepts.store') {
$data = Concept::getEmptyData();
}
if (
!$data and $this->route()->getName() === 'bo.news.store'
) {
$data = News::getEmptyData();
}
foreach ($data as $iptName => $input) {
$input = \json_decode(\json_encode($input), true);
switch ($input['inputType']) {
case InputType::number->value:
@ -80,7 +92,7 @@ abstract class UpdateMiniCrudRequest extends FormRequest
};
}
return $rule;
});
})->all();
$rules = array_merge($rules, [
"data.$iptName.value" => $mergeRules
]);
@ -100,33 +112,24 @@ abstract class UpdateMiniCrudRequest extends FormRequest
}) : $input['dimensions'];
// * Adapt dimensions
$sizes = (object)[
$sizes = (object) [
'minHeight' => $dim['height'],
'maxHeight' => $dim['height'],
'minWith' => $dim['width'],
'maxWith' => $dim['width'],
];
$rules = array_merge($rules, [
"data.$iptName.value" => [
function (string $attribute, $value, callable $fail) use ($sizes) {
return ToolboxHelper::validatePicture($attribute, $value, $fail, $sizes);
}
],
$this->compileValidate(
implode('|', [
"data.$iptName.value" => $this->compileValidate(
$required,
'image',
'mimes:png,jpg,jpeg',
sprintf(
'dimensions:%s=%d,%s=%d',
$max ? 'max_height' : 'height',
$dim['height'],
$max ? 'max_width' : 'width',
$dim['width']
)
]),
$input
),
"data.$iptName.value" => [
function (string $attribute, $value, callable $fail) use ($sizes) {
if ($value) {
ToolboxHelper::validatePicture($attribute, $value, $fail, $sizes);
}
}
],
"data.$iptName.alt" => $this->compileValidate("$required|string|min:5", $input),
"data.$iptName.title" => $this->compileValidate("$required|string|min:5", $input)
]);
@ -170,9 +173,11 @@ abstract class UpdateMiniCrudRequest extends FormRequest
* @param string|array $inputTypeValidate
* @param array $input
* @return array
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
*/
public function compileValidate(string|array $inputTypeValidate, array $input): array
{
// phpcs:enable
if (\is_string($inputTypeValidate)) {
$inputTypeValidate = explode('|', $inputTypeValidate);
}
@ -185,36 +190,46 @@ abstract class UpdateMiniCrudRequest extends FormRequest
}
}
$test = \collect($inputTypeValidate)->all();
$test = \collect($inputTypeValidate)->sort(function ($valueA, $valueB) {
$valueA = $this->ruleHasToComeFirst($valueA) ? 0 : 2;
$valueB = $this->ruleHasToComeFirst($valueB) ? 1 : 2;
$rules = \collect($inputTypeValidate)->unique()->sort(function ($valueA, $valueB) {
$valueA = $this->ruleHasToComeFirst($valueA);
$valueB = $this->ruleHasToComeFirst($valueB);
return $valueA - $valueB;
})->unique()->all();
});
return \collect($inputTypeValidate)->unique()->sort(function ($valueA, $valueB) {
$valueA = $this->ruleHasToComeFirst($valueA) ? 0 : 2;
$valueB = $this->ruleHasToComeFirst($valueB) ? 1 : 2;
return $valueA - $valueB;
})->all();
$hasRequire = $rules->first(fn ($rule) => $rule === 'required') ? true : false;
$hasRequireCond = $rules->first(fn ($rule) => \strpos($rule, 'required_') !== false) ? true : false;
$hasNullable = $rules->first(fn ($rule) => \strpos($rule, 'nullable') !== false) ? true : false;
$hasSometime = $rules->first(fn ($rule) => \strpos($rule, 'sometimes') !== false) ? true : false;
$hasPresent = $rules->first(fn ($rule) => \strpos($rule, 'present') !== false) ? true : false;
if ($hasRequire and ($hasRequireCond or $hasNullable or $hasSometime or $hasPresent)) {
$rules = $rules->reject(fn ($rule) => $rule === 'required');
}
return $rules->all();
}
/**
* Does the rulle need to come first ?
*
* @param string $rule
* @return boolean
* @return integer
*/
private function ruleHasToComeFirst(string $rule): bool
private function ruleHasToComeFirst(string $rule): int
{
$rule = \collect(\explode(':', $rule, 1))->filter()->first(null, '');
return \collect([
'nullable', 'present', 'required', 'required_if',
$rule = \collect(\explode(':', $rule, 2))->filter()->first(null, '');
$rules = \collect([
'required_if',
'required_unless', 'required_with', 'required_with_all',
'required_without', 'required_without_all', 'required_with_all',
'missing', 'missing_if', 'missing_unless',
'missing_with', 'missing_with_all',
])->first(fn (string $firstRule) => \strpos($rule, $firstRule) === 0) ? true : false;
'nullable', 'sometimes', 'present', 'required'
]);
$itemKey = $rules->search(fn (string $firstRule) => \strpos($rule, $firstRule) === 0);
if (\is_bool($itemKey)) {
return $rules->count() + 1;
}
return $itemKey;
}
/**

View file

@ -18,18 +18,6 @@ class ContactRequest extends FormRequest
return true;
}
/**
* Prepare the data for validation.
*
* @return void
*/
public function prepareForValidation(): void
{
$this->merge([
'terms' => $this->terms ? true : false
]);
}
/**
* Get the validation rules that apply to the request.
*
@ -42,8 +30,7 @@ class ContactRequest extends FormRequest
'last_name' => 'required|min:1',
'email' => 'required|email:rfc,spoof,dns,strict',
'message' => 'required|string|min:10',
'terms' => 'accepted',
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
'g-recaptcha-response' => function (string $attribute, mixed $value, \Closure $fail) {
try {
ToolboxHelper::validateRecaptcha($this, \config('services.google.recaptcha.version'));

View file

@ -0,0 +1,51 @@
<?php
namespace App\Interfaces\Models;
interface Publishable
{
/**
* Get status attribute.
*
* @return boolean
*/
public function getStatus(): bool;
/**
* Set status attribute.
*
* @param boolean $status
* @return void
*/
public function setStatus(bool $status): void;
/**
* Get publish_at attribute.
*
* @return \Carbon\Carbon|null
*/
public function getPublishAt(): ?\Carbon\Carbon;
/**
* Set publish_at attribute.
*
* @param \Carbon\Carbon|null $date
* @return void
*/
public function setPublishAt(?\Carbon\Carbon $date): void;
/**
* Get unpublish_at attribute.
*
* @return \Carbon\Carbon|null
*/
public function getUnpublishAt(): ?\Carbon\Carbon;
/**
* Set unpublish_at attribute.
*
* @param \Carbon\Carbon|null $date
* @return void
*/
public function setUnpublishAt(?\Carbon\Carbon $date): void;
}

View file

@ -0,0 +1,39 @@
<?php
namespace App\Jobs;
use App\Models\News;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Log;
/**
* Update status attribute reading its
* publish_at and unpublish_at attributes.
*/
class NewsStatusUpdate
{
/**
* Called when the job will be executed.
*
* @return void
*/
public function handle()
{
/** @var \Illuminate\Database\Eloquent\Collection<array-key, \App\Models\News> */
$newsListToPublish = News::query()->where('publish_at', '<=', Carbon::now()->toDateTime())
->where('status', false)->get();
Log::debug(__CLASS__ . " news to publish " . $newsListToPublish->count());
foreach ($newsListToPublish as $news) {
$news->status = true;
$news->saveOrFail();
}
/** @var \Illuminate\Database\Eloquent\Collection<array-key, \App\Models\News> */
$newsListToUnPublish = News::query()->where('unpublish_at', '<=', Carbon::now()->toDateTime())
->where('status', true)->get();
Log::debug(__CLASS__ . " news to unpublish " . $newsListToPublish->count());
foreach ($newsListToUnPublish as $news) {
$news->status = false;
$news->saveOrFail();
}
}
}

View file

@ -19,7 +19,8 @@ class SlidersStatusUpdate
*/
public function handle()
{
$slidersToPublish = Slider::where('publish_at', '<=', Carbon::now()->toDateTime())
/** @var \Illuminate\Database\Eloquent\Collection<array-key, \App\Models\Slider> */
$slidersToPublish = Slider::query()->where('publish_at', '<=', Carbon::now()->toDateTime())
->whereNotNull('publish_at')
->where('status', false)->get();
Log::debug(__CLASS__ . " sliders to publish " . $slidersToPublish->count());
@ -28,7 +29,9 @@ class SlidersStatusUpdate
$slider->status = true;
$slider->saveOrFail();
}
$slidersToUnPublish = Slider::where('unpublish_at', '<=', Carbon::now()->toDateTime())
/** @var \Illuminate\Database\Eloquent\Collection<array-key, \App\Models\Slider> */
$slidersToUnPublish = Slider::query()->where('unpublish_at', '<=', Carbon::now()->toDateTime())
->whereNotNull('unpublish_at')
->where('status', true)->get();
Log::debug(__CLASS__ . " sliders to unpublish " . $slidersToPublish->count());

View file

@ -145,7 +145,7 @@ class ExceptionsHelper
$traceStr .= self::handleArgs($stack);
}
$traceStr .= ")\n";
} elseif (isset($stack['function'])) {
} else {
$traceStr .= "{$stack['function']}(";
if (isset($stack['args'])) {
$traceStr .= self::handleArgs($stack);

View file

@ -118,7 +118,7 @@ class FileStorageHelper
);
return str_replace('/private/', '', $newPath);
}//end if
} //end if
if (\is_object($file) and $file instanceof \SplFileInfo) {
/** @var \SplFileInfo $file */
$filename = $filename ?: $file->getBaseName();
@ -309,7 +309,6 @@ class FileStorageHelper
$private ? 'app/private/modelfiles' : 'app/public/modelfiles',
$tableName,
$filename,
$private
);
$filename = self::getFileUniqueName($folderPath, $filename);
return "{$folderPath}/{$filename}";
@ -404,7 +403,7 @@ class FileStorageHelper
$filename = Str::of($filename)->ltrim('.-');
// * Optional beautification
if ($beautify) {
$filename = static::beautifyFilename($filename);
$filename = self::beautifyFilename($filename);
}
// * Maximize filename length to 255 bytes http://serverfault.com/a/9548/44086
/** @var string */

View file

@ -6,22 +6,55 @@ use Carbon\Carbon;
use Illuminate\Contracts\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Illuminate\Validation\ValidationException;
use Symfony\Component\Finder\SplFileInfo;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class ToolboxHelper
{
/**
* @param array<int|string, mixed> $array1
* @param array<int|string, mixed> $array2
* Fetch class list from a specific namespace
*
* @return array<int|string, mixed>
* @param string $namespace
* @return array<string> An array of classe namespaces
*/
public static function getClassesUsingNamespace(string $namespace): array
{
return collect(File::files(\app_path(Str::of($namespace)->replaceFirst('\App', ''))))
->filter(fn (SplFileInfo $splFileInfo) => $splFileInfo->getExtension() === 'php')
->map(fn (SplFileInfo $splFileInfo) => Str::of($splFileInfo->getBasename())
->replace('.' . $splFileInfo->getExtension(), '')->prepend("{$namespace}\\"))->all();
}
/**
* Get all classes from a specific namespace that implement a specific interface
*
* @param string $namespace
* @param string $interface
* @return array<string> An array of classe namespaces
*/
public static function getClassesUsingInterface(string $namespace, string $interface): array
{
return Arr::where(
static::getClassesUsingNamespace($namespace),
fn (string $class_namespace) => \collect(class_implements($class_namespace, true))->filter()
->contains(fn (string $class_interface) => $class_interface === $interface)
);
}
/**
* @param array<integer|string, mixed> $array1
* @param array<integer|string, mixed> $array2
*
* @return array<integer|string, mixed>
*/
public static function arrayMergeRecursiveDistinct(array &$array1, array &$array2): array
{
@ -171,11 +204,10 @@ class ToolboxHelper
$url = $match;
try {
$request = Request::create($url);
// If a route is match then it do not throws exception.
if (
\parse_url(config('app.url'), \PHP_URL_HOST) === \parse_url($url, \PHP_URL_HOST) &&
$routes->match($request)
) {
// Assert route matches existing routes.
$routes->match($request);
// ? Is url internal ?
if (\parse_url(config('app.url'), \PHP_URL_HOST) === \parse_url($url, \PHP_URL_HOST)) {
// Removes the matched url.
throw ValidationException::withMessages([
$field => trans(
@ -201,14 +233,14 @@ class ToolboxHelper
* @param array|string $replace
* @param array|string $subject
* @param integer $count
* @return array|string
* @return array|string|false
*/
public static function mbReplace(
array|string $search,
array|string $replace,
array|string $subject,
int &$count = 0
): array|string {
): array|string|false {
if (!is_array($search) && is_array($replace)) {
return false;
}
@ -285,9 +317,12 @@ class ToolboxHelper
public static function getOriginal(Model $model, string $attribute): mixed
{
if (\in_array('Spatie\Translatable\HasTranslations', \class_uses_recursive($model))) {
// @phpstan-ignore-next-line
return $model->getTranslation(
$attribute,
// @phpstan-ignore-next-line
$model->getLocale(),
// @phpstan-ignore-next-line
$model->useFallbackLocale()
);
}
@ -357,55 +392,55 @@ class ToolboxHelper
/**
* Convert deeply an object to array
*
* @param array|object $input
* @param mixed $input
* @return array
* @throws \RuntimeException If $input var is a scalar value.
*/
public static function objectToArray($input): array
public static function objectToArray(mixed $input): array
{
// Only process if it's an object or array being passed to the function.
if (is_object($input) or is_array($input)) {
$ret = (array)$input;
if (!(is_object($input) or is_array($input))) {
throw new \RuntimeException('Cannot handle $input of type ' . \gettype($input));
}
$ret = (array) $input;
foreach ($ret as &$item) {
// Recursively process EACH element only if not scalar.
$item = (is_object($item) or is_array($item)) ?
self::objectToArray($item) : $item;
}
return $ret;
} else {
throw new \RuntimeException('Cannot handle $input of type ' . \gettype($input));
}
}
/**
* Convert deeply an array to object
*
* @param array|object $input
* @param mixed $input
* @return object
* @throws \RuntimeException If $input var is a scalar value.
*/
public static function arrayToObject($input): object
public static function arrayToObject(mixed $input): object
{
// Only process if it's an object or array being passed to the function.
if (is_object($input) or is_array($input)) {
$ret = (object)$input;
if (!(is_object($input) or is_array($input))) {
throw new \RuntimeException('Cannot handle $input of type ' . \gettype($input));
}
$ret = (object) $input;
foreach ($ret as &$item) {
// Recursively process EACH element only if not scalar.
$item = (is_object($item) or is_array($item)) ?
self::arrayToObject($item) : $item;
}
return $ret;
} else {
throw new \RuntimeException('Cannot handle $input of type ' . \gettype($input));
}
}
/**
* Validate picture
*
* @param string $attribute
* @param string|null $value
* @param callback $fail
* @param callable $fail
* @param object $sizes
* @return void
*/
@ -428,7 +463,7 @@ class ToolboxHelper
'attribute' => $attribute
]));
}
if (!($dimensions = \getimagesize($fileFullPath)) or !isset($dimensions[0]) or !isset($dimensions[1])) {
if (!($dimensions = \getimagesize($fileFullPath))) {
$fail(trans(':attribute impossible de valider les dimensions', [
'attribute' => $attribute
]));

View file

@ -46,10 +46,9 @@ class ContactMessageReceived extends Mailable
'no-reply@nature-and-respect.com',
'Kontaktformular'
),
to: new Address(
to: [
'contact@nature-and-respect.com',
'contact@nature-and-respect.com'
)
]
);
}

View file

@ -14,6 +14,11 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use Illuminate\Validation\Rules\Enum;
use Spatie\Sitemap\Contracts\Sitemapable;
use Uwil\Seo\Laravel\Interfaces\SeoInterface;
use Uwil\Seo\Laravel\Objects\SeoItem;
use Uwil\Seo\Laravel\Traits\SeoTrait;
use Uwil\SitemapGenerator\Lib\SitemapHelper;
/**
* @property string $seo_title
@ -30,15 +35,18 @@ use Illuminate\Validation\Rules\Enum;
* @property string $created_at
* @property string $updated_at
*/
class Concept extends Model
class Concept extends Model implements SeoInterface, Sitemapable
{
use HasFactory;
use HasTranslations;
use IsCachedAsCollection;
use MiniCrudModel;
use SeoTrait;
/**
* @var array
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'seo_title',
@ -61,7 +69,7 @@ class Concept extends Model
/**
* The attributes that should be cast.
*
* @var array
* @var array<string, string>
*/
protected $casts = [
'data' => 'object',
@ -71,7 +79,7 @@ class Concept extends Model
/**
* The translatable columns.
*
* @var array
* @var array<string>
*/
public $translatable = [
'data',
@ -133,10 +141,10 @@ class Concept extends Model
/**
* Common methods function.
*
* @param Model $model
* @param self $model
* @return void
*/
private static function manageFields(Model $model)
private static function manageFields(self $model)
{
self::setSlug($model);
ToolboxHelper::assertNoInternalBoUrls('description', $model->description);
@ -146,11 +154,11 @@ class Concept extends Model
/**
* Set the slug.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param self $model
*
* @return void
*/
private static function setSlug(Model $model)
private static function setSlug(self $model)
{
$model->slug = Str::slug($model->name);
}
@ -158,10 +166,10 @@ class Concept extends Model
/**
* Set order after the last element of the list.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param self $model
* @return void
*/
private static function setOrder(Model $model): void
private static function setOrder(self $model): void
{
$model->order = \intval(self::query()->max('order')) + 1;
}
@ -199,11 +207,13 @@ class Concept extends Model
string $imgAlt = '',
string $imgTitle = ''
) {
$color = $color ?: \collect(ColorsEnum::cases())->random()->value;
/** @var \App\Enums\Concepts\ColorsEnum */
$defaultColor = \collect(ColorsEnum::cases())->random();
$color = $color ?: $defaultColor->value;
$data = [];
for ($i = 1; $i <= 6; $i++) {
$data = self::emptyDataBloc(
$i,
\strval($i),
$data,
$title,
$color,
@ -250,13 +260,17 @@ class Concept extends Model
'label' => "Bloc {$index} - Title",
'inputType' => InputType::string->value,
'value' => $title,
'validate' => 'required|min:4|max:100'
'validate' => ($index > 4 ? "required_if:bloc_{$index}_use_bloc,true" : 'required') . '|min:4|max:100'
];
$data["bloc_{$index}_color"] = [
'label' => "Bloc {$index} - Color",
'inputType' => InputType::selectEnum->value,
'value' => $color,
'validate' => ['required', 'integer', new Enum(ColorsEnum::class)]
'validate' => [
($index > 4 ? "required_if:bloc_{$index}_use_bloc,true" : 'required'),
'integer',
new Enum(ColorsEnum::class)
]
];
$data["bloc_{$index}_text"] = [
'label' => "Bloc {$index} - Text",
@ -271,7 +285,7 @@ class Concept extends Model
'alt' => $imgAlt,
'title' => $imgTitle,
'value' => $img,
'validate' => "required_if:data.bloc_{$index}_has_video.value,false",
'validate' => ($index > 4 ? "required_if:bloc_{$index}_use_bloc,true" : '') . '',
];
$data["bloc_{$index}_video"] = [
@ -280,7 +294,7 @@ class Concept extends Model
'value' => '',
// phpcs:ignore Generic.Files.LineLength.TooLong
'validate' => [
'required_if:data.bloc_{$i}_has_video.value,true',
"required_if:data.bloc_{$index}_has_video.value,true",
'nullable',
'regex:%([0-9]{8,10}|[^\"&?\/\s]{11})%i'
],
@ -293,6 +307,45 @@ class Concept extends Model
'value' => false,
];
if ($index > 4) {
$data["bloc_{$index}_title"]['required'] = false;
$data["bloc_{$index}_title"]['validate'] .= '|nullable';
$data["bloc_{$index}_color"]['required'] = false;
$data["bloc_{$index}_text"]['required'] = false;
$data["bloc_{$index}_text"]['validate'] .= '|nullable';
$data["bloc_{$index}_image"]['required'] = false;
$data["bloc_{$index}_image"]['validate'] .= '|nullable';
$data["bloc_{$index}_video"]['required'] = false;
$data["bloc_{$index}_has_video"]['required'] = false;
}
return $data;
}
/**
* Get the SEO object.
*
* @return \Uwil\Seo\Laravel\Objects\SeoItem
*/
public function toSeoItem(): \Uwil\Seo\Laravel\Objects\SeoItem
{
return new SeoItem(
\trans($this->getTable()),
$this->seo_title,
$this->seo_description,
true,
\route(\config('seo.bo_route_prefix') . $this->getTable() . '.edit', $this),
\route(Str::singular($this->getTable()) . '.show', $this)
);
}
/**
* To sitemap tag .
*
* @return \Spatie\Sitemap\Tags\Url|string|array
*/
public function toSitemapTag(): \Spatie\Sitemap\Tags\Url|string|array
{
return SitemapHelper::generateUrl('concept.show', ['concept' => $this], $this);
}
}

View file

@ -11,8 +11,6 @@ use Illuminate\Database\Eloquent\Model;
/**
* @property integer $part2_product1_id
* @property integer $part2_product2_id
* @property string $seo_title
* @property string $seo_description
* @property string $part1_title
* @property string $part1_subtitle
* @property string $part1_text_1
@ -32,13 +30,13 @@ class Home extends Model
use HasTranslations;
/**
* @var array
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'part2_product1_id',
'part2_product2_id',
'seo_title',
'seo_description',
'part1_title',
'part1_subtitle',
'part1_text_1',
@ -58,7 +56,7 @@ class Home extends Model
/**
* The attributes that should be cast.
*
* @var array
* @var array<string, string>
*/
protected $casts = [
'part2_list' => 'array',
@ -70,8 +68,6 @@ class Home extends Model
* @var array
*/
public $translatable = [
'seo_title',
'seo_description',
'part1_title',
'part1_subtitle',
'part1_text_1',
@ -113,10 +109,10 @@ class Home extends Model
/**
* Undocumented function
*
* @param Model $model
* @param self $model
* @return void
*/
private static function manageFields(Model $model)
private static function manageFields(self $model)
{
ToolboxHelper::assertNoInternalBoUrls('part1_text_1', $model->part1_text_1);
ToolboxHelper::assertNoInternalBoUrls('part1_text_2', $model->part1_text_2);

344
app/Models/News.php Normal file
View file

@ -0,0 +1,344 @@
<?php
namespace App\Models;
use App\Enums\InputType;
use App\Interfaces\Models\Publishable;
use App\Lib\Helpers\FileStorageHelper;
use App\Lib\Helpers\ToolboxHelper;
use App\Traits\Models\HasTranslations;
use App\Traits\Models\IsPublishable;
use App\Traits\Models\MiniCrudModel;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Spatie\SchemaOrg\Schema;
use Spatie\Sitemap\Contracts\Sitemapable;
use Uwil\SchemaOrg\Laravel\Interfaces\SchemaOrgInterface;
use Uwil\SchemaOrg\Laravel\Traits\SchemaOrgTrait;
use Uwil\Seo\Laravel\Interfaces\SeoInterface;
use Uwil\Seo\Laravel\Objects\SeoItem;
use Uwil\Seo\Laravel\Traits\SeoTrait;
use Uwil\SitemapGenerator\Lib\SitemapHelper;
/**
* @property string $seo_title
* @property string $seo_description
* @property string $title
* @property string $slug
* @property string $subtitle
* @property string $content
* @property \Illuminate\Support\Collection $picture_list
* @property object $data
* @property integer $order
* @property boolean $status
* @property \Carbon\Carbon|null $publish_at
* @property \Carbon\Carbon|null $unpublish_at
* @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at
*/
class News extends Model implements SeoInterface, Publishable, SchemaOrgInterface, Sitemapable
{
use HasFactory;
use HasTranslations;
use MiniCrudModel;
use SeoTrait;
use IsPublishable;
use SchemaOrgTrait;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'seo_title',
'seo_description',
'title',
'slug',
'subtitle',
'content',
'data',
'locales',
'order',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'data' => 'object',
'locales' => 'array',
'status' => 'bool',
'publish_at' => 'datetime',
'unpublish_at' => 'datetime'
];
/**
* The translatable columns.
*
* @var array
*/
public $translatable = [
'seo_title',
'seo_description',
'title',
'slug',
'subtitle',
'content',
'data'
];
// * EVENTS
/**
* Perform any actions required after the model boots.
*
* @return void
*/
protected static function booted()
{
static::creating(function (self $model) {
// * ASSERTIONS
self::assertTitleIsUnique($model->title);
ToolboxHelper::assertNoInternalBoUrls('content', $model->content);
// * TRANSFORMATIONS
self::setSlug($model);
$model->content = FileStorageHelper::storeModelFilesFromHtml($model, $model->content);
$model->makeStatusSense();
self::setOrder($model);
});
static::updating(function (self $model) {
// * ASSERTIONS
self::assertTitleIsUnique($model->title);
ToolboxHelper::assertNoInternalBoUrls('content', $model->content);
// * TRANSFORMATIONS
self::setSlug($model);
$model->content = FileStorageHelper::storeModelFilesFromHtml($model, $model->content);
$model->makeStatusSense();
});
static::updated(function (self $model) {
FileStorageHelper::removeOldModelFilesFromHtml(
$model->content,
ToolboxHelper::getOriginal($model, 'content')
);
});
static::deleted(function (self $model) {
FileStorageHelper::removeModelFilesOfHtml($model->content);
$model->minicrudDeleted();
});
}
// * METHODS
/**
* Apply function on data typed text while on deleted event
*
* @return void
*/
public function minicrudDeleted()
{
/** @var array */
foreach ($this->data as $input) {
switch ($input['inputType']) {
case InputType::text->value:
FileStorageHelper::removeModelFilesOfHtml($input['text']);
break;
}
}
}
/**
* Get picture_list attribute
*
* @return \Illuminate\Support\Collection
*/
public function getPictureListAttribute(): Collection
{
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
return \collect($this->data)->filter(fn($value, $key) => \preg_match('/bloc[0-9]+/u', $key) !== false)
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
->groupBy(fn($value, $key) => \collect(\explode('_', $key))->take(2)->implode('_'))
->filter(fn(Collection $blocks) => \collect($blocks->first())->get('value'))
->map(function (Collection $blocks) {
$pictureBlock = (object) $blocks->last();
return (object) [
'value' => $pictureBlock->value,
'title' => $pictureBlock->title,
'alt' => $pictureBlock->alt
];
})->values();
}
/**
* Set the slug.
*
* @param self $model
*
* @return void
*/
private static function setSlug(self $model)
{
$model->slug = Str::slug($model->title);
}
/**
* Set order after the last element of the list.
*
* @param self $model
* @return void
*/
private static function setOrder(self $model): void
{
$model->order = \intval(self::query()->max('order')) + 1;
}
/**
* Asserts using validation that the title is unique
*
* @param string|integer|float|boolean|null|array $title
* @param integer|null $id
* @return void
* @throws \Illuminate\Validation\ValidationException If an news title already exists.
*/
private static function assertTitleIsUnique(string|int|float|bool|null|array $title, ?int $id = null)
{
$table = (new self())->getTable();
ToolboxHelper::assertFieldIsUnique($table, 'title', $title, $id);
ToolboxHelper::assertFieldIsUnique($table, 'slug', Str::slug($title), $id);
}
/**
* Return the structure necessary of data.
*
* @param string $img
* @param string $imgAlt
* @param string $imgTitle
* @return ((string|\App\Enums\InputType)[]|(string|int[]|\App\Enums\InputType)[]|(string|\App\Enums\InputType|int|(string|\Illuminate\Validation\Rules\Enum)[])[])[]
*/
public static function getEmptyData(
string $img = '',
string $imgAlt = '',
string $imgTitle = ''
) {
$data = [];
$data = self::emptyDataBloc(
'1',
$data,
$img,
$imgAlt,
$imgTitle,
true
);
for ($i = 2; $i <= 3; $i++) {
$data = self::emptyDataBloc(
strval($i),
$data,
$img,
$imgAlt,
$imgTitle,
false
);
} //end for
return $data;
}
/**
* Empty data bloc
*
* @param string $index
* @param array $data
* @param string $img
* @param string $imgAlt
* @param string $imgTitle
* @param boolean $required
* @return array
*/
public static function emptyDataBloc(
string $index,
array $data,
string $img = '',
string $imgAlt = '',
string $imgTitle = '',
bool $required = false,
): array {
$data["bloc_{$index}_display_picture"] = [
'label' => "Bloc {$index} - Display picture",
'inputType' => InputType::boolean->value,
'value' => $required
];
$data["bloc_{$index}_image"] = [
'label' => "Bloc {$index} - Image",
'dimensions' => ['width' => 770, 'height' => 770],
'inputType' => InputType::image->value,
'alt' => $imgAlt,
'title' => $imgTitle,
'value' => $img,
'validate' => "required_if:data.bloc_{$index}_display_picture.value,true|nullable",
'required' => $required
];
return $data;
}
/**
* Create a SchemaOrg.
*
* @return \Spatie\SchemaOrg\NewsArticle
*/
public function toSchemaOrg(): \Spatie\SchemaOrg\NewsArticle
{
return Schema::NewsArticle()
->headline($this->seo_title)
->description($this->seo_description)
->name($this->title)
->inLanguage(config('schema-org.website.languages')[app()->currentLocale()])
->abstract($this->subtitle)
->dateCreated($this->created_at)
->dateModified($this->updated_at)
->datePublished($this->publish_at)
->articleBody(strip_tags($this->content))
->wordCount(str_word_count(strip_tags($this->content)))
->url(route('news.show', $this))
->author($this->getOrganizationSchema())
->creator($this->getOrganizationSchema())
->copyrightYear($this->created_at->year)
->image(
Schema::imageObject()
->url(asset($this->data['bloc_1_image']['value']))
->headline($this->data['bloc_1_image']['title'])
);
}
/**
* Get the SEO object.
*
* @return \Uwil\Seo\Laravel\Objects\SeoItem
*/
public function toSeoItem(): \Uwil\Seo\Laravel\Objects\SeoItem
{
return new SeoItem(
\trans($this->getTable()),
$this->seo_title,
$this->seo_description,
$this->status,
\route(\config('seo.bo_route_prefix') . $this->getTable() . '.edit', $this),
\route(Str::singular($this->getTable()) . '.show', $this)
);
}
/**
* To sitemap tag .
*
* @return \Spatie\Sitemap\Tags\Url|string|array
*/
public function toSitemapTag(): \Spatie\Sitemap\Tags\Url|string|array
{
return SitemapHelper::generateUrl('news.show', ['publishedNews' => $this], $this);
}
}

View file

@ -8,6 +8,14 @@ use App\Traits\Models\HasTranslations;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use Uwil\Seo\Laravel\Interfaces\SeoInterface;
use Uwil\Seo\Laravel\Traits\SeoTrait;
use Spatie\SchemaOrg\Schema;
use Spatie\Sitemap\Contracts\Sitemapable;
use Uwil\SchemaOrg\Laravel\Interfaces\SchemaOrgInterface;
use Uwil\SchemaOrg\Laravel\Traits\SchemaOrgTrait;
use Uwil\Seo\Laravel\Objects\SeoItem;
use Uwil\SitemapGenerator\Lib\SitemapHelper;
/**
* @property integer $range_id
@ -23,16 +31,20 @@ use Illuminate\Support\Str;
* @property array $list
* @property boolean $status
* @property integer $order
* @property string $created_at
* @property string $updated_at
* @property-read \Carbon\Carbon $created_at Created date.
* @property-read \Carbon\Carbon $updated_at Updated date.
*/
class Product extends Model
class Product extends Model implements SeoInterface, SchemaOrgInterface, Sitemapable
{
use HasFactory;
use HasTranslations;
use SeoTrait;
use SchemaOrgTrait;
/**
* @var array
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'range_id',
@ -60,7 +72,7 @@ class Product extends Model
/**
* The attributes that should be cast.
*
* @var array
* @var array<string, string>
*/
protected $casts = [
'certifications' => 'array',
@ -120,10 +132,10 @@ class Product extends Model
/**
* Undocumented function
*
* @param Model $model
* @param self $model
* @return void
*/
private static function manageFields(Model $model)
private static function manageFields(self $model)
{
self::setSlug($model);
if (is_array($model->list)) {
@ -143,11 +155,11 @@ class Product extends Model
/**
* Set the slug.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param self $model
*
* @return void
*/
private static function setSlug(Model $model)
private static function setSlug(self $model)
{
$model->slug = Str::slug($model->label);
}
@ -169,14 +181,72 @@ class Product extends Model
/**
* Set order after the last element of the list.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param self $model
* @return void
*/
private static function setOrder(Model $model): void
private static function setOrder(self $model): void
{
$model->order = \intval(self::query()->max('order')) + 1;
}
/**
* Create a SchemaOrg.
*
* @return \Spatie\SchemaOrg\Product
*/
public function toSchemaOrg(): \Spatie\SchemaOrg\Product
{
$model = $this->load(['range']);
// Main.
$schema = Schema::Product()
->name($model->seo_title)
->description($model->seo_description)
->url(route('product.show', $model->slug))
->keywords('produit')
->releaseDate($model->created_at)
->image([
Schema::imageObject()
->url(asset($model->picture))
->headline($model->picture_title),
])
->brand($model->getBrandSchema());
// Range associated.
if ($model->range->status) {
$schema->subjectOf($model->range->toSchemaOrg()->toArray());
}
return $schema;
}
/**
* Get the SEO object.
*
* @return \Uwil\Seo\Laravel\Objects\SeoItem
*/
public function toSeoItem(): \Uwil\Seo\Laravel\Objects\SeoItem
{
return new SeoItem(
\trans($this->getTable()),
$this->seo_title,
$this->seo_description,
$this->status,
\route(\config('seo.bo_route_prefix') . $this->getTable() . '.edit', $this),
\route(Str::singular($this->getTable()) . '.show', $this)
);
}
/**
* To sitemap tag .
*
* @return \Spatie\Sitemap\Tags\Url|string|array
*/
public function toSitemapTag(): \Spatie\Sitemap\Tags\Url|string|array
{
return SitemapHelper::generateUrl('product.show', ['publishedProduct' => $this], $this);
}
// * RELATIONSHIPS
/**

View file

@ -8,6 +8,12 @@ use App\Traits\Models\HasTranslations;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use Spatie\SchemaOrg\Schema;
use Uwil\SchemaOrg\Laravel\Interfaces\SchemaOrgInterface;
use Uwil\SchemaOrg\Laravel\Traits\SchemaOrgTrait;
use Uwil\Seo\Laravel\Interfaces\SeoInterface;
use Uwil\Seo\Laravel\Objects\SeoItem;
use Uwil\Seo\Laravel\Traits\SeoTrait;
/**
* @property string $seo_title
@ -20,13 +26,17 @@ use Illuminate\Support\Str;
* @property string $created_at
* @property string $updated_at
*/
class Range extends Model
class Range extends Model implements SeoInterface, SchemaOrgInterface
{
use HasFactory;
use HasTranslations;
use SeoTrait;
use SchemaOrgTrait;
/**
* @var array
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'seo_title',
@ -43,7 +53,7 @@ class Range extends Model
/**
* The attributes that should be cast.
*
* @var array
* @var array<string, string>
*/
protected $casts = [
'picto' => PictoEnum::class,
@ -85,11 +95,11 @@ class Range extends Model
/**
* Set the slug.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param self $model
*
* @return void
*/
private static function setSlug(Model $model)
private static function setSlug(self $model)
{
$model->slug = Str::slug($model->label);
}
@ -97,10 +107,10 @@ class Range extends Model
/**
* Common methods function
*
* @param Model $model
* @param self $model
* @return void
*/
private static function manageFields(Model $model)
private static function manageFields(self $model)
{
self::setSlug($model);
}
@ -122,14 +132,29 @@ class Range extends Model
/**
* Set order after the last element of the list.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param self $model
* @return void
*/
private static function setOrder(Model $model): void
private static function setOrder(self $model): void
{
$model->order = \intval(self::query()->max('order')) + 1;
}
/**
* Create a SchemaOrg.
*
* @return \Spatie\SchemaOrg\DefinedTermSet
*/
public function toSchemaOrg(): \Spatie\SchemaOrg\DefinedTermSet
{
return Schema::definedTermSet()
->hasDefinedTerm(
Schema::definedTerm()
->name($this->seo_title)
->description($this->seo_description)
);
}
// * RELATIONSHIPS
/**
@ -147,4 +172,21 @@ class Range extends Model
{
return $this->hasMany('App\Models\Product');
}
/**
* Get the SEO object.
*
* @return \Uwil\Seo\Laravel\Objects\SeoItem
*/
public function toSeoItem(): \Uwil\Seo\Laravel\Objects\SeoItem
{
return new SeoItem(
\trans($this->getTable()),
$this->seo_title,
$this->seo_description,
$this->status ?? false,
\route(\config('seo.bo_route_prefix') . $this->getTable() . '.edit', $this),
'#'
);
}
}

View file

@ -9,6 +9,14 @@ use App\Traits\Models\HasTranslations;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use Uwil\Seo\Laravel\Interfaces\SeoInterface;
use Uwil\Seo\Laravel\Traits\SeoTrait;
use Spatie\SchemaOrg\Schema;
use Spatie\Sitemap\Contracts\Sitemapable;
use Uwil\SchemaOrg\Laravel\Interfaces\SchemaOrgInterface;
use Uwil\SchemaOrg\Laravel\Traits\SchemaOrgTrait;
use Uwil\Seo\Laravel\Objects\SeoItem;
use Uwil\SitemapGenerator\Lib\SitemapHelper;
/**
* @property integer $range_id
@ -18,24 +26,28 @@ use Illuminate\Support\Str;
* @property string $slug
* @property string $picture
* @property string $picture_thumbnail
* @property string $ingredients
* @property array<array<string>> $ingredients
* @property string $teaser
* @property string $steps
* @property \App\Enums\Recipes\DifficultyEnum $difficulty
* @property string $duration
* @property integer $duration
* @property string $tips
* @property boolean $status
* @property integer $order
* @property string $created_at
* @property string $updated_at
* @property-read \Illuminate\Support\Carbon $created_at Created date.
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
*/
class Recipe extends Model
class Recipe extends Model implements SeoInterface, SchemaOrgInterface, Sitemapable
{
use HasFactory;
use HasTranslations;
use SeoTrait;
use SchemaOrgTrait;
/**
* @var array
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'range_id',
@ -64,11 +76,11 @@ class Recipe extends Model
/**
* The attributes that should be cast.
*
* @var array
* @var array<string, string>
*/
protected $casts = [
'ingredients' => 'json',
'difficulty' => DifficultyEnum::class
'ingredients' => 'array',
'difficulty' => DifficultyEnum::class,
];
/**
@ -88,7 +100,6 @@ class Recipe extends Model
'picture_thumbnail_alt',
'picture_thumbnail_title',
'ingredients',
'duration',
'teaser',
'steps',
'tips',
@ -127,19 +138,18 @@ class Recipe extends Model
/**
* Common methods function.
*
* @param Model $model
* @param self $model
* @return void
*/
private static function manageFields(Model $model)
private static function manageFields(self $model)
{
if (is_array($model->ingredients)) {
/** @var array<string,string> $itemIngredients */
foreach ($model->ingredients as $itemIngredients) {
if (isset($itemIngredients['header'])) {
ToolboxHelper::assertNoInternalBoUrls('ingredients', $itemIngredients['header']);
}
ToolboxHelper::assertNoInternalBoUrls('ingredients', \strval($itemIngredients['value']));
}
}
ToolboxHelper::assertNoInternalBoUrls('steps', $model->steps);
ToolboxHelper::assertNoInternalBoUrls('tips', $model->tips);
$model->picture = FileStorageHelper::storeFile($model, $model->picture, true);
@ -149,11 +159,11 @@ class Recipe extends Model
/**
* Set the slug.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param self $model
*
* @return void
*/
private static function setSlug(Model $model)
private static function setSlug(self $model)
{
$model->slug = Str::slug($model->name);
}
@ -161,10 +171,10 @@ class Recipe extends Model
/**
* Set order after the last element of the list.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param self $model
* @return void
*/
private static function setOrder(Model $model): void
private static function setOrder(self $model): void
{
$model->order = \intval(self::query()->max('order')) + 1;
}
@ -183,6 +193,88 @@ class Recipe extends Model
ToolboxHelper::assertFieldIsUnique($table, $nameField, $valueField, $id);
}
/**
* Create and return microdata.
*
* @return \Spatie\SchemaOrg\Recipe
*/
public function toSchemaOrg(): \Spatie\SchemaOrg\Recipe
{
$model = $this->load(['range']);
$schema = Schema::Recipe()
->name($model->seo_title)
->description($model->seo_description)
->url(route('recipe.show', $this))
->inLanguage(config('schema-org.website.languages')[app()->currentLocale()])
->keywords('recette')
->recipeCategory([
$model->difficulty->label(),
])
->recipeCuisine("Française")
->recipeInstructions(strip_tags($model->tips))
->dateCreated($model->created_at)
->dateModified($model->updated_at)
->datePublished($model->created_at)
->totalTime(
Schema::duration()->setProperty("@value", $model->formatDurationIso($model->duration))
)
->author($model->getOrganizationSchema())
->creator($model->getOrganizationSchema())
->image(
Schema::imageObject()
->url(asset($model->picture))
->headline($model->picture_title)
);
// Steps.
preg_match_all('/<li>(.*?)<\/li>/', $model->steps, $step);
if (count($step[1])) {
$schema->steps($step[1]);
}
// Ingredients.
$ingredientsList = [];
foreach ($model->ingredients as $ingredient) {
array_push($ingredientsList, $ingredient['value']);
};
$schema->ingredients($ingredientsList);
// Range associated.
if ($model->range->status) {
$schema->subjectOf($model->range->toSchemaOrg()->toArray());
}
return $schema;
}
/**
* Get the SEO object.
*
* @return \Uwil\Seo\Laravel\Objects\SeoItem
*/
public function toSeoItem(): \Uwil\Seo\Laravel\Objects\SeoItem
{
return new SeoItem(
\trans($this->getTable()),
$this->seo_title,
$this->seo_description,
$this->status,
\route(\config('seo.bo_route_prefix') . $this->getTable() . '.edit', $this),
\route(Str::singular($this->getTable()) . '.show', $this)
);
}
/**
* To sitemap tag .
*
* @return \Spatie\Sitemap\Tags\Url|string|array
*/
public function toSitemapTag(): \Spatie\Sitemap\Tags\Url|string|array
{
return SitemapHelper::generateUrl('recipe.show', ['publishedRecipe' => $this], $this);
}
// * RELATIONSHIPS
/**

View file

@ -10,7 +10,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
/**
* @property boolean $type
* @property \App\Enums\Sliders\TypeEnum $type
* @property string $title
* @property string $subtitle
* @property string $description
@ -20,10 +20,10 @@ use Illuminate\Database\Eloquent\Model;
* @property string $picture
* @property boolean $status
* @property integer $order
* @property string $unpublish_at
* @property string $publish_at
* @property string $created_at
* @property string $updated_at
* @property string|null $unpublish_at
* @property string|null $publish_at
* @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at
*/
class Slider extends Model
{
@ -31,7 +31,9 @@ class Slider extends Model
use HasTranslations;
/**
* @var array
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'type',
@ -46,6 +48,7 @@ class Slider extends Model
'picture_title',
'status',
'order',
'locales',
'unpublish_at',
'publish_at',
'created_at',
@ -71,13 +74,14 @@ class Slider extends Model
/**
* The attributes that should be cast.
*
* @var array
* @var array<string, string>
*/
protected $casts = [
'type' => TypeEnum::class,
'status' => 'bool',
'publish_at' => 'datetime',
'unpublish_at' => 'datetime'
'unpublish_at' => 'datetime',
'locales' => 'array',
];
// * EVENTS
@ -115,10 +119,10 @@ class Slider extends Model
/**
* Common methods function.
*
* @param Model $model
* @param self $model
* @return void
*/
private static function manageFields(Model $model)
private static function manageFields(self $model)
{
if ($model->link) {
ToolboxHelper::assertNoInternalBoUrls('link', $model->link);
@ -130,10 +134,10 @@ class Slider extends Model
/**
* Set order after the last element of the list.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param self $model
* @return void
*/
private static function setOrder(Model $model): void
private static function setOrder(self $model): void
{
$model->order = \intval(self::query()->max('order')) + 1;
}

172
app/Models/StaticPage.php Normal file
View file

@ -0,0 +1,172 @@
<?php
namespace App\Models;
use App\Enums\StaticPageType;
use App\Lib\Helpers\ToolboxHelper;
use App\Traits\Models\HasTranslations;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use Spatie\SchemaOrg\Schema;
use Uwil\SchemaOrg\Laravel\Interfaces\SchemaOrgInterface;
use Uwil\SchemaOrg\Laravel\Traits\SchemaOrgTrait;
use Uwil\Seo\Laravel\Interfaces\SeoInterface;
use Uwil\Seo\Laravel\Objects\SeoItem;
use Uwil\Seo\Laravel\Traits\SeoTrait;
/**
* @property \App\Enums\StaticPageType $type Page type (StaticPageEnum).
* @property string $seo_title Seo title about 70 chars as recommended.
* @property string $seo_description Seo description about 160 chars as recommended.
* @property string $title Title for the page.
* @property string $slug Slug of the title for the page.
* @property string $content WYSIWYG text content using ckeditor.
* @property-read \Illuminate\Support\Carbon $created_at Created date.
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
*/
class StaticPage extends Model implements SeoInterface, SchemaOrgInterface
{
use HasFactory;
use HasTranslations;
use SeoTrait;
use SchemaOrgTrait;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'seo_title',
'seo_description',
'title',
'content',
];
/**
* The translatable columns.
*
* @var array
*/
public $translatable = [
'seo_title',
'seo_description',
'title',
'slug',
'content',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'type' => StaticPageType::class,
];
/**
* Perform any actions required after the model boots.
*
* @return void
*/
protected static function booted(): void
{
static::creating(function (self $model) {
// * ASSERTIONS
self::assertTitleIsUnique($model->title);
// * CHANGES
$model->slug = Str::slug($model->title);
});
static::updating(function (self $model) {
// * ASSERTIONS
self::assertTitleIsUnique($model->title, $model->id);
// * CHANGES
$model->slug = Str::slug($model->title);
});
}
// * ROUTABLE
/**
* Get the value of the model's route key.
*
* @return string|integer
*/
public function getRouteKey(): string|int
{
/** @var \App\Enums\StaticPageType */
$enum = $this->getAttribute($this->getRouteKeyName());
return $enum->value();
}
/**
* Get the route key for the model.
*
* ! Type is the routable parameter
*
* @return string
*/
public function getRouteKeyName(): string
{
return 'type';
}
// * METHODS
/**
* Asserts using validation that the title is unique
*
* @param string|null $title
* @param integer|null $id
* @return void
* @throws \Illuminate\Validation\ValidationException If an actu title already exists.
*/
private static function assertTitleIsUnique(string|null $title, ?int $id = null): void
{
$table = (new self())->getTable();
ToolboxHelper::assertFieldIsUnique($table, 'title', $title, $id);
ToolboxHelper::assertFieldIsUnique($table, 'slug', Str::slug($title), $id);
}
/**
* Create a SchemaOrg.
*
* @return \Spatie\SchemaOrg\WebPage
*/
public function toSchemaOrg(): \Spatie\SchemaOrg\WebPage
{
return Schema::webPage()
->name($this->seo_title)
->description($this->seo_description)
->headline($this->title)
->isAccessibleForFree(true)
->keywords(['page'])
->dateCreated($this->created_at)
->dateModified($this->updated_at)
->reviewedBy($this->getOrganizationSchema())
->publisher($this->getOrganizationSchema())
->author($this->getOrganizationSchema())
->isPartOf($this->getWebsiteSchema());
}
/**
* Get the SEO object.
*
* @return \Uwil\Seo\Laravel\Objects\SeoItem
*/
public function toSeoItem(): \Uwil\Seo\Laravel\Objects\SeoItem
{
return new SeoItem(
\trans($this->getTable()),
$this->seo_title,
$this->seo_description,
true,
route('bo.static_pages.edit', $this),
'#',
);
}
}

View file

@ -23,7 +23,9 @@ class Store extends Model
use HasFactory;
/**
* @var array
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'type_id',
@ -42,7 +44,7 @@ class Store extends Model
/**
* The attributes that should be cast.
*
* @var array
* @var array<string, string>
*/
protected $casts = [
'latitude' => 'float',
@ -68,10 +70,10 @@ class Store extends Model
/**
* Set order after the last element of the list.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param self $model
* @return void
*/
private static function setOrder(Model $model): void
private static function setOrder(self $model): void
{
$model->order = \intval(self::query()->max('order')) + 1;
}

View file

@ -19,7 +19,9 @@ class StoreGroup extends Model
use HasFactory;
/**
* @var array
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
@ -59,10 +61,10 @@ class StoreGroup extends Model
/**
* Undocumented function
*
* @param Model $model
* @param self $model
* @return void
*/
private static function manageFields(Model $model)
private static function manageFields(self $model)
{
$model->picture = FileStorageHelper::storeFile($model, $model->picture, true);
}
@ -70,10 +72,10 @@ class StoreGroup extends Model
/**
* Set order after the last element of the list.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param self $model
* @return void
*/
private static function setOrder(Model $model): void
private static function setOrder(self $model): void
{
$model->order = \intval(self::query()->max('order')) + 1;
}

View file

@ -20,14 +20,17 @@ class StoreRegion extends Model
use HasFactory;
/**
* @var array
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'group_id',
'name',
'picture',
'order',
'created_at',
'updated_at'
'updated_at',
];
// * EVENTS
@ -60,10 +63,10 @@ class StoreRegion extends Model
/**
* Undocumented function
*
* @param Model $model
* @param self $model
* @return void
*/
private static function manageFields(Model $model)
private static function manageFields(self $model)
{
$model->picture = FileStorageHelper::storeFile($model, $model->picture, true);
}
@ -71,10 +74,10 @@ class StoreRegion extends Model
/**
* Set order after the last element of the list.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param self $model
* @return void
*/
private static function setOrder(Model $model): void
private static function setOrder(self $model): void
{
$model->order = \intval(self::query()->max('order')) + 1;
}

View file

@ -16,12 +16,15 @@ class StoreType extends Model
use HasFactory;
/**
* @var array
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'order',
'created_at',
'updated_at'
'updated_at',
];
// * EVENTS
@ -58,10 +61,10 @@ class StoreType extends Model
/**
* Set order after the last element of the list.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param self $model
* @return void
*/
private static function setOrder(Model $model): void
private static function setOrder(self $model): void
{
$model->order = \intval(self::query()->max('order')) + 1;
}

View file

@ -0,0 +1,36 @@
<?php
namespace App\Policies;
use App\Models\StaticPage;
use App\Models\User;
class StaticPagePolicy
{
/**
* Determine whether the user can view any models.
*
* @param \App\Models\User $authUser
* @return boolean
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.Found
*/
public function viewAny(User $authUser): bool
{
// phpcs:enable
return auth('backend')->check();
}
/**
* Determine whether the user can update the model.
*
* @param \App\Models\User $authUser
* @param \App\Models\StaticPage $static_page
* @return boolean
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed
*/
public function update(User $authUser, StaticPage $static_page): bool
{
// phpcs:enable
return auth('backend')->check();
}
}

View file

@ -4,6 +4,7 @@ namespace App\Providers;
use App\Lib\Helpers\ToolboxHelper;
use App\Models\Concept;
use App\Models\News;
use App\Models\Product;
use App\Models\Range;
use App\Models\Recipe;
@ -18,6 +19,7 @@ use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvi
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Str;
class RouteServiceProvider extends ServiceProvider
{
@ -55,27 +57,40 @@ class RouteServiceProvider extends ServiceProvider
Route::bind('publishedRecipe', function ($value) use ($defaultLocale) {
$query = Recipe::query()
->whereHas('range', fn (Builder $q) => $q->where('status', true))
->whereHas('range', fn(Builder $q) => $q->where('status', true))
->where('status', true);
return ToolboxHelper::queryColumnWithLocales(
$defaultLocale,
$query,
'slug',
$value
Str::slug(urldecode($value))
)->firstOrFail();
});
Route::bind('publishedProduct', function ($value) use ($defaultLocale) {
$query = Product::query()
->whereHas('range', fn (Builder $q) => $q->where('status', true))
->whereHas('range', fn(Builder $q) => $q->where('status', true))
->where('status', true);
return ToolboxHelper::queryColumnWithLocales(
$defaultLocale,
$query,
'slug',
$value
Str::slug(urldecode($value))
)->firstOrFail();
});
Route::bind('publishedNews', function ($value) use ($defaultLocale) {
$currentLocale = app()->currentLocale();
$query = News::query()
->whereJsonContains('locales', $currentLocale)
->where('status', true);
return ToolboxHelper::queryColumnWithLocales(
$defaultLocale,
$query,
'slug',
Str::slug(urldecode($value))
)->firstOrFail();
});
Route::model('news', News::class);
Route::model('concept', Concept::class);
Route::model('range', Range::class);
Route::model('product', Product::class);
@ -128,8 +143,11 @@ class RouteServiceProvider extends ServiceProvider
})->all();
// * Filter array keys
$cspReport = collect(array_intersect_key($cspReport, [
'blocked-uri' => '', 'document-uri' => '', 'original-policy' => '',
'referrer' => '', 'violated-directive' => ''
'blocked-uri' => '',
'document-uri' => '',
'original-policy' => '',
'referrer' => '',
'violated-directive' => ''
]));
\Illuminate\Support\Facades\Log::warning(sprintf(
"CSP REPORT for %s : \n %s",

View file

@ -32,7 +32,7 @@ class TranslationServiceProvider extends ServiceProvider
/**
* Gather provided langs checking from files
*
* @return \Illuminate\Support\Collection<string, string>
* @return \Illuminate\Support\Collection<int, string>
*/
private function collectLocalesStrings(): Collection
{

View file

@ -3,59 +3,56 @@
namespace App\Traits\Controllers;
use App\Http\Requests\Bo\ChangeOrderRequest;
use App\Traits\Models\IsCachedAsCollection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Validation\ValidationException;
use Illuminate\Support\Str;
trait ChangesModelOrder
{
/**
* Change order
*
* ! requires x64 server + order column as unique integer
* Change order.
*
* @param \App\Http\Requests\Bo\ChangeOrderRequest $request
* @param \Illuminate\Database\Eloquent\Model $model
* @return \Illuminate\Http\RedirectResponse
* @throws \RuntimeException Si le nom du parametre de la route ne correspond pas au model utilisé.
*/
public function changeOrder(ChangeOrderRequest $request, Model $model): RedirectResponse
public function changeOrder(ChangeOrderRequest $request, Model $model): \Illuminate\Http\RedirectResponse
{
return DB::transaction(function () use ($request, $model) {
$params = collect(request()->route()->parameterNames);
$className = Str::ucfirst(Str::lower($params->get($params->count() - 2)));
$className = "\\App\\Models\\$className";
if (!class_exists($className)) {
throw new \RuntimeException("The $className class doesn't exist.");
}
/** @var \Illuminate\Database\Eloquent\Model|null */
$tmp = (\get_class($model))::where('order', $request->direction ? '<' : '>', $model->order)
$model = $className::query()->where($model->getRouteKeyName(), $model->getRouteKey())->first();
if (!$model) {
return back()->with('error', trans('crud.messages.order_not_changed'));
}
return DB::transaction(function () use ($request, $className, $model) {
/** @var \Illuminate\Database\Eloquent\Model|null */
$tmp = $className::query()->where('order', $request->direction ? '<' : '>', $model->getOriginal('order'))
->orderBy('order', $request->direction ? 'DESC' : 'ASC')->first();
if (!$tmp) {
return back()->with('bo.error', trans('L\'ordre n\'a pas pu être modifié'));
return back()->with('error', trans('crud.messages.order_not_changed'));
}
$oldOrder = $model->order;
$newOrder = $tmp->order;
// * Silent update timestamps.
$tmp->timestamps = false;
$model->timestamps = false;
$newOrder = $tmp->getOriginal('order');
// Didn't use ->update() because it didn't work with Models which use MiniCrudModel.
$tmp->fill(['order' => $model->getOriginal('order')]);
$tmp->save();
$model->fill(['order' => $newOrder]);
$model->save();
$saveOk = false;
Session::flash('success', trans('crud.messages.order_changed'));
// ! Fake value to prevent unique SQL key to trigger.
$tmp->order = 4294967295;
$saveOk = $tmp->saveQuietly();
$model->order = $newOrder;
$saveOk = $model->saveQuietly() & $saveOk;
$tmp->order = $oldOrder;
$saveOk = $tmp->saveQuietly() & $saveOk;
if (\in_array(IsCachedAsCollection::class, class_uses_recursive(\get_class($model)))) {
$model::removeCached();
}
if (!$saveOk) {
throw ValidationException::withMessages([
'error' => \trans('L\'ordre n\'a pas pu être modifié')
]);
}
Session::flash('bo.success', trans('L\'ordre a été modifié'));
return back();
});
}

View file

@ -2,7 +2,9 @@
namespace App\Traits\Controllers;
use App\Interfaces\Models\Publishable;
use Illuminate\Database\Eloquent\Model;
use App\Traits\Models\IsPublishable;
/**
* This trait works with Route::bind in App service provider
@ -12,19 +14,54 @@ use Illuminate\Database\Eloquent\Model;
trait UpdateModelStatus
{
/**
* Change model published
* Change model published boolean
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return \Illuminate\Http\RedirectResponse
*/
public function changePublished(Model $model)
{
$model->status = !$model->status;
$model->saveOrFail();
if (!$model->saveOrFail()) {
return redirect()->back()->with('error', __('The status could not be changed'));
}
$model->update(['status' => !$model->getOriginal('status')]);
return redirect()->back()->with('success', __('The status has been changed'));
}
/**
* Change model publication date + boolean
*
* @param Model $model
* @return \Illuminate\Http\RedirectResponse
* @throws \InvalidArgumentException Model must use IsPublishable trait.
*/
public function updatePublicationDate(Model $model)
{
if (!$this->isPublishable($model)) {
throw new \InvalidArgumentException('Model must use IsPublishable trait');
}
/** @var Publishable&Model $model */
if ($model->getStatus()) {
$model->setUnpublishAt(now());
$model->setStatus(false);
} else {
$model->setPublishAt(now());
$model->setUnpublishAt(null);
$model->setStatus(true);
}
$model->saveOrFail();
return redirect()->back()->with('success', __('The status has been changed'));
}
/**
* Check if a Model implements Publishable interface.
*
* @param \Illuminate\Database\Eloquent\Model $model
*
* @return boolean
*/
protected function isPublishable(Model $model): bool
{
return $model instanceof Publishable &&
in_array(IsPublishable::class, class_uses_recursive($model));
}
}

View file

@ -4,14 +4,12 @@ namespace App\Traits\Enums;
use Illuminate\Support\Str;
/**
* @author Jérémy Munsch <jeremy.munsch@ldc.fr>
*/
trait BaseEnum
{
// * GENERIC METHODS
/**
* Get enum value
* Get enum value.
*
* @return string|integer
*/
@ -21,7 +19,7 @@ trait BaseEnum
}
/**
* Get enum label
* Get enum label.
*
* @return string
*/
@ -31,7 +29,7 @@ trait BaseEnum
}
/**
* Get enum name
* Get enum name.
*
* @return string
*/
@ -43,7 +41,7 @@ trait BaseEnum
// * STATIC FETCH METHODS
/**
* Get enum labels
* Get enum labels.
*
* @return array<string>
*/
@ -65,7 +63,7 @@ trait BaseEnum
}
/**
* Get enum values
* Get enum values.
*
* @return array<integer|string>
*/
@ -79,7 +77,7 @@ trait BaseEnum
}
/**
* Get enums
* Get enums.
*
* @return array
*/
@ -89,7 +87,7 @@ trait BaseEnum
}
/**
* Get enums
* Get enums.
*
* @return array
*/
@ -111,30 +109,36 @@ trait BaseEnum
}
$baseArray[$index] = $elements[$enum->name];
}
return [$enum->name => (object)$baseArray];
return [$enum->name => (object) $baseArray];
})->all());
}
return self::getCache('enums');
}
/**
* Fetch enum using value
* Fetch enum using value.
*
* @param \App\Traits\Enums\BaseEnum|integer|string $value
* @return \App\Traits\Enums\BaseEnum|null
* @param self|integer|string $value
* @param string $field
* @return self|null
*/
public static function make(self|int|string $value): self|null
public static function make(self|int|string $value, string $field = 'value'): self|null
{
if ($field === "label") {
$enumLabels = array_change_key_case(array_flip(self::toLabels()), CASE_LOWER);
$value = (isset($enumLabels[strtolower($value)])) ? $enumLabels[strtolower($value)] : false;
$field = 'name';
}
return !\is_object($value) ?
\collect(self::cases())->keyBy('value')->get($value) : $value;
\collect(self::cases())->keyBy($field)->get($value) : $value;
}
/**
* Test if 2 enum are equals
* Test if 2 enum are equals.
*
* @param object ...$others
* @return boolean
* @throws \Error If provided element are not enums taht extends BaseEnum.
* @throws \Error If provided element are not enums that extends BaseEnum.
*/
public function equals(object ...$others): bool
{
@ -154,7 +158,7 @@ trait BaseEnum
}
/**
* Serialize to json
* Serialize to json.
*
* @return mixed
*/
@ -167,7 +171,7 @@ trait BaseEnum
// * CACHE
/**
* Get cache array
* Get cache array.
*
* @param string $index
* @return array
@ -182,7 +186,7 @@ trait BaseEnum
}
/**
* Set cache array
* Set cache array.
*
* @param string $index
* @param array $items
@ -198,7 +202,7 @@ trait BaseEnum
}
/**
* Init cache if needed
* Init cache if needed.
*
* @return void
*/
@ -219,7 +223,7 @@ trait BaseEnum
// * PRIVATE
/**
* Fetch the LABELS constant if exists
* Fetch the LABELS constant if exists.
*
* @return array|null
*/
@ -235,7 +239,7 @@ trait BaseEnum
}
/**
* Get custom constants
* Get custom constants.
*
* @return array
*/

View file

@ -36,8 +36,12 @@ trait HasTranslations
// * Store Uploaded file
if (\is_object($value) and $value instanceof \Illuminate\Http\UploadedFile) {
if (\property_exists($this, 'privatePictures')) {
$storeAsPrivate = (\is_array($this->privatePictures) and
\in_array($key, $this->privatePictures)) ? true : false;
} else {
$storeAsPrivate = false;
}
$value = FileStorageHelper::storeFile($this, $value, true, null, $storeAsPrivate);
}

View file

@ -10,7 +10,8 @@ use Illuminate\Support\Facades\Cache;
/**
* ! Use this only on limited elements, (not on tags, or products, or posts for ex.)
*
* @property private static array $cacheConditions Eloquent condition to cache elements (to be used in where statement).
* @property array<string,string|integer|float|boolean> $cacheConditions
* Eloquent condition to cache elements (to be used in where statement).
*/
trait IsCachedAsCollection
{
@ -18,7 +19,7 @@ trait IsCachedAsCollection
* Get all available instances from cache.
* If cache was reset, it will fetch them from DB.
*
* @return \Illuminate\Database\Eloquent\Collection
* @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Support\Collection<(int|string), mixed>
*/
public static function getCached(): Collection
{
@ -52,10 +53,11 @@ trait IsCachedAsCollection
{
$conditions = [];
if (property_exists(get_called_class(), 'cacheConditions')) {
$conditions = collect(static::${'cacheConditions'})->all();
$conditions = collect(get_called_class()::${'cacheConditions'})->all();
}
Cache::put(static::getCacheKeyName(), static::queryCached(static::query())
->where($conditions)->get());
->where($conditions)->get()
->pipe(fn (Collection $collection) => \call_user_func([self::class, 'filterQuery'], $collection)));
}
/**
@ -69,6 +71,17 @@ trait IsCachedAsCollection
return $query;
}
/**
* Change query for cached elements
*
* @param \Illuminate\Support\Collection $results
* @return \Illuminate\Support\Collection
*/
protected static function filterQuery(Collection $results): Collection
{
return $results;
}
/**
* Get the class basename
*

View file

@ -0,0 +1,140 @@
<?php
namespace App\Traits\Models;
use Carbon\Carbon;
/**
*
*/
trait IsPublishable
{
/**
* Initialize the Trait (Laravel magic method)
*
* @return void
*/
public function initializeIsPublishable(): void
{
/** @var \Illuminate\Database\Eloquent\Model $this */
$this->mergeCasts([
'status' => 'string',
'publish_at' => 'datetime',
'unpublish_at' => 'datetime',
]);
$this->mergeFillable([
'status',
'publish_at',
'unpublish_at',
]);
}
/**
* Adjusts model status using current status and publish dates
*
* @return void
*/
public function makeStatusSense(): void
{
/** @var \Carbon\Carbon|null */
$publish_at = $this->publish_at;
/** @var \Carbon\Carbon|null */
$unpublish_at = $this->unpublish_at;
$wantedStatus = $this->status;
if ($publish_at or $unpublish_at) {
$this->status = $this->planificated_status;
}
if ($wantedStatus !== $this->status) {
$previousMessage = session()->get('bo.info', '');
session()->flash('bo.info', \trans(
'La publication est modifiée en concordance avec les dates enregistrées donc
pour modifier l\'état de publication, veuillez modifier ou enlever les dates correspondantes.'
) . " \n{$previousMessage}");
}
}
/**
* Getter the current status following planification dates planificated_status
*
* @return boolean
*/
public function getPlanificatedStatusAttribute(): bool
{
/** @var \Carbon\Carbon */
$publish_at = $this->publish_at;
/** @var \Carbon\Carbon|null */
$unpublish_at = $this->unpublish_at;
if ($unpublish_at) {
return $publish_at->lessThan(now()) && $unpublish_at->greaterThanOrEqualTo(now());
}
return $publish_at->lessThan(now());
}
// * GETTERS / SETTERS (for PHPStan)
/**
* Get status attribute.
*
* @return boolean
*/
public function getStatus(): bool
{
return $this->status;
}
/**
* Set status attribute.
*
* @param boolean $status
* @return void
*/
public function setStatus(bool $status): void
{
$this->status = $status;
}
/**
* Get publish_at attribute.
*
* @return \Carbon\Carbon|null
*/
public function getPublishAt(): Carbon|null
{
return $this->publish_at;
}
/**
* Set publish_at attribute.
*
* @param \Carbon\Carbon|null $date
* @return void
*/
public function setPublishAt(Carbon|null $date): void
{
$this->publish_at = $date;
}
/**
* Get unpublish_at attribute.
*
* @return \Carbon\Carbon|null
*/
public function getUnpublishAt(): Carbon|null
{
return $this->unpublish_at;
}
/**
* Set unpublish_at attribute.
*
* @param \Carbon\Carbon|null $date
* @return void
*/
public function setUnpublishAt(Carbon|null $date): void
{
$this->unpublish_at = $date;
}
}

View file

@ -12,6 +12,7 @@ trait MiniCrudModel
* Fill the model with an array of attributes.
*
* @param array $attributes
* @phpstan-ignore-next-line
* @return void
* @throws \Illuminate\Database\Eloquent\MassAssignmentException If fill prop is not allowed.
* @phpcs:disable Squiz.Commenting.FunctionComment.EmptyThrows
@ -62,7 +63,6 @@ trait MiniCrudModel
*/
public function minicrudUpdated()
{
/** @var array */
foreach ($this->data as $index => $input) {
switch ($input['inputType']) {
case InputType::text->value:
@ -166,7 +166,7 @@ trait MiniCrudModel
case InputType::string->value:
case InputType::text->value:
case InputType::url->value:
ToolboxHelper::assertNoInternalBoUrls('content', $input['value']);
ToolboxHelper::assertNoInternalBoUrls('content', $input['value'] ?? '');
break;
default:
throw new \ErrorException(sprintf(

View file

@ -56,7 +56,7 @@ trait HasPicture
?int $maxHeight = null,
bool $nullable = false
): array {
$sizes = (object)[
$sizes = (object) [
'minWith' => $minWith ?? $this->minWith,
'minHeight' => $minHeight ?? $this->minHeight,
'maxWith' => $maxWith ?? $this->maxWith,
@ -66,7 +66,7 @@ trait HasPicture
$name => [
!$nullable ? 'required' : 'nullable',
function (string $attribute, $value, callable $fail) use ($sizes) {
return ToolboxHelper::validatePicture($attribute, $value, $fail, $sizes);
ToolboxHelper::validatePicture($attribute, $value, $fail, $sizes);
}
]
];
@ -89,7 +89,7 @@ trait HasPicture
?int $maxWith = null,
?int $maxHeight = null
): array {
$sizes = (object)[
$sizes = (object) [
'minWith' => $minWith ?? $this->minWith,
'minHeight' => $minHeight ?? $this->minHeight,
'maxWith' => $maxWith ?? $this->maxWith,
@ -101,7 +101,7 @@ trait HasPicture
"{$name}Validate.*" => [
'required',
function (string $attribute, $value, callable $fail) use ($sizes) {
return $this->validatePicture($attribute, $value, $fail, $sizes);
ToolboxHelper::validatePicture($attribute, $value, $fail, $sizes);
}
]
];

View file

@ -15,7 +15,7 @@ class RecipeCard extends Component
/**
* Recipe model
*
* @var \App\Recipe
* @var \App\Models\Recipe
*/
public $recipe;
@ -27,7 +27,7 @@ class RecipeCard extends Component
*/
public function __construct(int $id)
{
$this->recipe = Recipe::where('id', $id)->first();
$this->recipe = Recipe::query()->where('id', $id)->first();
}
/**

View file

@ -15,7 +15,7 @@ class RecipeCardSmall extends Component
/**
* Recipe model
*
* @var \App\Recipe
* @var \App\Models\Recipe
*/
public $recipe;
@ -27,7 +27,7 @@ class RecipeCardSmall extends Component
*/
public function __construct(int $id)
{
$this->recipe = Recipe::where('id', $id)->first();
$this->recipe = Recipe::query()->where('id', $id)->first();
}
/**

View file

@ -17,7 +17,7 @@ class RecipeProductStoerer extends Component
/**
* product variable
*
* @var \App\Product
* @var \App\Models\Product
*/
public $product;
@ -29,7 +29,7 @@ class RecipeProductStoerer extends Component
*/
public function __construct(int $id)
{
$this->product = Product::where('id', $id)->first();
$this->product = Product::query()->where('id', $id)->first();
}
/**

View file

@ -24,7 +24,7 @@ class RecipeWidget extends Component
/**
* recipes variable
*
* @var \App\Recipe
* @var \Illuminate\Database\Eloquent\Collection<\App\Models\Recipe>
*/
private $recipes;
@ -43,10 +43,10 @@ class RecipeWidget extends Component
}
if ($id != null) {
$this->id = $id;
$this->recipes = Recipe::where('status', '1')
$this->recipes = Recipe::query()->where('status', '1')
->where('id', '!=', $this->id)->inRandomOrder()->limit($this->limit)->get();
} else {
$this->recipes = Recipe::where('status', '1')->inRandomOrder()->limit($this->limit)->get();
$this->recipes = Recipe::query()->where('status', '1')->inRandomOrder()->limit($this->limit)->get();
}
}

1
commitlint.config.js Normal file
View file

@ -0,0 +1 @@
export default { extends: ["@uwil/husky-config/commitlint.config.js"] };

View file

@ -1,44 +1,42 @@
{
"name": "ldcweb/wenn-dann-mit-respekt",
"name": "uwil/nature-and-respect",
"version": "1.0.0",
"type": "project",
"time": "2023-03-16",
"description": "Website of Wenn dann mit respekt.",
"support": {
"email": "equipe.web@ldc.fr"
},
"keywords": [
"framework",
"laravel"
],
"description": "Website of Nature & Respect.",
"license": "MIT",
"require": {
"php": "^8.1",
"codezero/laravel-localized-routes": "^3.1",
"codezero/laravel-unique-translation": "^4.1",
"diglactic/laravel-breadcrumbs": "^8.0",
"php": "^8.5",
"codezero/laravel-localized-routes": "^4.0.1",
"codezero/laravel-unique-translation": "^4.3.1",
"diglactic/laravel-breadcrumbs": "^9.0.0",
"guzzlehttp/guzzle": "^7.2",
"kwaadpepper/refresh-sitemap": "^2.0",
"laravel/framework": "^10.0",
"kwaadpepper/image-resizer": "^3.1.0",
"laravel/framework": "^11.0",
"laravel/tinker": "^2.8",
"laravel/ui": "^4.2",
"mews/purifier": "^3.4",
"sentry/sentry-laravel": "^3.3",
"simplesoftwareio/simple-qrcode": "~4",
"sentry/sentry-laravel": "^4.15.1",
"simplesoftwareio/simple-qrcode": "^4.2.0",
"spatie/laravel-translatable": "^6.4",
"uwil/k8s-laravel": "1.0.0"
"uwil/admin-secure-laravel": "^5.0",
"uwil/k8s-laravel": "^2.0.0",
"uwil/laravel-common": "^4.1.6",
"uwil/schema-org-laravel": "^2.2.0",
"uwil/seo-laravel": "^4.0.0",
"uwil/sitemap-generator": "^5.0.1"
},
"require-dev": {
"fakerphp/faker": "^1.9.1",
"kitloong/laravel-migrations-generator": "^6.8",
"krlove/eloquent-model-generator": "dev-l10-compatibility",
"kitloong/laravel-migrations-generator": "^7.0.0",
"larastan/larastan": "^2.6",
"laravel-lang/common": "^3.1",
"laravel/pint": "^1.0",
"laravel/sail": "^1.18",
"mockery/mockery": "^1.4.4",
"nunomaduro/collision": "^7.0",
"nunomaduro/collision": "^8.1",
"phpunit/phpunit": "^10.0",
"slevomat/coding-standard": "^8.10",
"slevomat/coding-standard": "^8.19",
"spatie/laravel-ignition": "^2.0",
"thedoctor0/laravel-factory-generator": "^1.2"
},
@ -75,6 +73,12 @@
],
"post-create-project-cmd": [
"@php artisan key:generate --ansi"
],
"phpcs": [
"./vendor/bin/phpcs"
],
"phpstan": [
"./vendor/bin/phpstan"
]
},
"extra": {

6919
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -41,7 +41,7 @@ return [
|
*/
'debug' => (bool)env('APP_DEBUG', false),
'debug' => (bool) env('APP_DEBUG', false),
/*
|--------------------------------------------------------------------------

View file

@ -15,7 +15,6 @@ return [
|
*/
// 'paths' => ['api/*', 'sanctum/csrf-cookie', '*/storefinder'],
'paths' => ['*'],
'allowed_methods' => ['*'],

82
config/image-resizer.php Normal file
View file

@ -0,0 +1,82 @@
<?php
return [
/**
* The php image driver to use
* this can be 'imagick' or 'gd'
*/
'driver' => 'imagick',
/**
* The cache driver to use as defined
* in config/cache of your app
*/
'cache' => 'file',
/**
* The path where to store image in cache
*/
'cachePath' => 'cache/images',
/**
* Image cache life time
* This is given in minutes
* Here the cache for images is
* one hour
*/
'lifetime' => 535680,
/**
* Format can specifiy to which format save the image
* JPEG PNG GIF TIF BMP ICO PSD WebP
* GD ✔️ ✔️ ✔️ - - - - ✔️ *
* Imagick ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ *
* For WebP support GD driver must be used with PHP 5 >= 5.5.0 or PHP 7
* in order to use imagewebp(). If Imagick is used, it must be compiled
* with libwebp for WebP support.
* resize => will resize the image (boolean)
* fit => Combine cropping and resizing to format image in a smart way (boolean)
* keepRatio => will keep image ratio wile resizing (boolean)
* trim => boolean to trim the image using border color
* inCanvas => to make sure image boundarie is respected
* format => select tha wantd ouput form, yan can just convert images if you want
* example :
* 'small' => [
* 'height' => 500,
* 'width' => 250,
* 'inCanvas' => true,
* 'trim' => ['transparent', null, 10]
* ],
* 'smallWebp' => [
* 'height' => 500,
* 'width' => 250,
* 'inCanvas' => true,
* 'format' => 'webp'
* ],
* 'justconvertImage' => [
* 'format' => 'webp'
* ]
*/
'templates' => [
'foNewsIndexPicture' => [
'height' => 520,
'width' => 768,
'fit' => true,
'resize' => false,
'keepRatio' => false,
'inCanvas' => false,
'trim' => false,
'format' => 'png'
],
'foNewsShowPicture' => [
'height' => 600,
'width' => 600,
'fit' => false,
'resize' => true,
'keepRatio' => true,
'inCanvas' => false,
'trim' => false,
'format' => 'png'
]
]
];

View file

@ -57,7 +57,9 @@ return [
* ]
*
*/
'queryConditions' => [],
'queryConditions' => [
'status' => true,
],
/**
* The default route frequency to use with sitemap generator

136
config/schema-org.php Normal file
View file

@ -0,0 +1,136 @@
<?php
return [
'brand' => [
/**
* App name.
* type: string
*/
'name' => env('APP_NAME', 'Laravel'),
/**
* Description (can be a translation key).
* type: string
*/
'description' => 'schema-org.description',
/**
* Logo path.
* type: string
* ex: 'resources/assets/images/logo.png
*/
'logo' => 'resources/assets/images/Icons/logo-nature-respect.svg',
/**
* Slogan (can be a translation key).
* type: string
*/
'slogan' => 'schema-org.slogan',
],
'organization' => [
/**
* Name.
* type: string
*/
'name' => env('APP_NAME', 'Laravel'),
/**
* Description (can be a translation key).
* type: string
*/
'description' => 'schema-org.description',
/**
* Logo path.
* type: string
*/
'logo' => 'resources/assets/images/Icons/logo-nature-respect.svg',
/**
* Slogan (can be a translation key).
* type: string
*/
'slogan' => 'schema-org.slogan',
/**
* Url associated.
* type: string|string[]
* ex: 'url' || ['url]
*/
'sameAs' => [
'https://www.instagram.com/nature_and_respect/',
'https://de.pinterest.com/natureandrespect/',
],
/**
* Place associated.
* type: <string, string>[]
* ex: [
* 'address' => '',
* 'keywords' => '' (can be a translation key),
* ]
*/
'place' => [
'address' => 'Zone Industrielle Saint-Laurent 72300 Sablé-sur-Sarthe',
'keywords' => 'schema-org.place',
],
],
'website' => [
/**
* About (can be a translation key).
* type: string
*/
'about' => 'schema-org.website',
/**
* Description (can be a translation key).
* type: string
*/
'description' => 'schema-org.website',
/**
* Genre (can be a translation key).
* type: string
*/
'genre' => 'schema-org.genre',
/**
* Created date.
* type: string
* ex: '2025-06-12'
*/
'created_at' => '2018-03-19',
/**
* Published date.
* type: string
* ex: '2025-06-12'
*/
'published_at' => '2018-03-19',
/**
* Locales codes (RFC 4647 - "Matching of Language Tags": 'language-range').
* link: https://datatracker.ietf.org/doc/html/rfc4647
* type: string[]
* ex: ['fr' => 'fr-FR']
*/
'languages' => [
'en' => 'en-US',
'de' => 'de-DE'
],
/**
* Keywords (can be a translation key).
* type: string|string[]
* ex: 'volaille' || ['volaille', 'élevage']
*/
'keywords' => 'schema-org.keywords',
/**
* Search path with parameters.
* type: string|null
* ex: '/recherche?texte={search_term_string}'
*/
'search' => null
]
];

Some files were not shown because too many files have changed in this diff Show more