Compare commits
415 commits
evoUpgrade
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a55af08121 | ||
|
|
05b51a7188 | ||
|
|
7809f430ef | ||
|
|
b240c614fc | ||
|
|
0e6b074794 | ||
|
|
6a6781831b | ||
|
|
956ae8693f | ||
|
|
79026a20d6 | ||
|
|
7f8284e300 | ||
|
|
342d2adced | ||
|
|
d462bc5f1c | ||
|
|
4e16b2e160 | ||
|
|
0c0cd0d476 | ||
|
|
157bcb491f | ||
|
|
3c1d4fe84c | ||
| a27f0bf4d8 | |||
| 87dbf384ca | |||
| d3f47bd120 | |||
| 4920902222 | |||
| d489fa29f8 | |||
| 0e0854ff3f | |||
| c40b80dd79 | |||
| eaa9303445 | |||
| ae2c0f146c | |||
| 7d4fdb3011 | |||
| d693885a90 | |||
| 09ca3ac738 | |||
| 12e6d2adf5 | |||
| 37278195e6 | |||
| 696132eddc | |||
|
|
379cff88c2 | ||
|
|
706577c606 | ||
|
|
7f9fb9d414 | ||
| e0b60f65da | |||
| 0ec5ab7f8c | |||
|
|
52b183bd9d | ||
|
|
24199b3ac6 | ||
|
|
37530c5826 | ||
|
|
d5cb4c7d78 | ||
|
|
9d0d2dc73b | ||
|
|
2e23da12e1 | ||
|
|
497786de7f | ||
|
|
fec87ad399 | ||
|
|
01b7f09fac | ||
|
|
cacc53e8a0 | ||
|
|
2b333d5c14 | ||
|
|
5a50f04f4f | ||
|
|
e572743f51 | ||
|
|
c77a587bda | ||
|
|
8cb0219c37 | ||
|
|
cc4e4e72e6 | ||
|
|
08df396de5 | ||
|
|
087a2c08fb | ||
|
|
25ecbca185 | ||
|
|
f8a4fa816c | ||
|
|
1443080cd3 | ||
|
|
5b06bc2c6c | ||
|
|
c47cf8d29a | ||
|
|
948cc09443 | ||
|
|
25cafe1a1c | ||
|
|
7e02516b65 | ||
|
|
7bddbdd356 | ||
|
|
ac4bb01c26 | ||
|
|
7240c5e35d | ||
|
|
6a5f07ae58 | ||
|
|
af4ac8883e | ||
|
|
2b936e308e | ||
|
|
cf41ecb748 | ||
|
|
6bb7e926fa | ||
|
|
fcc2d5b519 | ||
|
|
65f4ce155f | ||
|
|
6ae26c6a23 | ||
|
|
144c74e422 | ||
|
|
290f9aa570 | ||
|
|
8b6943df28 | ||
|
|
2c1c3eb2e6 | ||
|
|
688565c1ea | ||
|
|
4bdb75f866 | ||
|
|
317c7d95d0 | ||
|
|
d5d60f98e9 | ||
|
|
419573145c | ||
|
|
1a4d0a03ec | ||
|
|
2339684802 | ||
|
|
bf92d8542b | ||
|
|
5a361da75c | ||
|
|
48260952a4 | ||
|
|
dd97b1d6dc | ||
|
|
2b8fd6bbe4 | ||
|
|
e6839a71c8 | ||
|
|
3ee3b5c69a | ||
|
|
616593cdb8 | ||
|
|
8144bc9c62 | ||
|
|
ee22082f59 | ||
|
|
e719a96705 | ||
|
|
3ae492f193 | ||
|
|
ff86605bc8 | ||
|
|
1f1f95afcf | ||
|
|
52b5132021 | ||
|
|
0f1c71272b | ||
|
|
37a75e8680 | ||
|
|
bbfba0bda1 | ||
|
|
a5bbbfdcef | ||
|
|
2edb4df669 | ||
|
|
d649bc1eb1 | ||
|
|
633c33eead | ||
|
|
25147ac27e | ||
|
|
fe99d75513 | ||
|
|
7b08d0e1c8 | ||
|
|
1dd81a7d30 | ||
|
|
741aabed60 | ||
|
|
37a767c591 | ||
|
|
a28885f74e | ||
|
|
dc559dc1e7 | ||
|
|
62e28d1f3e | ||
|
|
6445e36c67 | ||
|
|
6a4fa79cc4 | ||
|
|
c8e0f71593 | ||
|
|
515e36ce06 | ||
|
|
d440842524 | ||
|
|
30007dbf1f | ||
|
|
52d5c2908f | ||
|
|
010aeb0221 | ||
|
|
2945692413 | ||
|
|
4223691742 | ||
|
|
dcf2ad6079 | ||
|
|
cbd674eaa1 | ||
|
|
854a2c7c47 | ||
|
|
f4c09329a1 | ||
|
|
e8ea255626 | ||
|
|
58fd71ed09 | ||
|
|
a0027a7747 | ||
|
|
6a4fae3552 | ||
|
|
4d98327f10 | ||
|
|
3453b4f44c | ||
|
|
9fc5c19cec | ||
|
|
a3406b03b9 | ||
|
|
cf42dfd311 | ||
|
|
0b3ff7628c | ||
|
|
618863ee30 | ||
|
|
7ab7a99a1f | ||
|
|
ecdcf81334 | ||
|
|
04d4e66918 | ||
|
|
b0b89669ef | ||
|
|
3a9b8e4530 | ||
|
|
31af560983 | ||
|
|
8763a7633d | ||
|
|
2b00e56b26 | ||
|
|
6767750b42 | ||
|
|
1084f1b68c | ||
|
|
53e70cd9a0 | ||
|
|
37544c5632 | ||
|
|
218a3a7891 | ||
|
|
500c841ac6 | ||
|
|
7e0159bdd0 | ||
|
|
31d84c337a | ||
|
|
ec8b4ffba5 | ||
|
|
816bab3cb3 | ||
|
|
6f480721ea | ||
|
|
5fce1d7241 | ||
|
|
c06d0a80cb | ||
|
|
527237d551 | ||
|
|
382d0d5470 | ||
|
|
3be9f378a9 | ||
|
|
528ef0ff0a | ||
|
|
d05a516172 | ||
|
|
a8bbeeba2a | ||
|
|
28ac2d3314 | ||
|
|
c4e571153f | ||
|
|
968bceefac | ||
|
|
532f294a77 | ||
|
|
de768737d8 | ||
|
|
e7d3e2e8da | ||
|
|
4739b48a28 | ||
|
|
d251607bc4 | ||
|
|
a06b0a9947 | ||
|
|
482eb9e603 | ||
|
|
64fe3a41d9 | ||
|
|
52960b5b72 | ||
|
|
369e9c9fd3 | ||
|
|
f349ed3c1e | ||
|
|
3515cd7253 | ||
|
|
ba418c5edf | ||
|
|
311dda7b6a | ||
|
|
6e7be9050e | ||
|
|
32e47c8d9c | ||
|
|
a1e612d74e | ||
|
|
3a1485c91e | ||
|
|
85a8bde47d | ||
|
|
5fa986ba0c | ||
|
|
2f36dd221d | ||
|
|
9242161f19 | ||
|
|
ff922a4127 | ||
|
|
d8ab0146e0 | ||
|
|
2ef26bc270 | ||
|
|
de748bb9bb | ||
|
|
ee8b0a6a41 | ||
|
|
b278bae91e | ||
|
|
44de0136e4 | ||
|
|
28e54a81f2 | ||
|
|
1d3f6138dd | ||
|
|
89e0aa0fdc | ||
|
|
c113c51800 | ||
|
|
50a4ccc958 | ||
|
|
d3575fff52 | ||
|
|
f5bb6baba2 | ||
|
|
d6d70a9509 | ||
|
|
78ad816e7c | ||
|
|
35eae0b542 | ||
|
|
b4a7b2000a | ||
|
|
b469549d53 | ||
|
|
dc0e6d9481 | ||
|
|
7779feaf88 | ||
|
|
a001cb83fc | ||
|
|
55907fadb0 | ||
|
|
7b699597d1 | ||
|
|
5b73723f03 | ||
|
|
3262b2553c | ||
|
|
f8528c4ec8 | ||
|
|
a5fcfa15e7 | ||
|
|
e10acc5756 | ||
|
|
5b05cf7c59 | ||
|
|
0f3bf5e2ca | ||
|
|
b8bb0f2392 | ||
|
|
e29c5580b8 | ||
|
|
8fab343dde | ||
|
|
573ac1a127 | ||
|
|
9a7fc876de | ||
|
|
b68b6c4aec | ||
|
|
247660f4dc | ||
|
|
b127390971 | ||
|
|
57f9ddad28 | ||
|
|
3301dd8de1 | ||
|
|
5258824967 | ||
|
|
9dda536e9e | ||
|
|
8ab8c7a0cc | ||
|
|
c12cf20050 | ||
|
|
3bf55161f9 | ||
|
|
9567c77ae9 | ||
|
|
94ac4f8d40 | ||
|
|
9b55bf09c4 | ||
|
|
3f383af05d | ||
|
|
cf0b1a54f0 | ||
|
|
9f73d89e5c | ||
|
|
48046fdbba | ||
|
|
15a75bc8ee | ||
|
|
20fb1fea8e | ||
|
|
c2421e5015 | ||
|
|
9328fe0b37 | ||
|
|
1ecc4d60d2 | ||
|
|
ca0c6484d0 | ||
|
|
d191b6ad56 | ||
|
|
b3abfbe66c | ||
|
|
47fc3e250a | ||
|
|
8986d93b11 | ||
|
|
090336b33e | ||
|
|
4659173811 | ||
|
|
1b388e7265 | ||
|
|
1c4a7d915e | ||
|
|
58623e9207 | ||
|
|
cae2ad7754 | ||
|
|
6683365cb1 | ||
|
|
8efa232036 | ||
|
|
723892063a | ||
|
|
57517b1772 | ||
|
|
f81026caff | ||
|
|
f8b1b7ab76 | ||
|
|
d66e34f5b8 | ||
|
|
880d722e5f | ||
|
|
f89688b3ec | ||
|
|
6761e040b6 | ||
|
|
72aa0297f1 | ||
|
|
edf18b2fb8 | ||
|
|
a34176419c | ||
|
|
ee429bc2e0 | ||
|
|
71c55a34be | ||
|
|
bfc72f09af | ||
|
|
5ba294b496 | ||
|
|
95bb4e3b09 | ||
|
|
79ee185e1c | ||
|
|
5374c26859 | ||
|
|
67c5eb07f3 | ||
|
|
f1b90801da | ||
|
|
da31943f11 | ||
|
|
560c0875d6 | ||
|
|
a41a3916fb | ||
|
|
712c000ff2 | ||
|
|
dc3d0642dc | ||
|
|
efca142995 | ||
|
|
298c787935 | ||
|
|
50cbb4b7ea | ||
|
|
dbbe8468c7 | ||
|
|
44883c1d7d | ||
|
|
1774e34acd | ||
|
|
4f8b257d17 | ||
|
|
d803889960 | ||
|
|
c10c4abc6a | ||
|
|
d2f44f9688 | ||
|
|
53ab1814aa | ||
|
|
232bc2f459 | ||
|
|
3e326ba3ca | ||
|
|
2f12ab0c1c | ||
|
|
93caefb196 | ||
|
|
b79b7dc151 | ||
|
|
d208854fb0 | ||
|
|
5dda42e9da | ||
|
|
d3f2942c68 | ||
|
|
e6a16ff965 | ||
|
|
47aaf436c6 | ||
|
|
6c34db1f2a | ||
|
|
80cf81bc4b | ||
|
|
6a5468df53 | ||
|
|
9011378232 | ||
|
|
0fe116851a | ||
|
|
d3d0daa167 | ||
|
|
05fa20765a | ||
|
|
247952ae5f | ||
|
|
c2421dfc57 | ||
|
|
a8ab9af6dc | ||
|
|
949b7ca13e | ||
|
|
4113e2254a | ||
|
|
ec7f20cf4d | ||
|
|
bc477627b3 | ||
|
|
82df7497ee | ||
|
|
89c5f19dfa | ||
|
|
c928f9a5c4 | ||
|
|
1f672491ca | ||
|
|
da8e008147 | ||
|
|
92c81ab937 | ||
|
|
7654b078c5 | ||
|
|
db4db55fe9 | ||
|
|
d604cf64b6 | ||
|
|
333d34d17a | ||
|
|
a529367fba | ||
|
|
afa735f0b8 | ||
|
|
e1d1238919 | ||
|
|
6d48e30cc0 | ||
|
|
6cc7ffa0ba | ||
|
|
c189ac6f18 | ||
|
|
0bc2a03ade | ||
|
|
386efc9be6 | ||
|
|
7ceccdf7b0 | ||
|
|
0e2f589251 | ||
|
|
31f75bdf0d | ||
|
|
b641ba5238 | ||
|
|
b15d2a86ab | ||
|
|
47661c3ceb | ||
|
|
d2c2503438 | ||
|
|
c25d447ca3 | ||
|
|
eec1adc588 | ||
|
|
8502fe7538 | ||
|
|
589f733601 | ||
|
|
a52fa1d08a | ||
|
|
bcadeab1d3 | ||
|
|
22f5e5b0f9 | ||
|
|
683a6824bc | ||
|
|
4846a6b888 | ||
|
|
8658088d9e | ||
|
|
b1108974d9 | ||
|
|
6613f5b8b9 | ||
|
|
bd98b50512 | ||
|
|
30033e2ed8 | ||
|
|
ac55e4ca69 | ||
|
|
3ec4993ae8 | ||
|
|
e303611223 | ||
|
|
2bb85255a4 | ||
|
|
b77b0452ba | ||
|
|
fb8e0cd066 | ||
|
|
f208463532 | ||
|
|
2e72dda5ec | ||
|
|
9d2152d549 | ||
|
|
081d4ca8f2 | ||
|
|
d63dfd34c1 | ||
|
|
bdcbf4f082 | ||
|
|
155116b1d1 | ||
|
|
0dea317174 | ||
|
|
50166c28e1 | ||
|
|
6868b153be | ||
|
|
4a4902ae7e | ||
|
|
8d4bbfbd98 | ||
|
|
f337413438 | ||
|
|
c81160a4dd | ||
|
|
079968f207 | ||
|
|
ed3b6c2e43 | ||
|
|
796e4436d9 | ||
|
|
59769cbff0 | ||
|
|
7de8fbd8bf | ||
|
|
3f8b85b6de | ||
|
|
3063e9fd93 | ||
|
|
91955f6f9e | ||
|
|
765cc236ef | ||
|
|
49390dbf7a | ||
|
|
24a1687a42 | ||
|
|
115a4de280 | ||
|
|
56a68bf234 | ||
|
|
07c430cb5c | ||
|
|
54a4808829 | ||
|
|
11fb17d63b | ||
|
|
64643d90f1 | ||
|
|
0e8c121f8f | ||
|
|
bf8a70f47b | ||
|
|
500219ca89 | ||
|
|
7fa1b84cb5 | ||
|
|
0546ab81a7 | ||
|
|
f4e6b41328 | ||
|
|
ec325a27f3 | ||
|
|
ffbe8ac531 | ||
|
|
f8e50b259b | ||
|
|
43f0d6aef2 | ||
|
|
7e3c225aaf | ||
|
|
55b5dd438d | ||
|
|
5e2fb194c1 | ||
|
|
9f6a9db628 | ||
|
|
50a73019a4 | ||
|
|
f4d6aa03b7 | ||
|
|
cb262b91e9 |
622 changed files with 48866 additions and 125135 deletions
5
.browserslistrc
Normal file
5
.browserslistrc
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# Browsers that we support
|
||||
|
||||
last 3 version
|
||||
> 0.3%
|
||||
not dead # no browsers without security updates
|
||||
|
|
@ -3,9 +3,9 @@ root = true
|
|||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
|
|
@ -13,3 +13,9 @@ trim_trailing_whitespace = false
|
|||
|
||||
[*.{yml,yaml}]
|
||||
indent_size = 2
|
||||
|
||||
[docker-compose.yml]
|
||||
indent_size = 4
|
||||
|
||||
[*.vue]
|
||||
indent_size = 2
|
||||
|
|
|
|||
39
.env.example
39
.env.example
|
|
@ -5,9 +5,11 @@ APP_DEBUG=true
|
|||
APP_URL=http://localhost
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
LOG_DEPRECATIONS_CHANNEL=null
|
||||
LOG_LEVEL=debug
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_HOST=dev-mysql
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=laravel
|
||||
DB_USERNAME=root
|
||||
|
|
@ -15,22 +17,51 @@ DB_PASSWORD=
|
|||
|
||||
BROADCAST_DRIVER=log
|
||||
CACHE_DRIVER=file
|
||||
FILESYSTEM_DISK=local
|
||||
QUEUE_CONNECTION=sync
|
||||
SESSION_DRIVER=file
|
||||
SESSION_LIFETIME=120
|
||||
|
||||
MEMCACHED_HOST=127.0.0.1
|
||||
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_MAILER=smtp
|
||||
MAIL_HOST=smtp.mailtrap.io
|
||||
MAIL_PORT=2525
|
||||
MAIL_HOST=dev-mailpit
|
||||
MAIL_PORT=1025
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
MAIL_FROM_ADDRESS=null
|
||||
MAIL_FROM_NAME="${APP_NAME}"
|
||||
MAIL_ADMIN=informatique.internet@ldc.fr
|
||||
MAIL_ADMIN=digital@ldc.fr
|
||||
|
||||
# Sentry
|
||||
SENTRY_LARAVEL_DSN=
|
||||
|
||||
# MATOMO
|
||||
MATOMO_SITE_ID=
|
||||
|
||||
# CRM
|
||||
CRM_ENDPOINT=
|
||||
CRM_TOKEN=
|
||||
CRM_PASSWORD=
|
||||
# MESBR
|
||||
MESBR_ENDPOINT=
|
||||
|
||||
# ADMIN SECURE
|
||||
# - API ENDPOINT (Optional)
|
||||
LDC_WEB_API_ENDPOINT=""
|
||||
# - API KEY
|
||||
LDC_WEB_API_KEY=""
|
||||
# - LIST SEPARATED WITH ',' (Optional)
|
||||
LDC_WEB_CIDR_MANUAL_ALLOWED_LIST=""
|
||||
|
||||
# Export pagination config, defaut 65530.
|
||||
CODE_PAGINATE=
|
||||
# Dictionnary of chars to use fo generating unique codes.
|
||||
CODE_CHAR_LIST=
|
||||
# Code length (chars).
|
||||
CODE_CHAR_LENGTH=
|
||||
|
|
|
|||
14
.gitattributes
vendored
14
.gitattributes
vendored
|
|
@ -1,5 +1,11 @@
|
|||
* text=auto
|
||||
*.css linguist-vendored
|
||||
*.scss linguist-vendored
|
||||
*.js linguist-vendored
|
||||
* text=auto eol=lf
|
||||
|
||||
*.blade.php diff=html
|
||||
*.css diff=css
|
||||
*.html diff=html
|
||||
*.md diff=markdown
|
||||
*.php diff=php
|
||||
|
||||
/.github export-ignore
|
||||
CHANGELOG.md export-ignore
|
||||
.styleci.yml export-ignore
|
||||
|
|
|
|||
55
.gitignore
vendored
55
.gitignore
vendored
|
|
@ -1,29 +1,46 @@
|
|||
public/front/*
|
||||
.env
|
||||
.env.backup
|
||||
.env.production
|
||||
.phpunit.result.cache
|
||||
.stylelintcache
|
||||
/.fleet
|
||||
/.idea
|
||||
/.phpunit.cache
|
||||
/.vscode
|
||||
/node_modules
|
||||
/bootstrap
|
||||
/public/build
|
||||
/public/cache
|
||||
/public/hot
|
||||
/public/sitemap.xml
|
||||
/public/storage
|
||||
/public/fichiers
|
||||
/public/images/produits
|
||||
/public/images/ranges
|
||||
/public/css/*
|
||||
/public/js/*
|
||||
resources/views/errors/*
|
||||
resources/views/front/basic/*
|
||||
mix-manifest.json
|
||||
/storage/*.key
|
||||
/vendor
|
||||
/resources/views/front/basic
|
||||
.env
|
||||
.env.dev
|
||||
.env.prod
|
||||
.env.backup
|
||||
.phpunit.result.cache
|
||||
auth.json
|
||||
docker-compose.override.yml
|
||||
Homestead.json
|
||||
Homestead.yaml
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
package-lock.json
|
||||
composer.lock
|
||||
resources/front
|
||||
.vscode
|
||||
.npmrc
|
||||
/resources/theme
|
||||
# https://lab.s-web.fr/ldc-web/projets/gen-game-web/-/issues/17
|
||||
public/fichiers
|
||||
storage
|
||||
resources/theme
|
||||
.npm/
|
||||
.composer/
|
||||
.zshrc
|
||||
|
||||
# Ignore public favicon
|
||||
/public/android-chrome-192x192.png
|
||||
/public/android-chrome-512x512.png
|
||||
/public/apple-touch-icon.png
|
||||
/public/browserconfig.xml
|
||||
/public/browserconfig.xml
|
||||
/public/favicon-16x16.png
|
||||
/public/favicon-32x32.png
|
||||
/public/favicon.ico
|
||||
/public/mstile-150x150.png
|
||||
/public/safari-pinned-tab.svg
|
||||
/public/site.webmanifest
|
||||
|
|
|
|||
11
.gitlab-ci.yml
Normal file
11
.gitlab-ci.yml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
include:
|
||||
- project: 'ldc-web/shared-ci'
|
||||
ref: 'main'
|
||||
file: 'lint/lint.yml'
|
||||
- project: 'ldc-web/shared-ci'
|
||||
ref: 'main'
|
||||
file: 'security/security.yml'
|
||||
|
||||
stages:
|
||||
- lint
|
||||
- security
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "resources/theme"]
|
||||
path = resources/theme
|
||||
url = ../gen-game-web-themes/theme-merger.git
|
||||
2
.husky/commit-msg
Normal file
2
.husky/commit-msg
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
npx commitlint --config node_modules/@uwil/husky-config/commitlint.config.js --edit $1
|
||||
13
.styleci.yml
13
.styleci.yml
|
|
@ -1,13 +0,0 @@
|
|||
php:
|
||||
preset: laravel
|
||||
disabled:
|
||||
- unused_use
|
||||
finder:
|
||||
not-name:
|
||||
- index.php
|
||||
- server.php
|
||||
js:
|
||||
finder:
|
||||
not-name:
|
||||
- webpack.mix.js
|
||||
css: true
|
||||
43
.stylelintrc.json
Normal file
43
.stylelintrc.json
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"extends": [
|
||||
"stylelint-config-standard-scss",
|
||||
"stylelint-config-sass-guidelines",
|
||||
"stylelint-config-idiomatic-order"
|
||||
],
|
||||
"plugins": [
|
||||
"stylelint-scss"
|
||||
],
|
||||
"files": [
|
||||
"**/*.css",
|
||||
"**/*.scss"
|
||||
],
|
||||
"ignoreFiles": [
|
||||
"**/vendor/*.css",
|
||||
"**/vendor/**/*.css",
|
||||
"**/vendor/*.scss",
|
||||
"**/vendor/**/*.scss",
|
||||
"**/vendor/*.sass",
|
||||
"**/vendor/**/*.sass",
|
||||
"**/vendor/*.less",
|
||||
"**/vendor/**/*.less"
|
||||
],
|
||||
"customSyntax": "postcss-scss",
|
||||
"rules": {
|
||||
"declaration-property-value-no-unknown": null,
|
||||
"selector-max-id": null,
|
||||
"color-no-invalid-hex": true,
|
||||
"order/properties-alphabetical-order": null,
|
||||
"max-nesting-depth": 5,
|
||||
"selector-max-compound-selectors": 5,
|
||||
"scss/double-slash-comment-empty-line-before": [
|
||||
"always",
|
||||
{
|
||||
"ignore": [
|
||||
"between-comments",
|
||||
"stylelint-commands",
|
||||
"inside-block"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
22
.vscode/settings.json
vendored
Normal file
22
.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"workbench.colorCustomizations": {
|
||||
"activityBar.activeBackground": "#962a40",
|
||||
"activityBar.background": "#962a40",
|
||||
"activityBar.foreground": "#e7e7e7",
|
||||
"activityBar.inactiveForeground": "#e7e7e799",
|
||||
"activityBarBadge.background": "#40952a",
|
||||
"activityBarBadge.foreground": "#e7e7e7",
|
||||
"commandCenter.border": "#e7e7e799",
|
||||
"sash.hoverBorder": "#962a40",
|
||||
"statusBar.background": "#6e1f2f",
|
||||
"statusBar.foreground": "#e7e7e7",
|
||||
"statusBarItem.hoverBackground": "#962a40",
|
||||
"statusBarItem.remoteBackground": "#6e1f2f",
|
||||
"statusBarItem.remoteForeground": "#e7e7e7",
|
||||
"titleBar.activeBackground": "#6e1f2f",
|
||||
"titleBar.activeForeground": "#e7e7e7",
|
||||
"titleBar.inactiveBackground": "#6e1f2f99",
|
||||
"titleBar.inactiveForeground": "#e7e7e799"
|
||||
},
|
||||
"peacock.remoteColor": "#6e1f2f"
|
||||
}
|
||||
80
README.md
80
README.md
|
|
@ -1,61 +1,59 @@
|
|||
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg" width="400"></a></p>
|
||||
# GEN GAME WEB
|
||||
|
||||
<p align="center">
|
||||
<a href="https://travis-ci.org/laravel/framework"><img src="https://travis-ci.org/laravel/framework.svg" alt="Build Status"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://poser.pugx.org/laravel/framework/d/total.svg" alt="Total Downloads"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://poser.pugx.org/laravel/framework/v/stable.svg" alt="Latest Stable Version"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://poser.pugx.org/laravel/framework/license.svg" alt="License"></a>
|
||||
</p>
|
||||
## Installation
|
||||
|
||||
## About Laravel
|
||||
``` Bash
|
||||
cp .env.example .env
|
||||
php artisan key:generate /!\ bien sauvegarder la key
|
||||
php artisan migrate:fresh --step
|
||||
# Seulement pour developper un theme par exemple
|
||||
php artisan db:seed --class DevelopmentSeeder
|
||||
php artisan uwil:user:create
|
||||
```
|
||||
|
||||
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
|
||||
## Création du compte Admin
|
||||
|
||||
- [Simple, fast routing engine](https://laravel.com/docs/routing).
|
||||
- [Powerful dependency injection container](https://laravel.com/docs/container).
|
||||
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
|
||||
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
|
||||
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
|
||||
- [Robust background job processing](https://laravel.com/docs/queues).
|
||||
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
|
||||
``` Bash
|
||||
php artisan uwil:user:create
|
||||
```
|
||||
|
||||
Laravel is accessible, powerful, and provides tools required for large, robust applications.
|
||||
## Ajouter Parametrage du jeu
|
||||
|
||||
## Learning Laravel
|
||||
**Les lots sont à ajouter avant de générer les instants gagants**. En effet les instants gagants sont liés à des lots.
|
||||
|
||||
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.
|
||||
|
||||
If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains over 1500 video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
|
||||
## Générer des coupons et les mails
|
||||
|
||||
## Laravel Sponsors
|
||||
``` Bash
|
||||
artisan queue:work
|
||||
```
|
||||
|
||||
We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the Laravel [Patreon page](https://patreon.com/taylorotwell).
|
||||
En cas de manipulation pourrie, penser a vider le cache pour supprimer le lock
|
||||
sur le job de generation des codes.
|
||||
|
||||
### Premium Partners
|
||||
## THEME
|
||||
|
||||
- **[Vehikl](https://vehikl.com/)**
|
||||
- **[Tighten Co.](https://tighten.co)**
|
||||
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
|
||||
- **[64 Robots](https://64robots.com)**
|
||||
- **[Cubet Techno Labs](https://cubettech.com)**
|
||||
- **[Cyber-Duck](https://cyber-duck.co.uk)**
|
||||
- **[Many](https://www.many.co.uk)**
|
||||
- **[Webdock, Fast VPS Hosting](https://www.webdock.io/en)**
|
||||
- **[DevSquad](https://devsquad.com)**
|
||||
- **[OP.GG](https://op.gg)**
|
||||
### Instalation
|
||||
|
||||
## Contributing
|
||||
Pour installer le theme bien **mettre à jour les submodules avec git**,
|
||||
`git submodule update --init --recursive`
|
||||
|
||||
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
|
||||
puis utiliser la commande `php artisan uwil:theme:switch NOM_DU_THEME` et `php artisan optimize:clear && php artisan optimize`
|
||||
|
||||
## Code of Conduct
|
||||
Pour mettre a jour la liste des themes :
|
||||
|
||||
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
|
||||
### Mise à jour
|
||||
|
||||
## Security Vulnerabilities
|
||||
**Note** : cette partie n'est pas encore certaine.
|
||||
|
||||
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
|
||||
- Mettre à jour `git submodule update --remote --merge resources/theme`
|
||||
Ou
|
||||
|
||||
## License
|
||||
``` Bash
|
||||
cd resources/themes;
|
||||
git pull origin main;
|
||||
cd ../..;
|
||||
git add resources/themes
|
||||
```
|
||||
|
||||
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
|
||||
Puis commit.
|
||||
|
|
|
|||
188
app/Auth/CrmUserProvider.php
Normal file
188
app/Auth/CrmUserProvider.php
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
<?php
|
||||
|
||||
namespace App\Auth;
|
||||
|
||||
use App\Models\Customer;
|
||||
use Illuminate\Auth\EloquentUserProvider;
|
||||
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Contracts\Auth\UserProvider as UserProviderContract;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Str;
|
||||
use LDC\LDCCRM\Enums\ApiError;
|
||||
use LDC\LDCCRM\Exceptions\ApiErrorException;
|
||||
use LDC\LDCCRM\Exceptions\CrmException;
|
||||
use LDC\LDCCRM\Models\Customer as CrmCustomer;
|
||||
|
||||
/**
|
||||
* Crm user provider to integrate nicely with Laravel
|
||||
*/
|
||||
class CrmUserProvider extends EloquentUserProvider implements UserProviderContract
|
||||
{
|
||||
/**
|
||||
* The model to use, specified in auth config guard.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $usedModel = Customer::class;
|
||||
|
||||
/**
|
||||
* Retrieve a user by the given credentials.
|
||||
*
|
||||
* @param array $credentials
|
||||
* @return \Illuminate\Contracts\Auth\Authenticatable|null
|
||||
*/
|
||||
public function retrieveByCredentials(array $credentials)
|
||||
{
|
||||
// * Let laravel find a model
|
||||
$model = parent::retrieveByCredentials($credentials) ??
|
||||
self::retrieveTrashed($credentials);
|
||||
|
||||
try {
|
||||
/** @var \LDC\LDCCRM\CrmApiV4 */
|
||||
$crm = app('crmAPI');
|
||||
|
||||
// Si pas de compte local.
|
||||
if (!$model) {
|
||||
$crmCustomer = $crm->getCustomer($credentials['email']);
|
||||
|
||||
if (!$crmCustomer) {
|
||||
// * Customer is not found on CRM.
|
||||
return null;
|
||||
}
|
||||
$model = $this->createLocalCustomer($crmCustomer);
|
||||
}
|
||||
|
||||
return $model;
|
||||
} catch (ApiErrorException $e) {
|
||||
// * Customer is not found.
|
||||
if ($e->getApiError()->equals(ApiError::modelNotFound)) {
|
||||
return null;
|
||||
}
|
||||
report($e);
|
||||
Log::error('Unhandled response ' . $e->getApiError()->label());
|
||||
} catch (CrmException | \Exception $e) {
|
||||
report($e);
|
||||
// Une erreur critique est survenue avec la CRM.
|
||||
return null;
|
||||
} //end try
|
||||
Log::error(__CLASS__ . '::retrieveByCredentials reached end of possibilities.');
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a user against the given credentials.
|
||||
*
|
||||
* @param UserContract $model
|
||||
* @param array $credentials
|
||||
* @return boolean|null
|
||||
* @throws \RuntimeException If model provided is not a Customer or connection to server fails.
|
||||
* @throws \LDC\LDCCRM\Exceptions\CrmException On CRM call error.
|
||||
* @throws \Exception On CRM call error.
|
||||
*/
|
||||
public function validateCredentials(UserContract $model, array $credentials): bool|null
|
||||
{
|
||||
/** @var \App\Models\Customer $model */
|
||||
if (\get_class($model) !== $this->usedModel) {
|
||||
throw new \RuntimeException('Cannot authenticate any thing else than ' . $this->usedModel);
|
||||
}
|
||||
|
||||
try {
|
||||
/** @var \LDC\LDCCRM\CrmApiV4 */
|
||||
$crm = app('crmAPI');
|
||||
|
||||
// * If has trait soft delete and customer trashed, then restore customer.
|
||||
if (
|
||||
\in_array(\Illuminate\Database\Eloquent\SoftDeletes::class, \class_uses_recursive($model)) and
|
||||
$model->trashed()
|
||||
) {
|
||||
$model->restore();
|
||||
}
|
||||
|
||||
// * Ne devrait pas survenir, $crm->login throws ApiError::authFailed()
|
||||
return $crm->login($credentials['email'], $credentials['password']);
|
||||
} catch (ApiErrorException $e) {
|
||||
if (
|
||||
$e->getApiError()->equals(ApiError::modelNotFound) ||
|
||||
($e->getApiError()->equals(ApiError::authFailed) && !$model->existsInCrm())
|
||||
) {
|
||||
$model->delete();
|
||||
return false;
|
||||
}
|
||||
if ($e->getApiError()->equals(ApiError::authFailed)) {
|
||||
return false;
|
||||
}
|
||||
// ! Assert Authenticable model must be valided (MustValidate trait).
|
||||
if ($e->getApiError()->equals(ApiError::customerNotActivated)) {
|
||||
$model->email_verified_at = null;
|
||||
$model->save();
|
||||
$model->sendEmailVerificationNotification();
|
||||
Session::flash('warning', \trans('front.messages.account_not_activated'));
|
||||
return true;
|
||||
}
|
||||
} catch (CrmException | \Exception $e) {
|
||||
report($e);
|
||||
if (config('app.debug')) {
|
||||
throw $e;
|
||||
}
|
||||
return false;
|
||||
} //end try
|
||||
|
||||
Log::error(__CLASS__ . '::validateCredentials reached end of possibilities.');
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a local customer
|
||||
*
|
||||
* @param \LDC\LDCCRM\Models\Customer $crmCustomer
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
* @throws \Throwable If saving to DB failed.
|
||||
*/
|
||||
private function createLocalCustomer(\LDC\LDCCRM\Models\Customer $crmCustomer): Model
|
||||
{
|
||||
/** @var \App\Models\Customer $model */
|
||||
$model = $this->usedModel::withTrashed()->firstOrNew([
|
||||
'email' => $crmCustomer->email
|
||||
]);
|
||||
$model->hashcode = $crmCustomer->hashcode;
|
||||
$model->email_verified_at = $crmCustomer->status ? now() : null;
|
||||
if ($model->trashed()) {
|
||||
$model->restore();
|
||||
}
|
||||
$model->saveOrFail();
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a trashed customer by the given credentials.
|
||||
*
|
||||
* @param array $credentials
|
||||
* @return \Illuminate\Contracts\Auth\Authenticatable|null
|
||||
* @throws \ErrorException If cannot connect to LDAP.
|
||||
*/
|
||||
private function retrieveTrashed(array $credentials): ?Authenticatable
|
||||
{
|
||||
// * Make changes
|
||||
if (empty($credentials)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// First we will add each credential element to the query as a where clause.
|
||||
// Then we can execute the query and, if we found a customer, return it in a
|
||||
// Eloquent User "model" that will be utilized by the Guard instances.
|
||||
$query = $this->createModel()->newQuery();
|
||||
|
||||
foreach ($credentials as $key => $value) {
|
||||
if (!Str::contains($key, 'password')) {
|
||||
$query->where($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/** @var \App\Models\Customer|null $query */
|
||||
return $query->withTrashed()->first();
|
||||
}
|
||||
}
|
||||
46
app/Casts/AsArrayOfDiscount.php
Normal file
46
app/Casts/AsArrayOfDiscount.php
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace App\Casts;
|
||||
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||
|
||||
class AsArrayOfDiscount implements CastsAttributes
|
||||
{
|
||||
/**
|
||||
* Cast the given value.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param array $attributes
|
||||
* @return array<\App\Lib\Discount>
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing
|
||||
*/
|
||||
public function get($model, string $key, $value, array $attributes): array
|
||||
{
|
||||
// phpcs:enable
|
||||
return \collect(\json_decode($value, true))->map(function ($input) use ($model, $key, $attributes) {
|
||||
$inputCast = new AsDiscount();
|
||||
return $inputCast->get($model, $key, \json_encode($input), $attributes);
|
||||
})->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the given value for storage.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param \App\Lib\Discount $value
|
||||
* @param array $attributes
|
||||
* @return string Json encoded array<\App\Lib\Discount>
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing
|
||||
*/
|
||||
public function set($model, string $key, $value, array $attributes)
|
||||
{
|
||||
// phpcs:enable
|
||||
return \json_encode(\collect($value)->map(function ($input) use ($model, $key, $attributes) {
|
||||
$inputCast = new AsDiscount();
|
||||
return \json_decode($inputCast->set($model, $key, $input, $attributes));
|
||||
})->all());
|
||||
}
|
||||
}
|
||||
65
app/Casts/AsDiscount.php
Normal file
65
app/Casts/AsDiscount.php
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace App\Casts;
|
||||
|
||||
use App\Lib\Discount;
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||
|
||||
class AsDiscount implements CastsAttributes
|
||||
{
|
||||
/**
|
||||
* Cast the given value.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param array $attributes
|
||||
* @return \App\Lib\Discount
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceBeforeLastUsed
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceAfterLastUsed
|
||||
*/
|
||||
public function get($model, string $key, $value, array $attributes): Discount
|
||||
{
|
||||
// phpcs:enable
|
||||
$inputData = \json_decode($value, true);
|
||||
return Discount::make(...\array_values($inputData));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the given value for storage.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param array $attributes
|
||||
* @return string Json encoded \App\Lib\Inputs\Definition\Input
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceBeforeLastUsed
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceAfterLastUsed
|
||||
*/
|
||||
public function set($model, string $key, $value, array $attributes)
|
||||
{
|
||||
// phpcs:enable
|
||||
$this->assertIsInput($value);
|
||||
/** @var \App\Lib\Discount $value */
|
||||
return $value->toJson();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert is instance of \App\Lib\Discount
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
* @throws \RuntimeException If the value is not an input.
|
||||
*/
|
||||
private function assertIsInput(mixed $value): void
|
||||
{
|
||||
if (!\is_object($value) or !($value instanceof Discount)) {
|
||||
$value = \json_encode($value);
|
||||
throw new \RuntimeException(
|
||||
__CLASS__ . ' needs value to be array of \'' . Discount::class . "' given is {$value}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
61
app/Casts/Ip.php
Normal file
61
app/Casts/Ip.php
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace App\Casts;
|
||||
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* @template TGet
|
||||
* @template TSet
|
||||
*/
|
||||
class Ip implements CastsAttributes
|
||||
{
|
||||
/**
|
||||
* Transform the attribute from the underlying model values.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param array<string,mixed> $attributes
|
||||
* @return \IPLib\Address\AddressInterface|null
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceBeforeLastUsed
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceAfterLastUsed
|
||||
*/
|
||||
public function get(Model $model, string $key, mixed $value, array $attributes)
|
||||
{
|
||||
// phpcs:enable
|
||||
return \IPLib\Factory::parseAddressString($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform the attribute to its underlying model values.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param \IPLib\Address\AddressInterface|string|null $value
|
||||
* @param array<string,mixed> $attributes
|
||||
* @return mixed
|
||||
* @throws \RuntimeException If value is not or instance of \IPLib\Address\AddressInterface.
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceAfterLastUsed
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceBeforeLastUsed
|
||||
*/
|
||||
public function set(Model $model, string $key, mixed $value, array $attributes)
|
||||
{
|
||||
// phpcs:enable
|
||||
if (is_null($value)) {
|
||||
return null;
|
||||
}
|
||||
if (is_string($value)) {
|
||||
$value = \IPLib\Factory::parseAddressString($value);
|
||||
}
|
||||
if (!is_object($value) or !($value instanceof \IPLib\Address\AddressInterface)) {
|
||||
throw new \RuntimeException(
|
||||
"{$key} has to be instance of " .
|
||||
\IPLib\Address\AddressInterface::class
|
||||
);
|
||||
}
|
||||
$value->getAddressType();
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class CreateAdmin extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'create:admin';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Command description';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$firstname = $this->ask('What is the firstname?', 'Informatique');
|
||||
$lastname = $this->ask('What is the lastname?', 'Internet');
|
||||
$email = $this->ask('What is the email?', 'equipe.web@ldc.fr');
|
||||
$pwd = $this->secret('What is the password?');
|
||||
$role = $this->ask('Role ?', '1');
|
||||
|
||||
$user = new User();
|
||||
$user->firstname = $firstname;
|
||||
$user->lastname = $lastname;
|
||||
$user->birth_date = now();
|
||||
$user->email = $email;
|
||||
$user->password = Hash::make($pwd);
|
||||
$user->address = "-";
|
||||
$user->town = "Le Mans";
|
||||
$user->postal_code = "72000";
|
||||
$user->country = "France";
|
||||
$user->email_verify_token = "-";
|
||||
$user->email_verified = 1;
|
||||
$user->role = $role;
|
||||
$user->save();
|
||||
|
||||
$this->info('User created.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class DeleteNotConfirmedUser extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'users:deletenc';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Remove users who have not confirmed their accounts within 24 hours of registration';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$users = User::where([['email_verified', 0], ['created_at', '<', Carbon::now()->subDay()]])->get();
|
||||
foreach ($users as $user) {
|
||||
$user->delete();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,192 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Mail\ExportCodesUniques as MailExportCodesUniques;
|
||||
use App\Models\Code;
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class ExportCodesUniques extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'export:codeunique';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Command description';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
// Nombre total de code à exporter.
|
||||
$nbCodeTot = $this->ask("Combien de code doivent être exporté ?");
|
||||
while (empty(intval($nbCodeTot)) || !is_int(intval($nbCodeTot))) {
|
||||
$this->info("Valeur incorrect, veuillez entrer un nombre entier.");
|
||||
$nbCodeTot = $this->ask("Veuillez entrer une nouvelle valeur");
|
||||
}
|
||||
$nbCodeTot = intval($nbCodeTot);
|
||||
|
||||
// Nombre de code par fichier.
|
||||
$nbCodeFic = $this->ask("Combien de code par fichier ?");
|
||||
while (empty(intval($nbCodeFic)) || !is_int(intval($nbCodeFic))) {
|
||||
$this->info("Valeur incorrect, veuillez entrer un nombre entier.");
|
||||
$nbCodeFic = $this->ask("Veuillez entrer une nouvelle valeur");
|
||||
}
|
||||
$nbCodeFic = intval($nbCodeFic);
|
||||
|
||||
// Nombre de code par ligne.
|
||||
$nbCodeLigne = $this->ask("Combien de code par ligne dans un fichier ?");
|
||||
while (empty(intval($nbCodeLigne)) || !is_int(intval($nbCodeLigne))) {
|
||||
$this->info("Valeur incorrect, veuillez entrer un nombre entier.");
|
||||
$nbCodeLigne = $this->ask("Veuillez entrer une nouvelle valeur");
|
||||
}
|
||||
$nbCodeLigne = intval($nbCodeLigne);
|
||||
|
||||
$totalExportedCodes = 0;
|
||||
$currentFilename = 1;
|
||||
$currentExportedCodes = 0;
|
||||
$currentLineCodes = ($nbCodeLigne === 1 ? 1 : 0);
|
||||
|
||||
$this->info("Traitement en cours, veuillez patienter...");
|
||||
|
||||
$this->process(
|
||||
$nbCodeFic,
|
||||
$nbCodeTot,
|
||||
$nbCodeLigne,
|
||||
$totalExportedCodes,
|
||||
$currentFilename,
|
||||
$currentExportedCodes,
|
||||
$currentLineCodes
|
||||
);
|
||||
|
||||
$this->info("Fin du traitement, creation de l'archive...");
|
||||
|
||||
// Compression des fichiers.
|
||||
$zip = new \ZipArchive();
|
||||
if (
|
||||
$zip->open(
|
||||
storage_path('export_codes_uniques/') . "CodesUniques_" . date('dmY') . ".zip",
|
||||
\ZipArchive::CREATE
|
||||
) === true
|
||||
) {
|
||||
if ($handle = opendir(storage_path('export_codes_uniques/tmp'))) {
|
||||
while (false !== ($file_to_zip = readdir($handle))) {
|
||||
if (pathinfo($file_to_zip, PATHINFO_EXTENSION) != 'csv') {
|
||||
continue;
|
||||
}
|
||||
$zip->addFile(storage_path('export_codes_uniques/tmp/') . $file_to_zip, "$file_to_zip");
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
$zip->close();
|
||||
}
|
||||
|
||||
// On vide le dossier temporaire des fichiers csv.
|
||||
if ($handle = opendir(storage_path('export_codes_uniques/tmp'))) {
|
||||
while (false !== ($file_to_zip = readdir($handle))) {
|
||||
if (pathinfo($file_to_zip, PATHINFO_EXTENSION) != 'csv') {
|
||||
continue;
|
||||
}
|
||||
unlink(storage_path('export_codes_uniques/tmp/') . $file_to_zip);
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
|
||||
$this->info("L'archive CodesUniques_" . date('dmY') . ".zip a ete creer.");
|
||||
|
||||
// Envoi de mail à MAIL_ADMIN avec le nom du ZIP "CodesUniques_". date('dmY') .".zip" .
|
||||
Mail::to(config('mail.MAIL_ADMIN'))
|
||||
->send(new MailExportCodesUniques(app(Settings::class)->name, $nbCodeFic, $nbCodeTot, $nbCodeLigne));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function process($nbCodeFic, $nbCodeTot, $nbCodeLigne, $totalExportedCodes, $currentFilename, $currentExportedCodes, $currentLineCodes, $lastExportedCodeId = null)
|
||||
{
|
||||
$paginate = config('codes.paginate');
|
||||
|
||||
if ($nbCodeTot < $paginate) {
|
||||
$nbCodeToRetrieve = $nbCodeTot;
|
||||
} else {
|
||||
if ($totalExportedCodes + $paginate > $nbCodeTot) {
|
||||
$nbCodeToRetrieve = $nbCodeTot - $totalExportedCodes;
|
||||
} else {
|
||||
$nbCodeToRetrieve = $paginate;
|
||||
}
|
||||
}
|
||||
|
||||
if ($lastExportedCodeId === null) {
|
||||
$codes = Code::where('code_exported', 0)->take($nbCodeToRetrieve)->get();
|
||||
} else {
|
||||
$codes = Code::where([
|
||||
['code_exported', '=', 0],
|
||||
['id', '>', $lastExportedCodeId]
|
||||
])->take($nbCodeToRetrieve)->get();
|
||||
}
|
||||
|
||||
$countCodes = count($codes);
|
||||
|
||||
$exportedCodesId = [];
|
||||
|
||||
foreach ($codes as $k => $code) {
|
||||
if ($currentExportedCodes < $nbCodeTot) {
|
||||
if ($currentLineCodes === ($nbCodeLigne === 1 ? 1 : $nbCodeLigne - 1)) {
|
||||
file_put_contents(
|
||||
storage_path('export_codes_uniques/tmp/') . $currentFilename . ".csv",
|
||||
$code->code_unique . PHP_EOL,
|
||||
FILE_APPEND
|
||||
);
|
||||
$totalExportedCodes++;
|
||||
$currentExportedCodes++;
|
||||
$currentLineCodes = ($nbCodeLigne === 1 ? 1 : 0);
|
||||
} else {
|
||||
file_put_contents(
|
||||
storage_path('export_codes_uniques/tmp/') . $currentFilename . ".csv",
|
||||
$code->code_unique . ";",
|
||||
FILE_APPEND
|
||||
);
|
||||
$totalExportedCodes++;
|
||||
$currentExportedCodes++;
|
||||
$currentLineCodes++;
|
||||
}
|
||||
|
||||
array_push($exportedCodesId, $code->id);
|
||||
$lastExportedCodeId = $code->id;
|
||||
|
||||
if ($currentExportedCodes === $nbCodeFic) {
|
||||
$currentFilename++;
|
||||
$currentExportedCodes = 0;
|
||||
}
|
||||
if ((($k + 1) === $countCodes) && $totalExportedCodes < $nbCodeTot) {
|
||||
Code::whereIn('id', $exportedCodesId)->update(['code_exported' => 1]);
|
||||
return $this->process(
|
||||
$nbCodeFic,
|
||||
$nbCodeTot,
|
||||
$nbCodeLigne,
|
||||
$totalExportedCodes,
|
||||
$currentFilename,
|
||||
$currentExportedCodes,
|
||||
$currentLineCodes,
|
||||
$lastExportedCodeId
|
||||
);
|
||||
}
|
||||
if (($k + 1) === $countCodes) {
|
||||
Code::whereIn('id', $exportedCodesId)->update(['code_exported' => 1]);
|
||||
}
|
||||
} //end if
|
||||
}//end foreach
|
||||
}
|
||||
}
|
||||
35
app/Console/Commands/TestMail.php
Normal file
35
app/Console/Commands/TestMail.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class TestMail extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'uwil:mail:test';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Send test email to equipe.web@ldc.fr';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
Mail::raw(sprintf('UWIL mail-test from %s %s', \config('app.name'), \config('app.url')), function ($msg) {
|
||||
$msg->to('equipe.web@ldc.fr')->subject('Test Email');
|
||||
});
|
||||
}
|
||||
}
|
||||
77
app/Console/Commands/Theme/SwitchCommand.php
Normal file
77
app/Console/Commands/Theme/SwitchCommand.php
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands\Theme;
|
||||
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Contracts\Console\PromptsForMissingInput;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
use function Laravel\Prompts\search;
|
||||
|
||||
class SwitchCommand extends Command implements PromptsForMissingInput
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'uwil:theme:switch {theme : The theme folder name on theme-merge project}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Switch GGW theme and install it';
|
||||
|
||||
/**
|
||||
* Prompt for missing input arguments using the returned questions.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function promptForMissingArgumentsUsing()
|
||||
{
|
||||
return [
|
||||
'theme' => fn () => search(
|
||||
label: 'Search for a theme:',
|
||||
placeholder: 'default-theme',
|
||||
options: fn (string $value): array => \collect(File::directories(\resource_path('theme')))
|
||||
->map(fn (string $dir_path) => \pathinfo($dir_path, \PATHINFO_BASENAME))
|
||||
->filter(fn (string $dir_path) => $value ? Str::of($dir_path)->contains($value) : true)
|
||||
->filter(fn (string $dir_path) => $dir_path !== 'mounted')
|
||||
->all()
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
$mount_path = \resource_path('theme/mounted');
|
||||
|
||||
/** @var string */
|
||||
$theme = $this->argument('theme');
|
||||
|
||||
if (File::exists($mount_path)) {
|
||||
\throw_if(
|
||||
empty(ToolboxHelper::runConsoleCommand("readlink {$mount_path}", false)),
|
||||
"{$mount_path} is not a link, cannot remove it"
|
||||
);
|
||||
\throw_if(
|
||||
!File::delete($mount_path),
|
||||
"{$mount_path} Failed to remove file"
|
||||
);
|
||||
}
|
||||
|
||||
File::link(\resource_path("theme/{$theme}"), $mount_path);
|
||||
|
||||
Artisan::call('optimize:clear');
|
||||
}
|
||||
}
|
||||
231
app/Console/Commands/UserCreate.php
Normal file
231
app/Console/Commands/UserCreate.php
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Enums\Users\RoleEnum;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class UserCreate extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'uwil:user:create';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $description = 'Create a backend admin user';
|
||||
|
||||
/**
|
||||
* The first name of the new user.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $first_name;
|
||||
|
||||
/**
|
||||
* The last name of the new user.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $last_name;
|
||||
|
||||
/**
|
||||
* The email of the new user.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $email;
|
||||
|
||||
/**
|
||||
* The password of the new user.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $password;
|
||||
|
||||
/**
|
||||
* The role of the new user.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $role;
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$this->first_name = null;
|
||||
$this->addFirstName();
|
||||
|
||||
$this->last_name = null;
|
||||
$this->addLastName();
|
||||
|
||||
$this->email = null;
|
||||
$this->addEmail();
|
||||
|
||||
$this->password = null;
|
||||
$this->addPassword();
|
||||
|
||||
$this->role = null;
|
||||
$this->addRole();
|
||||
|
||||
$user = new User([
|
||||
'first_name' => $this->first_name,
|
||||
'last_name' => $this->last_name,
|
||||
'email' => $this->email,
|
||||
'password' => $this->password,
|
||||
'role' => $this->role,
|
||||
'published' => true,
|
||||
'published_at' => Carbon::now(),
|
||||
]);
|
||||
$user->saveOrFail();
|
||||
|
||||
$this->info('User created 👌');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a first name to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addFirstName(): void
|
||||
{
|
||||
while (is_null($this->first_name)) {
|
||||
try {
|
||||
$tmp = $this->ask('Type the wanted user first name', 'Admin');
|
||||
$validator = Validator::make(['first_name' => $tmp], [
|
||||
'first_name' => 'required|min:3|max:255'
|
||||
]);
|
||||
$validator->validate();
|
||||
$this->first_name = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please provide a valid first name %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
continue;
|
||||
} //end try
|
||||
}; //end while
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a last name to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addLastName(): void
|
||||
{
|
||||
while (is_null($this->last_name)) {
|
||||
try {
|
||||
$tmp = $this->ask('Type the wanted user last name', 'Saïtama');
|
||||
$validator = Validator::make(['last_name' => $tmp], [
|
||||
'last_name' => 'required|min:3|max:255'
|
||||
]);
|
||||
$validator->validate();
|
||||
$this->last_name = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please provide a valid last_name %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
continue;
|
||||
} //end try
|
||||
}; //end while
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an email to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addEmail(): void
|
||||
{
|
||||
while (is_null($this->email)) {
|
||||
try {
|
||||
$tmp = $this->ask('Type the wanted user email', 'equipe.web@ldc.fr');
|
||||
$validator = Validator::make(['email' => $tmp], [
|
||||
'email' => 'required|unique:users,email|email:rfc,dns'
|
||||
]);
|
||||
$validator->validate();
|
||||
$this->email = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please provide a valid email %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
continue;
|
||||
} //end try
|
||||
}; //end while
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a password to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addPassword(): void
|
||||
{
|
||||
while (
|
||||
($this->password = $this->secret(
|
||||
(!\is_null($this->password) ? 'Failed to confirm, ' : '') . 'Type the wanted user password'
|
||||
)) !== $this->secret('Confirm the password')
|
||||
) {
|
||||
continue;
|
||||
}; //end while
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a role to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addRole(): void
|
||||
{
|
||||
while (is_null($this->role)) {
|
||||
try {
|
||||
$tmp = $this->choice(
|
||||
'Select his role',
|
||||
[RoleEnum::conceptor->label(), RoleEnum::admin->label(), RoleEnum::marketing->label()],
|
||||
RoleEnum::marketing->label(),
|
||||
$maxAttempts = null,
|
||||
$allowMultipleSelections = false
|
||||
);
|
||||
if ($tmp === RoleEnum::conceptor->label()) {
|
||||
$tmp = RoleEnum::conceptor;
|
||||
}
|
||||
if ($tmp === RoleEnum::admin->label()) {
|
||||
$tmp = RoleEnum::admin;
|
||||
}
|
||||
if ($tmp === RoleEnum::marketing->label()) {
|
||||
$tmp = RoleEnum::marketing;
|
||||
}
|
||||
$validator = Validator::make(['role' => $tmp], [
|
||||
'role' => 'required'
|
||||
]);
|
||||
$validator->validate();
|
||||
$this->role = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please choose from the selection %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
continue;
|
||||
} //end try
|
||||
}; //end while
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Console;
|
||||
|
||||
use App\Jobs\DeleteOlds\DeleteOldCustomers;
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
|
|
@ -22,6 +23,9 @@ class Kernel extends ConsoleKernel
|
|||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
// ! ATTENTION: Le job DeleteOldCustomers a été désactivé, car il n'est pas applicable pour l'instant.
|
||||
// ! Il faudra décorreler les customers des gains et participations via les FK.
|
||||
// $schedule->job(DeleteOldCustomers::class)->dailyAt('22:50');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
48
app/Enums/ActivityLogs/ActivityLogsEventEnum.php
Normal file
48
app/Enums/ActivityLogs/ActivityLogsEventEnum.php
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums\ActivityLogs;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
||||
enum ActivityLogsEventEnum: int
|
||||
{
|
||||
use BaseEnum;
|
||||
|
||||
case created = 1;
|
||||
case updated = 2;
|
||||
case duplicated = 3;
|
||||
case deleted = 4;
|
||||
|
||||
/**
|
||||
* Optionnal labels definition
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::created->name => 'Création',
|
||||
self::updated->name => 'Mise à jour',
|
||||
self::duplicated->name => 'Duplication',
|
||||
self::deleted->name => 'Suppression',
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Custom added classes definition
|
||||
*/
|
||||
private const BOOTSTRAPCLASS = [
|
||||
self::created->name => 'success',
|
||||
self::updated->name => 'warning',
|
||||
self::duplicated->name => 'secondary',
|
||||
self::deleted->name => 'danger',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get Class
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function bootstrapClass(): string
|
||||
{
|
||||
return self::BOOTSTRAPCLASS[$this->name];
|
||||
}
|
||||
}
|
||||
25
app/Enums/CodeType.php
Normal file
25
app/Enums/CodeType.php
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
||||
enum CodeType: int
|
||||
{
|
||||
use BaseEnum;
|
||||
|
||||
case unique = 1;
|
||||
case ean = 2;
|
||||
case both = 3;
|
||||
|
||||
/**
|
||||
* Optionnal labels definition.
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::unique->name => 'Codes uniques',
|
||||
self::ean->name => 'Codes EAN',
|
||||
self::both->name => 'Codes uniques et codes EAN'
|
||||
];
|
||||
}
|
||||
30
app/Enums/InputType.php
Normal file
30
app/Enums/InputType.php
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
||||
enum InputType: int
|
||||
{
|
||||
use BaseEnum;
|
||||
|
||||
case boolean = 1;
|
||||
case dropdownArray = 2;
|
||||
case email = 3;
|
||||
case image = 4;
|
||||
case imageArray = 5;
|
||||
case labelArray = 6;
|
||||
case miniblocArray = 7;
|
||||
case number = 8;
|
||||
case selectEnum = 9;
|
||||
case password = 10;
|
||||
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;
|
||||
}
|
||||
16
app/Enums/Pagination/ItemsPerPaginationEnum.php
Normal file
16
app/Enums/Pagination/ItemsPerPaginationEnum.php
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums\Pagination;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
||||
enum ItemsPerPaginationEnum: int
|
||||
{
|
||||
use BaseEnum;
|
||||
|
||||
case five = 5;
|
||||
case twelve = 12;
|
||||
case twentyfive = 25;
|
||||
case fifty = 50;
|
||||
case onehundred = 100;
|
||||
}
|
||||
25
app/Enums/StaticPageType.php
Normal file
25
app/Enums/StaticPageType.php
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
||||
enum StaticPageType: int
|
||||
{
|
||||
use BaseEnum;
|
||||
|
||||
case legals = 1;
|
||||
case rules = 2;
|
||||
case confidentiality = 3;
|
||||
|
||||
/**
|
||||
* Optionnal labels definition.
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::legals->name => 'Mentions légales',
|
||||
self::rules->name => 'Règlement',
|
||||
self::confidentiality->name => 'Charte de confidentialité'
|
||||
];
|
||||
}
|
||||
23
app/Enums/Theme/BootstrapThemeEnum.php
Normal file
23
app/Enums/Theme/BootstrapThemeEnum.php
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums\Theme;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
||||
enum BootstrapThemeEnum: int
|
||||
{
|
||||
use BaseEnum;
|
||||
|
||||
case light = 1;
|
||||
case dark = 2;
|
||||
|
||||
/**
|
||||
* Optionnal labels definition
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::light->name => 'Light',
|
||||
self::dark->name => 'Dark',
|
||||
];
|
||||
}
|
||||
25
app/Enums/Users/RoleEnum.php
Normal file
25
app/Enums/Users/RoleEnum.php
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums\Users;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
||||
enum RoleEnum: int
|
||||
{
|
||||
use BaseEnum;
|
||||
|
||||
case conceptor = 1;
|
||||
case admin = 2;
|
||||
case marketing = 3;
|
||||
|
||||
/**
|
||||
* Optionnal labels definition
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::conceptor->name => 'Concepteur',
|
||||
self::admin->name => 'Administrator',
|
||||
self::marketing->name => 'Marketing',
|
||||
];
|
||||
}
|
||||
|
|
@ -2,26 +2,47 @@
|
|||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Kwaadpepper\ExceptionHandler\Exceptions\ExceptionHandler;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Throwable;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
/**
|
||||
* A list of the exception types that are not reported.
|
||||
* A list of exception types with their corresponding custom log levels.
|
||||
*
|
||||
* @var array
|
||||
* @var array<class-string<\Throwable>, \Psr\Log\LogLevel::*>
|
||||
*/
|
||||
protected $dontReport = [
|
||||
RedirectTo::class
|
||||
];
|
||||
protected $levels = [];
|
||||
|
||||
/**
|
||||
* A list of the inputs that are never flashed for validation exceptions.
|
||||
* A list of the exception types that are not reported.
|
||||
*
|
||||
* @var array
|
||||
* @var array<int, class-string<\Throwable>>
|
||||
*/
|
||||
protected $dontReport = [];
|
||||
|
||||
/**
|
||||
* A list of the inputs that are never flashed to the session on validation exceptions.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $dontFlash = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
|
||||
/**
|
||||
* Register the exception handling callbacks for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->reportable(function (Throwable $e) {
|
||||
if (app()->bound('sentry')) {
|
||||
app('sentry')->captureException($e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
71
app/Http/Controllers/Bo/ActivityLogController.php
Normal file
71
app/Http/Controllers/Bo/ActivityLogController.php
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\ActivityLog;
|
||||
use App\Traits\Controllers\ChangesModelOrder;
|
||||
use App\Traits\Controllers\UpdateModelPublished;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ActivityLogController extends Controller
|
||||
{
|
||||
use ChangesModelOrder;
|
||||
use UpdateModelPublished;
|
||||
|
||||
/**
|
||||
* 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
|
||||
{
|
||||
$this->authorize('isConceptor');
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $query */
|
||||
$query = ActivityLog::query()->with('user');
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$query,
|
||||
$search,
|
||||
null,
|
||||
'model_class',
|
||||
);
|
||||
}
|
||||
$searchFields = \implode(', ', [
|
||||
trans('validation.custom.target'),
|
||||
]);
|
||||
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($query);
|
||||
|
||||
/** Custom pagination */
|
||||
$activitylogModels = $this->paginate($query);
|
||||
|
||||
return view('back::pages.activity_logs.index', compact('activitylogModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\ActivityLog $activity_log
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(ActivityLog $activity_log): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$this->authorize('isConceptor');
|
||||
$targetModelClass = $activity_log->model_class;
|
||||
$targetModel = $activity_log->model_class::where(
|
||||
(new $targetModelClass())->getRouteKeyName(),
|
||||
$activity_log->model_id
|
||||
)->first();
|
||||
|
||||
return view('back::pages.activity_logs.show', [
|
||||
'activitylogModel' => $activity_log,
|
||||
'targetModel' => $targetModel,
|
||||
]);
|
||||
}
|
||||
}
|
||||
72
app/Http/Controllers/Bo/Auth/LoginController.php
Normal file
72
app/Http/Controllers/Bo/Auth/LoginController.php
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Contracts\Auth\StatefulGuard;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
use AuthenticatesUsers;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest:backend')->except('logout');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
protected function guard(): StatefulGuard
|
||||
{
|
||||
return Auth::guard('backend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application's login form.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function showLoginForm(): View
|
||||
{
|
||||
return view('back::auth.login');
|
||||
}
|
||||
|
||||
/**
|
||||
* Where to redirect users after login.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function redirectTo(): string
|
||||
{
|
||||
return response()->redirectToIntended()->getTargetUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to log the user into the application.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return boolean
|
||||
*/
|
||||
protected function attemptLogin(Request $request)
|
||||
{
|
||||
$credentials = $this->credentials($request);
|
||||
// * Attempt login only using published users.
|
||||
$credentials['published'] = true;
|
||||
return $this->guard()->attempt(
|
||||
$credentials,
|
||||
$request->boolean('remember')
|
||||
);
|
||||
}
|
||||
}
|
||||
33
app/Http/Controllers/Bo/Auth/ResetPasswordController.php
Normal file
33
app/Http/Controllers/Bo/Auth/ResetPasswordController.php
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Contracts\Auth\StatefulGuard;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ResetPasswordController extends Controller
|
||||
{
|
||||
use ResetsPasswords;
|
||||
|
||||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
protected function guard(): StatefulGuard
|
||||
{
|
||||
return Auth::guard('backend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Where to redirect users after login.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function redirectTo(): string
|
||||
{
|
||||
return \route('bo.login');
|
||||
}
|
||||
}
|
||||
|
|
@ -3,38 +3,160 @@
|
|||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\BannedIps\StoreBannedIpRequest;
|
||||
use App\Http\Requests\Bo\BannedIps\UpdateBannedIpRequest;
|
||||
use App\Models\BannedIp;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class BannedIpController extends Controller
|
||||
{
|
||||
public function index()
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$ips = BannedIp::all();
|
||||
return view('bo.banned-ip.index', compact('ips'));
|
||||
$this->authorizeResource(BannedIp::class);
|
||||
}
|
||||
|
||||
public function saveDatas(Request $request)
|
||||
/**
|
||||
* 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
|
||||
{
|
||||
$ips = $request->ips;
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $bannedipModels */
|
||||
$bannedipModels = BannedIp::query();
|
||||
|
||||
for ($i = 0; $i < count($ips); $i++) {
|
||||
if (!empty($ips[$i]["ip"])) {
|
||||
$ip = BannedIp::updateOrCreate(['ip' => $ips[$i]["ip"]]);
|
||||
} else {
|
||||
unset($ips[$i]);
|
||||
$i--;
|
||||
}
|
||||
/** @var string $search Search field */
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$bannedipModels,
|
||||
$search,
|
||||
null,
|
||||
'ip',
|
||||
);
|
||||
}
|
||||
$searchFields = trans('validation.custom.ip');
|
||||
|
||||
return $ips;
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($bannedipModels);
|
||||
|
||||
/** Custom pagination */
|
||||
$bannedipModels = $this->paginate($bannedipModels);
|
||||
|
||||
return view('back::pages.banned-ips.index', compact('bannedipModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
public function destroy(Request $request)
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\BannedIp $banned_ip
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(BannedIp $banned_ip): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$ip = BannedIp::where("ip", $request->ip);
|
||||
$ip->delete();
|
||||
return view('back::pages.banned-ips.create', [
|
||||
'bannedipModel' => $banned_ip,
|
||||
]);
|
||||
}
|
||||
|
||||
return "Suppression terminée !";
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\BannedIps\StoreBannedIpRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreBannedIpRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$banned_ip = new BannedIp();
|
||||
$banned_ip->fill($request->validated());
|
||||
if ($banned_ip->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.banned_ips.edit', $banned_ip)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_created',
|
||||
['model' => Str::singular(trans('models.classes.banned_ips'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_created',
|
||||
['model' => Str::singular(trans('models.classes.banned_ips'))]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\BannedIp $banned_ip
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(BannedIp $banned_ip): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('back::pages.banned-ips.edit', [
|
||||
'bannedipModel' => $banned_ip,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\BannedIps\UpdateBannedIpRequest $request
|
||||
* @param \App\Models\BannedIp $banned_ip
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateBannedIpRequest $request, BannedIp $banned_ip): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $banned_ip) {
|
||||
$banned_ip->fill($request->validated());
|
||||
if ($banned_ip->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.banned_ips.edit', $banned_ip)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_updated',
|
||||
['model' => Str::singular(trans('models.classes.banned_ips'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_updated',
|
||||
['model' => Str::singular(trans('models.classes.banned_ips'))]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\BannedIp $banned_ip
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(BannedIp $banned_ip): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($banned_ip) {
|
||||
if ($banned_ip->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.banned_ips.index')
|
||||
->with('success', __(
|
||||
'crud.messages.has_been_deleted',
|
||||
['model' => Str::singular(trans('models.classes.banned_ips'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', __(
|
||||
':crud.messages.cannot_be_deleted',
|
||||
['model' => Str::singular(trans('models.classes.banned_ips'))]
|
||||
));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
135
app/Http/Controllers/Bo/CodeController.php
Normal file
135
app/Http/Controllers/Bo/CodeController.php
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\Codes\CodeSearchRequest;
|
||||
use App\Http\Requests\Bo\Codes\ExportCodesRequest;
|
||||
use App\Http\Requests\Bo\Codes\GenerateCodesRequest;
|
||||
use App\Jobs\ProcessExportCodesUniques;
|
||||
use App\Jobs\ProcessUniqueCode;
|
||||
use App\Models\Code;
|
||||
use App\Models\Participation;
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Contracts\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\Queue;
|
||||
use Kwaadpepper\Serial\Exceptions\SerialCasterException;
|
||||
|
||||
class CodeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show code form to generate and export
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$this->authorize('generate', Code::class);
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
$nbCodeBase = Code::query()->max('id');
|
||||
$nbCodeUsed = Code::query()->whereHas(
|
||||
'participations',
|
||||
operator: '>',
|
||||
count: $settings->nb_unique_code_use
|
||||
)->count();
|
||||
$nbCodeExported = Code::query()->where('code_exported', true)->count();
|
||||
$nbCodeRemainingToExport = Code::query()->where('code_exported', false)->count();
|
||||
return view('back::pages.codes.index', compact(
|
||||
'settings',
|
||||
'nbCodeBase',
|
||||
'nbCodeUsed',
|
||||
'nbCodeExported',
|
||||
'nbCodeRemainingToExport'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Run generate codes action
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Codes\GenerateCodesRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function generate(GenerateCodesRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$this->authorize('generate', Code::class);
|
||||
Queue::push(
|
||||
new ProcessUniqueCode(
|
||||
intval($request->quantity),
|
||||
config('codes.codeLength')
|
||||
)
|
||||
);
|
||||
|
||||
return back()->with(
|
||||
'success',
|
||||
trans(
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'La tache de génération à été ajoutée, un mail de notification sera envoyé à l\'adresse :email lorsque le traitement sera terminé.',
|
||||
[
|
||||
'email' => config('mail.admin')
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run export codes
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Codes\ExportCodesRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function export(ExportCodesRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$this->authorize('export', Code::class);
|
||||
Queue::push(
|
||||
new ProcessExportCodesUniques(
|
||||
intval($request->nb_code_fic),
|
||||
intval($request->nb_code_tot),
|
||||
intval($request->nb_code_ligne)
|
||||
)
|
||||
);
|
||||
|
||||
return back()->with(
|
||||
'success',
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
__('L\'export des codes à commencé, un mail de notification sera envoyé à l\'adresse :emaillorsque le traitement sera terminé.', [
|
||||
'email' => config('mail.admin')
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for a specific code.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Codes\CodeSearchRequest $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function search(CodeSearchRequest $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$this->authorize('search', Code::class);
|
||||
$code = null;
|
||||
try {
|
||||
$code = Code::query()->where('id', Code::serialToInt($request->code))->first();
|
||||
} catch (\Throwable $e) {
|
||||
if (\get_class($e) === SerialCasterException::class) {
|
||||
$code = false;
|
||||
}
|
||||
} finally {
|
||||
if ($code === false) {
|
||||
\session()->flash('warning', trans('Code non valide.'));
|
||||
}
|
||||
if ($code === null) {
|
||||
\session()->flash('warning', trans('Code introuvable.'));
|
||||
}
|
||||
}
|
||||
|
||||
$used_counter = null;
|
||||
if ($code) {
|
||||
$used_counter = Participation::query()
|
||||
->whereHas('code', fn(Builder $q) => $q->where('id', $code->id))
|
||||
->count();
|
||||
}
|
||||
|
||||
return view('back::pages.codes.search', compact('code', 'used_counter'));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\CodeSearchRequest;
|
||||
use App\Http\Requests\ExportCodesRequest;
|
||||
use App\Http\Requests\GenerateCodesRequest;
|
||||
use App\Jobs\ProcessExportCodesUniques;
|
||||
use App\Jobs\ProcessUniqueCode;
|
||||
use App\Models\Code;
|
||||
use App\Models\Settings;
|
||||
use Kwaadpepper\Serial\Exceptions\SerialCasterException;
|
||||
|
||||
class CodesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show code form to generate and export
|
||||
*
|
||||
* @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$settings = app(Settings::class);
|
||||
$nbCodeBase = Code::count();
|
||||
$nbCodeUsed = Code::where('code_used', 1)->count();
|
||||
$nbCodeExported = Code::where('code_exported', 1)->count();
|
||||
$nbCodeRemainingToExport = Code::where('code_exported', 0)->count();
|
||||
return view('bo.codes.index', compact(
|
||||
'settings',
|
||||
'nbCodeBase',
|
||||
'nbCodeUsed',
|
||||
'nbCodeExported',
|
||||
'nbCodeRemainingToExport'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Run generate codes action
|
||||
*
|
||||
* @param GenerateCodesRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function generate(GenerateCodesRequest $request)
|
||||
{
|
||||
ProcessUniqueCode::dispatch(
|
||||
$request->quantity,
|
||||
$request->code_length
|
||||
);
|
||||
|
||||
return back()->with(
|
||||
'success',
|
||||
"La génération à commencée, un mail de notification sera envoyé à l'adresse " .
|
||||
config('mail.MAIL_ADMIN') . " lorsque le traitement sera terminé."
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run export codes
|
||||
*
|
||||
* @param ExportCodesRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function export(ExportCodesRequest $request)
|
||||
{
|
||||
ProcessExportCodesUniques::dispatch(
|
||||
intval($request->nb_code_fic),
|
||||
intval($request->nb_code_tot),
|
||||
intval($request->nb_code_ligne)
|
||||
);
|
||||
|
||||
return back()->with(
|
||||
'success',
|
||||
"L'export des codes à commencé, un mail de notification sera envoyé à l'adresse " .
|
||||
config('mail.MAIL_ADMIN') . " lorsque le traitement sera terminé."
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for a specific code.
|
||||
*
|
||||
* @param CodeSearchRequest $request
|
||||
* @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
public function search(CodeSearchRequest $request)
|
||||
{
|
||||
$code = null;
|
||||
try {
|
||||
$code = Code::whereId(Code::serialToInt($request->code))->first();
|
||||
} catch (\Throwable $e) {
|
||||
if (\get_class($e) === SerialCasterException::class) {
|
||||
$code = false;
|
||||
}
|
||||
} finally {
|
||||
if ($code === false) {
|
||||
\session()->flash('warning', trans('Code non valide.'));
|
||||
}
|
||||
if ($code === null) {
|
||||
\session()->flash('warning', trans('Code introuvable.'));
|
||||
}
|
||||
}
|
||||
return view('bo.codes.search', compact('code'));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\CodeEan;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CodesEANController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$ean = CodeEan::all();
|
||||
return view('bo.codes-ean.index', compact('ean'));
|
||||
}
|
||||
|
||||
public function saveDatas(Request $request)
|
||||
{
|
||||
$codes = $request->codes;
|
||||
|
||||
for ($i = 0; $i < count($codes); $i++) {
|
||||
$codeToInsert = !empty($codes[$i]["code"]) && !empty($codes[$i]["product"]);
|
||||
if (isset($codes[$i]["id"]) && $codes[$i]["id"] !== null && $codeToInsert) {
|
||||
$c = CodeEan::findOrFail($codes[$i]["id"]);
|
||||
$c->code = $codes[$i]["code"];
|
||||
$c->product = $codes[$i]["product"];
|
||||
$c->save();
|
||||
} else {
|
||||
if ($codeToInsert) {
|
||||
$c = CodeEan::updateOrCreate(['code' => $codes[$i]["code"], 'product' => $codes[$i]["product"]]);
|
||||
$codes[$i]["id"] = $c->id;
|
||||
} else {
|
||||
unset($codes[$i]);
|
||||
$i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $codes;
|
||||
}
|
||||
|
||||
public function destroy(Request $request)
|
||||
{
|
||||
$code = CodeEan::findOrFail($request->id);
|
||||
$code->delete();
|
||||
|
||||
return "Suppression terminée !";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Content;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ContentController extends Controller
|
||||
{
|
||||
public function manage($id, Request $request)
|
||||
{
|
||||
$content = Content::findOrFail($id);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$value = $request->value;
|
||||
$content->value = $value;
|
||||
$content->save();
|
||||
|
||||
return redirect()->route('bo.content', $content->id)->with('success', 'Enregistré !');
|
||||
}
|
||||
|
||||
return view('bo.content.manage', compact('content'));
|
||||
}
|
||||
}
|
||||
|
|
@ -6,65 +6,76 @@ use App\Http\Controllers\Controller;
|
|||
use App\Models\Participation;
|
||||
use App\Models\Settings;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
public function index()
|
||||
/**
|
||||
* Dashboard Page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
// Pour les stats.
|
||||
$settings = app(Settings::class);
|
||||
$participations = Participation::selectRaw("COUNT(*) AS count, DATE(created_at) AS date")
|
||||
->groupByRaw("DATE(created_at)")->get();
|
||||
$participationsUniquePerDay = Participation::selectRaw("DISTINCT user_id AS user, COUNT(*) AS count, DATE(created_at) AS date")
|
||||
->groupByRaw("DATE(created_at), user")->get();
|
||||
$statsUnique = [];
|
||||
foreach ($participationsUniquePerDay as $participationPerDay) {
|
||||
$dateUnique = Carbon::parse($participationPerDay->date)->format('d/m/Y');
|
||||
$statsUnique[$dateUnique] = isset($statsUnique[$dateUnique]) ? $statsUnique[$dateUnique] + 1 : 1;
|
||||
}
|
||||
$participationsUnique = Participation::selectRaw("DISTINCT user_id AS user, COUNT(*) AS count")
|
||||
->groupBy("user")->orderBy("user")->get();
|
||||
// * Pour les stats.
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
$avgParticipUser = 0;
|
||||
$participationPeriod = [];
|
||||
$statsUnique = [];
|
||||
$query = DB::table((new Participation())->getTable());
|
||||
$dateFrmtr = function (object $row) {
|
||||
$row->date = Carbon::parse($row->date)->isoFormat('DD/MM/YYYY');
|
||||
return $row;
|
||||
};
|
||||
|
||||
// Données calculées à afficher.
|
||||
$totalParticipation = Participation::count();
|
||||
if (count($participationsUnique) > 0) {
|
||||
$avgParticipUser = round($totalParticipation / count($participationsUnique), 1);
|
||||
} else {
|
||||
$avgParticipUser = 0;
|
||||
/** @var \Illuminate\Support\Collection<string,object> */
|
||||
$participationsPerDay = (clone $query)
|
||||
->selectRaw('COUNT(*) AS count, DATE(created_at) AS date')
|
||||
->groupByRaw('DATE(created_at)')->get()->map($dateFrmtr)->keyBy('date');
|
||||
|
||||
/** @var \Illuminate\Support\Collection<object> */
|
||||
$participationsUniquePerDay = (clone $query)
|
||||
->selectRaw('DISTINCT customer_id AS user, COUNT(*) AS count, DATE(created_at) AS date')
|
||||
->groupByRaw('DATE(created_at), user')->get()->map($dateFrmtr);
|
||||
|
||||
/** @var \Illuminate\Support\Collection<object> */
|
||||
$participationsUniquePerCustomer = (clone $query)
|
||||
->selectRaw("DISTINCT customer_id AS user, COUNT(*) AS count")
|
||||
->groupBy('user')->orderBy('user')->get();
|
||||
|
||||
$participationsTotal = Participation::query()->count();
|
||||
|
||||
/** @var \Illuminate\Support\Collection<object> 3 codes EAN les plus utilisés */
|
||||
$codesEan = (clone $query)
|
||||
->selectRaw('COUNT(product_id) AS nb_usage, product_id, ean_code')
|
||||
->join('products', 'product_id', '=', 'products.id')
|
||||
->groupBy('product_id', 'ean_code')
|
||||
->orderByDesc('nb_usage')->limit(3)->get();
|
||||
|
||||
$participationsUniquePerDay->each(function (object $row) use (&$statsUnique) {
|
||||
Arr::set($statsUnique, $row->date, (Arr::get($statsUnique, $row->date) ?? 0) + 1);
|
||||
});
|
||||
|
||||
// * Calcul participation moyenne par utilisateur.
|
||||
if ($participationsUniquePerCustomer->count() > 0) {
|
||||
$avgParticipUser = round($participationsTotal / $participationsUniquePerCustomer->count(), 1);
|
||||
}
|
||||
|
||||
// Tableau des dates comprises dans la table participation.
|
||||
foreach ($participations as $participation) {
|
||||
$datesParticipations[Carbon::parse($participation->date)->format('d/m/Y')] = $participation->count;
|
||||
}
|
||||
// * Création des tableaux avec toutes les dates depuis le début du jeu
|
||||
// * et le nombre de participations associées pour le graph JS.
|
||||
$start_date = $settings->start_date;
|
||||
$end_date = now()->lt($settings->end_date) ? now() : $settings->end_date;
|
||||
$dates = $participationsPerDay->keys();
|
||||
$count = $participationsPerDay->pluck('count');
|
||||
$countUnique = $dates->map(fn (string $formated_date) => Arr::get($statsUnique, $formated_date, 0));
|
||||
|
||||
// Création des tableaux avec toutes les dates depuis le début du jeu et le nombre de participations associées.
|
||||
$date = Carbon::parse($settings->start_date);
|
||||
$dateFin = now() < $settings->end_date ? Carbon::now() : Carbon::parse($settings->end_date);
|
||||
|
||||
// Récupération des 3 codes EAN les plus utilisés.
|
||||
$codesEan = Participation::select(
|
||||
DB::raw('COUNT(code_ean_id) AS nb_usage, code_ean_id')
|
||||
)->groupBy('code_ean_id')->orderByDesc('nb_usage')->limit(3)->get();
|
||||
|
||||
// Génération des tableaux de date depuis le début du jeu.
|
||||
$dates = [];
|
||||
$count = [];
|
||||
$countUnique = [];
|
||||
while ($dateFin > $date) {
|
||||
$dates[] = $date->format('d/m/Y');
|
||||
$count[] = isset($datesParticipations[$date->format('d/m/Y')]) ?
|
||||
$datesParticipations[$date->format('d/m/Y')] : 0;
|
||||
$countUnique[] = isset($statsUnique[$date->format('d/m/Y')]) ? $statsUnique[$date->format('d/m/Y')] : 0;
|
||||
$date->addDay();
|
||||
}
|
||||
|
||||
return view('bo.dashboard.index', compact(
|
||||
return view('back::pages.dashboard.index', compact(
|
||||
'dates',
|
||||
'count',
|
||||
'countUnique',
|
||||
'totalParticipation',
|
||||
'participationsTotal',
|
||||
'avgParticipUser',
|
||||
'codesEan',
|
||||
'settings'
|
||||
|
|
|
|||
180
app/Http/Controllers/Bo/FaqQuestionController.php
Normal file
180
app/Http/Controllers/Bo/FaqQuestionController.php
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\FaqQuestions\StoreFaqQuestionRequest;
|
||||
use App\Http\Requests\Bo\FaqQuestions\UpdateFaqQuestionRequest;
|
||||
use App\Models\FaqQuestion;
|
||||
use App\Models\FaqTheme;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class FaqQuestionController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(FaqQuestion::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 $faqQuestionModels */
|
||||
$faqQuestionModels = FaqQuestion::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$faqQuestionModels,
|
||||
$search,
|
||||
null,
|
||||
'question',
|
||||
'answer'
|
||||
);
|
||||
}
|
||||
$searchFields = \sprintf(
|
||||
'%s, %s ...',
|
||||
Str::ucfirst(__('validation.custom.question')),
|
||||
__('validation.custom.answer'),
|
||||
);
|
||||
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($faqQuestionModels);
|
||||
|
||||
/** Custom pagination */
|
||||
$faqQuestionModels = $this->paginate($faqQuestionModels);
|
||||
|
||||
return view('back::pages.faq-questions.index', compact('faqQuestionModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\FaqQuestion $faqQuestion
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(FaqQuestion $faqQuestion): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$faqThemeModels = FaqTheme::all();
|
||||
return view('back::pages.faq-questions.create', [
|
||||
'faqQuestionModel' => $faqQuestion,
|
||||
'faqThemeModels' => $faqThemeModels
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\FaqQuestions\StoreFaqQuestionRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreFaqQuestionRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$faqQuestion = new FaqQuestion();
|
||||
$faqQuestion->fill($request->validated());
|
||||
if ($faqQuestion->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.faq-questions.edit', $faqQuestion)
|
||||
->with(
|
||||
'success',
|
||||
trans(
|
||||
'crud.messages.has_been_created',
|
||||
['model' => trans_choice('models.classes.faq-questions', 1)]
|
||||
)
|
||||
);
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_created',
|
||||
['model' => trans_choice('models.classes.faq-questions', 1)]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\FaqQuestion $faqQuestion
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(FaqQuestion $faqQuestion): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$faqThemeModels = FaqTheme::all();
|
||||
return view('back::pages.faq-questions.edit', [
|
||||
'faqQuestionModel' => $faqQuestion,
|
||||
'faqThemeModels' => $faqThemeModels
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\FaqQuestions\UpdateFaqQuestionRequest $request
|
||||
* @param \App\Models\FaqQuestion $faqQuestion
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(
|
||||
UpdateFaqQuestionRequest $request,
|
||||
FaqQuestion $faqQuestion
|
||||
): \Illuminate\Http\RedirectResponse {
|
||||
return DB::transaction(function () use ($request, $faqQuestion) {
|
||||
$faqQuestion->fill($request->validated());
|
||||
if ($faqQuestion->saveOrFail()) {
|
||||
return redirect()
|
||||
->route(
|
||||
'bo.faq-questions.edit',
|
||||
$faqQuestion
|
||||
)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_updated',
|
||||
['model' => trans_choice('models.classes.faq-questions', 1)]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_updated',
|
||||
['model' => trans_choice('models.classes.faq-questions', 1)]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\FaqQuestion $faqQuestion
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(FaqQuestion $faqQuestion): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($faqQuestion) {
|
||||
if ($faqQuestion->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.faq-questions.index')
|
||||
->with('success', __(
|
||||
'crud.messages.has_been_deleted',
|
||||
['model' => trans_choice('models.classes.faq-questions', 1)]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', __(
|
||||
':crud.messages.cannot_be_deleted',
|
||||
['model' => trans_choice('models.classes.faq-questions', 1)]
|
||||
));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\FaqQuestion;
|
||||
use App\Models\FaqTheme;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class FaqQuestionsController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$questions = FaqQuestion::all();
|
||||
for ($i = 0; $i < count($questions); $i++) {
|
||||
$questions[$i]['toggle'] = false;
|
||||
}
|
||||
$themes = FaqTheme::all();
|
||||
return view('bo.faq-questions.index', compact('questions', 'themes'));
|
||||
}
|
||||
|
||||
public function destroy(Request $request)
|
||||
{
|
||||
if ($request->id !== null) {
|
||||
$question = FaqQuestion::findOrFail($request->id);
|
||||
$question->delete();
|
||||
}
|
||||
}
|
||||
|
||||
public function saveDatas(Request $request)
|
||||
{
|
||||
$questions = $request->questions;
|
||||
|
||||
for ($i = 0; $i < count($questions); $i++) {
|
||||
if (isset($questions[$i]["id"])) {
|
||||
$q = FaqQuestion::findOrFail($questions[$i]["id"]);
|
||||
$q->question = $questions[$i]["question"];
|
||||
$q->answer = $questions[$i]["answer"];
|
||||
$q->positive_vote = $questions[$i]["positive_vote"];
|
||||
$q->negative_vote = $questions[$i]["negative_vote"];
|
||||
$q->theme_id = $questions[$i]["theme_id"];
|
||||
$q->save();
|
||||
} else {
|
||||
$t = FaqQuestion::updateOrCreate(
|
||||
[
|
||||
'question' => $questions[$i]["question"],
|
||||
'answer' => $questions[$i]["answer"],
|
||||
'positive_vote' => $questions[$i]["positive_vote"],
|
||||
'negative_vote' => $questions[$i]["negative_vote"],
|
||||
'theme_id' => $questions[$i]["theme_id"]
|
||||
]
|
||||
);
|
||||
$questions[$i]["id"] = $t->id;
|
||||
}
|
||||
}//end for
|
||||
|
||||
return $questions;
|
||||
}
|
||||
}
|
||||
170
app/Http/Controllers/Bo/FaqThemeController.php
Normal file
170
app/Http/Controllers/Bo/FaqThemeController.php
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\FaqThemes\StoreFaqThemeRequest;
|
||||
use App\Http\Requests\Bo\FaqThemes\UpdateFaqThemeRequest;
|
||||
use App\Models\FaqTheme;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class FaqThemeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(FaqTheme::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 $faqThemeModels */
|
||||
$faqThemeModels = FaqTheme::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$faqThemeModels,
|
||||
$search,
|
||||
null,
|
||||
'name',
|
||||
);
|
||||
}
|
||||
$searchFields = Str::ucfirst(__('validation.attributes.name'));
|
||||
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($faqThemeModels);
|
||||
|
||||
/** Custom pagination */
|
||||
$faqThemeModels = $this->paginate($faqThemeModels);
|
||||
|
||||
return view('back::pages.faq-themes.index', compact('faqThemeModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\FaqTheme $faqTheme
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(FaqTheme $faqTheme): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('back::pages.faq-themes.create', [
|
||||
'faqThemeModel' => $faqTheme,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\FaqThemes\StoreFaqThemeRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreFaqThemeRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$faqTheme = new FaqTheme();
|
||||
$faqTheme->fill($request->validated());
|
||||
if ($faqTheme->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.faq-themes.edit', $faqTheme)
|
||||
->with(
|
||||
'success',
|
||||
trans(
|
||||
'crud.messages.has_been_created',
|
||||
['model' => trans_choice('models.classes.faq-themes', 1)]
|
||||
)
|
||||
);
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_created',
|
||||
['model' => trans_choice('models.classes.faq-themes', 1)]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\FaqTheme $faqTheme
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(FaqTheme $faqTheme): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('back::pages.faq-themes.edit', [
|
||||
'faqThemeModel' => $faqTheme,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\FaqThemes\UpdateFaqThemeRequest $request
|
||||
* @param \App\Models\FaqTheme $faqTheme
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(
|
||||
UpdateFaqThemeRequest $request,
|
||||
FaqTheme $faqTheme
|
||||
): \Illuminate\Http\RedirectResponse {
|
||||
return DB::transaction(function () use ($request, $faqTheme) {
|
||||
$faqTheme->fill($request->validated());
|
||||
if ($faqTheme->saveOrFail()) {
|
||||
return redirect()
|
||||
->route(
|
||||
'bo.faq-themes.edit',
|
||||
$faqTheme
|
||||
)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_updated',
|
||||
['model' => trans_choice('models.classes.faq-themes', 1)]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_updated',
|
||||
['model' => trans_choice('models.classes.faq-themes', 1)]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\FaqTheme $faqTheme
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(FaqTheme $faqTheme): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($faqTheme) {
|
||||
if ($faqTheme->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.faq-themes.index')
|
||||
->with('success', __(
|
||||
'crud.messages.has_been_deleted',
|
||||
['model' => trans_choice('models.classes.faq-themes', 1)]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', __(
|
||||
'crud.messages.cannot_be_deleted',
|
||||
['model' => trans_choice('models.classes.faq-themes', 1)]
|
||||
));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\FaqQuestion;
|
||||
use App\Models\FaqTheme;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class FaqThemesController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$themes = FaqTheme::all();
|
||||
return view('bo.faq-themes.index', compact('themes'));
|
||||
}
|
||||
|
||||
public function destroy(Request $request)
|
||||
{
|
||||
$deleteOk = 0;
|
||||
|
||||
if (FaqQuestion::where('theme_id', $request->id)->count() > 0) {
|
||||
$deleteOk = 1;
|
||||
} elseif ($request->id !== null) {
|
||||
$theme = FaqTheme::findOrFail($request->id);
|
||||
$theme->delete();
|
||||
} else {
|
||||
$deleteOk = 2;
|
||||
}
|
||||
|
||||
return $deleteOk;
|
||||
}
|
||||
|
||||
public function saveDatas(Request $request)
|
||||
{
|
||||
$themes = $request->themes;
|
||||
|
||||
for ($i = 0; $i < count($themes); $i++) {
|
||||
if (isset($themes[$i]["id"])) {
|
||||
$t = FaqTheme::findOrFail($themes[$i]["id"]);
|
||||
$t->name = $themes[$i]["name"];
|
||||
$t->save();
|
||||
} else {
|
||||
$t = FaqTheme::updateOrCreate(['name' => $themes[$i]["name"]]);
|
||||
$themes[$i]["id"] = $t->id;
|
||||
}
|
||||
}
|
||||
|
||||
return $themes;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\GainView;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class GainViewController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$gv = GainView::all();
|
||||
return view('bo.gain-views.index', compact('gv'));
|
||||
}
|
||||
|
||||
public function destroy(Request $request)
|
||||
{
|
||||
$retour = "Suppression terminée !";
|
||||
|
||||
if ($request->id !== null) {
|
||||
$gv = GainView::findOrFail($request->id);
|
||||
$gv->delete();
|
||||
}
|
||||
|
||||
return $retour;
|
||||
}
|
||||
|
||||
public function saveDatas(Request $request)
|
||||
{
|
||||
$gv = $request->gainViews;
|
||||
|
||||
for ($i = 0; $i < count($gv); $i++) {
|
||||
if (isset($gv[$i]["id"])) {
|
||||
$g = GainView::findOrFail($gv[$i]["id"]);
|
||||
$g->name = $gv[$i]["name"];
|
||||
$g->file_name = $gv[$i]["file_name"];
|
||||
$g->save();
|
||||
} else {
|
||||
$g = GainView::updateOrCreate(['name' => $gv[$i]["name"], 'file_name' => $gv[$i]["file_name"]]);
|
||||
$gv[$i]["id"] = $g->id;
|
||||
}
|
||||
}
|
||||
|
||||
return $gv;
|
||||
}
|
||||
}
|
||||
|
|
@ -6,104 +6,177 @@ use App\Http\Controllers\Controller;
|
|||
use App\Models\InstantWin;
|
||||
use App\Models\Prize;
|
||||
use App\Models\Settings;
|
||||
use Carbon\CarbonInterval;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class InstantWinController extends Controller
|
||||
{
|
||||
public function index()
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$nbInstantWin = InstantWin::count();
|
||||
$canGenerate = 0;
|
||||
$this->authorizeResource(InstantWin::class);
|
||||
}
|
||||
|
||||
if (intval($nbInstantWin) > 0) {
|
||||
$canGenerate = 0;
|
||||
} else {
|
||||
$nbLots = Prize::count();
|
||||
if (intval($nbLots) > 0) {
|
||||
$canGenerate = 1;
|
||||
} else {
|
||||
$canGenerate = 0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$instantWinModelList = InstantWin::query()->orderBy('available_at')->get();
|
||||
|
||||
$instantWin = InstantWin::orderBy('appear_date')->get();
|
||||
|
||||
return view('bo.instant-win.index', [
|
||||
'can_generate' => $canGenerate,
|
||||
'instant_win' => $instantWin
|
||||
return view('back::pages.instant-win.index', [
|
||||
'instantWinModelList' => $instantWinModelList
|
||||
]);
|
||||
}
|
||||
|
||||
public function instantWinGenerate()
|
||||
/**
|
||||
* Returns generated instant win.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function generate(): JsonResponse
|
||||
{
|
||||
$start_date = Settings::latest()->value("start_date");
|
||||
$end_date = Settings::latest()->value("end_date");
|
||||
$lots = Prize::all();
|
||||
$this->authorize('generate', InstantWin::class);
|
||||
|
||||
return DB::transaction(function () {
|
||||
/**
|
||||
* À partir de quelle heure on peut gagner
|
||||
* ! Seul l'heure sera prize en compte
|
||||
*/
|
||||
$day_start = now()->setTime(6, 0);
|
||||
/**
|
||||
* Jusqu'à quelle heure on peut gagner
|
||||
* ! Seul l'heure sera prize en compte
|
||||
*/
|
||||
$day_end = now()->setTime(22, 29);
|
||||
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
$prizeModelList = Prize::all();
|
||||
|
||||
$begin = new \DateTime($start_date);
|
||||
$end = new \DateTime($end_date);
|
||||
$interval = new \DateInterval('P1D');
|
||||
$daterange = new \DatePeriod($begin, $interval, $end);
|
||||
$dateGlobal = [];
|
||||
$lotsGlobal = [];
|
||||
/** @var \Illuminate\Support\Collection<array-key,\App\Http\Controllers\Bo\WinDayCalendar> */
|
||||
$datesGlobal = collect();
|
||||
/**
|
||||
* @var \Illuminate\Support\Collection<array-key,\App\Http\Controllers\Bo\WinTimeElement>
|
||||
* Liste de tous les lots à gagner
|
||||
*/
|
||||
$lotsGlobal = collect();
|
||||
|
||||
// * Seed srand !
|
||||
\mt_srand(time());
|
||||
|
||||
// * Init prize list
|
||||
$prizeModelList->each(function (Prize $prize) use ($lotsGlobal, $day_start, $day_end) {
|
||||
for ($i = 0; $i < $prize->quantity; $i++) {
|
||||
$el = new WinTimeElement();
|
||||
$el->prize = $prize;
|
||||
$el->time = now()->setTime(
|
||||
mt_rand($day_start->hour, $day_end->hour),
|
||||
mt_rand($day_start->minute, $day_end->minute)
|
||||
);
|
||||
$lotsGlobal->push($el);
|
||||
}
|
||||
});
|
||||
|
||||
foreach ($lots as $k => $lot) {
|
||||
for ($i = 0; $i < $lot->quantity; $i++) {
|
||||
$lotsGlobal[] = [
|
||||
'id' => $lot->id,
|
||||
'name' => $lot->label_one,
|
||||
'hour' => str_pad(mt_rand(6, 22), 2, "0", STR_PAD_LEFT)
|
||||
. ":" . str_pad(mt_rand(0, 59), 2, "0", STR_PAD_LEFT) . ":00"
|
||||
];
|
||||
$lotsGlobal->shuffle(time());
|
||||
|
||||
// * Init days calendar
|
||||
foreach ($settings->start_date->toPeriod($settings->end_date, CarbonInterval::make('1day')) as $date) {
|
||||
$el = new WinDayCalendar();
|
||||
$el->lots = collect();
|
||||
$el->time = $date->setTime(0, 0);
|
||||
$datesGlobal->push($el);
|
||||
}
|
||||
}
|
||||
shuffle($lotsGlobal);
|
||||
foreach ($daterange as $date) {
|
||||
array_push($dateGlobal, ['date' => $date->format("Y-m-d"), 'lots' => []]);
|
||||
}
|
||||
|
||||
$res = $this->generate($lotsGlobal, $dateGlobal, 0);
|
||||
// * Save Instant wins
|
||||
$this->generateArray($lotsGlobal, $datesGlobal, 0)->each(function (WinDayCalendar $winDayCalendar) {
|
||||
$winDayCalendar->lots->each(function (WinTimeElement $winTimeElement) {
|
||||
$instantWin = new InstantWin();
|
||||
$instantWin->available_at = $winTimeElement->time;
|
||||
$instantWin->prize()->associate($winTimeElement->prize);
|
||||
$instantWin->saveOrFail();
|
||||
});
|
||||
});
|
||||
|
||||
foreach ($res as $date) {
|
||||
foreach ($date['lots'] as $lot) {
|
||||
$iw = new InstantWin();
|
||||
$iw->prize_id = $lot['id'];
|
||||
$iw->appear_date = date('Y-m-d H:i:s', strtotime($date['date'] . " " . $lot['hour']));
|
||||
$iw->save();
|
||||
}
|
||||
}
|
||||
|
||||
$instantWins = InstantWin::all();
|
||||
return json_encode($instantWins);
|
||||
// * Output instant wins to ajax response
|
||||
return response()->json(InstantWin::all());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
private function generate($lotsGlobal, $dateGlobal, $lotsDone)
|
||||
/**
|
||||
* Generate instant win.
|
||||
*
|
||||
* Même algo que celui implémenté par Romain.
|
||||
*
|
||||
* @param \Illuminate\Support\Collection<array-key,\App\Http\Controllers\Bo\WinTimeElement> $lotsGlobal
|
||||
* Liste de tous les lots à gagner
|
||||
* @param \Illuminate\Support\Collection<array-key,\App\Http\Controllers\Bo\WinDayCalendar> $dateGlobal
|
||||
* @param integer $prizesDone
|
||||
* @return \Illuminate\Support\Collection<array-key,\App\Http\Controllers\Bo\WinDayCalendar>
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.IncorrectTypeHint
|
||||
*/
|
||||
private function generateArray(Collection $lotsGlobal, Collection $dateGlobal, int $prizesDone): Collection
|
||||
{
|
||||
$rKey = array_rand($dateGlobal, 1);
|
||||
if ($lotsDone < count($dateGlobal)) {
|
||||
if (count($dateGlobal[$rKey]['lots']) > 0) {
|
||||
return $this->generate($lotsGlobal, $dateGlobal, $lotsDone);
|
||||
}
|
||||
// phpcs:enable
|
||||
/** @var array-key Un jour sélectionné aléatoire. */
|
||||
$rKey = $dateGlobal->keys()->random(1)->firstOrFail();
|
||||
|
||||
// ? À-t-on déjà assigné un lot par jour (au moins) ?
|
||||
// ? Le jour aléatoire sélectionné à déja un lot ?
|
||||
if ($prizesDone < $dateGlobal->count() and $dateGlobal->get($rKey)->lots->count() > 0) {
|
||||
return $this->generateArray($lotsGlobal, $dateGlobal, $prizesDone);
|
||||
}
|
||||
array_push($dateGlobal[$rKey]['lots'], $lotsGlobal[$lotsDone++]);
|
||||
if ($lotsDone < count($lotsGlobal)) {
|
||||
return $this->generate($lotsGlobal, $dateGlobal, $lotsDone);
|
||||
}
|
||||
foreach ($dateGlobal as $k => $date) {
|
||||
usort($dateGlobal[$k]['lots'], [$this, 'sortFunction']);
|
||||
|
||||
// * Insert next prize on a randowm day
|
||||
$dateGlobal->get($rKey)->lots->push($lotsGlobal->get($prizesDone++));
|
||||
|
||||
// ? On a distribué assez de lots ?
|
||||
if ($prizesDone < $lotsGlobal->count()) {
|
||||
return $this->generateArray($lotsGlobal, $dateGlobal, $prizesDone);
|
||||
}
|
||||
|
||||
// * Tri par heure et assignation du jour correct.
|
||||
$dateGlobal->each(function (WinDayCalendar $date) {
|
||||
$date->lots = $date->lots->sort(fn (WinTimeElement $a, WinTimeElement $b) =>
|
||||
$a->time->timestamp - $b->time->timestamp)
|
||||
->map(function (WinTimeElement $time) use ($date) {
|
||||
$time->time->setDate(
|
||||
$date->time->year,
|
||||
$date->time->month,
|
||||
$date->time->day
|
||||
);
|
||||
return $time;
|
||||
});
|
||||
});
|
||||
|
||||
return $dateGlobal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private function sortFunction($a, $b)
|
||||
{
|
||||
return strtotime($a["hour"]) - strtotime($b["hour"]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @property \App\Models\Prize $prize Le lot à gagner.
|
||||
* @property \Carbon\Carbon $time Une heure aléatoire.
|
||||
* @phpcs:disable PSR1.Classes.ClassDeclaration.MultipleClasses
|
||||
*/
|
||||
class WinTimeElement extends \stdClass
|
||||
{
|
||||
// phpcs:enable
|
||||
}
|
||||
|
||||
/**
|
||||
* @property \Carbon\Carbon|\Carbon\CarbonInterface $time
|
||||
* Un jour dans le temps.
|
||||
* @property \Illuminate\Support\Collection<array-key,\App\Http\Controllers\Bo\WinTimeElement> $lots
|
||||
* Liste des lots tombant ce jour.
|
||||
* @phpcs:disable PSR1.Classes.ClassDeclaration.MultipleClasses
|
||||
*/
|
||||
class WinDayCalendar extends \stdClass
|
||||
{
|
||||
// phpcs:enable
|
||||
}
|
||||
|
|
|
|||
88
app/Http/Controllers/Bo/ParticipationController.php
Normal file
88
app/Http/Controllers/Bo/ParticipationController.php
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Participation;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
|
||||
class ParticipationController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(Participation::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* View all winners
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function viewWinnerList(): View
|
||||
{
|
||||
$this->authorize('viewWinnerList', Participation::class);
|
||||
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $participationModels */
|
||||
$participationModels = Participation::query()->with(['customer', 'code', 'instantWin', 'product'])->whereHas('instantWin');
|
||||
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($participationModels);
|
||||
|
||||
/** Custom pagination */
|
||||
$participationModels = $this->paginate($participationModels);
|
||||
|
||||
return view('back::pages.winners-list.index', compact(
|
||||
'participationModels'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display participation form
|
||||
*
|
||||
* @param \App\Models\Participation $participation
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function setComment(Participation $participation): View
|
||||
{
|
||||
$this->authorize('setComment', $participation);
|
||||
return view('back::pages.winners-list.set-comment', [
|
||||
'participationModel' => $participation
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Comment
|
||||
*
|
||||
* @param \App\Models\Participation $participation
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function setCommentSubmit(Participation $participation): RedirectResponse
|
||||
{
|
||||
$this->authorize('setComment', $participation);
|
||||
$participation->comment = request()->string('comment');
|
||||
$participation->saveOrFail();
|
||||
return back()->with('success', \trans(
|
||||
'Le commentaire à bien été mis à jour'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Change prize sent
|
||||
*
|
||||
* @param \App\Models\Participation $participation
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function changePrizeSent(Participation $participation): RedirectResponse
|
||||
{
|
||||
$this->authorize('changePrizeSent', $participation);
|
||||
$participation->prize_sent = true;
|
||||
$participation->saveOrFail();
|
||||
return back()->with('success', \trans(
|
||||
'Le lot est bien marqué comme envoyé et une notification à été envoyé au gagant'
|
||||
));
|
||||
}
|
||||
}
|
||||
176
app/Http/Controllers/Bo/PrizeController.php
Normal file
176
app/Http/Controllers/Bo/PrizeController.php
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\Prizes\StorePrizeRequest;
|
||||
use App\Http\Requests\Bo\Prizes\UpdatePrizeRequest;
|
||||
use App\Models\Prize;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class PrizeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(Prize::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 $prizeModels */
|
||||
$prizeModels = Prize::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$prizeModels,
|
||||
$search,
|
||||
null,
|
||||
'label',
|
||||
);
|
||||
}
|
||||
$searchFields = \sprintf(
|
||||
'%s ...',
|
||||
Str::ucfirst(__('validation.custom.label'))
|
||||
);
|
||||
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($prizeModels);
|
||||
|
||||
/** Custom pagination */
|
||||
$prizeModels = $this->paginate($prizeModels);
|
||||
|
||||
return view('back::pages.prizes.index', compact('prizeModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \App\Models\Prize $prize
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(Prize $prize): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('back::pages.prizes.show', ['prizeModel' => $prize]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\Prize $prize
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(Prize $prize): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('back::pages.prizes.create', [
|
||||
'prizeModel' => $prize
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Prizes\StorePrizeRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StorePrizeRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$prize = new Prize();
|
||||
$prize->fill($request->validated());
|
||||
if ($prize->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.prizes.edit', $prize)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_created',
|
||||
['model' => Str::singular(__('models.classes.prize'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_created',
|
||||
['model' => Str::singular(__('models.classes.prize'))]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Prize $prize
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Prize $prize): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('back::pages.prizes.edit', [
|
||||
'prizeModel' => $prize
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Prizes\UpdatePrizeRequest $request
|
||||
* @param \App\Models\Prize $prize
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdatePrizeRequest $request, Prize $prize): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $prize) {
|
||||
$prize->fill($request->validated());
|
||||
if ($prize->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.prizes.edit', $prize)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_updated',
|
||||
['model' => Str::singular(__('models.classes.prize'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_updated',
|
||||
['model' => Str::singular(__('models.classes.prize'))]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Prize $prize
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Prize $prize): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($prize) {
|
||||
if ($prize->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.prizes.index')
|
||||
->with('success', __(
|
||||
'crud.messages.has_been_deleted',
|
||||
['model' => Str::singular(__('models.classes.prize'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', __(
|
||||
':crud.messages.cannot_be_deleted',
|
||||
['model' => Str::singular(__('models.classes.prize'))]
|
||||
));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\GainView;
|
||||
use App\Models\Prize;
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class PrizesController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$prizes = Prize::all();
|
||||
$gainViews = GainView::all();
|
||||
return view('bo.prizes.index', compact('prizes', 'gainViews'));
|
||||
}
|
||||
|
||||
public function saveDatas(Request $request)
|
||||
{
|
||||
$prizes = json_decode($request->prizes);
|
||||
$pdfs = $request->file('pdf');
|
||||
|
||||
try {
|
||||
$request->validate([
|
||||
'pdf_winning_proof.*' => 'file|mimes:pdf|size:20480',
|
||||
]);
|
||||
|
||||
for ($i = 0; $i < count($prizes); $i++) {
|
||||
$prize = $prizes[$i];
|
||||
if ($prize->id !== null) {
|
||||
$p = Prize::findOrFail($prize->id);
|
||||
|
||||
$p->arcadia_id = $prize->arcadia_id;
|
||||
$p->label_one = $prize->label_one;
|
||||
$p->label_many = $prize->label_many;
|
||||
$p->quantity = $prize->quantity;
|
||||
$p->arcadia_operation_code = $prize->arcadia_operation_code;
|
||||
$p->arcadia_support_code = $prize->arcadia_support_code;
|
||||
$p->need_proof = $prize->need_proof;
|
||||
$p->gain_view_id = $prize->gain_view_id;
|
||||
|
||||
if (isset($pdfs[$i])) {
|
||||
$fileName = Str::slug($prize->label_one) . '-' .
|
||||
date('d-m-Y') . '.' . $pdfs[$i]->extension();
|
||||
$p->pdf_winning_proof = $fileName;
|
||||
$pdfs[$i]->move(public_path('fichiers/pdf/'), $fileName);
|
||||
$prizes[$i]->pdf_winning_proof = $fileName;
|
||||
}
|
||||
|
||||
$p->save();
|
||||
} else {
|
||||
$p = new Prize();
|
||||
$p->arcadia_id = $prize->arcadia_id;
|
||||
$p->label_one = $prize->label_one;
|
||||
$p->label_many = $prize->label_many;
|
||||
$p->quantity = $prize->quantity;
|
||||
$p->arcadia_operation_code = $prize->arcadia_operation_code;
|
||||
$p->arcadia_support_code = $prize->arcadia_support_code;
|
||||
$p->need_proof = $prize->need_proof;
|
||||
$p->gain_view_id = $prize->gain_view_id;
|
||||
|
||||
if (isset($pdfs[$i])) {
|
||||
$fileName = Str::slug($prize->label_one) . '-' .
|
||||
date('d-m-Y') . '.' . $pdfs[$i]->extension();
|
||||
$p->pdf_winning_proof = $fileName;
|
||||
$pdfs[$i]->move(public_path('fichiers/pdf/'), $fileName);
|
||||
$prizes[$i]->pdf_winning_proof = $fileName;
|
||||
}
|
||||
|
||||
$p->save();
|
||||
$prizes[$i]->id = $p->id;
|
||||
} //end if
|
||||
}//end for
|
||||
} catch (Exception $e) {
|
||||
//
|
||||
}//end try
|
||||
|
||||
return $prizes;
|
||||
}
|
||||
|
||||
public function destroy(Request $request)
|
||||
{
|
||||
$retour = "Suppression terminée !";
|
||||
|
||||
if ($request->id !== null) {
|
||||
try {
|
||||
$prize = Prize::findOrFail($request->id);
|
||||
$prize->delete();
|
||||
} catch (Exception $e) {
|
||||
$retour = "Erreur lors de la suppression : " . $e->getMessage();
|
||||
}
|
||||
} else {
|
||||
$retour = "Erreur lors de la suppression : Aucun ID envoyé.";
|
||||
}
|
||||
|
||||
return $retour;
|
||||
}
|
||||
}
|
||||
190
app/Http/Controllers/Bo/ProductController.php
Normal file
190
app/Http/Controllers/Bo/ProductController.php
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\Products\StoreProductRequest;
|
||||
use App\Http\Requests\Bo\Products\UpdateProductRequest;
|
||||
use App\Models\Product;
|
||||
use App\Models\Range;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ProductController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(Product::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 $productModels */
|
||||
$productModels = Product::query()->with('range');
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$productModels,
|
||||
$search,
|
||||
null,
|
||||
'name',
|
||||
'ean_code',
|
||||
);
|
||||
}
|
||||
$searchFields = \sprintf(
|
||||
'%s, %s ...',
|
||||
Str::ucfirst(__('validation.attributes.name')),
|
||||
__('validation.custom.ean_code'),
|
||||
);
|
||||
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($productModels);
|
||||
|
||||
/** Custom pagination */
|
||||
$productModels = $this->paginate($productModels);
|
||||
|
||||
return view('back::pages.products.index', compact('productModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \App\Models\Product $product
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(Product $product): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('back::pages.products.show', ['productModel' => $product]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\Product $product
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function create(Product $product): \Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$rangeModels = Range::all();
|
||||
if (!count($rangeModels)) {
|
||||
return \redirect()->route('bo.ranges.index')
|
||||
->with(
|
||||
'error',
|
||||
'Vous devez ajouter une gamme avant de pouvoir ajouter un produit'
|
||||
);
|
||||
}
|
||||
return view('back::pages.products.create', [
|
||||
'productModel' => $product,
|
||||
'rangeModels' => $rangeModels
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Products\StoreProductRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreProductRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$product = new Product();
|
||||
$product->fill($request->validated());
|
||||
if ($product->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.products.edit', $product)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_created',
|
||||
['model' => Str::singular(__('models.classes.product'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_created',
|
||||
['model' => Str::singular(__('models.classes.product'))]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Product $product
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Product $product): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$rangeModels = Range::all();
|
||||
return view('back::pages.products.edit', [
|
||||
'productModel' => $product,
|
||||
'rangeModels' => $rangeModels
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Products\UpdateProductRequest $request
|
||||
* @param \App\Models\Product $product
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateProductRequest $request, Product $product): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $product) {
|
||||
$product->fill($request->validated());
|
||||
if ($product->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.products.edit', $product)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_updated',
|
||||
['model' => Str::singular(__('models.classes.product'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_updated',
|
||||
['model' => Str::singular(__('models.classes.product'))]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Product $product
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Product $product): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($product) {
|
||||
if ($product->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.products.index')
|
||||
->with('success', __(
|
||||
'crud.messages.has_been_deleted',
|
||||
['model' => Str::singular(__('models.classes.product'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', __(
|
||||
':crud.messages.cannot_be_deleted',
|
||||
['model' => Str::singular(__('models.classes.product'))]
|
||||
));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,155 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\StoreProductRequest;
|
||||
use App\Http\Requests\UpdateProductRequest;
|
||||
use App\Models\Product;
|
||||
use App\Models\Range;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ProductsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$products = Product::all();
|
||||
return view('bo.products.index', compact('products'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$ranges = Range::all();
|
||||
if (!count($ranges)) {
|
||||
return \redirect()->route('bo.ranges.index')
|
||||
->with(
|
||||
'error',
|
||||
'Vous devez ajouter une gamme avant de pouvoir ajouter un produit'
|
||||
);
|
||||
}
|
||||
return view('bo.products.create', compact('ranges'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\StoreProductRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(StoreProductRequest $request)
|
||||
{
|
||||
$name = $request->name;
|
||||
$slug = Str::slug($name);
|
||||
$no_art = $request->no_art;
|
||||
$code_ean = $request->code_ean;
|
||||
$picture = $request->picture;
|
||||
|
||||
$product = new Product();
|
||||
$product->name = $name;
|
||||
$product->no_art = $no_art;
|
||||
$product->code_ean = $code_ean;
|
||||
$product->range()->associate($request->range_id);
|
||||
$product->save();
|
||||
|
||||
if ($picture !== null) {
|
||||
$imageName = $product->id . '_' . $slug . '_' . Str::random(5) . '.' . $picture->extension();
|
||||
$picture->move(public_path('images/produits'), $imageName);
|
||||
$product->picture = $imageName;
|
||||
$product->save();
|
||||
}
|
||||
|
||||
return redirect()->route('bo.products.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param integer $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param integer $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
$ranges = Range::all();
|
||||
if (!count($ranges)) {
|
||||
return \redirect()->route('bo.ranges.index')
|
||||
->with(
|
||||
'error',
|
||||
'Vous devez ajouter une gamme avant de pouvoir ajouter un produit'
|
||||
);
|
||||
}
|
||||
$product = Product::findOrFail($id);
|
||||
return view('bo.products.edit', compact('product', 'ranges'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\UpdateProductRequest $request
|
||||
* @param integer $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(UpdateProductRequest $request, $id)
|
||||
{
|
||||
$name = $request->name;
|
||||
$slug = Str::slug($name);
|
||||
$no_art = $request->no_art;
|
||||
$code_ean = $request->code_ean;
|
||||
$picture = $request->picture;
|
||||
|
||||
$product = Product::findOrFail($id);
|
||||
$product->range()->associate($request->range_id);
|
||||
|
||||
if ($picture !== null) {
|
||||
if ($product->picture !== null && file_exists(public_path('images/produits/') . $product->picture)) {
|
||||
unlink(public_path('images/produits/') . $product->picture);
|
||||
}
|
||||
$imageName = $product->id . '_' . $slug . '_' . Str::random(5) . '.' . $picture->extension();
|
||||
$picture->move(public_path('images/produits'), $imageName);
|
||||
}
|
||||
|
||||
$product->name = $name;
|
||||
$product->no_art = $no_art;
|
||||
$product->code_ean = $code_ean;
|
||||
|
||||
if ($picture !== null) {
|
||||
$product->picture = $imageName;
|
||||
}
|
||||
$product->save();
|
||||
|
||||
return redirect()->route('bo.products.edit', $product->id)->with('success', 'Modifications enregistrés !');
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param integer $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
$product = Product::findOrFail($id);
|
||||
$product->delete();
|
||||
return redirect()->route('bo.products.index');
|
||||
}
|
||||
}
|
||||
|
|
@ -3,135 +3,176 @@
|
|||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\StoreRangeRequest;
|
||||
use App\Http\Requests\UpdateRangeRequest;
|
||||
use App\Http\Requests\Bo\Ranges\StoreRangeRequest;
|
||||
use App\Http\Requests\Bo\Ranges\UpdateRangeRequest;
|
||||
use App\Models\Range;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class RangeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(Range::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index()
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$ranges = Range::paginate();
|
||||
return view('bo.ranges.index', compact('ranges'));
|
||||
}
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $rangeModels */
|
||||
$rangeModels = Range::query();
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return view('bo.ranges.create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\StoreRangeRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(StoreRangeRequest $request)
|
||||
{
|
||||
$name = $request->name;
|
||||
$slug = Str::slug($name);
|
||||
$picture = $request->picture;
|
||||
|
||||
$range = new Range();
|
||||
$range->name = $name;
|
||||
$range->save();
|
||||
|
||||
if ($picture !== null) {
|
||||
$imageName = $range->id . '_' . $slug . '_' . Str::random(5) . '.' . $picture->extension();
|
||||
$picture->move(public_path('images/ranges'), $imageName);
|
||||
$range->picture = $imageName;
|
||||
$range->save();
|
||||
/** @var string $search Search field */
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$rangeModels,
|
||||
$search,
|
||||
null,
|
||||
'name',
|
||||
);
|
||||
}
|
||||
$searchFields = Str::ucfirst(__('validation.attributes.name'));
|
||||
|
||||
return \response()->redirectToRoute('bo.ranges.index')
|
||||
->with('success', 'La gamme à bien été enregistré !');
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($rangeModels);
|
||||
|
||||
/** Custom pagination */
|
||||
$rangeModels = $this->paginate($rangeModels);
|
||||
|
||||
return view('back::pages.ranges.index', compact('rangeModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \App\Models\Range $range
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(Range $range)
|
||||
public function show(Range $range): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.ranges.view', compact('range'));
|
||||
return view('back::pages.ranges.show', ['rangeModel' => $range]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\Range $range
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(Range $range): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('back::pages.ranges.create', [
|
||||
'rangeModel' => $range,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Ranges\StoreRangeRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreRangeRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$range = new Range();
|
||||
$range->fill($request->validated());
|
||||
if ($range->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.ranges.edit', $range)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_created',
|
||||
['model' => Str::singular(__('models.classes.range'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_created',
|
||||
['model' => Str::singular(__('models.classes.range'))]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Range $range
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Range $range)
|
||||
public function edit(Range $range): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.ranges.edit', compact('range'));
|
||||
return view('back::pages.ranges.edit', [
|
||||
'rangeModel' => $range
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\UpdateRangeRequest $request
|
||||
* @param \App\Models\Range $range
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param \App\Http\Requests\Bo\Ranges\UpdateRangeRequest $request
|
||||
* @param \App\Models\Range $range
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateRangeRequest $request, Range $range)
|
||||
public function update(UpdateRangeRequest $request, Range $range): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$name = $request->name;
|
||||
$slug = Str::slug($name);
|
||||
$picture = $request->picture;
|
||||
|
||||
if ($picture !== null) {
|
||||
if ($range->picture !== null && file_exists(public_path('images/ranges/') . $range->picture)) {
|
||||
unlink(public_path('images/ranges/') . $range->picture);
|
||||
return DB::transaction(function () use ($request, $range) {
|
||||
$range->fill($request->validated());
|
||||
if ($range->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.ranges.edit', $range)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_updated',
|
||||
['model' => Str::singular(__('models.classes.range'))]
|
||||
));
|
||||
}
|
||||
$imageName = $range->id . '_' . $slug . '_' . Str::random(5) . '.' . $picture->extension();
|
||||
$picture->move(public_path('images/ranges'), $imageName);
|
||||
}
|
||||
|
||||
$range->name = $name;
|
||||
|
||||
if ($picture !== null) {
|
||||
$range->picture = $imageName;
|
||||
}
|
||||
$range->saveOrFail();
|
||||
|
||||
|
||||
return \response()->redirectToRoute('bo.ranges.edit', $range)
|
||||
->with('success', 'La gamme à bien été mise à jour !');
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_updated',
|
||||
['model' => Str::singular(__('models.classes.range'))]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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->products()->count()) {
|
||||
return back()->withError(
|
||||
'Cette gamme est associé a des produits, la supression n\'est pas possible'
|
||||
);
|
||||
}
|
||||
if (!$range->delete()) {
|
||||
return back()->withError(
|
||||
'Erreur lors de la suppression de la gamme'
|
||||
);
|
||||
}
|
||||
return \response()->redirectToRoute('bo.ranges.index')
|
||||
->with('warning', 'La gamme à bien été supprimée !');
|
||||
return DB::transaction(function () use ($range) {
|
||||
if ($range->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.ranges.index')
|
||||
->with('success', __(
|
||||
'crud.messages.has_been_deleted',
|
||||
['model' => Str::singular(__('models.classes.range'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', __(
|
||||
':crud.messages.cannot_be_deleted',
|
||||
['model' => Str::singular(__('models.classes.range'))]
|
||||
));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
269
app/Http/Controllers/Bo/Re7Controller.php
Normal file
269
app/Http/Controllers/Bo/Re7Controller.php
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Mail\Won\DiscountWonMail;
|
||||
use App\Mail\Won\PrizeIsSentMail;
|
||||
use App\Mail\Won\PrizeWonMail;
|
||||
use App\Mail\Won\WinningProofSubmitedMail;
|
||||
use App\Models\Prize;
|
||||
use App\Models\Settings;
|
||||
use App\Lib\Discount;
|
||||
use App\Models\Participation;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Mail\Mailables\Address;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class Re7Controller extends Controller
|
||||
{
|
||||
/**
|
||||
* Re7Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware(function (Request $request, \Closure $next) {
|
||||
$this->authorize('fo.showRe7');
|
||||
return $next($request);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show Home page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function home(): View
|
||||
{
|
||||
return view('theme::pages.home');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show Teaser page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function teaser(): View
|
||||
{
|
||||
return view('theme::pages.teaser');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show Teaser page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function endGame(): View
|
||||
{
|
||||
return view('theme::pages.end-game');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show code input page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function participate(): View
|
||||
{
|
||||
return view('theme::pages.participation.participate');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show code input page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function participationExhausted(): View
|
||||
{
|
||||
return view('theme::pages.participation.participation-exhausted');
|
||||
}
|
||||
|
||||
// * -- Participation
|
||||
|
||||
/**
|
||||
* Show prize page
|
||||
*
|
||||
* @param \App\Models\Prize $prize
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function prize(Prize $prize): View
|
||||
{
|
||||
// * Fake participation model
|
||||
$participationModel = new Participation();
|
||||
$participationModel = 9999999;
|
||||
return view('theme::pages.participation.won', [
|
||||
'prizeModel' => $prize,
|
||||
'participationModel' => $participationModel
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show discount page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function discount(): View
|
||||
{
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
/** @var \App\Lib\Discount */
|
||||
$discount = Arr::get(
|
||||
$settings->web_coupons,
|
||||
$this->getRandomWeightedElementIndex($settings->web_coupons)
|
||||
);
|
||||
|
||||
if (!$settings->discounts_activated) {
|
||||
return abort(404);
|
||||
}
|
||||
|
||||
$mesBrDiscount = new Discount();
|
||||
return view('theme::pages.participation.won', compact('discount', 'mesBrDiscount'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show loose page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function loose(): View
|
||||
{
|
||||
return view('theme::pages.participation.loose');
|
||||
}
|
||||
|
||||
// * -- END Participation
|
||||
|
||||
/**
|
||||
* View won prize mail
|
||||
*
|
||||
* @param \App\Models\Prize $prize
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function mailPrize(Prize $prize): View
|
||||
{
|
||||
return view('back::pages.re7-preview-mail', [
|
||||
'render_url' => route('re7.mail-print', [
|
||||
'type' => 'prize',
|
||||
'prize' => $prize
|
||||
])
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* View won discount mail
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function mailDiscount(): View
|
||||
{
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
if (!$settings->discounts_activated) {
|
||||
return abort(404);
|
||||
}
|
||||
|
||||
return view('back::pages.re7-preview-mail', [
|
||||
'render_url' => route('re7.mail-print', [
|
||||
'type' => 'discount'
|
||||
])
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* View proof mail received mail
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function mailProofReceived(): View
|
||||
{
|
||||
return view('back::pages.re7-preview-mail', [
|
||||
'render_url' => route('re7.mail-print', [
|
||||
'type' => 'proof'
|
||||
])
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* View sent prize mail
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function mailPrizeSent(): View
|
||||
{
|
||||
return view('back::pages.re7-preview-mail', [
|
||||
'render_url' => route('re7.mail-print', [
|
||||
'type' => 'prize-sent'
|
||||
])
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a specific mail
|
||||
*
|
||||
* @param string $type
|
||||
* @param \App\Models\Prize|null $prize
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function mailPrint(string $type, Prize|null $prize = null): Response
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
$user = auth('backend')->user();
|
||||
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
|
||||
switch ($type) {
|
||||
case 'discount':
|
||||
/** @var \App\Lib\Discount */
|
||||
$discount = Arr::get(
|
||||
$settings->web_coupons,
|
||||
$this->getRandomWeightedElementIndex($settings->web_coupons)
|
||||
);
|
||||
|
||||
return response((new DiscountWonMail(
|
||||
new Address(
|
||||
$user->email,
|
||||
$user->first_name
|
||||
),
|
||||
$settings->name,
|
||||
$discount,
|
||||
config('app.url'),
|
||||
$settings->company,
|
||||
))->render());
|
||||
case 'prize':
|
||||
return response((new PrizeWonMail(
|
||||
new Address(
|
||||
$user->email,
|
||||
$user->first_name
|
||||
),
|
||||
$settings->name,
|
||||
$prize,
|
||||
config('app.url'),
|
||||
$settings->company,
|
||||
))->render());
|
||||
case 'prize-sent':
|
||||
return response((new PrizeIsSentMail(
|
||||
new Address(
|
||||
$user->email,
|
||||
$user->first_name
|
||||
),
|
||||
$settings->name,
|
||||
$settings->company,
|
||||
))->render());
|
||||
case 'proof':
|
||||
return response((new WinningProofSubmitedMail(
|
||||
new Address(
|
||||
$user->email,
|
||||
$user->first_name
|
||||
),
|
||||
$settings->name,
|
||||
$settings->company,
|
||||
))->render());
|
||||
default:
|
||||
return response('', 404);
|
||||
} //end switch
|
||||
}
|
||||
}
|
||||
|
|
@ -3,89 +3,101 @@
|
|||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\Settings\UpdateSettingsRequest;
|
||||
use App\Lib\Discount;
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class SettingsController extends Controller
|
||||
{
|
||||
public function manage(Request $request)
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
/** @var \App\Models\Settings $settings */
|
||||
$settings = app(Settings::class);
|
||||
$this->authorizeResource(Settings::class);
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$name = $request->name;
|
||||
$startDate = $request->start_date;
|
||||
$endDate = $request->end_date;
|
||||
$nbParticipationPlayer = $request->nb_participation_player;
|
||||
$nbParticipationIp = $request->nb_participation_ip;
|
||||
$nbUniqueCodeUse = $request->nb_unique_code_use;
|
||||
$useEanCodes = $request->use_ean_codes === null ? 0 : 1;
|
||||
$activatedTeaser = $request->activated_teaser === null ? 0 : 1;
|
||||
$teaserEndActivity = $request->teaser_end_activity;
|
||||
$activatedClosePage = $request->activated_close_page === null ? 0 : 1;
|
||||
$closePageActiveDate = $request->close_page_active_date;
|
||||
$redirectClose = $request->redirect_close;
|
||||
$reductionsActivated = $request->reductions_activated === null ? 0 : 1;
|
||||
$reductionsSite = $request->reductions_site;
|
||||
$reductionsCampaign = $request->reductions_campaign;
|
||||
$webCoupons = $request->web_coupons;
|
||||
$facebookActivated = $request->facebook_activated === null ? 0 : 1;
|
||||
$facebookAppId = $request->facebook_app_id;
|
||||
$facebookSecret = $request->facebook_secret;
|
||||
$notificationEmails = $request->notification_emails;
|
||||
$winningProof = $request->winning_proof === null ? 0 : 1;
|
||||
$company = $request->company;
|
||||
$analytics = $request->analytics;
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Settings $settings
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Settings $settings): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('back::pages.settings.edit', [
|
||||
'settingsModel' => $settings
|
||||
]);
|
||||
}
|
||||
|
||||
// Check du lien de redirection après fermeture.
|
||||
if (strpos($redirectClose, 'https://') === false && strpos($redirectClose, 'http://') === false) {
|
||||
$redirectClose = 'https://' . $redirectClose;
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Settings\UpdateSettingsRequest $request
|
||||
* @param \App\Models\Settings $settings
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateSettingsRequest $request, Settings $settings): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $settings) {
|
||||
$data = $request->validated();
|
||||
|
||||
// * Assign parsed Web coupon objects
|
||||
Arr::set($data, 'web_coupons', collect(Arr::get($data, 'web_coupons'))->filter()
|
||||
->map(fn (array $coupon) => $this->parseWebCoupon($coupon))
|
||||
->filter()->all());
|
||||
|
||||
$settings->fill($data);
|
||||
if ($settings->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.settings.edit', $settings)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_updated',
|
||||
['model' => Str::singular(__('models.classes.settings'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_updated',
|
||||
['model' => Str::singular(__('models.classes.settings'))]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
$settings->name = $name;
|
||||
$settings->start_date = $startDate;
|
||||
$settings->end_date = $endDate;
|
||||
$settings->nb_participation_player = $nbParticipationPlayer;
|
||||
$settings->nb_participation_ip = $nbParticipationIp;
|
||||
$settings->nb_unique_code_use = $nbUniqueCodeUse;
|
||||
$settings->use_ean_codes = $useEanCodes;
|
||||
$settings->activated_teaser = $activatedTeaser;
|
||||
if ($activatedTeaser === 1) {
|
||||
$settings->teaser_end_activity = Carbon::parse($teaserEndActivity);
|
||||
}
|
||||
$settings->activated_close_page = $activatedClosePage;
|
||||
if ($activatedClosePage === 1) {
|
||||
$settings->close_page_active_date = Carbon::parse($closePageActiveDate);
|
||||
}
|
||||
$settings->redirect_close = $redirectClose;
|
||||
$settings->reductions_activated = $reductionsActivated;
|
||||
if ($reductionsActivated === 1) {
|
||||
$settings->reductions_site = $reductionsSite;
|
||||
$settings->reductions_campaign = $reductionsCampaign;
|
||||
$settings->web_coupons = $webCoupons;
|
||||
}
|
||||
$settings->facebook_activated = $facebookActivated;
|
||||
$settings->facebook_app_id = $facebookAppId;
|
||||
$settings->facebook_secret = $facebookSecret;
|
||||
$settings->notification_emails = $notificationEmails;
|
||||
$settings->winning_proof = $winningProof;
|
||||
$settings->company = $company;
|
||||
$settings->analytics = $analytics;
|
||||
|
||||
$settings->save();
|
||||
|
||||
$settingsGlobal = app(Settings::class)
|
||||
->select('name', 'company', 'analytics', 'start_date', 'end_date')->first();
|
||||
Cache::put('settingsGlobal', $settingsGlobal);
|
||||
|
||||
$success = "Modifications enregistrés !";
|
||||
|
||||
return view('bo.settings.manage', compact('settings', 'success'));
|
||||
}//end if
|
||||
|
||||
return view('bo.settings.manage', compact('settings'));
|
||||
/**
|
||||
* Try to parse webCoupon
|
||||
*
|
||||
* @param array<string,string> $coupon
|
||||
* @return \App\Lib\Discount|null
|
||||
*/
|
||||
private function parseWebCoupon(array $coupon): Discount | null
|
||||
{
|
||||
/** @var \Illuminate\Http\UploadedFile|string */
|
||||
$picture = Arr::get($coupon, 'picture');
|
||||
if (is_object($picture) and ($picture instanceof \Illuminate\Http\UploadedFile)) {
|
||||
$picture = FileStorageHelper::storeFile(
|
||||
new Settings(),
|
||||
$picture,
|
||||
true,
|
||||
'web-coupon.' . $picture->extension()
|
||||
);
|
||||
}
|
||||
try {
|
||||
return Discount::make(
|
||||
$picture,
|
||||
Arr::get($coupon, 'valid_on'),
|
||||
Arr::get($coupon, 'face_value'),
|
||||
Arr::get($coupon, 'percentage'),
|
||||
Arr::get($coupon, 'web_coupon_identifiant'),
|
||||
);
|
||||
} catch (\RuntimeException | \TypeError) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
91
app/Http/Controllers/Bo/StaticPageController.php
Normal file
91
app/Http/Controllers/Bo/StaticPageController.php
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
<?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;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
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 */
|
||||
$staticPageModelList = $this->paginate($query);
|
||||
|
||||
return view('back::pages.static_pages.index', compact('staticPageModelList', '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('back::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' => Str::ucfirst(\trans_choice('models.classes.static_page', 1))
|
||||
]));
|
||||
}
|
||||
return redirect()->route('bo.static_pages.edit', $static_page)
|
||||
->with('error', __('crud.messages.cannot_be_updated', [
|
||||
'model' => Str::ucfirst(\trans_choice('models.classes.static_page', 1))
|
||||
]));
|
||||
});
|
||||
}
|
||||
}
|
||||
169
app/Http/Controllers/Bo/UserController.php
Normal file
169
app/Http/Controllers/Bo/UserController.php
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\Users\StoreUserRequest;
|
||||
use App\Http\Requests\Bo\Users\UpdateUserRequest;
|
||||
use App\Models\User;
|
||||
use App\Traits\Controllers\UpdateModelPublished;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
use UpdateModelPublished;
|
||||
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(User::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 $userModels */
|
||||
$userModels = User::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$userModels,
|
||||
$search,
|
||||
null,
|
||||
'first_name',
|
||||
'last_name',
|
||||
'email',
|
||||
'role',
|
||||
);
|
||||
}
|
||||
$searchFields = \implode(', ', [
|
||||
trans('validation.attributes.first_name'),
|
||||
trans('validation.attributes.last_name'),
|
||||
trans('validation.attributes.email'),
|
||||
trans('validation.attributes.role'),
|
||||
]);
|
||||
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($userModels);
|
||||
|
||||
/** Custom pagination */
|
||||
$userModels = $this->paginate($userModels);
|
||||
|
||||
return view('back::pages.users.index', compact('userModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(User $user): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('back::pages.users.create', ['userModel' => $user]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Users\StoreUserRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreUserRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$user = new User();
|
||||
$user->fill($request->validated());
|
||||
|
||||
if ($user->saveOrFail()) {
|
||||
return redirect()->route('bo.users.edit', $user)
|
||||
->with('success', __('crud.messages.has_been_created', [
|
||||
'model' => Str::ucfirst(__('models.classes.user'))
|
||||
]));
|
||||
}
|
||||
return redirect()->back()
|
||||
->with('error', __('crud.messages.cannot_be_created', [
|
||||
'model' => Str::ucfirst(__('models.classes.user'))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(User $user): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('back::pages.users.edit', ['userModel' => $user]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Users\UpdateUserRequest $request
|
||||
* @param \App\Models\User $user
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateUserRequest $request, User $user): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $user) {
|
||||
$user->fill($request->validated());
|
||||
|
||||
if ($user->saveOrFail()) {
|
||||
return redirect()->route('bo.users.edit', $user)
|
||||
->with('success', __('crud.messages.has_been_updated', [
|
||||
'model' => Str::ucfirst(__('models.classes.user'))
|
||||
]));
|
||||
}
|
||||
return redirect()->route('bo.users.edit', $user)
|
||||
->with('error', __('crud.messages.cannot_be_updated', [
|
||||
'model' => Str::ucfirst(__('models.classes.user'))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(User $user): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
if ($user->deleteOrFail()) {
|
||||
return redirect()->route('bo.users.index')
|
||||
->with('success', __('crud.messages.has_been_deleted', [
|
||||
'model' => Str::ucfirst(__('models.classes.user'))
|
||||
]));
|
||||
}
|
||||
return redirect()->back()
|
||||
->with('error', __('crud.messages.cannot_be_deleted', [
|
||||
'model' => Str::ucfirst(__('models.classes.user'))
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate the specified resource.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function duplicate(User $user): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return $this->create($user->replicate());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Mail\CourrierArcadiaError;
|
||||
use App\Models\Participation;
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class WinnersListController extends Controller
|
||||
{
|
||||
private $apiCrm;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->apiCrm = new \LDCCRM\ApiV1(config('crm.endpoint'), config('crm.token'));
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$winnersList = Participation::has('instantWin')->get();
|
||||
$settings = Settings::select('use_ean_codes', 'winning_proof')->first();
|
||||
return view('bo.winners-list.index', compact('winnersList', 'settings'));
|
||||
}
|
||||
|
||||
public function courrierArcadia($id)
|
||||
{
|
||||
$participation = Participation::findOrFail($id);
|
||||
|
||||
$crmUser = $this->apiCrm->getCustomer($participation->user->crm_id);
|
||||
if ($crmUser->status === 'NOK') {
|
||||
return back()->withErrors("Erreur lors de la récupération de l'utilisateur dans la CRM : Code : " .
|
||||
$crmUser->code . " Message : " . $crmUser->message);
|
||||
}
|
||||
|
||||
$crmId = $participation->user->crm_id;
|
||||
|
||||
$crmUser = $crmUser->user;
|
||||
|
||||
$corps = '<arcadia>' . "\n";
|
||||
$corps .= '<Commande> ' . "\n";
|
||||
$corps .= "\t" . '<Num_Commande></Num_Commande>' . "\n";
|
||||
$corps .= "\t" . '<Date_Commande>' . date('d/m/Y') . '</Date_Commande>' . "\n";
|
||||
$corps .= "\t" . '<Operation></Operation> ' . "\n";
|
||||
$corps .= "\t" . '<Civilite></Civilite>' . "\n";
|
||||
$corps .= "\t" . '<Nom><![CDATA[' . trim($crmUser->firstname) . ']]></Nom>' . "\n";
|
||||
$corps .= "\t" . '<Prenom><![CDATA[' . trim($crmUser->lastname) . ']]></Prenom>' . "\n";
|
||||
$corps .= "\t" . '<Adresse><![CDATA[' . trim($crmUser->address) . ']]></Adresse>' . "\n";
|
||||
$corps .= "\t" . '<Adresse_Complementaire><![CDATA[' . trim($crmUser->address2) . ']]></Adresse_Complementaire>' . "\n";
|
||||
$corps .= "\t" . '<CP><![CDATA[' . trim($crmUser->postcode) . ']]></CP>' . "\n";
|
||||
$corps .= "\t" . '<Ville><![CDATA[' . trim($crmUser->city) . ']]></Ville>' . "\n";
|
||||
$corps .= '<Ligne_de_Commande>' . "\n";
|
||||
$corps .= "\t" . '<Code_Support></Code_Support> ' . "\n";
|
||||
$corps .= "\t" . '<Libelle_Type_Support></Libelle_Type_Support> ' . "\n";
|
||||
$corps .= "\t" . '<Quantite>1</Quantite>' . "\n";
|
||||
$corps .= "\t" . '<Poids_Unitaire_Colis></Poids_Unitaire_Colis>' . "\n";
|
||||
$corps .= '</Ligne_de_Commande>' . "\n";
|
||||
$corps .= '</Commande> ' . "\n";
|
||||
$corps .= '</arcadia>';
|
||||
|
||||
return view('bo.winners-list.arcadia', compact('participation', 'corps', 'crmId'));
|
||||
}
|
||||
|
||||
public function createCourrierArcadia(Request $request, $id)
|
||||
{
|
||||
$participation = Participation::findOrFail($id);
|
||||
$instantWin = $participation->instantWin;
|
||||
|
||||
if ($instantWin->prize->arcadia_operation_code !== 0 && $instantWin->prize->arcadia_support_code !== 0) {
|
||||
$fields = [
|
||||
'root' => [
|
||||
[
|
||||
'fieldName' => 'order_date',
|
||||
'fieldValue' => date('d/m/Y')
|
||||
],
|
||||
[
|
||||
'fieldName' => 'operation',
|
||||
'fieldValue' => $instantWin->prize->arcadia_operation_code
|
||||
]
|
||||
],
|
||||
'orderLine' => [
|
||||
[
|
||||
'fieldName' => 'code_unique',
|
||||
'fieldValue' => $participation->code->code_unique
|
||||
],
|
||||
[
|
||||
'fieldName' => 'support_code',
|
||||
'fieldValue' => $instantWin->prize->arcadia_support_code
|
||||
],
|
||||
[
|
||||
'fieldName' => 'label_type_support',
|
||||
'fieldValue' => 'Gain du lot : ' . $instantWin->prize->label_one
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
/** @var \App\Models\Settings $settings */
|
||||
$settings = app(Settings::class);
|
||||
if ($settings->use_ean_codes === 1) {
|
||||
$fields['orderLine'][] = [
|
||||
'fieldName' => 'code_on_pack',
|
||||
'fieldValue' => $participation->codeEan->code
|
||||
];
|
||||
}
|
||||
|
||||
$arcadiaMail = $this->apiCrm->ArcadiaOutgoingMail($participation->user->crm_id, $fields, 'game');
|
||||
if ($arcadiaMail->status === 'NOK') {
|
||||
Mail::to(config('mail.MAIL_ADMIN'))->send(new CourrierArcadiaError($participation->user));
|
||||
return back()->withErrors("Erreur lors de l'envoi du courrier Arcadia. Code : " .
|
||||
$arcadiaMail->code . " Message : " . $arcadiaMail->message);
|
||||
}
|
||||
}//end if
|
||||
return back()->with('success', 'Courrier envoyé !');
|
||||
}
|
||||
}
|
||||
|
|
@ -2,14 +2,267 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Enums\Pagination\ItemsPerPaginationEnum;
|
||||
use App\Enums\Theme\BootstrapThemeEnum;
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
use DispatchesJobs;
|
||||
use ValidatesRequests;
|
||||
|
||||
|
||||
/**
|
||||
* Utility function for getting random values with weighting.
|
||||
* Pass in an associative array, such as array('A'=>5, 'B'=>45, 'C'=>50)
|
||||
* An array like this means that "A" has a 5% chance of being selected, "B" 45%, and "C" 50%.
|
||||
* The return value is the array key, A, B, or C in this case. Note that the values assigned
|
||||
* do not have to be percentages. The values are simply relative to each other. If one value
|
||||
* weight was 2, and the other weight of 1, the value with the weight of 2 has about a 66%
|
||||
* chance of being selected. Also note that weights should be integers.
|
||||
*
|
||||
* @param array<\App\Lib\Discount> $weightedValues
|
||||
* @return integer The winning key
|
||||
* @url https://stackoverflow.com/a/11872928/4355295
|
||||
*/
|
||||
protected function getRandomWeightedElementIndex(array $weightedValues): int
|
||||
{
|
||||
mt_srand(time());
|
||||
$rand = mt_rand(1, max((int) collect($weightedValues)->sum('percentage'), 1));
|
||||
|
||||
foreach ($weightedValues as $key => $value) {
|
||||
$rand -= $value->percentage;
|
||||
if ($rand <= 0) {
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
return $rand;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the redirection path for FO Auth controllers
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function authLoggedRedirectPath(): string
|
||||
{
|
||||
return response()->redirectToRoute('fo.homepage')->getTargetUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build Search query on specified fields
|
||||
* splitting search into words or using whole sentence
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query The eloquent query builder.
|
||||
* @param string $search The query string.
|
||||
* @param callable $searchQuery The query string.
|
||||
* @param string ...$fields Either a simple array or a string
|
||||
* in case of a string the two fields
|
||||
* would be concatenate to make the search.
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected function searchQuery(
|
||||
Builder $query,
|
||||
string $search,
|
||||
callable $searchQuery = null,
|
||||
string ...$fields
|
||||
): \Illuminate\Database\Eloquent\Builder {
|
||||
if (count($fields)) {
|
||||
// Search using words.
|
||||
$words = explode(' ', $search);
|
||||
$query->where(function ($query) use ($searchQuery, $words, $search, $fields) {
|
||||
foreach ($words as $word) {
|
||||
if (!strlen($word)) {
|
||||
continue;
|
||||
}
|
||||
$this->searchOnFields($query, $word, $fields);
|
||||
} //end foreach
|
||||
// Search whole using whole sentence.
|
||||
$this->searchOnFields($query, $search, $fields);
|
||||
if ($searchQuery) {
|
||||
$searchQuery($query);
|
||||
}
|
||||
});
|
||||
} //end if
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build query search on all fields
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param string $search
|
||||
* @param array $fields
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
private function searchOnFields(
|
||||
Builder $query,
|
||||
string $search,
|
||||
array $fields
|
||||
): \Illuminate\Database\Eloquent\Builder {
|
||||
$table = $query->getModel()->getTable();
|
||||
foreach ($fields as $field) {
|
||||
$field = str_replace('?', '\?', $field);
|
||||
if (is_array($field)) {
|
||||
$query->orWhereRaw(
|
||||
sprintf("UPPER(CONCAT(%s)) LIKE UPPER(?)", collect($field)->map(function ($q) use ($table) {
|
||||
return "`$table`.`$q`";
|
||||
})->implode(', \' \', ')),
|
||||
['%' . htmlspecialchars($search) . '%']
|
||||
);
|
||||
return $query;
|
||||
}
|
||||
// Get models woth enum's label.
|
||||
if (is_array($this->getSearchValue($query, $search, $field))) {
|
||||
foreach ($this->getSearchValue($query, $search, $field) as $array) {
|
||||
$query->orWhereRaw(
|
||||
"UPPER(`$table`.`$field`) LIKE UPPER(?)",
|
||||
['%' . htmlspecialchars($array->value) . '%']
|
||||
);
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
// Get models with relation's name/label.
|
||||
if (Str::endsWith($field, '_id')) {
|
||||
$query->orWhereHas(Str::remove('_id', $field), function ($queryRelation) use ($field, $search) {
|
||||
if (Schema::hasColumn(Str::remove('_id', $field) . 's', 'name')) {
|
||||
$queryRelation->where('name', 'like', '%' . $search . '%');
|
||||
} elseif (Schema::hasColumn(Str::remove('_id', $field) . 's', 'label')) {
|
||||
$queryRelation->where('label', 'like', '%' . $search . '%');
|
||||
}
|
||||
});
|
||||
return $query;
|
||||
}
|
||||
$query->orWhereRaw(
|
||||
"UPPER(`$table`.`$field`) LIKE UPPER(?)",
|
||||
['%' . htmlspecialchars($this->getSearchValue($query, $search, $field)) . '%']
|
||||
);
|
||||
} //end foreach
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the search value (on string or Enum).
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param string $search
|
||||
* @param string $field
|
||||
* @return string|array
|
||||
*/
|
||||
protected function getSearchValue(Builder $query, string $search, string $field): string|array
|
||||
{
|
||||
$cast = $query->getModel()->getCasts()[$field] ?? null;
|
||||
if (
|
||||
count($query->getModel()->getCasts()) and // Check if the model has casts.
|
||||
$cast and // Check if there is cast about specific field.
|
||||
enum_exists($cast) // Check if the cast is an enum.
|
||||
) {
|
||||
// @phpstan-ignore-next-line
|
||||
$cases = collect($cast::toArray());
|
||||
$enum = $cases->filter(function ($item) use ($search) {
|
||||
return preg_match('/' . Str::lower($search) . '/', Str::lower($item->label));
|
||||
});
|
||||
return $enum->toArray();
|
||||
} else {
|
||||
return $search;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort columns with a query.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param array $ignore
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected function sortQuery(Builder $query, array $ignore = []): \Illuminate\Database\Eloquent\Builder
|
||||
{
|
||||
$rName = request()->route()->getName();
|
||||
$table = $query->getModel()->getTable();
|
||||
if (request()->sort_col) {
|
||||
Session::put("$rName.sort_col", request()->sort_col);
|
||||
Session::put("$rName.sorted", true);
|
||||
}
|
||||
if (request()->sort_way) {
|
||||
Session::put("$rName.sort_way", request()->sort_way);
|
||||
Session::put("$rName.sorted", true);
|
||||
}
|
||||
if (request()->rst) {
|
||||
Session::remove("$rName.sorted");
|
||||
Session::remove("$rName.sort_col");
|
||||
Session::remove("$rName.sort_way");
|
||||
}
|
||||
if (request()->sort_col and request()->sort_way and Schema::hasColumn($table, request()->sort_col)) {
|
||||
if (!in_array(request()->sort_col, $ignore)) {
|
||||
$query = $query->orderBy(\sprintf("$table.%s", request()->sort_col), request()->sort_way);
|
||||
}
|
||||
} elseif (Schema::hasColumn($table, 'order')) {
|
||||
$query = $query->orderBy('order', 'ASC');
|
||||
Session::put("$rName.sort_col", 'order');
|
||||
Session::put("$rName.sort_way", 'asc');
|
||||
} elseif (Schema::hasColumn($table, 'updated_at')) {
|
||||
$query = $query->orderBy('updated_at', 'DESC');
|
||||
Session::put("$rName.sort_col", 'updated_at');
|
||||
Session::put("$rName.sort_way", 'desc');
|
||||
} elseif (Schema::hasColumn($table, 'created_at')) {
|
||||
$query = $query->orderBy('created_at', 'DESC');
|
||||
Session::put("$rName.sort_col", 'created_at');
|
||||
Session::put("$rName.sort_way", 'desc');
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Customize pagination with cache or config (default).
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \App\Enums\Pagination\ItemsPerPaginationEnum|null $pagination
|
||||
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
protected function paginate(
|
||||
Builder $query,
|
||||
ItemsPerPaginationEnum $pagination = null
|
||||
): \Illuminate\Contracts\Pagination\LengthAwarePaginator {
|
||||
$currentRoutePath = Str::slug(request()->route()->getName());
|
||||
$cacheKey = "pagination.{$currentRoutePath}";
|
||||
$pagination = $pagination ?? ItemsPerPaginationEnum::twelve;
|
||||
$pagination = ToolboxHelper::getValidatedEnum(
|
||||
Cache::get($cacheKey, $pagination->value()),
|
||||
'pagination',
|
||||
'\App\Enums\Pagination\ItemsPerPaginationEnum',
|
||||
);
|
||||
if (Cache::get($cacheKey) !== $pagination) {
|
||||
Cache::put($cacheKey, $pagination);
|
||||
}
|
||||
$query = $query->paginate($pagination);
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the bootstrap theme or light (default).
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
protected function setTheme(Request $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$theme = ToolboxHelper::getValidatedEnum(
|
||||
$request->theme ?: Cache::get('theme', BootstrapThemeEnum::light->value()),
|
||||
'theme',
|
||||
'\App\Http\Controllers\BootstrapThemeEnum',
|
||||
);
|
||||
if (Cache::get("theme") !== $theme) {
|
||||
Cache::put("theme", $theme);
|
||||
}
|
||||
return redirect()->back()->with('success', __('crud.messages.theme_updated'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Settings;
|
||||
|
||||
class EndPageController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$settings = app(Settings::class)
|
||||
->select('start_date', 'end_date', 'activated_close_page', 'close_page_active_date', 'redirect_close')
|
||||
->first();
|
||||
if (
|
||||
$settings->end_date < now() &&
|
||||
$settings->activated_close_page === 1 &&
|
||||
$settings->close_page_active_date > now()
|
||||
) {
|
||||
return view('front.basic.end', compact('settings'));
|
||||
}
|
||||
return redirect()->route('home');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,290 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\ParticipateRequest;
|
||||
use App\Mail\CourrierArcadiaError;
|
||||
use App\Mail\NotifAdmin;
|
||||
use App\Mail\NotifWinAdmin;
|
||||
use App\Mail\PrizeWon;
|
||||
use App\Mail\ReductionWon;
|
||||
use App\Models\BannedIp;
|
||||
use App\Models\InstantWin;
|
||||
use App\Models\Participation;
|
||||
use App\Models\Reduction;
|
||||
use LDCWeb\MesBR;
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class EnterCodeController extends Controller
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var \LDCCRM\ApiV1
|
||||
*/
|
||||
private $apiCrm;
|
||||
|
||||
/**
|
||||
* EnterCodeController
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->apiCrm = new \LDCCRM\ApiV1(config('crm.endpoint'), config('crm.token'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show enter code form
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$nbParticipations = Participation::where('user_id', Auth::user()->id)->count();
|
||||
$settings = app(Settings::class)->select('use_ean_codes', 'nb_participation_player')->first();
|
||||
if ($nbParticipations >= $settings->nb_participation_player) {
|
||||
return view('front.basic.participation-exhausted', compact('settings'));
|
||||
}
|
||||
return view('front.basic.enter-code', compact('settings'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Participate Method
|
||||
*
|
||||
* @param ParticipateRequest $request
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
public function participate(ParticipateRequest $request)
|
||||
{
|
||||
// Récupération des données à utilisées.
|
||||
/** @var \App\Models\Settings $settings */
|
||||
$settings = app(Settings::class);
|
||||
|
||||
// * Cas IP bannie.
|
||||
$ipBanned = BannedIp::where('ip', app('clientIp'))->first() === null ? 0 : 1;
|
||||
if ($ipBanned) {
|
||||
return view('front.basic.participation-exhausted', compact('settings'));
|
||||
}
|
||||
|
||||
// * Cas nombre de participation maximale atteint.
|
||||
$nbParticipations = Participation::where('user_id', auth()->user()->id)->count();
|
||||
if ($nbParticipations >= $settings->nb_participation_player) {
|
||||
return view('front.basic.participation-exhausted', compact('settings'));
|
||||
}
|
||||
|
||||
// * Tous les cas "bloquants" sont passé, l'utilisateur participe à partir d'ici.
|
||||
$participation = new Participation();
|
||||
$participation->user_id = auth()->user()->id;
|
||||
$participation->code_unique_id = $request->code->id;
|
||||
$participation->code_ean_id = $request->code_ean ? $request->code_ean->id : null;
|
||||
$participation->ip = app('clientIp');
|
||||
$participation->save();
|
||||
|
||||
// * Gestion des instants gagnants.
|
||||
$userAlreadyWon = Participation::has('instantWin')
|
||||
->whereHas('user', function ($q) {
|
||||
$q->whereId(auth()->user()->id);
|
||||
})->first();
|
||||
|
||||
// * Si l'utilisateur actuel à déjà gagné un gros lot, pas d'instant gagnant.
|
||||
if ($userAlreadyWon) {
|
||||
return $this->serveCouponWin($settings, $participation);
|
||||
}
|
||||
|
||||
$instantWin = InstantWin::where([['appear_date', '<', now()], ['won', 0]])
|
||||
->orderBy('appear_date', 'ASC')->first();
|
||||
if ($instantWin) {
|
||||
// Ici si fail car unique dupliqué catch.
|
||||
try {
|
||||
// Gain d'un gros lot.
|
||||
return $this->instantWin($settings, $request, $participation, $instantWin);
|
||||
} catch (\ErrorException $e) {
|
||||
// Unbind instant gagnant.
|
||||
$participation->instantWin()->delete();
|
||||
// TODO: si erreur il faut envoyer un mail à equipe.web@ldc.fr
|
||||
} //end try
|
||||
}
|
||||
return $this->serveCouponWin($settings, $participation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle instant wins
|
||||
*
|
||||
* @param Settings $settings
|
||||
* @param Request $request
|
||||
* @param Participation $participation
|
||||
* @param InstantWin|null $instantWin
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
private function instantWin(Settings $settings, Request $request, Participation &$participation, $instantWin)
|
||||
{
|
||||
$instantWin->won = true;
|
||||
// Should save now to prevent next player win on the same winning moment.
|
||||
$instantWin->save();
|
||||
$participation->instantWin()->save($instantWin);
|
||||
// Envoi du courrier Arcadia.
|
||||
if (
|
||||
$instantWin->prize->arcadia_operation_code !== 0 &&
|
||||
$instantWin->prize->arcadia_support_code !== 0
|
||||
) {
|
||||
$crmId = auth()->user()->crm_id;
|
||||
|
||||
$fields = [
|
||||
'root' => [
|
||||
[
|
||||
'fieldName' => 'order_date',
|
||||
'fieldValue' => date('d/m/Y')
|
||||
],
|
||||
[
|
||||
'fieldName' => 'operation',
|
||||
'fieldValue' => $instantWin->prize->arcadia_operation_code
|
||||
]
|
||||
],
|
||||
'orderLine' => [
|
||||
[
|
||||
'fieldName' => 'code_unique',
|
||||
'fieldValue' => $request->serial
|
||||
],
|
||||
[
|
||||
'fieldName' => 'support_code',
|
||||
'fieldValue' => $instantWin->prize->arcadia_support_code
|
||||
],
|
||||
[
|
||||
'fieldName' => 'label_type_support',
|
||||
'fieldValue' => 'Gain du lot : ' . $instantWin->prize->label_one
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
if ($settings->use_ean_codes === 1) {
|
||||
$codeEan = $request->code_ean;
|
||||
$fields['orderLine'][] = [
|
||||
'fieldName' => 'code_on_pack',
|
||||
'fieldValue' => "$codeEan"
|
||||
];
|
||||
}
|
||||
|
||||
$arcadiaMail = $this->apiCrm->ArcadiaOutgoingMail($crmId, $fields, 'game');
|
||||
if ($arcadiaMail->status === 'KO') {
|
||||
Mail::to(config('mail.MAIL_ADMIN'))->send(new CourrierArcadiaError(auth()->user()));
|
||||
}
|
||||
} //end if
|
||||
|
||||
Mail::to(auth()->user()->email)->send(new PrizeWon(auth()->user(), $instantWin->prize, $settings));
|
||||
$mails = json_decode($settings->notification_emails);
|
||||
foreach ($mails as $mail) {
|
||||
Mail::to($mail->email)->send(new NotifWinAdmin($settings, $participation));
|
||||
}
|
||||
$participation->save();
|
||||
return view("front.basic." . $instantWin->prize->gain_view->file_name, compact('settings'))
|
||||
->with('prize', $instantWin->prize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Détermine si un BR doit être servi
|
||||
* renvoi la vue de gain BR ou la vue "Perdu"
|
||||
*
|
||||
* @param Settings $settings
|
||||
* @param Participation $participation
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
private function serveCouponWin(Settings $settings, Participation $participation)
|
||||
{
|
||||
// Si le jeu est 100% gagnant.
|
||||
if ($settings->reductions_activated === 1) {
|
||||
$coupon = $this->getRandomCoupon($settings);
|
||||
$crmCoupon = $this->updateCoupon($settings, $coupon->web_coupon_identifiant, $participation);
|
||||
if (!$crmCoupon) {
|
||||
$participation->delete();
|
||||
return back()->withErrors("Une erreur est survenue, merci de réessayez ultérieurement.");
|
||||
}
|
||||
Mail::to(Auth::user()->email)->send(new ReductionWon(Auth::user(), $coupon, $settings, $crmCoupon));
|
||||
return view('front.basic.reduction', compact('crmCoupon', 'coupon'));
|
||||
} else {
|
||||
return view('front.basic.loose');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random coupon
|
||||
*
|
||||
* @param Settings $settings
|
||||
* @return mixed
|
||||
*/
|
||||
private function getRandomCoupon(Settings $settings)
|
||||
{
|
||||
$webCoupons = json_decode($settings->web_coupons);
|
||||
if (count($webCoupons) > 1) {
|
||||
$lots = [];
|
||||
foreach ($webCoupons as $webCoupon) {
|
||||
$lots[] = $webCoupon;
|
||||
}
|
||||
foreach ($lots as $lot) {
|
||||
for ($i = 0; $i < $lot->percentage; $i++) {
|
||||
$tmp[] = $lot;
|
||||
}
|
||||
}
|
||||
shuffle($tmp);
|
||||
return $tmp[0];
|
||||
} else {
|
||||
return $webCoupons[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a coupon
|
||||
*
|
||||
* @param Settings $settings
|
||||
* @param mixed $coupon
|
||||
* @param Participation $participation
|
||||
* @return \App\Models\Reduction|null
|
||||
*/
|
||||
private function updateCoupon(Settings $settings, $coupon, Participation $participation)
|
||||
{
|
||||
$reduction = null;
|
||||
$mesBR = new MesBR(config('mesbr.endpoint'), $settings->reductions_site, $settings->reductions_campaign);
|
||||
|
||||
$crmUser = $this->apiCrm->getCustomer(Auth::user()->crm_id);
|
||||
if ($crmUser->status === 'OK') {
|
||||
$mesBR->updateContact($crmUser->user);
|
||||
$result = $mesBR->updatePanier($crmUser->user, $coupon);
|
||||
if ($result["status"] === "OK") {
|
||||
$reduction = new Reduction();
|
||||
$reduction->link = $result["link"];
|
||||
$reduction->verification = $result["verif"];
|
||||
$reduction->basket_id = $result["basketId"];
|
||||
$reduction->save();
|
||||
$participation->reduction_id = $reduction->id;
|
||||
$participation->save();
|
||||
} else {
|
||||
Mail::to(config('mail.MAIL_ADMIN'))
|
||||
->send(new NotifAdmin(\sprintf(
|
||||
'MESBR : Une erreur est survenue. Code : %s Message : %s',
|
||||
$result["code"],
|
||||
$result["message"]
|
||||
)));
|
||||
}
|
||||
} //end if
|
||||
return $reduction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function formWinningProof()
|
||||
{
|
||||
$participation = Participation::where([
|
||||
['user_id', Auth::user()->id],
|
||||
['sticker', null],
|
||||
['ticket', null],
|
||||
['barcode', null]
|
||||
])->has('instantWin')->first();
|
||||
if ($participation) {
|
||||
return view('front.basic.winning-proof', compact('participation'));
|
||||
}
|
||||
return redirect()->route('home');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\FaqQuestion;
|
||||
use App\Models\FaqTheme;
|
||||
|
||||
class FAQController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$questions = FaqQuestion::all();
|
||||
$themes = FaqTheme::all();
|
||||
if (count($questions) === 0 && count($themes) === 0) {
|
||||
return redirect()->route('home');
|
||||
}
|
||||
return view('front.basic.faq', compact('questions', 'themes'));
|
||||
}
|
||||
}
|
||||
46
app/Http/Controllers/Fo/Auth/ConfirmPasswordController.php
Normal file
46
app/Http/Controllers/Fo/Auth/ConfirmPasswordController.php
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Fo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\ConfirmsPasswords;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ConfirmPasswordController extends Controller
|
||||
{
|
||||
use ConfirmsPasswords;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth:frontend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the password confirmation view.
|
||||
*
|
||||
* @return \Illuminate\View\View|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function showConfirmForm(): \Illuminate\View\View|\Illuminate\Http\RedirectResponse
|
||||
{
|
||||
if (Auth::guard('frontend')->check()) {
|
||||
return \response()->redirectToRoute('home');
|
||||
}
|
||||
return view('theme::auth.passwords.confirm');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the post register / login redirect path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function redirectPath(): string
|
||||
{
|
||||
return $this->authLoggedRedirectPath();
|
||||
}
|
||||
}
|
||||
85
app/Http/Controllers/Fo/Auth/ForgotPasswordController.php
Normal file
85
app/Http/Controllers/Fo/Auth/ForgotPasswordController.php
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Fo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Contracts\Auth\PasswordBroker;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
|
||||
class ForgotPasswordController extends Controller
|
||||
{
|
||||
use SendsPasswordResetEmails;
|
||||
|
||||
/**
|
||||
* Message to user
|
||||
*
|
||||
* @var string
|
||||
* @phpcs:disable Generic.Files.LineLength.TooLong
|
||||
*/
|
||||
private $message = 'front.messages.password_reset_email_sent';
|
||||
//phpcs:enable
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest:frontend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the form to request a password reset link.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function showLinkRequestForm(): View
|
||||
{
|
||||
return view('theme::auth.passwords.email');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the broker to be used during password reset.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\PasswordBroker
|
||||
*/
|
||||
public function broker(): PasswordBroker
|
||||
{
|
||||
return Password::broker('customers');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response for a successful password reset link.
|
||||
* ! Dans les deux cas on ne divulgue pas si un user existe.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
protected function sendResetLinkResponse()
|
||||
{
|
||||
return back()->with('info', trans($this->message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response for a failed password reset link.
|
||||
* ! Dans les deux cas on ne divulgue pas si un user existe.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $response
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
protected function sendResetLinkFailedResponse(Request $request, string $response)
|
||||
{
|
||||
// ! Ne pas notifier que l'utilisateur n'existe pas.
|
||||
if ($response === 'passwords.user') {
|
||||
return back()->with('info', trans($this->message));
|
||||
}
|
||||
// * Renvoyer les autres message d'erreur style throttle.
|
||||
return back()
|
||||
->withInput($request->only('email'))
|
||||
->withErrors(['email' => trans($response)]);
|
||||
}
|
||||
}
|
||||
107
app/Http/Controllers/Fo/Auth/LoginController.php
Normal file
107
app/Http/Controllers/Fo/Auth/LoginController.php
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Fo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Customer;
|
||||
use App\Models\Settings;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Contracts\Auth\StatefulGuard;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
use Illuminate\Foundation\Auth\ThrottlesLogins;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
use AuthenticatesUsers;
|
||||
use ThrottlesLogins;
|
||||
|
||||
/**
|
||||
* Where to redirect users after login.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest:frontend')->except('logout');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
protected function guard(): StatefulGuard
|
||||
{
|
||||
return Auth::guard('frontend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application's login form.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function showLoginForm(): View
|
||||
{
|
||||
return view('theme::auth.login');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the authenticated user can access the game
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \App\Models\Customer $user
|
||||
* @return void
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing, Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
*/
|
||||
protected function authenticated(Request $request, Customer $user): void
|
||||
{
|
||||
/** @var \LDC\LDCCRM\Models\Customer $crmCustomer */
|
||||
$crmCustomer = $user->api_data;
|
||||
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
$countries = $settings->authorized_countries;
|
||||
|
||||
if (count($countries) && !in_array($crmCustomer->country->value, $countries)) {
|
||||
$this->logout($request);
|
||||
Session::flash('info', trans('front.messages.game_not_available_in_country'));
|
||||
} else {
|
||||
$user->last_connection = \now();
|
||||
$user->saveOrFail();
|
||||
Session::flash('info', trans('front.messages.login_success'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The user has logged out of the application.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return void
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
*/
|
||||
protected function loggedOut(Request $request): void
|
||||
{
|
||||
Session::flash('info', trans('front.messages.logout_success'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the post register / login redirect path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function redirectPath(): string
|
||||
{
|
||||
return response()->redirectToIntended()->getTargetUrl();
|
||||
}
|
||||
}
|
||||
157
app/Http/Controllers/Fo/Auth/RegisterController.php
Normal file
157
app/Http/Controllers/Fo/Auth/RegisterController.php
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Fo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Fo\Customers\CreateAccountRequest;
|
||||
use App\Models\Customer;
|
||||
use Illuminate\Contracts\Validation\Validator as ValidationValidator;
|
||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException as IlluminateValidationException;
|
||||
use LDC\LDCCRM\Enums\ApiError;
|
||||
use LDC\LDCCRM\Exceptions\ApiErrorException;
|
||||
use LDC\LDCCRM\Exceptions\ValidationException as CrmValidationException;
|
||||
use LDC\LDCCRM\Models\Customer as CrmCustomer;
|
||||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
use RegistersUsers;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest:frontend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
protected function guard()
|
||||
{
|
||||
return Auth::guard('frontend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application registration form.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function showRegistrationForm()
|
||||
{
|
||||
return view('theme::auth.register');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a validator for an incoming registration request.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \Illuminate\Contracts\Validation\Validator
|
||||
* @throws IlluminateValidationException If data is incorrect.
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
*/
|
||||
protected function validator(array $data): ValidationValidator
|
||||
{
|
||||
// phpcs:enable
|
||||
$request = CreateAccountRequest::capture();
|
||||
$request->prepareForValidation();
|
||||
return Validator::make(
|
||||
$request->validationData(),
|
||||
$request->rules(),
|
||||
$request->messages(),
|
||||
$request->attributes()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new user instance after a valid registration.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \App\Models\Customer
|
||||
* @throws IlluminateValidationException If there are validation errors.
|
||||
* @throws \RuntimeException On unhandled api Error.
|
||||
*/
|
||||
protected function create(array $data): Customer
|
||||
{
|
||||
$data['ok_cgv'] = \request()->boolean('ok_cgv');
|
||||
$data['opt_in'] = \request()->boolean('opt_in');
|
||||
$data['phone'] = Arr::get($data, 'phone');
|
||||
// * This field is not standard in crm
|
||||
$data['postcode'] = Arr::get($data, 'postal_code');
|
||||
Arr::forget($data, 'postal_code');
|
||||
|
||||
try {
|
||||
return DB::transaction(function () use ($data) {
|
||||
$crmCustomer = new CrmCustomer(Arr::only(
|
||||
$data,
|
||||
[
|
||||
'firstname', 'lastname', 'birth_date', 'address',
|
||||
'address2', 'postcode', 'country', 'city', 'phone',
|
||||
'email', 'password', 'opt_in',
|
||||
]
|
||||
));
|
||||
|
||||
$crmCustomer->save();
|
||||
|
||||
// * Enregistrement du Hashcode
|
||||
/** @var \App\Models\Customer $customer */
|
||||
$customer = Customer::withTrashed()->firstOrNew([
|
||||
'email' => $data['email']
|
||||
]);
|
||||
$customer->fill(Arr::only($data, $customer->getFillable()));
|
||||
$customer->hashcode = $crmCustomer->hashcode;
|
||||
if ($customer->trashed()) {
|
||||
$customer->restore();
|
||||
}
|
||||
$customer->email_verified_at = $crmCustomer->status ? now() : null;
|
||||
// ! Last connection sera null, pour identifier la deuxième connexion,
|
||||
// ! Pour accéder au partie du Klub.
|
||||
if ($customer->saveOrFail()) {
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
Session::flash('success', trans('front.messages.account_created_email_confirmation_sent'));
|
||||
}
|
||||
|
||||
return $customer;
|
||||
});
|
||||
} catch (ApiErrorException $e) {
|
||||
if ($e->getApiError()->equals(ApiError::customerExists)) {
|
||||
throw IlluminateValidationException::withMessages([
|
||||
'error' => trans('front.messages.email_already_in_use')
|
||||
]);
|
||||
}
|
||||
if ($e->getApiError()->equals(ApiError::validationFailed)) {
|
||||
throw IlluminateValidationException::withMessages([
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
}
|
||||
report($e);
|
||||
Log::error(__CLASS__ . '::create reached end of possibilities.');
|
||||
throw new \RuntimeException(__CLASS__ . '::create reached end of possibilities.');
|
||||
} catch (CrmValidationException $e) {
|
||||
throw IlluminateValidationException::withMessages([
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
} //end try
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the post register / login redirect path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function redirectPath()
|
||||
{
|
||||
return $this->authLoggedRedirectPath();
|
||||
}
|
||||
}
|
||||
122
app/Http/Controllers/Fo/Auth/ResetPasswordController.php
Normal file
122
app/Http/Controllers/Fo/Auth/ResetPasswordController.php
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Fo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Auth\Events\PasswordReset;
|
||||
use Illuminate\Contracts\Auth\PasswordBroker;
|
||||
use Illuminate\Contracts\Auth\StatefulGuard;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use LDC\LDCCRM\Exceptions\ApiErrorException;
|
||||
use LDC\LDCCRM\Exceptions\CrmException;
|
||||
use LDC\LDCCRM\Exceptions\ValidationException as ExceptionsValidationException;
|
||||
|
||||
class ResetPasswordController extends Controller
|
||||
{
|
||||
use ResetsPasswords;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest:frontend');
|
||||
$this->middleware('signed')->only('showResetForm');
|
||||
$this->middleware('throttle:6,1')->only('showResetForm');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
protected function guard(): StatefulGuard
|
||||
{
|
||||
return Auth::guard('frontend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the password reset view for the given token.
|
||||
*
|
||||
* If no token is present, display the link request form.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function showResetForm(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$token = $request->route()->parameter('token');
|
||||
|
||||
return view('theme::auth.passwords.reset')->with(
|
||||
['token' => $token, 'email' => $request->email]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the given user's password.
|
||||
*
|
||||
* @param \App\Models\Customer $customer
|
||||
* @param string $password
|
||||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException If something goes wrong.
|
||||
*/
|
||||
protected function resetPassword(\App\Models\Customer $customer, string $password): void
|
||||
{
|
||||
/** @var \LDC\LDCCRM\CrmApiV4 */
|
||||
$crm = app('crmAPI');
|
||||
|
||||
try {
|
||||
if (!($crmCustomer = $crm->getCustomer($customer->hashcode))) {
|
||||
throw ValidationException::withMessages([
|
||||
'error' => trans('Changement impossible, compte inexistant.')
|
||||
]);
|
||||
}
|
||||
$crmCustomer->password = $password;
|
||||
$crmCustomer->save();
|
||||
} catch (\TypeError | CrmException | ApiErrorException $e) {
|
||||
report($e);
|
||||
throw ValidationException::withMessages([
|
||||
'error' => trans('front.messages.unexpected_error_try_later')
|
||||
]);
|
||||
} catch (ExceptionsValidationException $e) {
|
||||
throw ValidationException::withMessages([
|
||||
'password' => $e->getMessage()
|
||||
]);
|
||||
}
|
||||
|
||||
$customer->setRememberToken(Str::random(60));
|
||||
|
||||
$customer->save();
|
||||
|
||||
event(new PasswordReset($customer));
|
||||
|
||||
$this->guard()->login($customer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the post register / login redirect path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function redirectPath(): string
|
||||
{
|
||||
return $this->authLoggedRedirectPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the broker to be used during password reset.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\PasswordBroker
|
||||
*/
|
||||
public function broker(): PasswordBroker
|
||||
{
|
||||
return Password::broker('customers');
|
||||
}
|
||||
}
|
||||
148
app/Http/Controllers/Fo/Auth/VerificationController.php
Normal file
148
app/Http/Controllers/Fo/Auth/VerificationController.php
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Fo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Customer;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
use Illuminate\Auth\Events\Verified;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Foundation\Auth\VerifiesEmails;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use LDC\LDCCRM\Enums\ApiError;
|
||||
use LDC\LDCCRM\Exceptions\ApiErrorException;
|
||||
use LDC\LDCCRM\Exceptions\CrmException;
|
||||
use LDC\LDCCRM\Exceptions\ValidationException;
|
||||
|
||||
class VerificationController extends Controller
|
||||
{
|
||||
use VerifiesEmails;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth:frontend')->except('verify');
|
||||
$this->middleware('signed')->only('verify');
|
||||
$this->middleware('throttle:6,1')->only('verify', 'resend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the email verification notice.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(Request $request): RedirectResponse|View
|
||||
{
|
||||
return $request->user('frontend')->hasVerifiedEmail()
|
||||
? redirect($this->redirectPath())
|
||||
: view('theme::auth.verify');
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the authenticated user's email address as verified.
|
||||
*
|
||||
* ! Overloaded trait
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException If request is invalid.
|
||||
*/
|
||||
public function verify(Request $request): JsonResponse|RedirectResponse
|
||||
{
|
||||
/** @var \App\Models\Customer */
|
||||
$user = Customer::findOrFail($request->route('id'));
|
||||
|
||||
if (!hash_equals((string) $request->route('id'), (string) $user->getKey())) {
|
||||
throw new AuthorizationException();
|
||||
}
|
||||
|
||||
if (!hash_equals((string) $request->route('hash'), sha1($user->getEmailForVerification()))) {
|
||||
throw new AuthorizationException();
|
||||
}
|
||||
|
||||
if ($user->hasVerifiedEmail()) {
|
||||
return $request->wantsJson()
|
||||
? new JsonResponse([], 204)
|
||||
: redirect($this->redirectPath());
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($user) {
|
||||
if ($user->markEmailAsVerified()) {
|
||||
$this->setCrmCustomerAsVerified($user);
|
||||
event(new Verified($user));
|
||||
}
|
||||
});
|
||||
|
||||
if ($response = $this->verified($request)) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
return $request->wantsJson()
|
||||
? new JsonResponse([], 204)
|
||||
: redirect($this->redirectPath())->with('verified', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* The user has been verified.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return mixed
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
*/
|
||||
protected function verified(Request $request)
|
||||
{
|
||||
// phpcs:enable
|
||||
return redirect($this->redirectPath())->with('success', trans(
|
||||
'front.messages.account_activated_can_play'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the post register / login redirect path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function redirectPath(): string
|
||||
{
|
||||
return response()->redirectToRoute('fo.participate')->getTargetUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Crm Customer active
|
||||
*
|
||||
* @param \App\Models\Customer $customer
|
||||
* @return void
|
||||
* @throws \Illuminate\Http\Exceptions\HttpResponseException In case of failure.
|
||||
*/
|
||||
private function setCrmCustomerAsVerified(Customer $customer): void
|
||||
{
|
||||
try {
|
||||
$customer->clearApiDataCache();
|
||||
$crmCustomer = $customer->api_data;
|
||||
$crmCustomer->activate();
|
||||
$customer->clearApiDataCache();
|
||||
} catch (ValidationException) {
|
||||
redirect($this->redirectPath())->with('error', trans(
|
||||
'front.messages.unexpected_error_try_later'
|
||||
))->throwResponse();
|
||||
} catch (CrmException | ApiErrorException $e) {
|
||||
if ($e->getApiError()->equals(ApiError::customerAlreadyActive)) {
|
||||
// * Ignore this and continue, as it may be activated via another CRM service.
|
||||
return;
|
||||
} else {
|
||||
report($e);
|
||||
redirect($this->redirectPath())->with('error', trans(
|
||||
'front.messages.unexpected_error_try_later'
|
||||
))->throwResponse();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
175
app/Http/Controllers/Fo/CustomerController.php
Normal file
175
app/Http/Controllers/Fo/CustomerController.php
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Fo\Customers\VerifyInformationsRequest;
|
||||
use App\Http\Requests\Fo\Customers\SingleOptinRequest;
|
||||
use App\Repositories\Fo\CrmRepository;
|
||||
use Illuminate\Contracts\Database\Eloquent\Builder;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Validation\ValidationException as IlluminateValidationException;
|
||||
use LDC\LDCCRM\Enums\ApiError;
|
||||
use LDC\LDCCRM\Exceptions\ApiErrorException;
|
||||
use LDC\LDCCRM\Exceptions\CrmException;
|
||||
use LDC\LDCCRM\Exceptions\ValidationException as CrmValidationException;
|
||||
use LDC\LDCCRM\Models\SingleOptin;
|
||||
|
||||
class CustomerController extends Controller
|
||||
{
|
||||
/** @var \App\Repositories\Fo\CrmRepository $crmRepository */
|
||||
private $crmRepository;
|
||||
|
||||
/**
|
||||
* ParticipateController
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->crmRepository = new CrmRepository();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify profil info form
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function profilVerify(): View
|
||||
{
|
||||
// ! Pas de Gate/Policies Ici volontairement, vu avec Vincent
|
||||
|
||||
/** @var \App\Models\Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
$crmCustomer = $customer->api_data;
|
||||
|
||||
return view('theme::auth.profil-verify', compact('crmCustomer'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Profile verify
|
||||
*
|
||||
* @param \App\Http\Requests\Fo\Customers\VerifyInformationsRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws IlluminateValidationException In case of any error validation or within the crm.
|
||||
*/
|
||||
public function profilVerifySubmit(VerifyInformationsRequest $request): RedirectResponse
|
||||
{
|
||||
// ! Pas de Gate/Policies Ici volontairement, vu avec Vincent
|
||||
try {
|
||||
return DB::transaction(function () use ($request) {
|
||||
// * --- FILL AND SAVE CUSTOMER
|
||||
/** @var \App\Models\Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
// * Màj, on ne mets pas à jour le mdp ou l'adresse email, juste les champs pour mesBr
|
||||
$customer->updateApiData(\array_merge(Arr::only(
|
||||
$request->validated(),
|
||||
[
|
||||
'firstname',
|
||||
'lastname',
|
||||
'birth_date',
|
||||
'address',
|
||||
'country',
|
||||
'city',
|
||||
'phone',
|
||||
'opt_in',
|
||||
]
|
||||
), ['postcode' => $request->input('postal_code')]));
|
||||
Session::flash('success', trans('front.messages.profile_updated_success'));
|
||||
|
||||
return response()->redirectToRoute('fo.participate');
|
||||
});
|
||||
} catch (CrmValidationException $e) {
|
||||
// * Local Validation failure
|
||||
throw IlluminateValidationException::withMessages([
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
} catch (ApiErrorException $e) {
|
||||
if ($e->getApiError()->equals(ApiError::validationFailed)) {
|
||||
throw IlluminateValidationException::withMessages([
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
}
|
||||
report($e);
|
||||
Log::error(__CLASS__ . '::update reached end of possibilities.');
|
||||
} catch (CrmException $e) {
|
||||
report($e);
|
||||
Log::error(__CLASS__ . '::error occured on calling crm.');
|
||||
throw IlluminateValidationException::withMessages([
|
||||
'error' => trans('Une erreur est survenue, veuillez réssayer plus tard')
|
||||
]);
|
||||
} //end try
|
||||
return back()->withInput()->withErrors(trans('front.messages.unexpected_error_try_later'));
|
||||
}
|
||||
|
||||
/**
|
||||
* View all customer winnig participations
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function viewWinningParticipations(): View
|
||||
{
|
||||
$this->authorize('viewWonList', \App\Models\Participation::class);
|
||||
|
||||
/** @var \App\Models\Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
// * Recupération des informations CRM
|
||||
/** @var \LDC\LDCCRM\Models\Customer*/
|
||||
$crmUser = $this->crmRepository->fetchCrmCustomer($customer);
|
||||
|
||||
/** @var \LDC\MESBR\MesBr */
|
||||
$mesBr = app('mesBrAPI');
|
||||
$brBasket = $mesBr->getBasket($crmUser);
|
||||
if (!empty($brBasket['coupons'])) {
|
||||
$canPrint = (collect($brBasket['coupons'])->sum('quantity') - collect($brBasket['coupons'])->sum('printed'));
|
||||
}
|
||||
|
||||
$winningList = $customer->participations()
|
||||
->with(['instantWin'])->where(function (Builder $q) {
|
||||
$q->whereHas('instantWin');
|
||||
})->get();
|
||||
|
||||
return view('theme::pages.participation.winning-participations', [
|
||||
'winningList' => $winningList,
|
||||
'canPrint' => $canPrint ?? null
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the CRM to add a single optin
|
||||
*
|
||||
* @param \App\Http\Requests\Fo\Customers\SingleOptinRequest $request
|
||||
* @return string|array|null|\Illuminate\Contracts\Translation\Translator
|
||||
* @throws \LDC\LDCCRM\Exceptions\ValidationException ValidationException.
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException BindingResolutionException.
|
||||
*/
|
||||
public function addOptIn(SingleOptinRequest $request)
|
||||
{
|
||||
try {
|
||||
SingleOptin::setStatus($request->email, true);
|
||||
return \response(trans("front.messages.newsletter_subscription_success"), 200);
|
||||
} catch (ApiErrorException $e) {
|
||||
// Il y a deja un customerInfo avec optin a true pour ce customer.
|
||||
if ($e->getApiError()->equals(ApiError::singleOptinCustomerExists)) {
|
||||
return trans('front.messages.newsletter_email_already_subscribed');
|
||||
}
|
||||
if (app()->bound('sentry')) {
|
||||
app('sentry')->captureException($e);
|
||||
}
|
||||
return \response(trans('front.messages.unexpected_error_try_later'), 404);
|
||||
} catch (CrmException $e) {
|
||||
if (app()->bound('sentry')) {
|
||||
app('sentry')->captureException($e);
|
||||
}
|
||||
return \response(trans('front.messages.unexpected_error_try_later'), 404);
|
||||
}
|
||||
}
|
||||
}
|
||||
90
app/Http/Controllers/Fo/DiscountController.php
Normal file
90
app/Http/Controllers/Fo/DiscountController.php
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Customer;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class DiscountController extends Controller
|
||||
{
|
||||
/**
|
||||
* Fetch PDF BR.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function fetchBrPdf(): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
/** @var \App\Models\Customer $customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
$pdf = $this->fetchBrPdfFromMesBr($customer);
|
||||
|
||||
if ($pdf === null) {
|
||||
\back()->withErrors([
|
||||
'coupon' => trans('front.messages.pdf_download_error')
|
||||
])->throwResponse();
|
||||
}
|
||||
|
||||
return redirect()->to(
|
||||
sprintf(
|
||||
"%s/basket/%s/print",
|
||||
config('mesbr.endpoint'),
|
||||
$pdf
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch coupons PDF.
|
||||
*
|
||||
* @param \App\Models\Customer $customer
|
||||
* @return string|null
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
|
||||
*/
|
||||
private function fetchBrPdfFromMesBr(Customer $customer): ?string
|
||||
{
|
||||
// phpcs:enable
|
||||
// * Phase - 1 Recupération des informations CRM
|
||||
/** @var \App\Models\Customer $customer */
|
||||
$customer = auth('frontend')->user();
|
||||
/** @var \LDC\LDCCRM\Models\Customer $crmCustomer */
|
||||
$crmCustomer = $customer->api_data;
|
||||
|
||||
try {
|
||||
/** @var \LDC\MESBR\MesBr */
|
||||
$mesBr = app('mesBrAPI');
|
||||
$result = $mesBr->getBasket($crmCustomer);
|
||||
$result = \is_object($result) ? (array) $result : $result;
|
||||
|
||||
if (Arr::get($result, 'status') !== "OK") {
|
||||
report(new \RuntimeException(
|
||||
\sprintf(
|
||||
'MESBR : Une erreur est survenue. Code : %s Message : %s',
|
||||
Arr::get($result, 'code') ?? 'Undefined',
|
||||
Arr::get($result, 'message') ?? 'Undefined',
|
||||
)
|
||||
));
|
||||
return null;
|
||||
}
|
||||
|
||||
// * La réponse est conforme ?
|
||||
$needed_fields = ['uuid'];
|
||||
if (!Arr::has($result, $needed_fields)) {
|
||||
report(new \RuntimeException(sprintf(
|
||||
'MESBR : Il manques des champs dans la réponse, attendu => %s, donné => %s',
|
||||
json_encode($needed_fields),
|
||||
json_encode($result),
|
||||
)));
|
||||
return null;
|
||||
}
|
||||
|
||||
// * Tout est OK
|
||||
return Arr::get($result, 'uuid') ?: null;
|
||||
} catch (\RuntimeException $e) {
|
||||
report($e);
|
||||
// * Retenter ?
|
||||
return null;
|
||||
} //end try
|
||||
}
|
||||
}
|
||||
95
app/Http/Controllers/Fo/HomeController.php
Normal file
95
app/Http/Controllers/Fo/HomeController.php
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\FaqQuestion;
|
||||
use App\Models\FaqTheme;
|
||||
use App\Models\Range;
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display home page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function home(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
if (!Gate::check('fo.gameEnabled')) {
|
||||
\session()->flash('warning', trans('front.messages.game_missing_required_elements'));
|
||||
}
|
||||
return view('theme::pages.home');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display products with game stickers
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @phpcs:ignore Squiz.Commenting.FunctionComment.EmptyThrows
|
||||
* @throws \Illuminate\Http\Exceptions\HttpResponseException
|
||||
*/
|
||||
public function showProducts(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
// ? Show product list authorized ?
|
||||
if (!Gate::allows('fo.showProducts')) {
|
||||
\response()->redirectToRoute('fo.homepage')->throwResponse();
|
||||
}
|
||||
|
||||
$rangeModelList = Range::query()->with('products')->orderBy('id')->get();
|
||||
return view('theme::pages.products', compact('rangeModelList'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display Faq page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function showFaq(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
// ? Show QA authorized ?
|
||||
if (!Gate::allows('fo.showFaq')) {
|
||||
\response()->redirectToRoute('fo.homepage')->throwResponse();
|
||||
}
|
||||
|
||||
$questionModelList = FaqQuestion::getCached();
|
||||
$themeModelList = FaqTheme::getCached();
|
||||
|
||||
return view('theme::pages.faq', compact(
|
||||
'questionModelList',
|
||||
'themeModelList'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the teaser page if it is activated
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function teaser(): \Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
|
||||
{
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
if (!$settings->should_display_teaser_page) {
|
||||
return redirect()->route('fo.homepage');
|
||||
}
|
||||
return view('theme::pages.teaser');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the end game page if it is activated
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function endGame(): \Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
|
||||
{
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
if (!$settings->should_display_end_page) {
|
||||
return redirect()->route('fo.homepage');
|
||||
}
|
||||
return view('theme::pages.end-game');
|
||||
}
|
||||
}
|
||||
308
app/Http/Controllers/Fo/ParticipateController.php
Normal file
308
app/Http/Controllers/Fo/ParticipateController.php
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Fo\Customers\CreateAccountRequest;
|
||||
use App\Http\Requests\Fo\ParticipateRequest;
|
||||
use App\Lib\Discount as LibDiscount;
|
||||
use App\Mail\Won\PrizeWonAdminMail;
|
||||
use App\Models\Customer;
|
||||
use App\Models\InstantWin;
|
||||
use App\Models\Participation;
|
||||
use App\Models\Settings;
|
||||
use App\Notifications\Customer\HasWonDiscount;
|
||||
use App\Notifications\Customer\HasWonInstantWin;
|
||||
use App\Repositories\Fo\CrmRepository;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class ParticipateController extends Controller
|
||||
{
|
||||
/** @var \App\Repositories\Fo\CrmRepository $crmRepository */
|
||||
private $crmRepository;
|
||||
/**
|
||||
* ParticipateController
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->crmRepository = new CrmRepository();
|
||||
$this->middleware(function (Request $request, callable $next) {
|
||||
$this->authorize('fo.gameEnabled');
|
||||
$this->assertUserHasEnoughInfoToUseMesBr();
|
||||
return $next($request);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Display participation form
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function participate(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
if (!Gate::check('participate', Participation::class)) {
|
||||
return view('theme::pages.participation.participation-exhausted');
|
||||
}
|
||||
return view('theme::pages.participation.participate');
|
||||
}
|
||||
|
||||
/**
|
||||
* Participate Method
|
||||
*
|
||||
* @param \App\Http\Requests\Fo\ParticipateRequest $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function participateSubmit(ParticipateRequest $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
// ! On verrouille le ou les instants gagnant
|
||||
/** @var \App\Models\InstantWin|null */
|
||||
$instantWin = InstantWin::query()->lockForUpdate()
|
||||
->where('available_at', '<', now())
|
||||
->whereDoesntHave('participation')
|
||||
->get()->sortBy('available_at')->first();
|
||||
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
|
||||
/** @var \App\Models\Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
/** @var \App\Models\Code|null */
|
||||
$code = $request->post('unique_code');
|
||||
/** @var \App\Models\Product|null */
|
||||
$product = $request->post('product');
|
||||
|
||||
// * Make new participation
|
||||
$participation = Participation::makeNew(
|
||||
app('clientIp'),
|
||||
$customer,
|
||||
$code,
|
||||
$product
|
||||
);
|
||||
|
||||
// * Si l'utilisateur actuel à déjà gagné un gros lot, pas d'instant gagnant.
|
||||
// ? As-t-on un instant gagnant ?
|
||||
if (Participation::customerAlreadyHasAnInstantWin($customer) or !$instantWin) {
|
||||
// * --- DISCOUNT WIN ---
|
||||
// ? Les BR sont activés ?
|
||||
if (!$settings->discounts_activated) {
|
||||
// * On enregistre la participation du joueur.
|
||||
$participation->save();
|
||||
|
||||
// * Pas de coupons disponibles, le joueur à perdu
|
||||
return view('theme::pages.participation.loose');
|
||||
}
|
||||
|
||||
// * Le joueur à gagné un coupon.
|
||||
/** @var \App\Lib\Discount Coupon aléatoire en fonction du ratio de chaque coupon */
|
||||
$discount = Arr::get(
|
||||
$settings->web_coupons,
|
||||
$this->getRandomWeightedElementIndex($settings->web_coupons)
|
||||
);
|
||||
|
||||
$this->setDiscountAsWon($customer, $discount);
|
||||
|
||||
// * Le joueur à remporté un coupon
|
||||
$participation->discount_code = (string) $discount->web_coupon_identifiant;
|
||||
// * On enregistre la participation du joueur.
|
||||
$participation->save();
|
||||
|
||||
$crmCustomer = $this->crmRepository->fetchCrmCustomer($customer);
|
||||
|
||||
$customer->notify(new HasWonDiscount(
|
||||
$discount,
|
||||
$crmCustomer->firstname
|
||||
));
|
||||
|
||||
return view('theme::pages.participation.won', compact('discount'));
|
||||
} //end if
|
||||
|
||||
// * --- INSTANT WIN ---
|
||||
// * On enregistre la participation du joueur.
|
||||
$participation->save();
|
||||
// * Le joueur à remporté un instant gagnant
|
||||
$instantWin->participation()->associate($participation);
|
||||
$instantWin->save();
|
||||
|
||||
$crmCustomer = $this->crmRepository->fetchCrmCustomer($customer);
|
||||
|
||||
// * Notify customer for his win
|
||||
$customer->notify(new HasWonInstantWin(
|
||||
$instantWin->prize,
|
||||
$crmCustomer->firstname
|
||||
));
|
||||
|
||||
// * Dispatch notification to mail list
|
||||
Mail::to($settings->notification_emails)->send(new PrizeWonAdminMail(
|
||||
$settings->name,
|
||||
$participation->created_at,
|
||||
$instantWin->prize->label,
|
||||
$crmCustomer,
|
||||
optional($code)->code_unique,
|
||||
optional($product)->ean_code
|
||||
));
|
||||
|
||||
return view('theme::pages.participation.won', [
|
||||
'prizeModel' => $instantWin->prize,
|
||||
'participationModel' => $participation,
|
||||
'crmCustomer' => $crmCustomer
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
// * --- PRIVATE METHODS ---
|
||||
|
||||
/**
|
||||
* Try Call CRM + MesBr to setup discount
|
||||
*
|
||||
* @param \App\Models\Customer $customer
|
||||
* @param LibDiscount $discount
|
||||
* @return void
|
||||
* @throws \Illuminate\Http\Exceptions\HttpResponseException If Any error occurs.
|
||||
* @phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
||||
*/
|
||||
private function setDiscountAsWon(Customer $customer, LibDiscount $discount): void
|
||||
{
|
||||
// phpcs:enable
|
||||
// * Phase - 1 Recupération des informations CRM
|
||||
/** @var \LDC\LDCCRM\Models\Customer*/
|
||||
$crmUser = $this->crmRepository->fetchCrmCustomer($customer);
|
||||
|
||||
// * Phase - 2 Mise à jour du coupon dans MesBr
|
||||
try {
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
|
||||
/** @var \LDC\MESBR\MesBr */
|
||||
$mesBr = app('mesBrAPI');
|
||||
|
||||
// * MaJ Customer
|
||||
/** @var string */
|
||||
$crm_customer_hashcode = retry(3, function () use ($mesBr, $crmUser) {
|
||||
/**
|
||||
* Parce que MesBr n'est pas fiable il faut retenter pour avoir
|
||||
* l'id client, des fois cet id sera dans hashcode...
|
||||
*
|
||||
* Id est necessaire pour update panier..
|
||||
*/
|
||||
$result = $mesBr->updateCustomer($crmUser->hashcode, $crmUser->email, $crmUser->country->label());
|
||||
if (optional($result)->status !== "OK") {
|
||||
throw new \RuntimeException(
|
||||
\sprintf(
|
||||
'MESBR : Une erreur est survenue. Code : %s Message : %s',
|
||||
$result->code ?? 'Undefined',
|
||||
$result->message ?? 'Undefined'
|
||||
)
|
||||
);
|
||||
}
|
||||
/** @var object|null */
|
||||
$crm_customer = optional($result)->customer;
|
||||
if (empty(optional($crm_customer)->hashcode)) {
|
||||
throw new \RuntimeException(
|
||||
'MESBR : Une erreur est survenue. Update Customer n\'as pas retourné le customer hashcode'
|
||||
);
|
||||
}
|
||||
|
||||
return $crm_customer->hashcode;
|
||||
}, 100);
|
||||
|
||||
// * Maj Panier
|
||||
$result = $mesBr->updateBasket(
|
||||
$crmUser,
|
||||
strval($discount->web_coupon_identifiant)
|
||||
);
|
||||
|
||||
if (Arr::get($result, 'status') === "OK") {
|
||||
// * La réponse est conforme ?
|
||||
$needed_fields = ['ref'];
|
||||
if (!Arr::has($result, $needed_fields)) {
|
||||
throw new \RuntimeException(sprintf(
|
||||
'MESBR : Il manques des champs dans la réponse, attendu => %s, donné => %s',
|
||||
json_encode($needed_fields),
|
||||
json_encode($result),
|
||||
));
|
||||
}
|
||||
|
||||
// * Tout est OK
|
||||
return;
|
||||
}
|
||||
|
||||
throw new \RuntimeException(
|
||||
\sprintf(
|
||||
'MESBR : Une erreur est survenue. Code : %s Message : %s',
|
||||
$result["code"] ?? 'Undefined',
|
||||
$result["message"] ?? 'Undefined'
|
||||
)
|
||||
);
|
||||
} catch (\RuntimeException $e) {
|
||||
report($e);
|
||||
// * Retenter ?
|
||||
back()->with('error', trans('front.messages.unexpected_error_try_later'))->throwResponse();
|
||||
} //end try
|
||||
|
||||
throw new \Error('Should not reach this point');
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that user has enough info filled on his profile to win a Discount
|
||||
* Or redirect him to the fill form
|
||||
* ! Also validates its birth date (because beeing an adult is required to participate)
|
||||
*
|
||||
* @return void
|
||||
* @throws \Illuminate\Http\Exceptions\HttpResponseException If customer data doest not validate
|
||||
* or and error occurs.
|
||||
*/
|
||||
private function assertUserHasEnoughInfoToUseMesBr(): void
|
||||
{
|
||||
|
||||
// * Valider que le client dispose des donnés requises pour MesBr
|
||||
try {
|
||||
/** @var \App\Models\Customer */
|
||||
$authUser = auth('frontend')->user();
|
||||
$crmCustomer = $this->crmRepository->fetchCrmCustomer($authUser);
|
||||
|
||||
// * On valide les données selon les critères du site
|
||||
$rules = collect((new CreateAccountRequest())->rules());
|
||||
Validator::make(
|
||||
[
|
||||
'birth_date' => $crmCustomer->birth_date,
|
||||
'address' => $crmCustomer->address,
|
||||
'postal_code' => $crmCustomer->postcode,
|
||||
'country' => $crmCustomer->country->value,
|
||||
'city' => $crmCustomer->city
|
||||
],
|
||||
[
|
||||
'birth_date' => $rules->get('birth_date'),
|
||||
'address' => $rules->get('address'),
|
||||
'postal_code' => $rules->get('postal_code'),
|
||||
'country' => $rules->get('country'),
|
||||
'city' => $rules->get('city')
|
||||
]
|
||||
)->validate();
|
||||
Session::remove('needCrmInfoUpdate');
|
||||
} catch (ValidationException) {
|
||||
response()->redirectToRoute('fo.profil.verify')
|
||||
->with('warning', trans(
|
||||
'front.messages.profile_incomplete_cannot_play'
|
||||
))->throwResponse();
|
||||
} catch (\Exception $e) {
|
||||
report($e);
|
||||
// * Retenter ?
|
||||
response()->redirectToRoute('fo.homepage')
|
||||
->with('error', trans('front.messages.unexpected_error_try_later'))
|
||||
->throwResponse();
|
||||
} //end try
|
||||
}
|
||||
|
||||
// * --- END PRIVATE METHODS ---
|
||||
}
|
||||
57
app/Http/Controllers/Fo/StaticPageController.php
Normal file
57
app/Http/Controllers/Fo/StaticPageController.php
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Enums\StaticPageType;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\StaticPage;
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
||||
class StaticPageController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show the rules view
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
public function reglement()
|
||||
{
|
||||
$staticPageModel = StaticPage::query()->where('type', StaticPageType::rules)->firstOrFail();
|
||||
return $this->viewStaticPage($staticPageModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the privacy view
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
public function charte()
|
||||
{
|
||||
$staticPageModel = StaticPage::query()->where('type', StaticPageType::confidentiality)->firstOrFail();
|
||||
return $this->viewStaticPage($staticPageModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the legals view
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
public function legals()
|
||||
{
|
||||
$staticPageModel = StaticPage::query()->where('type', StaticPageType::legals)->firstOrFail();
|
||||
return $this->viewStaticPage($staticPageModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a static page
|
||||
*
|
||||
* @param \App\Models\StaticPage $staticPageModel
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
private function viewStaticPage(StaticPage $staticPageModel): View
|
||||
{
|
||||
return view('theme::pages.static_page', [
|
||||
'staticPageModel' => $staticPageModel
|
||||
]);
|
||||
}
|
||||
}
|
||||
160
app/Http/Controllers/Fo/WinningProofController.php
Normal file
160
app/Http/Controllers/Fo/WinningProofController.php
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Fo\SubmitWinningProofRequest;
|
||||
use App\Mail\Won\WinningProofAdminMail;
|
||||
use App\Models\Participation;
|
||||
use App\Models\Settings;
|
||||
use App\Notifications\Customer\HasSubmitedWinProof;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Validation\ValidationException as IlluminateValidationException;
|
||||
use LDC\LDCCRM\Enums\ApiError;
|
||||
use LDC\LDCCRM\Exceptions\ApiErrorException;
|
||||
use LDC\LDCCRM\Exceptions\ValidationException as CrmValidationException;
|
||||
|
||||
class WinningProofController extends Controller
|
||||
{
|
||||
/**
|
||||
* WinningProofController
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware(function (Request $request, callable $next) {
|
||||
$this->authorize('fo.gameEnabled');
|
||||
$this->authorize('submitProof', $request->route('participation'));
|
||||
return $next($request);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Display winning proof form
|
||||
*
|
||||
* @param \App\Models\Participation $participation
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function displayForm(Participation $participation): View
|
||||
{
|
||||
$participation->load('instantWin.prize');
|
||||
|
||||
/** @var \App\Models\Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
$crmCustomer = $customer->api_data;
|
||||
|
||||
return view('theme::pages.participation.won-form-only', [
|
||||
'participationModel' => $participation,
|
||||
'prizeModel' => $participation->instantWin->prize,
|
||||
'crmCustomer' => $crmCustomer
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit winning proofs,
|
||||
* - 1 Met à jour le profil du customer (sans lui en faire part),
|
||||
* - 2 Save les pictures de preuve de gains
|
||||
* - 3 Envoi un mail au abonnés (settings notification_emails) avec les infos client
|
||||
*
|
||||
* @param \App\Http\Requests\Fo\SubmitWinningProofRequest $request
|
||||
* @param \App\Models\Participation $participation
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws IlluminateValidationException In case of failure.
|
||||
* @phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
||||
*/
|
||||
public function displayFormSubmit(
|
||||
SubmitWinningProofRequest $request,
|
||||
Participation $participation
|
||||
): RedirectResponse {
|
||||
// phpcs:enable
|
||||
try {
|
||||
return DB::transaction(function () use ($request, $participation) {
|
||||
$participation->load([
|
||||
'instantWin.prize',
|
||||
'code',
|
||||
'product'
|
||||
]);
|
||||
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
|
||||
// * --- PHASE 1 Update Crm Customer ---
|
||||
/** @var \App\Models\Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
$crmCustomer = $customer->api_data;
|
||||
/** @var array */
|
||||
$data = $request->validated();
|
||||
|
||||
// * This field is not standard in crm
|
||||
$data['postcode'] = Arr::get($data, 'postal_code');
|
||||
Arr::forget($data, 'postal_code');
|
||||
|
||||
$customer->updateApiData(Arr::only(
|
||||
$data,
|
||||
[
|
||||
'firstname',
|
||||
'lastname',
|
||||
'birth_date',
|
||||
'address',
|
||||
'address2',
|
||||
'postcode',
|
||||
'country',
|
||||
'city',
|
||||
'phone',
|
||||
'email',
|
||||
]
|
||||
));
|
||||
|
||||
// * --- PHASE 2 Update participation ---
|
||||
$participation->fill(Arr::only($request->validated(), [
|
||||
'barcode',
|
||||
'ticket',
|
||||
'sticker'
|
||||
]));
|
||||
$participation->save();
|
||||
|
||||
$customer->notify(new HasSubmitedWinProof($request->input('firstname')));
|
||||
|
||||
// * Dispatch notification to mail list
|
||||
Mail::to($settings->notification_emails)->send(new WinningProofAdminMail(
|
||||
$settings->name,
|
||||
$participation->created_at,
|
||||
$participation->instantWin->prize->label,
|
||||
$crmCustomer,
|
||||
optional($participation->code)->code_unique,
|
||||
optional($participation->product)->ean_code,
|
||||
$participation->sticker,
|
||||
$participation->ticket,
|
||||
$participation->barcode,
|
||||
));
|
||||
|
||||
return response()->redirectToRoute('fo.homepage')
|
||||
->with('success', trans(
|
||||
'front.messages.winning_proof_submitted_will_be_contacted'
|
||||
));
|
||||
});
|
||||
} catch (ApiErrorException $e) {
|
||||
if ($e->getApiError()->equals(ApiError::validationFailed)) {
|
||||
throw IlluminateValidationException::withMessages([
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
}
|
||||
report($e);
|
||||
Log::error(__CLASS__ . '::create reached end of possibilities.');
|
||||
throw new \RuntimeException(__CLASS__ . '::create reached end of possibilities.');
|
||||
} catch (CrmValidationException $e) {
|
||||
throw IlluminateValidationException::withMessages([
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
} //end try
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
class GainsController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
if (view()->exists('front.basic.gains')) {
|
||||
return view('front.basic.gains');
|
||||
}
|
||||
return redirect()->route('home');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
public function home()
|
||||
{
|
||||
return view('front.basic.home');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
class HowToPlayController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
if (view()->exists('front.basic.how-to-play')) {
|
||||
return view('front.basic.how-to-play');
|
||||
}
|
||||
return redirect()->route('home');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,275 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Mail\PasswordReset;
|
||||
use App\Mail\VerifyEmail;
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
|
||||
private $apiCrm;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest')->except('logout');
|
||||
$this->apiCrm = new \LDCCRM\ApiV1(config('crm.endpoint'), config('crm.token'));
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
return view('front.basic.login');
|
||||
}
|
||||
|
||||
public function authenticate(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'email' => 'required|email',
|
||||
'password' => 'required',
|
||||
]);
|
||||
|
||||
$email = filter_var($request->email, FILTER_SANITIZE_EMAIL);
|
||||
$password = $request->password;
|
||||
$remember = $request->remember !== null ? true : false;
|
||||
|
||||
$userLocal = User::where('email', $email)->first();
|
||||
|
||||
if ($userLocal) {
|
||||
if ($userLocal->email_verified === 1) {
|
||||
if ($userLocal->role > 2) {
|
||||
$connect = $this->apiCrm->loginCustomer($email, $password);
|
||||
|
||||
if ($connect->status === 'KO') {
|
||||
if ($connect->code === 500) {
|
||||
return back()->withInput($request->except("password"))
|
||||
->withErrors("La connexion est impossible pour le moment, veuillez réessayer plus tard.");
|
||||
} else {
|
||||
return back()->withInput($request->except("password"))
|
||||
->withErrors("Email ou mot de passe incorrect.");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$userLocal->email_verify_token = Str::uuid();
|
||||
$userLocal->save();
|
||||
Mail::to($email)->send(new VerifyEmail($userLocal));
|
||||
return back()->withInput($request->except("password"))
|
||||
->withErrors("Votre compte existe mais votre email n'est pas confirmé, merci de vérifier vos emails.");
|
||||
}//end if
|
||||
} else {
|
||||
$connect = $this->apiCrm->loginCustomer($email, $password);
|
||||
|
||||
if ($connect->status === 'OK') {
|
||||
$userLocal = User::create([
|
||||
'crm_id' => $connect->user->crm_id,
|
||||
'firstname' => $connect->user->firstname,
|
||||
'lastname' => $connect->user->lastname,
|
||||
'birth_date' => $connect->user->birth_date,
|
||||
'email' => $email,
|
||||
// TODO : MOTDEPASSE ???.
|
||||
'password' => Hash::make("MOTDEPASSE"),
|
||||
'address' => $connect->user->address,
|
||||
'address2' => $connect->user->address2,
|
||||
'town' => $connect->user->city,
|
||||
'postal_code' => $connect->user->postcode,
|
||||
'country' => $connect->user->country,
|
||||
'email_verified' => 1
|
||||
]);
|
||||
} else {
|
||||
// Compte existant mais non activé.
|
||||
if ($connect->code === 116) {
|
||||
$userLocal = User::create([
|
||||
'crm_id' => $connect->user->crm_id,
|
||||
'firstname' => $connect->user->firstname,
|
||||
'lastname' => $connect->user->lastname,
|
||||
'birth_date' => $connect->user->birth_date,
|
||||
'email' => $email,
|
||||
// TODO : MOTDEPASSE ???.
|
||||
'password' => Hash::make("MOTDEPASSE"),
|
||||
'address' => $connect->user->address,
|
||||
'address2' => $connect->user->address2,
|
||||
'town' => $connect->user->city,
|
||||
'postal_code' => $connect->user->postcode,
|
||||
'country' => $connect->user->country
|
||||
]);
|
||||
|
||||
$userLocal->email_verify_token = Str::uuid();
|
||||
$userLocal->save();
|
||||
Mail::to($email)->send(new VerifyEmail($userLocal));
|
||||
return back()->withInput($request->except("password"))
|
||||
->withErrors("Votre compte existe mais votre email n'est pas confirmé, merci de vérifier vos emails.");
|
||||
} elseif ($connect->code === 500) {
|
||||
return back()->withInput($request->except("password"))
|
||||
->withErrors("La connexion est impossible pour le moment, veuillez réessayer plus tard.");
|
||||
} else {
|
||||
return back()->withInput($request->except("password"))
|
||||
->withErrors("Email ou mot de passe incorrect.");
|
||||
} //end if
|
||||
} //end if
|
||||
}//end if
|
||||
|
||||
// TODO : Modifier avec separation guard.
|
||||
$tmpPwd = "MOTDEPASSE";
|
||||
if ($userLocal->role <= 2) {
|
||||
$tmpPwd = $password;
|
||||
}
|
||||
|
||||
if (Auth::attempt(["email" => $email, "password" => $tmpPwd], $remember)) {
|
||||
if ($userLocal->role <= 2) {
|
||||
return redirect()->route('bo.dashboard');
|
||||
}
|
||||
return redirect()->route('saisir-code');
|
||||
} else {
|
||||
return back()->withInput($request->except('password'))->withErrors('Les identifiants entrés sont incorrects.');
|
||||
}
|
||||
}
|
||||
|
||||
public function logout()
|
||||
{
|
||||
Auth::logout();
|
||||
return redirect()->route('home');
|
||||
}
|
||||
|
||||
public function confirmEmail($verifyToken)
|
||||
{
|
||||
$result = false;
|
||||
$user = User::where('email_verify_token', $verifyToken)->first();
|
||||
if (!$user) {
|
||||
return view('front.basic.confirm-email', compact('result'));
|
||||
}
|
||||
|
||||
$activation = $this->apiCrm->activateCustomer($user->crm_id);
|
||||
|
||||
if ($activation->status === 'OK') {
|
||||
$user->email_verified = 1;
|
||||
$user->email_verify_token = null;
|
||||
$user->save();
|
||||
$result = true;
|
||||
} else {
|
||||
// User already active.
|
||||
if ($activation->code === 110) {
|
||||
$user->email_verified = 1;
|
||||
$user->email_verify_token = null;
|
||||
$user->save();
|
||||
$result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return view('front.basic.confirm-email', compact('result'));
|
||||
}
|
||||
|
||||
public function forgotPassword(Request $request)
|
||||
{
|
||||
if ($request->tokenValid && $request->token) {
|
||||
$tokenValid = $request->tokenValid;
|
||||
$token = $request->token;
|
||||
return view('front.basic.forgot-password', compact('tokenValid', 'token'));
|
||||
}
|
||||
return view('front.basic.forgot-password');
|
||||
}
|
||||
|
||||
public function forgotPasswordReset(Request $request, $token)
|
||||
{
|
||||
if (!$request->hasValidSignature(false)) {
|
||||
return redirect()->route('login')
|
||||
->withErrors("Le lien de changement de votre mot de passe n'est plus valide, veuillez réessayer.");
|
||||
}
|
||||
$tokenValid = false;
|
||||
$user = User::where('password_token', $token)->first();
|
||||
if (!$user) {
|
||||
return redirect()->route('forgot-password', compact('tokenValid'))
|
||||
->withErrors('Le lien de changement du mot de passe est incorrect.');
|
||||
}
|
||||
$tokenValid = true;
|
||||
return redirect()->route('forgot-password', compact('tokenValid', 'token'));
|
||||
}
|
||||
|
||||
public function mailPassword(Request $request)
|
||||
{
|
||||
$email = filter_var($request->email, FILTER_SANITIZE_STRING);
|
||||
$user = User::where('email', $email)->first();
|
||||
|
||||
if (!$user) {
|
||||
$userCrm = $this->apiCrm->getCustomerByEmail($email);
|
||||
if ($userCrm->status === 'OK') {
|
||||
$user = User::create([
|
||||
'crm_id' => $userCrm->user->crm_id,
|
||||
'firstname' => $userCrm->user->firstname,
|
||||
'lastname' => $userCrm->user->lastname,
|
||||
'birth_date' => $userCrm->user->birth_date,
|
||||
'email' => $email,
|
||||
// TODO : MOTDEPASSE ???
|
||||
'password' => Hash::make("MOTDEPASSE"),
|
||||
'address' => $userCrm->user->address,
|
||||
'address2' => $userCrm->user->address2,
|
||||
'town' => $userCrm->user->city,
|
||||
'postal_code' => $userCrm->user->postcode,
|
||||
'country' => $userCrm->user->country,
|
||||
'email_verified' => 1
|
||||
]);
|
||||
|
||||
if ($userCrm->user->status === 0) {
|
||||
$user->email_verified = 0;
|
||||
$user->email_verify_token = Str::uuid();
|
||||
$user->save();
|
||||
Mail::to($email)->send(new VerifyEmail($user));
|
||||
return back()->withInput($request->except("password"))
|
||||
->withErrors("Votre compte existe mais votre email n'est pas confirmé, merci de vérifier vos emails.");
|
||||
}
|
||||
} else {
|
||||
if ($userCrm->code === 101) {
|
||||
return back()->withInput($request->only('email'))
|
||||
->withErrors("Le mail que vous avez entré n'est pas enregistré dans nos services.");
|
||||
} else {
|
||||
return back()->withErrors("Une erreur est survenue, veuillez réessayer plus tard.");
|
||||
}
|
||||
} //end if
|
||||
}//end if
|
||||
|
||||
$user->password_token = Str::uuid();
|
||||
$user->save();
|
||||
/** @var \App\Models\Settings $settings */
|
||||
$settings = app(Settings::class);
|
||||
Mail::to($email)->send(new PasswordReset($user, $settings));
|
||||
return redirect()->route('login')
|
||||
->with('success', 'Un mail de réinitialisation de votre mot de passe vous a été envoyé(e).');
|
||||
}
|
||||
|
||||
public function changePassword(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'password' => 'required|min:8|confirmed',
|
||||
]);
|
||||
|
||||
$user = User::where('password_token', filter_var($request->token, FILTER_SANITIZE_STRING))->first();
|
||||
if (!$user) {
|
||||
return back()->withErrors('Le lien de changement de votre mot de passe est incorrect, veuillez réessayer.');
|
||||
}
|
||||
|
||||
// TODO : Ajouter controle du contenu du mot de passe.
|
||||
$newPassword = $request->password;
|
||||
|
||||
$update = $this->apiCrm->changePwdCustomer($user->crm_id, $newPassword);
|
||||
|
||||
if ($update->status === 'OK') {
|
||||
$user->password_token = null;
|
||||
$user->save();
|
||||
return redirect()->route('login')
|
||||
->with('success', 'Vous pouvez désormais vous connecter avec votre nouveau mot de passe.');
|
||||
} else {
|
||||
if ($update->code === 123) {
|
||||
return back()
|
||||
->withErrors("Il semblerait que vous ayez déjà utilisé ce mot de passe pour votre compte. Veuillez réessayer en changeant de mot de passe.");
|
||||
} else {
|
||||
return back()->withErrors("Une erreur est survenue, veuillez réessayer plus tard.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Range;
|
||||
|
||||
class ProduitsController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$ranges = Range::with('products')->orderBy('id')->get();
|
||||
if (view()->exists('front.basic.produits-porteurs')) {
|
||||
return view('front.basic.produits-porteurs', compact('ranges'));
|
||||
}
|
||||
return redirect()->route('home');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,143 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Mail\VerifyEmail;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
use RegistersUsers;
|
||||
|
||||
// TODO : Utilité ??
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
private $apiCrm;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest');
|
||||
$this->apiCrm = new \LDCCRM\ApiV1(config('crm.endpoint'), config('crm.token'));
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
return view('front.basic.register-crm');
|
||||
}
|
||||
|
||||
public function register(Request $request)
|
||||
{
|
||||
|
||||
$request->validate([
|
||||
'lastname' => 'required|string|max:255',
|
||||
'firstname' => 'required|string|max:255',
|
||||
'birth_date' => 'required|string|max:10',
|
||||
'email' => 'required|string|email|max:255|unique:users|confirmed',
|
||||
'password' => 'required|string|min:8|confirmed',
|
||||
'address' => 'required|string|max:255',
|
||||
'address2' => 'max:255',
|
||||
'town' => 'required|string|max:255',
|
||||
'postal_code' => 'required|string|max:255',
|
||||
'country' => 'required|string|max:255',
|
||||
'reglement' => 'accepted',
|
||||
]);
|
||||
|
||||
$lastname = filter_var($request->lastname, FILTER_SANITIZE_STRING);
|
||||
$firstname = filter_var($request->firstname, FILTER_SANITIZE_STRING);
|
||||
$birthdate = $request->birth_date;
|
||||
$email = filter_var($request->email, FILTER_SANITIZE_EMAIL);
|
||||
$password = $request->password;
|
||||
$address = filter_var($request->address, FILTER_SANITIZE_STRING);
|
||||
$address2 = $request->address2 !== null ? filter_var($request->address2, FILTER_SANITIZE_STRING) : null;
|
||||
$town = filter_var($request->town, FILTER_SANITIZE_STRING);
|
||||
$postcode = filter_var($request->postal_code, FILTER_SANITIZE_STRING);
|
||||
$country = filter_var($request->country, FILTER_SANITIZE_STRING);
|
||||
$optin = $request->news !== null ? 1 : 0;
|
||||
$tokenMail = Str::uuid();
|
||||
|
||||
$MJ = Carbon::now()->subYears(18);
|
||||
|
||||
if ($this->isSQLDate($birthdate)) {
|
||||
$d = Carbon::createFromFormat('Y-m-d', $birthdate);
|
||||
if (!$d->lessThanOrEqualTo($MJ)) {
|
||||
return back()
|
||||
->withInput($request->except('password'))
|
||||
->withErrors("Vous devez être majeur pour vous inscrire au jeu.");
|
||||
}
|
||||
} elseif ($this->isFormDate($birthdate)) {
|
||||
$d = Carbon::createFromFormat('d/m/Y', $birthdate);
|
||||
if (!$d->lessThanOrEqualTo($MJ)) {
|
||||
return back()
|
||||
->withInput($request->except('password'))
|
||||
->withErrors("Vous devez être majeur pour vous inscrire au jeu.");
|
||||
}
|
||||
|
||||
$birthdate = $d->toDateString();
|
||||
} else {
|
||||
return back()
|
||||
->withInput($request->except('password'))
|
||||
->withErrors("Erreur sur le champs : date de naissance.");
|
||||
}
|
||||
|
||||
$crmUser = $this->apiCrm->createCustomer($email, $password, $firstname, $lastname, $optin, $birthdate, null, $address, $address2, $town, $postcode, ucfirst($country));
|
||||
|
||||
if ($crmUser->status === 'OK') {
|
||||
$user = User::create([
|
||||
'crm_id' => $crmUser->user->crm_id,
|
||||
'firstname' => $firstname,
|
||||
'lastname' => $lastname,
|
||||
'birth_date' => $birthdate,
|
||||
'email' => $email,
|
||||
'password' => Hash::make("MOTDEPASSE"), // TODO : ???
|
||||
'address' => $address,
|
||||
'address2' => $address2,
|
||||
'town' => $town,
|
||||
'postal_code' => $postcode,
|
||||
'country' => ucfirst($country),
|
||||
'email_verify_token' => $tokenMail,
|
||||
]);
|
||||
|
||||
Mail::to($email)->send(new VerifyEmail($user));
|
||||
|
||||
return redirect()->route('login')
|
||||
->with('success', "Pour finaliser votre inscription, merci de cliquer sur le lien qui vient de vous être envoyé par email<br>" .
|
||||
"Informations complémentaires :<br>" .
|
||||
"- Vérifiez vos spams : l'email de confirmation s'y trouve peut-être<br>" .
|
||||
"- Attention : le mail peut parfois mettre quelques minutes à vous parvenir<br>" .
|
||||
"- L'activation de votre compte doit se faire dans les 24 heures qui suivent la demande de création.");
|
||||
} else {
|
||||
if ($crmUser->code === 103) {
|
||||
return back()
|
||||
->withInput($request->except('password'))
|
||||
->withErrors("Un compte utilisateur est déjà associé à votre email.");
|
||||
} else {
|
||||
return back()
|
||||
->withInput($request->except('password'))
|
||||
->withErrors("Une erreur est survenue, merci de recommencer.");
|
||||
}
|
||||
}//end if
|
||||
}
|
||||
|
||||
private function isSQLDate($date)
|
||||
{
|
||||
if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/", $date)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function isFormDate($date)
|
||||
{
|
||||
if (preg_match("/^(0[1-9]|[1-2][0-9]|3[0-1])\/(0[1-9]|1[0-2])\/[0-9]{4}$/", $date)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Settings;
|
||||
|
||||
class TeaserController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$settings = app(Settings::class)
|
||||
->select('start_date', 'end_date', 'activated_teaser', 'teaser_end_activity')->first();
|
||||
if ($settings->activated_teaser === 1 && $settings->teaser_end_activity > now()) {
|
||||
return view('front.basic.teaser', compact('settings'));
|
||||
}
|
||||
return redirect()->route('home');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Content;
|
||||
|
||||
class ViewContentController extends Controller
|
||||
{
|
||||
public function reglement()
|
||||
{
|
||||
$content = Content::find(3);
|
||||
return view('front.basic.reglement', compact('content'));
|
||||
}
|
||||
|
||||
public function charte()
|
||||
{
|
||||
$content = Content::find(2);
|
||||
return view('front.basic.charte', compact('content'));
|
||||
}
|
||||
|
||||
public function legals()
|
||||
{
|
||||
$content = Content::find(1);
|
||||
return view('front.basic.legals', compact('content'));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,133 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Mail\NotifAdmin;
|
||||
use App\Mail\WinningProof;
|
||||
use App\Models\Participation;
|
||||
use App\Models\Settings;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class WinningProofController extends Controller
|
||||
{
|
||||
|
||||
private $apiCrm;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->apiCrm = new \LDCCRM\ApiV1(config('crm.endpoint'), config('crm.token'));
|
||||
}
|
||||
|
||||
public function sendWinningProof(Request $request)
|
||||
{
|
||||
// On récupère la participation gagnante en attente des infos
|
||||
$participation = Participation::where([
|
||||
['user_id', Auth::user()->id],
|
||||
['sticker', null],
|
||||
['ticket', null],
|
||||
['barcode', null]
|
||||
])->has('instantWin')->first();
|
||||
if (!$participation) {
|
||||
return redirect()->route('home');
|
||||
}
|
||||
|
||||
$request->validate([
|
||||
'lastname' => 'required|string|max:255',
|
||||
'firstname' => 'required|string|max:255',
|
||||
'address' => 'required|string|max:255',
|
||||
'address2' => 'max:255',
|
||||
'town' => 'required|string|max:255',
|
||||
'postal_code' => 'required|max:255',
|
||||
'country' => 'required|string|max:255',
|
||||
'phone' => 'required|string|max:50',
|
||||
'sticker' => 'required|mimes:jpeg,png,jpg,pdf|max:2048',
|
||||
'ticket' => 'required|mimes:jpeg,png,jpg,pdf|max:2048',
|
||||
'barcode' => 'required|mimes:jpeg,png,jpg,pdf|max:2048',
|
||||
]);
|
||||
|
||||
$lastname = filter_var($request->lastname, FILTER_SANITIZE_STRING);
|
||||
$firstname = filter_var($request->firstname, FILTER_SANITIZE_STRING);
|
||||
$address = filter_var($request->address, FILTER_SANITIZE_STRING);
|
||||
$address2 = $request->address2 !== null ? filter_var($request->address2, FILTER_SANITIZE_STRING) : null;
|
||||
$town = filter_var($request->town, FILTER_SANITIZE_STRING);
|
||||
$postalCode = filter_var($request->postal_code, FILTER_SANITIZE_STRING);
|
||||
$country = filter_var($request->country, FILTER_SANITIZE_STRING);
|
||||
$phone = filter_var($request->phone, FILTER_SANITIZE_STRING);
|
||||
$sticker = $request->sticker;
|
||||
$ticket = $request->ticket;
|
||||
$barcode = $request->barcode;
|
||||
|
||||
// Mise à jour de l'utilisateur en local.
|
||||
$user = User::find(Auth::user()->id);
|
||||
$user->lastname = $lastname;
|
||||
$user->firstname = $firstname;
|
||||
$user->address = $address;
|
||||
$user->address2 = $address2;
|
||||
$user->town = $town;
|
||||
$user->postal_code = $postalCode;
|
||||
$user->country = $country;
|
||||
$user->phone = $phone;
|
||||
$user->save();
|
||||
|
||||
// Mise à jour utilisateur dans la CRM.
|
||||
$update = $this->apiCrm->updateCustomer(
|
||||
$user->crm_id,
|
||||
$firstname,
|
||||
$lastname,
|
||||
null,
|
||||
null,
|
||||
$phone,
|
||||
$address,
|
||||
$address2,
|
||||
$town,
|
||||
$postalCode,
|
||||
ucfirst($country)
|
||||
);
|
||||
if ($update->status !== 'OK') {
|
||||
Log::warning('Erreur lors de la mise a jour du user (crm_id : ' . $user->crm_id .
|
||||
') - code : ' . $update->code . ' - message : ' . $update->message);
|
||||
Mail::to(config('mail.MAIL_ADMIN'))->send(new NotifAdmin(
|
||||
'CRM : Erreur lors de la mise a jour du user (crm_id : ' .
|
||||
$user->crm_id . ') - code : ' . $update->code . ' - message : ' . $update->message
|
||||
));
|
||||
}
|
||||
|
||||
$participationId = $participation->id;
|
||||
$stickerFileName = $participationId . '-sticker.' . $sticker->extension();
|
||||
$sticker->move(public_path('fichiers/preuve-de-gain/' . $participationId . '/'), $stickerFileName);
|
||||
$stickerPath = public_path() . '/fichiers/preuve-de-gain/' . $participationId . '/' . $stickerFileName;
|
||||
|
||||
$ticketFileName = $participationId . '-ticket.' . $ticket->extension();
|
||||
$ticket->move(public_path('fichiers/preuve-de-gain/' . $participationId . '/'), $ticketFileName);
|
||||
$ticketPath = public_path() . '/fichiers/preuve-de-gain/' . $participationId . '/' . $ticketFileName;
|
||||
|
||||
$barcodeFileName = $participationId . '-code-barre.' . $barcode->extension();
|
||||
$barcode->move(public_path('fichiers/preuve-de-gain/' . $participationId . '/'), $barcodeFileName);
|
||||
$barcodePath = public_path() . '/fichiers/preuve-de-gain/' . $participationId . '/' . $barcodeFileName;
|
||||
|
||||
$participation->sticker = $stickerFileName;
|
||||
$participation->ticket = $ticketFileName;
|
||||
$participation->barcode = $barcodeFileName;
|
||||
$participation->save();
|
||||
|
||||
/** @var \App\Models\Settings $settings */
|
||||
$settings = app(Settings::class);
|
||||
$mails = json_decode($settings->notification_emails);
|
||||
foreach ($mails as $mail) {
|
||||
Mail::to($mail->email)->send(new WinningProof(
|
||||
$stickerPath,
|
||||
$ticketPath,
|
||||
$barcodePath,
|
||||
$participation,
|
||||
$user,
|
||||
$settings
|
||||
));
|
||||
}
|
||||
|
||||
return view('front.basic.replay');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Settings;
|
||||
use App\Models\Reduction;
|
||||
|
||||
class re7Controller extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('re7');
|
||||
}
|
||||
|
||||
public function teaser()
|
||||
{
|
||||
$settings = app(Settings::class)
|
||||
->select('start_date', 'end_date', 'activated_teaser', 'teaser_end_activity')->first();
|
||||
return view('front.basic.teaser', compact('settings'));
|
||||
}
|
||||
|
||||
public function prizeMail()
|
||||
{
|
||||
return view('front.basic.prize-mail');
|
||||
}
|
||||
|
||||
public function reductionMail()
|
||||
{
|
||||
return view('front.basic.reduction-mail');
|
||||
}
|
||||
|
||||
public function br()
|
||||
{
|
||||
$settings = app(Settings::class);
|
||||
$coupon = $this->getRandomCoupon($settings);
|
||||
$crmCoupon = new Reduction();
|
||||
return view('front.basic.reduction', compact('coupon', 'crmCoupon'));
|
||||
}
|
||||
|
||||
public function gain1()
|
||||
{
|
||||
return view('front.basic.gain1');
|
||||
}
|
||||
|
||||
public function gain2()
|
||||
{
|
||||
return view('front.basic.gain2');
|
||||
}
|
||||
|
||||
|
||||
private function getRandomCoupon($settings)
|
||||
{
|
||||
$webCoupons = json_decode($settings->web_coupons);
|
||||
if (count($webCoupons) > 1) {
|
||||
$lots = [];
|
||||
foreach ($webCoupons as $webCoupon) {
|
||||
$lots[] = $webCoupon;
|
||||
}
|
||||
foreach ($lots as $lot) {
|
||||
for ($i = 0; $i < $lot->percentage; $i++) {
|
||||
$tmp[] = $lot;
|
||||
}
|
||||
}
|
||||
shuffle($tmp);
|
||||
return $tmp[0];
|
||||
} else {
|
||||
return $webCoupons[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,12 +11,13 @@ class Kernel extends HttpKernel
|
|||
*
|
||||
* These middleware are run during every request to your application.
|
||||
*
|
||||
* @var array
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $middleware = [
|
||||
\App\Http\Middleware\TrustHosts::class,
|
||||
\App\Http\Middleware\TrustProxies::class,
|
||||
\Fruitcake\Cors\HandleCors::class,
|
||||
\App\Http\Middleware\CheckForMaintenanceMode::class,
|
||||
\Illuminate\Http\Middleware\HandleCors::class,
|
||||
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\App\Http\Middleware\TrimStrings::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
|
|
@ -25,20 +26,23 @@ class Kernel extends HttpKernel
|
|||
/**
|
||||
* The application's route middleware groups.
|
||||
*
|
||||
* @var array
|
||||
* @var array<string, array<int, string>>
|
||||
*/
|
||||
protected $middlewareGroups = [
|
||||
'web' => [
|
||||
'htmlsanitize',
|
||||
\App\Http\Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
\App\Http\Middleware\SecureHeaders::class,
|
||||
\App\Http\Middleware\CheckThemeVersion::class
|
||||
],
|
||||
|
||||
'api' => [
|
||||
'throttle:60,1',
|
||||
\Illuminate\Routing\Middleware\ThrottleRequests::class . ':api',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
];
|
||||
|
|
@ -48,22 +52,20 @@ class Kernel extends HttpKernel
|
|||
*
|
||||
* These middleware may be assigned to groups or used individually.
|
||||
*
|
||||
* @var array
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $routeMiddleware = [
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
'game-date' => \App\Http\Middleware\GameCheckDate::class,
|
||||
'is-admin' => \App\Http\Middleware\isAdmin::class,
|
||||
'is-super-admin' => \App\Http\Middleware\isSuperAdmin::class,
|
||||
're7' => \App\Http\Middleware\re7Middleware::class,
|
||||
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
||||
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
|
||||
'check-game-status' => \App\Http\Middleware\CheckGameStatus::class,
|
||||
'signed' => \App\Http\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
'htmlsanitize' => \App\Http\Middleware\HtmlSanitizer::class,
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,19 +3,37 @@
|
|||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
|
||||
class Authenticate extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the path the user should be redirected to when they are not authenticated.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return string|null
|
||||
*/
|
||||
protected function redirectTo($request)
|
||||
protected function redirectTo(Request $request): ?string
|
||||
{
|
||||
if (! $request->expectsJson()) {
|
||||
return route('login');
|
||||
$logins = [
|
||||
'backend' => route('bo.login')
|
||||
];
|
||||
if (!$request->expectsJson()) {
|
||||
// * Notify must login
|
||||
Session::flash('warning', trans('Veuillez vous connecter pour continuer'));
|
||||
|
||||
foreach ($request->route()->gatherMiddleware() as $middleware) {
|
||||
if (\is_string($middleware) and strpos($middleware, 'auth:') !== false) {
|
||||
$route = $logins[str_replace('auth:', '', $middleware)] ?? null;
|
||||
if ($route) {
|
||||
return $route;
|
||||
}
|
||||
}
|
||||
}
|
||||
return route('fo.login');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode as Middleware;
|
||||
|
||||
class CheckForMaintenanceMode extends Middleware
|
||||
{
|
||||
|
||||
/**
|
||||
* The URIs that should be reachable while maintenance mode is enabled.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
||||
38
app/Http/Middleware/CheckGameStatus.php
Normal file
38
app/Http/Middleware/CheckGameStatus.php
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CheckGameStatus
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* * Check with game settings which page should be shown and redirect if needed.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
* @throws \RuntimeException If tha game has an unhandled state.
|
||||
*/
|
||||
public function handle(Request $request, \Closure $next)
|
||||
{
|
||||
/** @var \App\Models\Settings $settings */
|
||||
$settings = app(Settings::class);
|
||||
|
||||
return match (true) {
|
||||
// * End page
|
||||
$settings->should_display_end_page => redirect()->route('fo.end'),
|
||||
// * Teaser
|
||||
$settings->should_display_teaser_page => redirect()->route('fo.teaser'),
|
||||
// * Game is ended
|
||||
$settings->game_has_ended => redirect($settings->redirect_close),
|
||||
// * Game has started
|
||||
$settings->game_has_begun => $next($request),
|
||||
// * The game will begun, but has no teaser activated.
|
||||
default => redirect($settings->redirect_close)
|
||||
};
|
||||
}
|
||||
}
|
||||
48
app/Http/Middleware/CheckThemeVersion.php
Normal file
48
app/Http/Middleware/CheckThemeVersion.php
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class CheckThemeVersion
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request):(\Symfony\Component\HttpFoundation\Response) $next
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.IncorrectTypeHint
|
||||
*/
|
||||
public function handle(Request $request, \Closure $next): Response
|
||||
{
|
||||
// phpcs:enable
|
||||
|
||||
if (!app()->runningInConsole()) {
|
||||
$appInfos = Cache::remember('composer', 84600, function () {
|
||||
return json_decode(File::get(\app_path('../composer.json')));
|
||||
});
|
||||
// * Assert theme version does not diverge more than minor
|
||||
$appVer = Str::of($appInfos->version)->explode('.');
|
||||
$themeVer = Str::of(config('theme.version'))->explode('.');
|
||||
if (
|
||||
// * Major check
|
||||
Arr::get($appVer, 0) !== Arr::get($themeVer, 0) or
|
||||
// * Patch check
|
||||
Arr::get($appVer, 1) !== Arr::get($themeVer, 1)
|
||||
) {
|
||||
Session::flash('warning', trans(
|
||||
'Ce thème n\'a semble t-il pas été vérifié pour cette version du moteur'
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
|
@ -6,13 +6,10 @@ use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
|
|||
|
||||
class EncryptCookies extends Middleware
|
||||
{
|
||||
|
||||
/**
|
||||
* The names of the cookies that should not be encrypted.
|
||||
*
|
||||
* @var array
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
protected $except = [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,40 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Models\Settings;
|
||||
use Closure;
|
||||
|
||||
class GameCheckDate
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
/** @var \App\Models\Settings $settings */
|
||||
$settings = app(Settings::class);
|
||||
|
||||
// Check si le teaser est actif
|
||||
if ($settings->start_date > now()) {
|
||||
if ($settings->activated_teaser === 1 && $settings->teaser_end_activity > now()) {
|
||||
return redirect()->route('teaser');
|
||||
}
|
||||
return redirect($settings->redirect_close);
|
||||
}
|
||||
|
||||
// Check si le jeu est terminé
|
||||
if ($settings->end_date < now()) {
|
||||
if ($settings->activated_close_page === 1 && $settings->close_page_active_date > now()) {
|
||||
return redirect()->route('end');
|
||||
}
|
||||
return redirect($settings->redirect_close);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
61
app/Http/Middleware/HtmlSanitizer.php
Normal file
61
app/Http/Middleware/HtmlSanitizer.php
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class HtmlSanitizer
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string|array ...$params
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function handle(Request $request, \Closure $next, string|array ...$params): Response
|
||||
{
|
||||
$inputs = $request->all();
|
||||
/** @var callable|null */
|
||||
$cleanInput = null;
|
||||
$cleanInput = function (
|
||||
null|string|array &$input,
|
||||
string $name,
|
||||
?string $rootName = null
|
||||
) use (
|
||||
$params,
|
||||
&$cleanInput
|
||||
): void {
|
||||
// * Nested element array
|
||||
if (is_array($input)) {
|
||||
array_walk_recursive($input, $cleanInput, $name);
|
||||
}
|
||||
if (!is_string($input)) {
|
||||
return;
|
||||
}
|
||||
if (in_array($name, $params) or in_array($rootName ?? $name, $params)) {
|
||||
// ? Is a json input ?
|
||||
if ($isJson = \json_decode($input, true) and is_array($isJson)) {
|
||||
// ! Decode each json field recursive.
|
||||
\array_walk_recursive($isJson, function (string|array &$item) {
|
||||
if (\is_string($item)) {
|
||||
$item = clean($item);
|
||||
$item = ToolboxHelper::stripCkEditorSchemesOnMediaInputs($item);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$input = clean($input);
|
||||
$input = ToolboxHelper::stripCkEditorSchemesOnMediaInputs($input);
|
||||
}
|
||||
} else {
|
||||
$input = strip_tags($input);
|
||||
}
|
||||
};
|
||||
\array_walk($inputs, $cleanInput);
|
||||
$request->merge($inputs);
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
15
app/Http/Middleware/PreventRequestsDuringMaintenance.php
Normal file
15
app/Http/Middleware/PreventRequestsDuringMaintenance.php
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
|
||||
|
||||
class PreventRequestsDuringMaintenance extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be reachable while maintenance mode is enabled.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [];
|
||||
}
|
||||
|
|
@ -2,24 +2,40 @@
|
|||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Closure;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class RedirectIfAuthenticated
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string|null $guard
|
||||
* @return mixed
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
* @param string|null ...$guards
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* @throws \RuntimeException If guard is unhandled.
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.IncorrectTypeHint
|
||||
*/
|
||||
public function handle($request, Closure $next, $guard = null)
|
||||
public function handle(Request $request, \Closure $next, ...$guards): Response
|
||||
{
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect(RouteServiceProvider::HOME);
|
||||
// phpcs:enable phpcs:disable
|
||||
$guards = empty($guards) ? [null] : $guards;
|
||||
|
||||
foreach ($guards as $guard) {
|
||||
if (auth($guard)->check()) {
|
||||
switch ($guard) {
|
||||
case 'frontend':
|
||||
return \redirect()->route('fo.homepage');
|
||||
case 'backend':
|
||||
if (!$request->routeIs('bo.*')) {
|
||||
continue 2;
|
||||
}
|
||||
return \redirect()->route('bo.dashboard');
|
||||
default:
|
||||
throw new \RuntimeException("Unhandled guard `{$guard}` .");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
|
|
|
|||
97
app/Http/Middleware/SecureHeaders.php
Normal file
97
app/Http/Middleware/SecureHeaders.php
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Illuminate\Support\Facades\Vite;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class SecureHeaders
|
||||
{
|
||||
private $unwantedHeaderList = [
|
||||
'X-Powered-By',
|
||||
'Server',
|
||||
];
|
||||
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
// * For Vite DEV
|
||||
$host = \parse_url((string) \config('app.url'), \PHP_URL_HOST);
|
||||
|
||||
$viteDevOrigin = config('app.debug') && \is_string($host) && $host !== '' ? "https://{$host}:4443" : null;
|
||||
$viteDevSocket = config('app.debug') && \is_string($host) && $host !== '' ? "wss://{$host}:4443" : null;
|
||||
|
||||
View::share('nonce', $nonce = Vite::useCspNonce());
|
||||
|
||||
// * For VueJS dev tool to execute
|
||||
$jsDev = config('app.debug') ? "'unsafe-eval' 'unsafe-inline'" : "'nonce-{$nonce}' 'strict-dynamic'";
|
||||
$scheme = config('app.env') === 'local' ? 'http' : 'https';
|
||||
$reportUri = Route::has('cspReportUri') ? \sprintf(' report-uri %s ;', \parse_url(route('cspReportUri'), \PHP_URL_PATH)) : '';
|
||||
|
||||
$this->removeUnwantedHeaders($this->unwantedHeaderList);
|
||||
$response = $next($request);
|
||||
|
||||
$response->headers->set('Referrer-Policy', 'no-referrer-when-downgrade');
|
||||
$response->headers->set('X-Content-Type-Options', 'nosniff');
|
||||
$response->headers->set('X-XSS-Protection', '1; mode=block');
|
||||
$response->headers->set('X-Frame-Options', 'SAMEORIGIN');
|
||||
$response->headers->set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains;');
|
||||
|
||||
// Utilisation de array_filter pour ne pas inclure les valeurs null en production
|
||||
$cspPolicies = [
|
||||
"default-src 'none';",
|
||||
"manifest-src 'self';",
|
||||
"connect-src 'self' blob: " . implode(' ', array_filter([
|
||||
$viteDevSocket,
|
||||
$viteDevOrigin,
|
||||
'https://yl.s-web.fr'
|
||||
])) . ';',
|
||||
"img-src 'self' data: blob: " . implode(' ', array_filter([
|
||||
$viteDevOrigin,
|
||||
])) . ';',
|
||||
"object-src 'self';",
|
||||
"frame-src 'self' " . implode(' ', [
|
||||
'https://www.google.com/recaptcha/',
|
||||
'https://recaptcha.google.com/recaptcha/',
|
||||
'https://www.google.com/maps/'
|
||||
]) . ';',
|
||||
"font-src 'self' data: " . implode(' ', array_filter([
|
||||
$viteDevOrigin,
|
||||
'https://fonts.gstatic.com' // <-- Point-virgule retiré ici
|
||||
])) . ';',
|
||||
"style-src 'self' 'unsafe-inline' " . implode(' ', array_filter([
|
||||
'https://cdnjs.cloudflare.com',
|
||||
'https://fonts.googleapis.com',
|
||||
'https://cdn.jsdelivr.net',
|
||||
'https://use.fontawesome.com',
|
||||
$viteDevOrigin,
|
||||
])) . ';',
|
||||
"script-src 'self' {$jsDev} " . implode(' ', array_filter([
|
||||
'https:',
|
||||
'blob:',
|
||||
'https://www.googletagmanager.com',
|
||||
'https://cdnjs.cloudflare.com',
|
||||
"$scheme://www.google-analytics.com",
|
||||
$viteDevOrigin,
|
||||
])) . ';'
|
||||
];
|
||||
|
||||
$response->headers->set(
|
||||
'Content-Security-Policy',
|
||||
implode(' ', $cspPolicies) . $reportUri
|
||||
);
|
||||
$response->headers->set('Feature-Policy', 'fullscreen \'self\';');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function removeUnwantedHeaders(array $headerList): void
|
||||
{
|
||||
foreach ($headerList as $header) {
|
||||
header_remove($header);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,13 +6,13 @@ use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
|
|||
|
||||
class TrimStrings extends Middleware
|
||||
{
|
||||
|
||||
/**
|
||||
* The names of the attributes that should not be trimmed.
|
||||
*
|
||||
* @var array
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ class TrustHosts extends Middleware
|
|||
/**
|
||||
* Get the host patterns that should be trusted.
|
||||
*
|
||||
* @return array
|
||||
* @return array<int, string|null>
|
||||
*/
|
||||
public function hosts()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,23 +2,27 @@
|
|||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Fideloper\Proxy\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Middleware\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
{
|
||||
|
||||
/**
|
||||
* The trusted proxies for this application.
|
||||
*
|
||||
* @var array|string|null
|
||||
* @var array<int, string>|string|null
|
||||
*/
|
||||
protected $proxies;
|
||||
protected $proxies = '*';
|
||||
|
||||
/**
|
||||
* The headers that should be used to detect proxies.
|
||||
*
|
||||
* @var int
|
||||
* @var integer
|
||||
*/
|
||||
protected $headers = Request::HEADER_X_FORWARDED_ALL;
|
||||
protected $headers =
|
||||
Request::HEADER_X_FORWARDED_FOR |
|
||||
Request::HEADER_X_FORWARDED_HOST |
|
||||
Request::HEADER_X_FORWARDED_PORT |
|
||||
Request::HEADER_X_FORWARDED_PROTO |
|
||||
Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||
}
|
||||
|
|
|
|||
15
app/Http/Middleware/ValidateSignature.php
Normal file
15
app/Http/Middleware/ValidateSignature.php
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Routing\Middleware\ValidateSignature as Middleware;
|
||||
|
||||
class ValidateSignature extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the query string parameters that should be ignored.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [];
|
||||
}
|
||||
|
|
@ -6,13 +6,12 @@ use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
|
|||
|
||||
class VerifyCsrfToken extends Middleware
|
||||
{
|
||||
|
||||
/**
|
||||
* The URIs that should be excluded from CSRF verification.
|
||||
*
|
||||
* @var array
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
'/csp-report'
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class isAdmin
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$role = Auth::user()->role;
|
||||
if ($role === 1 || $role === 2) {
|
||||
return $next($request);
|
||||
}
|
||||
abort(404, "Cette page n'existe pas.");
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue