Compare commits

..

153 commits

Author SHA1 Message Date
Vincent BRIDIER
c5ef81f668 Merge branch 'trunk' 2026-10-23 15:30:00 +02:00
Vincent BRIDIER
4fcc529864 Merge branch 'develop' into trunk 2026-10-23 15:29:41 +02:00
Vincent BRIDIER
bfbf4e9e01 feat: Change Apache PID 2026-10-23 15:29:33 +02:00
K.
500f127090 Merge branch 'hotfix' into 'master'
Hotfix

See merge request ldc-web/projets/jeusselin!31
2026-10-22 15:51:59 +00:00
Jeremy Munsch
54848f4be6
chore: bump php deps to 8.5 2026-10-22 17:43:14 +02:00
Jeremy Munsch
23b40f4d63
build: bump php version 2026-10-22 17:43:05 +02:00
Noah Lancien
250058c085 Merge branch 'develop' into trunk 2026-10-22 17:37:30 +02:00
Noix
b52e4d2747 Merge branch 'bump-php' into 'develop'
Bump php

See merge request ldc-web/projets/jeusselin!30
2026-10-22 15:36:06 +00:00
Jeremy Munsch
883060e2dd
chore: bump php deps to 8.5 2026-10-22 17:23:08 +02:00
Jeremy Munsch
b8005a2a04
build: bump php version 2026-10-22 17:22:17 +02:00
K Muller
d8428b494e Merge branch 'develop' into trunk 2026-10-08 13:06:04 +02:00
Karl M'muller
470a84ae86 Merge branch 'fix-wysiwyg' into 'develop'
fix: 🐛 missing exclude sanitize html on news->content

See merge request ldc-web/projets/jeusselin!27
2026-10-08 11:05:04 +00:00
K Muller
8d281c2159 fix: 🐛 missing exclude sanitize html on news->content 2026-10-05 11:23:26 +02:00
Noah Lancien
a8426f80c6 Merge branch 'develop' into trunk 2026-10-01 10:37:41 +02:00
Noix
872332ea9a Merge branch 'issue-21' into 'develop'
feat: ✨ update info on cantact-us page

See merge request ldc-web/projets/jeusselin!26
2026-10-01 08:31:26 +00:00
Abdel LAMRANI
7c134c1fb2 feat: ✨ update info on cantact-us page 2026-09-29 09:30:30 +02:00
Noah Lancien
1c18491a86 Merge branch 'develop' into trunk 2026-09-28 11:08:04 +02:00
Noah Lancien
71b8339d96 fix: 🐛 fix compilation for prod 2026-09-28 11:07:24 +02:00
Noah Lancien
fcf49ba582 Merge branch 'develop' into trunk 2026-09-25 16:58:40 +02:00
Noix
968ee32e8d Merge branch 'create-customer' into 'develop'
fix: 🐛 add missing fields when creating local customer when exists in CRM #30

See merge request ldc-web/projets/jeusselin!20
2026-09-25 10:43:57 +00:00
Noix
a41085e550 Merge branch 'attempt-null' into 'develop'
fix: 🐛 determines whether show cotations or not when the base is empty #32

See merge request ldc-web/projets/jeusselin!21
2026-09-25 10:16:20 +00:00
Noix
040efd9ec3 Merge branch 'issue-12' into 'develop'
feat: ✨ handle image on general config

See merge request ldc-web/projets/jeusselin!25
2026-09-25 10:15:34 +00:00
Noix
4785300c85 Merge branch 'issue-24' into 'develop'
fix: 🐛 filter and show objectives

See merge request ldc-web/projets/jeusselin!24
2026-09-25 10:13:56 +00:00
Noix
74692d7664 Merge branch 'issue-13' into 'develop'
feat: ✨ update section

See merge request ldc-web/projets/jeusselin!23
2026-09-25 10:13:29 +00:00
Abdel LAMRANI
0b33324ff5 add alt and title 2026-09-24 16:41:59 +02:00
Abdel LAMRANI
4c45312724 feat: ✨ handle image on general config 2026-09-24 16:16:23 +02:00
Abdel LAMRANI
8a28d31e5f bug: 🐛 fix filter and show objectives 2026-09-24 12:37:43 +02:00
Abdel LAMRANI
0e430f84d0 feat: ✨ update section 2026-09-23 15:56:57 +02:00
Noah Lancien
c9178a139d Merge branch 'develop' into trunk 2026-09-10 12:32:28 +02:00
Noix
159b96b8db Merge branch '27-add-missing-links' into 'develop'
feat: ✨ add missing links to register page

See merge request ldc-web/projets/jeusselin!22
2026-09-10 10:29:01 +00:00
Corentin Huet
3a7b4a9bf2 feat: ✨ add missing links to register page 2026-09-02 15:05:42 +02:00
Alexis Gousseau
8346e604e3
fix: 🐛 determines whether show cotations or not when the base is empty #32 2026-08-04 17:15:14 +02:00
Alexis Gousseau
b60f61ad1f
fix: 🐛 add missing fields when update local customer when exists in CRM #30 #31 2026-08-04 15:16:05 +02:00
K Muller
09959e412b Merge branch 'trunk' 2026-07-31 14:04:46 +02:00
K Muller
76824459f8 Merge branch 'develop' into trunk 2026-07-31 14:04:30 +02:00
Karl M'muller
9a0c18b6dc Merge branch '28-disconnect' into 'develop'
fix: 🐛 disconnect bouton was broken

See merge request ldc-web/projets/jeusselin!19
2026-07-31 12:03:35 +00:00
Noah Lancien
dcf00f61ac fix: 🐛 disconnect bouton was broken 2026-07-30 16:57:03 +02:00
K Muller
6ea7a4117f Merge branch 'trunk' 2026-07-17 15:39:05 +02:00
K Muller
4ea9f35108 Merge branch 'develop' into trunk 2026-07-17 14:31:42 +02:00
Karl M'muller
e3eb3167ec Merge branch 'issue-25' into 'develop'
fix: 🐛 error with trash customer model

See merge request ldc-web/projets/jeusselin!18
2026-07-17 12:31:05 +00:00
K Muller
89db64859b fix: 🐛 error with trash customer model 2026-07-17 14:01:31 +02:00
Noix
702ea23e02 Merge branch 'hotfix' into 'master'
HOTFIX -> à répliquer sur Develop, fix: Fixes #23 correction sur l'affichage des dates isoFormat

See merge request ldc-web/projets/jeusselin!16
2026-05-04 15:16:31 +00:00
Jeremy Munsch
4501d36a40
fix: Fixes #23 correction sur l'affichage des dates isoFormat 2026-05-04 12:00:46 +02:00
Noah Lancien
a10ff94d4a Merge branch 'trunk' 2026-04-24 11:36:44 +02:00
Noah Lancien
6583a8f01e Merge branch 'develop' into trunk 2026-04-24 11:36:31 +02:00
Noah Lancien
921dafcd82 fix: 🐛 formatLocalized is removed 2026-04-24 11:36:18 +02:00
Noah Lancien
3c6762ae2d Merge branch 'trunk' 2026-04-21 16:51:27 +02:00
Noah Lancien
ee1e33e036 Merge branch 'develop' into trunk 2026-04-21 16:51:11 +02:00
Noah Lancien
fa399e49ee fix: 🐛 Updated htaccess to redirect index.php 2026-04-21 16:50:58 +02:00
Noah Lancien
8c52e52079 Merge branch 'develop' into trunk 2026-03-25 16:43:59 +01:00
Noah Lancien
39f06241b7 ci: added variable for DB HOST 2026-03-25 16:43:45 +01:00
Noah Lancien
2023eca826 Merge branch 'develop' into trunk 2026-03-24 15:27:39 +01:00
Noah Lancien
ff578e6f0a fix: remove handmade admin-secure 2026-03-24 15:27:26 +01:00
Noah Lancien
48a50d07f8 Merge branch 'develop' into trunk 2026-03-24 15:05:49 +01:00
Noah Lancien
95a8fb27d2 fix: added favicon 2026-03-24 15:05:27 +01:00
Noah Lancien
81125b461e Merge branch 'develop' into trunk 2026-03-24 14:53:01 +01:00
Noah Lancien
861a8f7a5b ci: added multi-stage ci 2026-03-24 14:52:47 +01:00
Noah Lancien
f813cc214a Merge branch 'develop' into trunk 2026-03-24 14:46:41 +01:00
Noah Lancien
abd91f967f ci: updated ci steps 2026-03-24 14:46:33 +01:00
Noah Lancien
42da6618dc Merge branch 'develop' into trunk 2026-03-24 14:39:28 +01:00
noah.lancien
1fcd0e979e Merge branch 'bump' into 'develop'
feat: bump laravel 12 / vite / vue3 / tutti quanti

See merge request ldc-web/projets/jeusselin!15
2026-03-24 13:38:47 +00:00
Noah Lancien
8ace1f3d4a fix: removed k8s-queues.sh 2026-03-24 09:09:08 +01:00
Noah Lancien
effc5db63f feat: bump laravel 12 / vite / vue3 / tutti quanti 2026-03-19 11:25:27 +01:00
Noah Lancien
6013663d73 Merge branch 'trunk' 2026-03-04 16:40:11 +01:00
Noah Lancien
ba79189293 Merge branch 'develop' into trunk 2026-03-04 16:25:08 +01:00
noah.lancien
fe02fcca8f Merge branch '20-admin-secure' into 'develop'
refactor: ♻️ remove admin-secure package and integrate middleware

See merge request ldc-web/projets/jeusselin!14
2026-03-04 15:23:52 +00:00
Corentin Huet
af9604bb3a refactor: ♻️ remove admin-secure package and integrate middleware 2026-03-04 16:05:36 +01:00
Noah Lancien
29ef828dbe Merge branch 'trunk' 2026-02-13 12:51:17 +01:00
Noah Lancien
ed8798ac66 Merge branch 'develop' into trunk 2026-02-13 12:50:53 +01:00
Noah Lancien
54ffd9b574 ci: limit jobs history to 1 2026-02-13 12:50:38 +01:00
Noah Lancien
76edd08394 Merge branch 'develop' into trunk 2026-01-08 17:06:19 +01:00
Noah Lancien
fba950df20 ci: added ci variables to define pod resources 2026-01-08 17:05:55 +01:00
Noah Lancien
a8d34cd23b Merge branch 'trunk' 2025-10-09 13:11:31 +02:00
Noah Lancien
eb51d562c1 Merge branch 'develop' into trunk 2025-10-09 13:02:12 +02:00
Noah Lancien
1ed2156da3 ci: updated dockerignore 2025-10-09 13:01:53 +02:00
Noah Lancien
fa19527c3e Merge branch 'trunk' 2025-10-09 12:11:51 +02:00
Noah Lancien
e6b8b7402a Merge branch 'develop' into trunk 2025-10-09 12:11:35 +02:00
Noah Lancien
7fd337c6f3 ci: added staging-resources.yaml 2025-10-09 12:11:08 +02:00
noah.lancien
a2e3cfe5a9 Merge branch 'issue-15' into 'develop'
fix: handle null validity date in ternary

See merge request ldc-web/projets/jeusselin!13
2025-10-09 10:02:16 +00:00
Corentin Huet
73fdf2f781 fix: handle null validity date in ternary 2025-09-15 15:22:47 +02:00
Noah Lancien
bc53526a08 Merge branch 'trunk' 2025-01-14 12:39:44 +01:00
Noah Lancien
86052f72b5 Merge branch 'develop' into trunk 2025-01-14 12:39:05 +01:00
Noah Lancien
15c7dae65c ci: Added 'concurrencyPolicy: Forbid' in cron jobs 2025-01-14 12:38:42 +01:00
Noah Lancien
28d3eb9045 fix: composer update to fix CVE 2025-01-14 12:37:48 +01:00
Noah Lancien
e1275ecf96 Merge branch 'trunk' 2024-09-10 12:13:19 +02:00
Noah Lancien
52b80aba00 Merge branch 'develop' into trunk 2024-09-10 12:12:54 +02:00
Noah Lancien
ef0098538e fix: updated the migration to move uploaded pdf 2024-09-10 12:12:44 +02:00
Noah Lancien
13a1340a61 Merge branch 'trunk' 2024-09-10 11:41:26 +02:00
Noah Lancien
63548d0e3c Merge branch 'develop' into trunk 2024-09-10 11:27:26 +02:00
noah.lancien
8d9289ca11 Merge branch 'issue-9-uploads-to-storage-migrations' into 'develop'
fix: Added a migration to replace uploaded files links in DB

See merge request ldc-web/projets/jeusselin!12
2024-09-10 09:27:12 +00:00
Noah Lancien
102f21961a fix: Added a migration to replace uploaded files links in D
B
2024-09-10 11:24:58 +02:00
Noah Lancien
8d351fbc6c Merge branch 'develop' into trunk 2024-09-10 11:03:24 +02:00
noah.lancien
797ef95663 Merge branch 'issue-9-move-uploads-to-storage' into 'develop'
fix: Moved uploaded files to the storage folder

See merge request ldc-web/projets/jeusselin!11
2024-09-10 09:02:42 +00:00
Noah Lancien
fa571ada9a fix: Moved uploaded files to the storage folder 2024-09-10 10:37:40 +02:00
Noah Lancien
b16c89eb88 Merge branch 'trunk' 2024-09-03 10:11:23 +02:00
Noah Lancien
6fa7f53714 Merge branch 'develop' into trunk 2024-09-03 10:11:07 +02:00
noah.lancien
51214f7262 Merge branch 'fixes-20240903' into 'develop'
Fixes 2024-09-03

See merge request ldc-web/projets/jeusselin!10
2024-09-03 08:10:33 +00:00
Noah Lancien
49de2bbd5e fix: wrong parameter given in Log::error() when the customer isn't found in the CRM 2024-09-03 10:06:37 +02:00
Noah Lancien
531d08f768 fix: couldn't create local customer when exists in CRM beacause of missing fields 2024-09-03 10:01:48 +02:00
Noah Lancien
579eff439f Merge branch 'trunk' 2024-09-02 14:39:54 +02:00
Noah Lancien
6c47de0cf0 Merge branch 'develop' into trunk 2024-09-02 14:39:20 +02:00
Noah Lancien
f92d357b72 Merge branch 'fix-search-bar-bo' into develop 2024-09-02 14:38:47 +02:00
Noah Lancien
7f681679b5 fix: Updated form action in BO search bar 2024-09-02 14:35:46 +02:00
noah.lancien
962ced20b2 Merge branch 'issue-11-delete-not-found-users' into 'develop'
fix: Delete a customer if it doesn't exists in CRM when clicking on 'edit' button in BO

See merge request ldc-web/projets/jeusselin!9
2024-09-02 12:29:27 +00:00
Noah Lancien
2ad908bce2 fix: Delete a customer if it doesn't exists in CRM when clicking on 'edit' button in BO 2024-09-02 14:23:04 +02:00
Noah Lancien
3f7059e9fb Merge branch 'trunk' 2024-08-13 15:25:57 +02:00
Noah Lancien
4b522e7c21 Merge branch 'develop' into trunk 2024-08-13 15:25:32 +02:00
Noah Lancien
4ad0d7ae9d Added www dns in production-resources.yaml 2024-08-13 15:25:17 +02:00
Vincent BRIDIER
66e0f1d523
Merge branch 'trunk' 2024-08-13 14:34:33 +02:00
Noah Lancien
456a5deeab Merge branch 'develop' into trunk 2024-08-13 12:55:53 +02:00
Noah Lancien
74b6fd1c75 Updated manifest.yaml - match www 2024-08-13 12:55:19 +02:00
Noah Lancien
b3674eb3f6 fix: Removed useless require 2024-08-13 12:55:07 +02:00
Noah Lancien
e35081cfa7 Merge branch 'develop' into trunk 2024-08-13 12:46:39 +02:00
Noah Lancien
5c4eba388b Updated manifest.yaml 2024-08-13 12:46:10 +02:00
noah.lancien
e22c55ef4c Merge branch 'many-fixes' into 'develop'
Many fixes

See merge request ldc-web/projets/jeusselin!8
2024-08-13 10:44:46 +00:00
Noah Lancien
8618382ec9 Fixed conflicts with develop 2024-08-13 12:37:27 +02:00
Noah Lancien
7519cb68e3 Removed some useless comments 2024-08-13 12:33:05 +02:00
Vincent BRIDIER
ca220d6ef6 Merge branch 'issue-7-2' into 'develop'
fix: #7 Updated 'Cherre' location and picture

See merge request ldc-web/projets/jeusselin!7
2024-08-13 10:27:45 +00:00
Noah Lancien
c1d8dbc9f3 fix: #7 Updated 'Cherre' location and picture 2024-08-13 12:21:26 +02:00
Noah Lancien
fd4d387c39 fix: #6 - Cookie notice + Matomo 2024-08-13 11:48:26 +02:00
Noah Lancien
c9ac965e74 Merge branch 'develop' into trunk 2024-08-05 10:50:37 +02:00
Noah Lancien
ba3ad76c61 Updated manifest.yaml 2024-08-05 10:50:22 +02:00
Noah Lancien
2bb81e7bcd Merge branch 'develop' into trunk 2024-08-05 09:44:27 +02:00
Noah Lancien
4942bc932d Updated manifest.yaml 2024-08-05 09:44:17 +02:00
Jérémy Munsch
bfb62cf5ba
Merge branch 'develop' into trunk 2024-01-29 17:11:32 +01:00
Jérémy Munsch
b66a4d6458
disable executeJavascript for sitemap as no puppeteer 2024-01-29 17:11:19 +01:00
Jérémy Munsch
df4db5fb5a
Merge branch 'develop' into trunk 2024-01-29 10:39:08 +01:00
Jérémy Munsch
7aae4b585f Merge branch 'add-CICD-files' into 'develop'
add dockerignore gitlab-ci Dockerfile and manifest for CICD

See merge request ldc-web/projets/jeusselin!5
2024-01-29 09:38:28 +00:00
Jérémy Munsch
4eef94e76f
npm update 2024-01-29 10:37:40 +01:00
Jérémy Munsch
49ec811619
Update en vars renove useless and update manifest + default .env 2024-01-29 10:15:12 +01:00
Jérémy Munsch
617aba7bfb
composer update 2024-01-29 10:10:50 +01:00
Jérémy Munsch
8fad56f09e
remove unused ldc web projet uuid 2024-01-29 10:07:33 +01:00
Jérémy Munsch
b8c8353f48
add k8s package 2024-01-29 09:54:35 +01:00
Jérémy Munsch
fd93a917ad
Fix gitlab ci and docker file version 2024-01-29 09:53:24 +01:00
Jérémy Munsch
8fda9a8663
remove sitemap generator 2024-01-29 09:50:51 +01:00
Nicolas Demangeat
99f8e9a6e0
add dockerignore gitlab-ci Dockerfile and manifest for CICD 2024-01-29 09:35:23 +01:00
Jérémy Munsch
7825210e0b Merge branch 'jeremy-upgrade' into 'develop'
Closes #2 and #4

See merge request ldc-web/projets/jeusselin!2
2024-01-29 08:34:01 +00:00
Jérémy Munsch
3078de582b
Fix using wrong relation objective user 2024-01-29 09:31:33 +01:00
Jérémy Munsch
a839a9a32b Merge branch 'issue-5' into 'jeremy-upgrade'
Compiled files are now in public/build folder

See merge request ldc-web/projets/jeusselin!3
2024-01-29 08:22:40 +00:00
Noah Lancien
acf71df53a Replaced asset() by mix(), Added missing silo-sille.jpg, Removed pictures which were previously compiled in public 2023-09-01 15:04:31 +02:00
Noah Lancien
8d4a4c0666 Compiled files are now in public/build folder 2023-09-01 10:10:09 +02:00
Olivier Legat
79c33aa0fb composer config for local params 2023-08-22 14:08:29 +02:00
Jérémy Munsch
de4dcfb283
Closes #2 and #4
- Add status checker + admin secure packages + upgrade enum + add sentry + upgrade to sitemap generator + bump to CRMV2
- Set customer role enum and user role enum
- Update customer migration to set roles
- phpcbf
- faker local to fr
- update lang
- composer update
- bump laravel ui
- Redo all user crud
- npm bump
- Create admin command
- rearrange views
- redo all auth system
- redo customer pro bo
2023-08-21 15:43:33 +02:00
Jérémy Munsch
4c9402ef8e
1st Step split DB customers and users 2023-08-16 15:27:31 +02:00
Jérémy Munsch
1026a70934
update phpcs and add slevomat/coding-standard 2023-08-16 13:29:09 +02:00
Vincent BRIDIER
655eedb52e
Merge branch 'trunk' 2023-07-26 11:15:40 +02:00
Vincent BRIDIER
aec90d91e8
Merge branch 'develop' into trunk 2023-07-26 11:15:08 +02:00
Olivier Legat
a5c72b9cbe Merge branch 'trunk' 2022-03-15 14:12:34 +01:00
Olivier Legat
a473d4a49c Merge branch 'develop' into trunk 2022-03-15 14:12:18 +01:00
Olivier Legat
dbf2d39f8a Merge branch 'trunk' 2022-03-14 16:45:46 +01:00
Olivier Legat
1f1ccf0807 Merge branch 'develop' into trunk 2022-03-14 16:45:20 +01:00
Olivier Legat
194bf51032 Merge branch 'trunk' 2022-01-24 15:32:19 +01:00
Olivier Legat
90451c7a89 Merge branch 'develop' into trunk 2022-01-24 15:31:44 +01:00
649 changed files with 40404 additions and 178585 deletions

11
.dockerignore Normal file
View file

@ -0,0 +1,11 @@
.git/
.gitlab/
.gitlab-ci.yml
*.md
.vscode/
auth.json
Dockerfile
manifest.yaml
node_modules/
production-resources.yaml
staging-resources.yaml

View file

@ -35,18 +35,34 @@ MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
# UWIL ADMIN SECURE
# - LIST SEPARATED WITH ',' (Required)
UWIL_ADMIN_SECURE_CIDR_LIST=""
# - LIST SEPARATED WITH ',' (Optional)
UWIL_ADMIN_SECURE_CIDR_PROJECT_ALLOWED_LIST=""
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
# CRM
CRM_ENDPOINT=
CRM_TOKEN=
CRM_PASSWORD=
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
# SENTRY
SENTRY_LARAVEL_DSN=
# Matomo
# MATOMO
MATOMO_SITE_ID=
##MAILJET CLE API PRINCIPALE
MAILJET_APIKEY=
MAILJET_APISECRET=
MAILJET_SMSTOKEN=
#MAILJET_SMSENDPOINT=
#MAILJET_SMSFROM=
# SAML
SAML2_DEFAULT_TENANT_UUID=
SAML2_SP_CERT_x509=
SAML2_SP_CERT_PRIVATEKEY=
SAML2_CONTACT_TECHNICAL_EMAIL=
SAML2_CONTACT_SUPPORT_EMAIL=

62
.eslintrc.json Normal file
View file

@ -0,0 +1,62 @@
{
"env": {
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:vue/vue3-strongly-recommended",
"@vue/eslint-config-typescript"
],
"overrides": [
{
"files": ["*.ts", "*.vue"],
"rules": {
"no-undef": "off"
}
},
{
"files": ["*.vue"],
"rules": {
"indent": "off"
}
}
],
"parser": "vue-eslint-parser",
"parserOptions": {
"parser": "@typescript-eslint/parser",
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": ["vue", "@typescript-eslint"],
"ignorePatterns": [
"webpack.mix.js",
"**/*.php",
"**/*.svg",
"**/vendor/*.js",
"**/vendor/**/*.js",
"**/vendor/**/*.scss"
],
"rules": {
"indent": ["error", 4, { "SwitchCase": 1 }],
"linebreak-style": ["error", "unix"],
"quotes": ["error", "double"],
"semi": ["error", "always"],
"vue/script-indent": ["error", 2, { "baseIndent": 0, "switchCase": 1 }],
"vue/one-component-per-file": "off"
},
"settings": {
"import/resolver": {
"node": {
"extensions": [".js", ".vue", ".ts", ".d.ts"]
},
"alias": {
"extensions": [".vue", ".js", ".ts", ".scss", ".d.ts"],
"map": [
["~", "./resources/assets"],
["@", "./node_modules"]
]
}
}
}
}

30
.gitignore vendored
View file

@ -1,22 +1,38 @@
/node_modules
/integration
/public/css
/public/hot
/public/images
/public/js
public/uploads/*
!public/uploads/.gitkeep
/public/storage
/public/assets/*
/public/js/*
/public/css/*
/public/fonts/*
/public/build
/public/content/*
/public/images/*
/public/cache/*
/public/uploads/*
/public/sitemap.xml
mix-manifest.json
/storage/*.key
/storage/framework/laravel-excel/*
/vendor
.env
.env.backup
.env.dev
.env.prod
.phpunit.result.cache
.npmrc
docker-compose.override.yml
Homestead.json
Homestead.yaml
npm-debug.log
yarn-error.log
workspace.code-workspace
.vscode
# IGNORE THEME SUBMODULES CHANGES
resources/theme
# Ignore compiled mail theme
resource/vendor/mail/html/themes/default.css
auth.json
.npmrc
.zshrc
.npm/
.composer/

23
.gitlab-ci.yml Normal file
View file

@ -0,0 +1,23 @@
include:
- project: "ldc-web/shared-ci"
ref: "main"
file: "lint/lint.yml"
- project: "ldc-web/shared-ci"
ref: "main"
file: "security/security.yml"
- project: "ldc-web/shared-ci"
ref: "main"
file: "build/docker-multistage.yml"
- project: "ldc-web/shared-ci"
ref: "main"
file: "test/test.yml"
- project: "ldc-web/shared-ci"
ref: "main"
file: "deploy/deploy.yml"
stages:
- lint
- security
- build
- test
- deploy

45
.stylelintrc.json Normal file
View file

@ -0,0 +1,45 @@
{
"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": true,
"selector-max-id": null,
"color-no-invalid-hex": true,
"order/properties-alphabetical-order": null,
"max-nesting-depth": 5,
"selector-max-compound-selectors": 5,
"declaration-colon-newline-after": null,
"value-list-comma-newline-after": null,
"scss/double-slash-comment-empty-line-before": [
"always",
{
"ignore": [
"between-comments",
"stylelint-commands",
"inside-block"
]
}
]
}
}

22
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,22 @@
{
"workbench.colorCustomizations": {
"activityBar.activeBackground": "#f1deae",
"activityBar.background": "#f1deae",
"activityBar.foreground": "#15202b",
"activityBar.inactiveForeground": "#15202b99",
"activityBarBadge.background": "#1ca37d",
"activityBarBadge.foreground": "#e7e7e7",
"commandCenter.border": "#15202b99",
"sash.hoverBorder": "#f1deae",
"statusBar.background": "#e9cc83",
"statusBar.foreground": "#15202b",
"statusBarItem.hoverBackground": "#e1ba58",
"statusBarItem.remoteBackground": "#e9cc83",
"statusBarItem.remoteForeground": "#15202b",
"titleBar.activeBackground": "#e9cc83",
"titleBar.activeForeground": "#15202b",
"titleBar.inactiveBackground": "#e9cc8399",
"titleBar.inactiveForeground": "#15202b99"
},
"peacock.remoteColor": "#e9cc83"
}

49
Dockerfile Normal file
View file

@ -0,0 +1,49 @@
ARG PHP_8_5_TAG=latest
FROM composer:2.9.2 AS vendor
WORKDIR /app
ARG GITLAB_USER
ARG GITLAB_PASSWORD
COPY database/ database/
COPY composer.json composer.json
COPY composer.lock composer.lock
RUN composer config gitlab-token.lab.s-web.fr "${GITLAB_USER}" "${GITLAB_PASSWORD}"
RUN composer install \
--ignore-platform-reqs \
--no-interaction \
--no-plugins \
--no-scripts \
--no-dev \
--prefer-dist
FROM node:20.18 AS frontend
ARG GITLAB_PASSWORD
RUN mkdir -p /app/public/build
COPY package*.json tsconfig.json vite.config.ts .eslintrc.json .stylelintrc.json /app/
COPY resources/ /app/resources/
WORKDIR /app
RUN npm config set @ldc-web:registry https://lab.s-web.fr/api/v4/packages/npm/
RUN npm config set -- '//lab.s-web.fr/api/v4/packages/npm/:_authToken' "${GITLAB_PASSWORD}"
RUN npm ci --no-audit --no-fund --loglevel=error && npm run prod
ARG PHP_8_5_TAG
FROM registry.s-web.fr/ldc-web/projets/ldc-web-images-docker/uwil-production-8.5:${PHP_8_5_TAG}
ARG USER=www-data
COPY --chown=${USER}:${USER} . /app/srcs
COPY --chown=${USER}:${USER} ./resources/favicon /app/srcs/public
COPY --from=vendor --chown=${USER}:${USER} /app/vendor/ /app/srcs/vendor/
COPY --from=frontend --chown=${USER}:${USER} /app/public/build/ /app/srcs/public/build/
USER root
RUN chmod -R 755 /app/srcs/storage
USER ${USER}

View file

@ -0,0 +1,144 @@
<?php
namespace App\Auth;
use App\Models\Customer;
use Illuminate\Auth\EloquentUserProvider;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Session;
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 UserProvider
{
/**
* 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): \Illuminate\Contracts\Auth\Authenticatable|null
{
/** @var \Illuminate\Contracts\Auth\Authenticatable|null $model */
$model = parent::retrieveByCredentials($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 \Illuminate\Contracts\Auth\Authenticatable $model
* @param array $credentials
* @return boolean
* @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(Authenticatable $model, array $credentials): bool
{
/** @var \Illuminate\Database\Eloquent\Model $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');
// * Ne devrait pas survenir, $crm->login throws ApiError::authFailed
return $crm->login($credentials['email'], $credentials['password']);
} catch (ApiErrorException $e) {
// @phpstan-ignore-next-line
if (!$model->hashcode or !CrmCustomer::find($model->hashcode)) {
$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)) {
Session::flash('warning', \trans('Vous devez activer votre compte'));
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 false;
}
/**
* 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): \Illuminate\Database\Eloquent\Model
{
/** @var \Illuminate\Database\Eloquent\Model $model */
$model = $this->usedModel::firstOrNew([
'email' => $crmCustomer->email,
'firstname' => $crmCustomer->firstname,
'lastname' => $crmCustomer->lastname,
]);
// @phpstan-ignore-next-line
$model->hashcode = $crmCustomer->hashcode;
// @phpstan-ignore-next-line
$model->email_verified_at = $crmCustomer->status ? now() : null;
$model->saveOrFail();
return $model;
}
}

View file

@ -1,56 +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 = 'creates an admin user upon password entry';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$pwd = $this->secret('What is the password?');
$user = new User();
$user->firstname = "Informatique";
$user->lastname = "Internet";
$user->email = "informatique.internet@ldc.fr";
$user->password = Hash::make($pwd);
$user->email_verify_token = "-";
$user->email_verified = 1;
$user->role = 1;
$user->save();
$this->info('User created.');
}
}

View file

@ -1,85 +0,0 @@
<?php
/*
* Command Name: LDC Web Status Checker
* Description: Envoi des infos Serveur/Laravel vers LDC Web
* Version: 1.0
* Author: Vincent BRIDIER
* Author URI: vincent.bridier@ldc.fr
*/
namespace App\Console\Commands;
use Illuminate\Console\Command;
class LDCWebStatusChecker extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'ldcweb:statuschecker';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Envoi des infos Serveur/Laravel vers LDC Web';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$data = [];
$data['uuid'] = env('PROJECT_UUID');
// Sitemap.xml ?
if (file_exists(public_path() . '/sitemap.xml')) {
$data['sitemap'] = 'true';
}else{
$data['sitemap'] = 'false';
}
// Robots.txt ?
if (file_exists(public_path() . '/robots.txt')) {
$data['robots'] = 'true';
}else{
$data['robots'] = 'false';
}
//Check logs
$data['logs'] = 0;
$patherror = storage_path('/logs');
$files = glob($patherror.'/*.log');
if(count($files) > 0){
foreach ($files as $file) {
$data['logs'] = $data['logs'] + filesize($file);
}
}
$data['code']['version'] = app()->version();
// Send by cURL
$url = 'https://ldc-web.ldc.fr/api/status-checker';
$ch = curl_init($url);
$payload = ['token' => 'CE8S52Qq7stf5k8frF4T', 'datas' => json_encode($data)];
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
}
}

View file

@ -1,38 +0,0 @@
<?php
namespace App\Console\Commands;
use App\Jobs\RefreshSiteMap as JobsRefreshSiteMap;
use Illuminate\Console\Command;
class RefreshSiteMap extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'sitemap:refresh';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Run the RefreshSiteMapJob manually';
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$this->info('Running the Job, this could take some time.');
$job = new JobsRefreshSiteMap();
$job->console = $this;
$job->handle();
$this->info('Job completed');
}
}

View file

@ -0,0 +1,201 @@
<?php
namespace App\Console\Commands;
use App\Enums\UserRoleEnum;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException;
use Illuminate\Support\Str;
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
*/
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 role of the new user.
*
* @var string|null
*/
protected $role;
/**
* Execute the console command.
*
* @return void
*/
public function handle(): void
{
$this->first_name = null;
$this->addFirstName();
$this->last_name = null;
$this->addLastName();
$this->email = null;
$this->addEmail();
$this->role = null;
$this->addRole();
$user = new User([
'firstname' => $this->first_name,
'lastname' => $this->last_name,
'email' => $this->email,
'role' => $this->role,
'published' => true,
'published_at' => Carbon::now(),
]);
$user->saveOrFail();
$this->info('User created 👌');
}
/**
* 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 role to the user.
*
* @return void
*/
private function addRole(): void
{
while (is_null($this->role)) {
try {
$tmp = $this->choice(
'Select his role',
[
Str::ucFirst(UserRoleEnum::superAdmin->label()),
Str::ucFirst(UserRoleEnum::admin->label())
],
Str::ucFirst(UserRoleEnum::admin->label()),
);
if ($tmp === Str::ucFirst(UserRoleEnum::superAdmin->label())) {
$tmp = UserRoleEnum::superAdmin;
}
if ($tmp === Str::ucFirst(UserRoleEnum::admin->label())) {
$tmp = UserRoleEnum::admin;
}
$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
}
}

View file

@ -12,19 +12,16 @@ class Kernel extends ConsoleKernel
*
* @var array
*/
protected $commands = [
//
];
protected $commands = [];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// $schedule->command('inspire')->hourly();
}
/**
@ -34,7 +31,7 @@ class Kernel extends ConsoleKernel
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
$this->load(__DIR__ . '/Commands');
require base_path('routes/console.php');
}

View file

@ -0,0 +1,23 @@
<?php
namespace App\Enums;
use Uwil\LaravelCommon\Traits\Enums\BaseEnum;
enum CustomerTypeEnum: int
{
use BaseEnum;
case professional = 3;
case individual = 4;
/**
* Optionnal labels definition
*
* @phpstan-ignore-next-line
*/
private const LABELS = [
self::professional->name => 'Professionnel',
self::individual->name => 'Particulier',
];
}

View file

@ -2,44 +2,30 @@
namespace App\Enums;
use Kwaadpepper\Enum\BaseEnum;
use Uwil\LaravelCommon\Traits\Enums\BaseEnum;
/**
* @method static self Ble()
* @method static self Colza()
* @method static self Mais()
* @method static self Orge()
* @method static self Tournesol_Oleique()
* @method static self Tournesol_Standard()
*/
final class ProduitEnum extends BaseEnum
enum ProduitEnum: int
{
protected static function values(): array
{
return [
'Ble' => 1,
'Colza' => 2,
'Mais' => 3,
'Orge' => 4,
'Tournesol_Oleique' => 5,
'Tournesol_Standard' => 6,
];
}
use BaseEnum;
protected static function labels(): array
{
return [
'Ble' => __('Ble'),
'Colza' => __('Colza'),
'Mais' => __('Maïs'),
'Orge' => __('Orge'),
'Tournesol_Oleique' => __('Tournesol Oléique'),
'Tournesol_Standard' => __('Tournesol Standard'),
];
}
case ble = 1;
case colza = 2;
case mais = 3;
case orge = 4;
case tournesol_oleique = 5;
case tournesol_standard = 6;
public function __toString(): string
{
return (string) $this->label;
}
/**
* Optionnal labels definition
*
* @phpstan-ignore-next-line
*/
private const LABELS = [
self::ble->name => 'Ble',
self::colza->name => 'Colza',
self::mais->name => 'Maïs',
self::orge->name => 'Orge',
self::tournesol_oleique->name => 'Tournesol Oléique',
self::tournesol_standard->name => 'Tournesol Standard',
];
}

View file

@ -0,0 +1,23 @@
<?php
namespace App\Enums;
use Uwil\LaravelCommon\Traits\Enums\BaseEnum as BaseEnum;
enum StaticPageType: int
{
use BaseEnum;
case legals = 1;
case confidentiality = 2;
/**
* Optionnal labels definition.
*
* @phpstan-ignore-next-line
*/
private const LABELS = [
self::legals->name => 'Mentions légales',
self::confidentiality->name => 'Confidentialité',
];
}

View file

@ -0,0 +1,23 @@
<?php
namespace App\Enums;
use Uwil\LaravelCommon\Traits\Enums\BaseEnum;
enum UserRoleEnum: int
{
use BaseEnum;
case superAdmin = 1;
case admin = 2;
/**
* Optionnal labels definition
*
* @phpstan-ignore-next-line
*/
private const LABELS = [
self::superAdmin->name => 'Super-Administrateur',
self::admin->name => 'Administrateur',
];
}

View file

@ -1,10 +0,0 @@
<?php
namespace App\Exceptions;
use Exception;
class CrmException extends Exception
{
//
}

View file

@ -8,20 +8,26 @@ 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 = [
//
];
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',
];
@ -34,7 +40,9 @@ class Handler extends ExceptionHandler
public function register()
{
$this->reportable(function (Throwable $e) {
//
if (app()->bound('sentry')) {
app('sentry')->captureException($e);
}
});
}
}

View file

@ -1,13 +0,0 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class AboutUsController extends Controller
{
public function index(Request $request)
{
return view('front.aboutus');
}
}

View file

@ -1,40 +0,0 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\ConfirmsPasswords;
class ConfirmPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Confirm Password Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password confirmations and
| uses a simple trait to include the behavior. You're free to explore
| this trait and override any functions that require customization.
|
*/
use ConfirmsPasswords;
/**
* Where to redirect users when the intended url fails.
*
* @var string
*/
protected $redirectTo = RouteServiceProvider::HOME;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
}

View file

@ -1,22 +0,0 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
class ForgotPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset emails and
| includes a trait which assists in sending these notifications from
| your application to your users. Feel free to explore this trait.
|
*/
use SendsPasswordResetEmails;
}

View file

@ -1,271 +0,0 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Mail\VerifyEmail;
use App\Mail\PasswordReset;
use App\Mail\InformProVerified;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Hash;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
private $apiCrm;
/**
* Where to redirect users after login.
*
* @var string
*/
public function redirectTo() {
$role = Auth::user()->role;
switch ($role) {
case '1':
case '2':
return '/bo';
case '3':
return '/pro';
default:
return '/home';
}
}
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
$this->apiCrm = new \LDCCRM\ApiV1(config('crm.endpoint'), config('crm.token'));
}
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 !== 1 && $userLocal->role !== 2) {
$connect = $this->apiCrm->loginCustomer($email, $password);
if ($connect->status === 'OK') {
/** @var \Illuminate\Auth\SessionGuard */
$guard = Auth::guard('web');
$guard->login($userLocal, $remember);
$url = $this->redirectTo();
return redirect()->to($url);
} else {
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.");
}
} else {
//création d'un compte local car il existe en crm
$connect = $this->apiCrm->loginCustomer($email, $password);
if ($connect->status === 'OK') {
$userLocal = User::create([
'crm_id' => $connect->user->crm_id,
'crm_hashcode' => $connect->user->hashcode,
'firstname' => $connect->user->firstname,
'lastname' => $connect->user->lastname,
'email' => $email,
'password' => Hash::make("MOTDEPASSE"), // Quelle infamie!!!
'email_verified' => 1
]);
} else {
if ($connect->code === 116) { // Compte existant mais non activé
$userLocal = User::create([
'crm_id' => $connect->user->crm_id,
'crm_hashcode' => $connect->user->hashcode,
'firstname' => $connect->user->firstname,
'lastname' => $connect->user->lastname,
'email' => $email,
'password' => Hash::make("MOTDEPASSE"), // Quelle infamie!!!
]);
$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.");
}
}
}
if ($userLocal->role === 1 || $userLocal->role === 2) {
if (Auth::attempt(["email" => $email, "password" => $password], $remember)) {
return redirect()->route('bo.dashboard');
} else {
return back()->withInput($request->except('password'))->withErrors('Les identifiants entrés sont incorrects.');
}
}
}
public function confirmEmail($verifyToken)
{
$result = false;
$user = User::where('email_verify_token', $verifyToken)->first();
if (!$user) {
return view('front.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 {
if ($activation->code === 110) { // User already active
$user->email_verified = 1;
$user->email_verify_token = null;
$user->save();
$result = true;
}
}
//envoi de mail à contact.jeusselin@jeusselin.fr
$email = "contact.jeusselin@jeusselin.fr";
Mail::to($email)->send(new InformProVerified($user));
return view('front.confirm-email', compact('result'));
}
public function forgotPassword(Request $request)
{
if ($request->tokenValid && $request->token) {
$tokenValid = $request->tokenValid;
$token = $request->token;
return view('front.forgot-password', compact('tokenValid', 'token'));
}
return view('front.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,
'crm_hashcode' => $userCrm->user->hashcode,
'firstname' => $userCrm->user->firstname,
'lastname' => $userCrm->user->lastname,
'email' => $email,
'password' => Hash::make("MOTDEPASSE"), // TODO : ???
'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.");
}
}
}
$user->password_token = Str::uuid();
$user->save();
Mail::to($email)->send(new PasswordReset($user));
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'){
return redirect()->route('login')->with('success', 'Vous pouvez désormais vous connecter avec votre nouveau mot de passe.');
}else{
return back()->withErrors("Une erreur est survenue, veuillez réessayer plus tard.");
}
}
}

View file

@ -1,228 +0,0 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Mail\VerifyEmail;
use Illuminate\Support\Facades\Mail;
use App\Providers\RouteServiceProvider;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
/**
* Where to redirect users after registration.
*
* @var string
*/
protected $redirectTo = RouteServiceProvider::HOME;
private $apiCrm;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest');
$this->apiCrm = new \LDCCRM\ApiV1(config('crm.endpoint'), config('crm.token'));
}
/**
* Get a validator for an incoming registration request.
*
* @param array $data
* @return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'lastname' => 'required|string|max:255',
'firstname' => 'required|string|max:255',
'phone' => 'required|max:50',
'adress' => 'required|string|max:255',
'postal_code' => 'required|string|max:50',
'town' => 'required|string|max:255',
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
'ok_cgv' => 'accepted',
]);
}
/**
* Create a new user instance after a valid registration.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
*/
public function create(Request $request)
{
$data = $request->all();
$this->validator($data)->validate();
$lastname = filter_var($request->lastname, FILTER_SANITIZE_STRING);
$firstname = filter_var($request->firstname, FILTER_SANITIZE_STRING);
$birthdate = $request->birth_date;
$phone = filter_var($request->phone, FILTER_SANITIZE_STRING);
$email = filter_var($request->email, FILTER_SANITIZE_EMAIL);
$address = filter_var($request->adress, FILTER_SANITIZE_STRING);
//$address2 = $request->address2 !== null ? filter_var($request->address2, FILTER_SANITIZE_STRING) : null;
$postal_code = filter_var($request->postal_code, FILTER_SANITIZE_STRING);
$town = filter_var($request->town, FILTER_SANITIZE_STRING);
//$country = filter_var($request->country, FILTER_SANITIZE_STRING);
$password = $request->password;
$optin = $request->news !== null ? 1 : 0;
$user_cat = $request->user_cat;
$social_denomination = filter_var($request->social_denomination, FILTER_SANITIZE_STRING);
$tech_commercial = filter_var($request->tech_commercial, FILTER_SANITIZE_STRING);
$siret =$request->siret;
$numtva = $request->numtva;
$certiphyto = $request->certiphyto;
$certiphyto_date = $request->certiphyto_date;
$eleveur_volailles = isset($request->eleveur_volailles) ? true : false;
$eleveur_porcs = isset($request->eleveur_porcs) ? true : false;
$eleveur_bovins = isset($request->eleveur_bovins) ? true : false;
$capacite_stockage = filter_var($request->capacite_stockage, FILTER_SANITIZE_STRING);
$temps_chargement = filter_var($request->temps_chargement, FILTER_SANITIZE_STRING);
$stockage_aplat = isset($request->stockage_aplat) ? true : false;
$stockage_cellule = isset($request->stockage_cellule) ? true : false;
$adress_chargement = filter_var($request->adress_chargement, FILTER_SANITIZE_STRING);
$optional_contact = filter_var($request->optional_contact, FILTER_SANITIZE_STRING);
$ok_cgv = \Carbon\Carbon::now();
$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.");
} 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.");
}
$birthdate = $d->toDateString();
} else {
return back()
->withInput($request->except('password'))
->withErrors("Erreur sur le champs : date de naissance.");
}
if ($user_cat == "professionnel") {
$role = 3;
} else {
$role = 4;
}
//on inscrit que des pros dans cette phase
$role = 3;
$userData = [
'lastname' => $lastname,
'firstname' => $firstname,
'phone' => $phone,
'birth_date' => $birthdate,
'email' => $email,
'adress' => $address,
'postal_code' => $postal_code,
'town' => $town,
'password' => Hash::make($password),
'role' => $role,
'email_verify_token' => $tokenMail,
'ok_cgv' => $ok_cgv,
];
if ($role == 3) {
$proData = [
'social_denomination' => $social_denomination,
'tech_commercial' => $tech_commercial,
'siret' => $siret,
'numtva' => $numtva,
'certiphyto' => $certiphyto,
'certiphyto_date' => $certiphyto_date,
'eleveur_volailles' => $eleveur_volailles,
'eleveur_porcs' => $eleveur_porcs,
'eleveur_bovins' => $eleveur_bovins,
'capacite_stockage' => $capacite_stockage,
'temps_chargement' => $temps_chargement,
'stockage_aplat' => $stockage_aplat,
'stockage_cellule' => $stockage_cellule,
'adress_chargement' => $adress_chargement,
'optional_contact' => $optional_contact,
];
$userData = array_merge($userData, $proData);
}
//création dans la CRM
$crmUser = $this->apiCrm->createCustomer($email, $password, $firstname, $lastname, $optin, $birthdate, $phone, $address, null, $town, $postal_code, null);
//création OK
if ($crmUser->status === 'OK') {
//enregistrement local du user
$userData['crm_id'] = $crmUser->user->crm_id;
$userData['crm_hashcode'] = $crmUser->user->hashcode;
$user = User::create($userData);
//envoi du mail de vérification
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." . $crmUser->code. " " . $crmUser->message . " " . print_r($crmUser->errors));
}
}
}
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;
}
}

View file

@ -1,30 +0,0 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\ResetsPasswords;
class ResetPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset requests
| and uses a simple trait to include this behavior. You're free to
| explore this trait and override any methods you wish to tweak.
|
*/
use ResetsPasswords;
/**
* Where to redirect users after resetting their password.
*
* @var string
*/
protected $redirectTo = RouteServiceProvider::HOME;
}

View file

@ -1,42 +0,0 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\VerifiesEmails;
class VerificationController extends Controller
{
/*
|--------------------------------------------------------------------------
| Email Verification Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling email verification for any
| user that recently registered with the application. Emails may also
| be re-sent if the user didn't receive the original email message.
|
*/
use VerifiesEmails;
/**
* Where to redirect users after verification.
*
* @var string
*/
protected $redirectTo = RouteServiceProvider::HOME;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
$this->middleware('signed')->only('verify');
$this->middleware('throttle:6,1')->only('verify', 'resend');
}
}

View file

@ -14,16 +14,16 @@ class ArticlesController extends Controller
{
public function index(Request $request)
{
//$a = Articles::with('category')->get();
$a = $this->filterArticles($request);
$a->with('category');
$a = $a->paginate(10);
return view('bo.articles.index', compact('a'));
}
protected function filterArticles(Request $request) {
protected function filterArticles(Request $request)
{
$articles = Articles::query();
if ($request->rst) {
@ -39,7 +39,7 @@ class ArticlesController extends Controller
Session::save();
}
if (Session::has('articles.sort_col') and Session::has('articles.sort_way')) {
if (Session::has('articles.sort_col') && Session::has('articles.sort_way')) {
switch (Session::get('articles.sort_col')) {
case 'category_id':
$articles = $articles->orderBy('category_id', Session::get('articles.sort_way'));
@ -68,40 +68,52 @@ class ArticlesController extends Controller
'content' => 'required',
]);
$title = $request->title;
$slug = Str::slug($title);
$picture = $request->picture;
$picture_r = $request->picture_r;
$content = $request->content;
$title = $request->title;
$slug = Str::slug($title);
$picture = $request->picture;
$picture_r = $request->picture_r;
$content = $request->content;
$categoryId = $request->category;
$status = 0;
$status = 0;
$imageName = Str::slug($title) .'-jeusselin-' . date('d-m-Y') . '.' . $picture->extension();
$picture->move(public_path('uploads/images/articles/' . date('Y') . '/' . date('m')), $imageName);
$imageName_r = Str::slug($title) .'-jeusselin-' . date('d-m-Y') . '_r.' . $picture_r->extension();
$picture_r->move(public_path('uploads/images/articles/' . date('Y') . '/' . date('m')), $imageName_r);
$imageName = Str::slug($title) . '-jeusselin-' . date('d-m-Y') . '.' . $picture->extension();
$picture->move(
storage_path(sprintf('app/public/modelfiles/articles/%s/%s', date('Y'), date('m'))),
$imageName
);
$imageName_r = Str::slug($title) . '-jeusselin-' . date('d-m-Y') . '_r.' . $picture_r->extension();
$picture_r->move(
storage_path(sprintf('app/public/modelfiles/articles/%s/%s', date('Y'), date('m'))),
$imageName_r
);
$a = new Articles();
$a->title = $title;
$a->slug = $slug;
$a->picture = 'uploads/images/articles/' . date('Y') . '/' . date('m') . '/' . $imageName;
$a->picture_r = 'uploads/images/articles/' . date('Y') . '/' . date('m') . '/' . $imageName_r;
$a->content = $content;
$a = new Articles();
$a->title = $title;
$a->slug = $slug;
$a->picture = sprintf('storage/modelfiles/articles/%s/%s/%s', date('Y'), date('m'), $imageName);
$a->picture_r = sprintf('storage/modelfiles/articles/%s/%s/%s', date('Y'), date('m'), $imageName_r);
$a->content = $content;
$a->category_id = $categoryId;
$a->status = $status;
$a->save();
$a->status = $status;
return redirect()->route('bo.articles.index');
if ($a->saveOrFail()) {
return redirect()
->route('bo.articles.index')
->with('success', trans(
':model a été crée',
['model' => 'Article']
));
}
return back();
}
public function edit($id)
{
$a = Articles::findOrFail($id);
$a = Articles::findOrFail($id);
$ac = ArticlesCategories::all();
return view('bo.articles.edit')
->with('a', $a)
->with('ac', $ac)
;
->with('a', $a)
->with('ac', $ac);
}
public function update(Request $request, $id)
@ -111,24 +123,24 @@ class ArticlesController extends Controller
'content' => 'required',
]);
$title = $request->title;
$slug = Str::slug($title);
$picture = $request->picture;
$picture_r = $request->picture_r;
$content = $request->content;
$title = $request->title;
$slug = Str::slug($title);
$picture = $request->picture;
$picture_r = $request->picture_r;
$content = $request->content;
$categoryId = $request->category;
$status = $request->status === null ? 0 : 1;
$status = $request->status === null ? 0 : 1;
if ($picture !== NULL && $picture_r !== NULL){
if ($picture !== null && $picture_r !== null) {
$request->validate([
'picture' => 'image|mimes:jpeg,png,jpg|max:2048|dimensions:width=340,height=340',
'picture_r' => 'image|mimes:jpeg,png,jpg|max:2048|dimensions:width=780,height=508',
]);
}elseif ($picture !== NULL && $picture_r === NULL){
} elseif ($picture !== null && $picture_r === null) {
$request->validate([
'picture' => 'required|image|mimes:jpeg,png,jpg|max:2048|dimensions:width=340,height=340'
]);
}elseif ($picture === NULL && $picture_r !== NULL){
} elseif ($picture === null && $picture_r !== null) {
$request->validate([
'picture_r' => 'required|image|mimes:jpeg,png,jpg|max:2048|dimensions:width=780,height=508'
]);
@ -136,28 +148,38 @@ class ArticlesController extends Controller
$a = Articles::findOrFail($id);
if ($picture !== NULL){
if(file_exists(public_path() . '/' . $a->picture))
unlink(public_path() . '/' . $a->picture);
$imageName = Str::slug($title) .'.'.$picture->extension();
$picture->move(public_path('uploads/images/articles/' . date('Y') . '/' . date('m') . '/'), $imageName);
if ($picture !== null) {
if (file_exists(storage_path(Str::replaceFirst('storage', 'app/public', $a->picture)))) {
unlink(storage_path(Str::replaceFirst('storage', 'app/public', $a->picture)));
}
$imageName = Str::slug($title) . '.' . $picture->extension();
$picture->move(
storage_path(sprintf('app/public/modelfiles/articles/%s/%s', date('Y'), date('m'))),
$imageName
);
}
if ($picture_r !== NULL) {
if(file_exists(public_path() . '/' . $a->picture_r))
unlink(public_path() . '/' . $a->picture_r);
if ($picture_r !== null) {
if (file_exists(storage_path(Str::replaceFirst('storage', 'app/public', $a->picture_r)))) {
unlink(storage_path(Str::replaceFirst('storage', 'app/public', $a->picture_r)));
}
$imageName_r = Str::slug($title) . '_r.' . $picture_r->extension();
$picture_r->move(public_path('uploads/images/articles/' . date('Y') . '/' . date('m') . '/'), $imageName_r);
$picture_r->move(
storage_path(sprintf('app/public/modelfiles/articles/%s/%s', date('Y'), date('m'))),
$imageName_r
);
}
$a->title = $title;
$a->slug = $slug;
if ($picture !== null)
$a->picture = 'uploads/images/articles/' . date('Y') . '/' . date('m') . '/' . $imageName;
if ($picture_r !== null)
$a->picture_r = 'uploads/images/articles/' . date('Y') . '/' . date('m') . '/' . $imageName_r;
$a->content = $content;
$a->slug = $slug;
if ($picture !== null) {
$a->picture = sprintf('storage/modelfiles/articles/%s/%s/%s', date('Y'), date('m'), $imageName);
}
if ($picture_r !== null) {
$a->picture_r = sprintf('storage/modelfiles/articles/%s/%s/%s', date('Y'), date('m'), $imageName_r);
}
$a->content = $content;
$a->category_id = $categoryId;
$a->status = $status;
$a->status = $status;
$a->save();
if ($a->category_id == 1 && $a->status === 1) {
@ -165,20 +187,36 @@ class ArticlesController extends Controller
Cache::put('actusGlobal', $actus);
}
return redirect()->route('bo.articles.edit', $a->id)->with('success', 'Enregistré !');
if ($a->saveOrFail()) {
return redirect()
->route('bo.articles.index')
->with('success', trans(
':model a été mis à jour',
['model' => 'Article']
));
}
return back();
}
public function destroy($id)
{
$a = Articles::findOrFail($id);
if (file_exists(public_path() . '/' . $a->picture))
unlink(public_path() . '/' . $a->picture);
if (file_exists(public_path() . '/' . $a->picture_r))
unlink(public_path() . '/' . $a->picture_r);
if (file_exists(storage_path(Str::replaceFirst('storage', 'app/public', $a->picture)))) {
unlink(storage_path(Str::replaceFirst('storage', 'app/public', $a->picture)));
}
if (file_exists(storage_path(Str::replaceFirst('storage', 'app/public', $a->picture_r)))) {
unlink(storage_path(Str::replaceFirst('storage', 'app/public', $a->picture_r)));
}
$a->delete();
return redirect()->route('bo.articles.index');
if ($a->deleteOrFail()) {
return redirect()
->route('bo.articles.index')
->with('warning', trans(
':model a bien été supprimé',
['model' => 'Article']
));
}
return back();
}
}

View file

@ -0,0 +1,87 @@
<?php
namespace App\Http\Controllers\Bo\Auth;
use App\Http\Controllers\Controller;
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
*/
private $message =
'Si votre compte existe vous devriez recevoir un message avec un lien pour réinitialiser votre mot de passe';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest:backend');
$this->middleware('throttle', [
'maxAttempts' => 15,
'decayMinutes' => 2
]);
}
/**
* Display the form to request a password reset link.
*
* @return \Illuminate\View\View
*/
public function showLinkRequestForm()
{
return view('bo.auth.passwords.email');
}
/**
* Get the broker to be used during password reset.
*
* @return \Illuminate\Contracts\Auth\PasswordBroker
*/
public function broker()
{
return Password::broker('users');
}
/**
* 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)]);
}
}

View file

@ -0,0 +1,57 @@
<?php
namespace App\Http\Controllers\Bo\Auth;
use App\Http\Controllers\Controller;
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');
$this->middleware('throttle:15,2')->except('logout');
}
/**
* Get the guard to be used during authentication.
*
* @return \Illuminate\Contracts\Auth\StatefulGuard
*/
protected function guard()
{
return Auth::guard('backend');
}
/**
* Show the application's login form.
*
* @return \Illuminate\View\View
*/
public function showLoginForm()
{
return view('bo.auth.login');
}
/**
* Where to redirect users after login.
* @return string
*/
protected function redirectTo(): string
{
$intendedUrl = response()->redirectToIntended()->getTargetUrl();
$intendedRequest = Request::create($intendedUrl);
return \strpos($intendedRequest->path(), '/ bo') === 0 ?
response()->redirectToIntended()->getTargetUrl() :
\route('bo.dashboard');
}
}

View file

@ -0,0 +1,59 @@
<?php
namespace App\Http\Controllers\Bo\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class ResetPasswordController extends Controller
{
use ResetsPasswords;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest:backend');
$this->middleware('throttle:15,2');
}
/**
* Get the guard to be used during authentication.
*
* @return \Illuminate\Contracts\Auth\StatefulGuard
*/
protected function guard()
{
return Auth::guard('backend');
}
/**
* Where to redirect users after login.
* @return string
*/
protected function redirectTo(): string
{
return \route('bo.dashboard');
}
/**
* Display the password reset view for the given token.
*
* If no token is present, display the link request form.
*
* @param \Illuminate\Http\Request $request
* @param string|null $token
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function showResetForm(Request $request, $token = null)
{
return view('bo.auth.passwords.reset')->with(
['token' => $token, 'email' => $request->email]
);
}
}

View file

@ -15,24 +15,24 @@ class BusinessSectorsController extends Controller
*/
public function index()
{
$sector = BusinessSector::orderBy('order', 'ASC')->get();
$sector = BusinessSector::orderBy('order', 'ASC')->get();
$psectors = BusinessSector::orderBy('order', 'ASC')->get();
return view('bo.business-sector.index', compact('sector','psectors'));
return view('bo.business-sector.index', compact('sector', 'psectors'));
}
public function saveDatas(Request $request) {
public function saveDatas(Request $request)
{
$sector = $request->sectors;
for ($i = 0; $i < count($sector); $i++) {
if (isset($sector[$i]["id"])) {
$s = BusinessSector::findOrFail($sector[$i]["id"]);
$s->name = $sector[$i]["name"];
$s->order = $sector[$i]["order"];
$s = BusinessSector::findOrFail($sector[$i]["id"]);
$s->name = $sector[$i]["name"];
$s->order = $sector[$i]["order"];
$s->parent_id = $sector[$i]["parent_id"];
$s->save();
}
else {
$s = BusinessSector::updateOrCreate([
} else {
$s = BusinessSector::updateOrCreate([
'name' => $sector[$i]["name"],
'order' => $sector[$i]["order"],
'parent_id' => $sector[$i]["parent_id"],
@ -51,68 +51,63 @@ class BusinessSectorsController extends Controller
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*
* @param int $id
* @param integer $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @param integer $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @param \Illuminate\Http\Request $request
* @param integer $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function destroy(Request $request)
{
$deleteOk = 0;
//check if there are Employees associated before deleting
//if (FaqQuestions::where('theme_id', $request->id)->count() > 0) {
// $deleteOk = 1;
//} else
// check if there are Employees associated before deleting
// if (FaqQuestions::where('theme_id', $request->id)->count() > 0) {
// $deleteOk = 1;
// } else
if ($request->id !== null) {
$sector = BusinessSector::findOrFail($request->id);
$sector->delete();

View file

@ -17,8 +17,8 @@ class CotationsController extends Controller
{
public function index(Request $request)
{
$cotations = Cotations::all();
return view('bo.cotations.index',compact('cotations'));
$cotations = Cotations::all()->sortBy('updated_at', \SORT_REGULAR, 'DESC');
return view('bo.cotations.index', compact('cotations'));
}
public function create()
@ -29,35 +29,35 @@ class CotationsController extends Controller
public function store(Request $request)
{
$request->validate([
'xmlfile' => ['required','mimes:application/xml,xml','max:2048',new Cotationsxml],
'xmlfile' => ['required','mimes:application/xml,xml','max:2048',new Cotationsxml()],
]);
$is_published = isset($request->is_published) ? true : false;
$xmlfile = $request->xmlfile;
$xmlfile = $request->xmlfile;
$path = $xmlfile->store('/cotations/' . date('Y') . '/' . date('m') . '/' . date("d"));
//save data to show in pro view
$xml = simplexml_load_string(Storage::get($path));
$json = json_encode($xml);
$data = json_decode($json,TRUE);
// save data to show in pro view
$xml = simplexml_load_string(Storage::get($path));
$json = json_encode($xml);
$data = json_decode($json, true);
$cotations = $data['enregistrement'];
//first truncate
// first truncate
CotationsData::truncate();
foreach($cotations as $cotation) {
$enreg = new CotationsData();
$enreg->produit = $cotation['Produit'];
$enreg->qualite = $cotation['Qualité'];
$enreg->recolte = $cotation['Récolte'];
foreach ($cotations as $cotation) {
$enreg = new CotationsData();
$enreg->produit = $cotation['Produit'];
$enreg->qualite = $cotation['Qualité'];
$enreg->recolte = $cotation['Récolte'];
$enreg->echeance = $cotation['Échéance'];
$enreg->prix = isset($cotation['Prix']) ? $cotation['Prix'] : null;
$enreg->prix = isset($cotation['Prix']) ? $cotation['Prix'] : null;
$enreg->save();
}
$c = new Cotations();
$c->file_path = $path;
$c = new Cotations();
$c->file_path = $path;
$c->is_published = $is_published;
$c->save();
@ -67,10 +67,10 @@ class CotationsController extends Controller
public function checkObjectives()
{
$counter = 0;
//get all cotations
// get all cotations
$cotations = CotationsData::all();
foreach ($cotations as $cotation) {
//get relevant objectives
// get relevant objectives
$objectives = Objectives::where([
['status_id', 1],
['produit', $cotation->produit],
@ -80,72 +80,76 @@ class CotationsController extends Controller
])->orderBy('updated_at', 'DESC')->get();
foreach ($objectives as $objectif) {
//check la hausse pour avertir le vendeur (agri) de l'atteinte de son objectif
if($cotation->prix >= $objectif->prix) {
//objectif atteint
// check la hausse pour avertir le vendeur (agri) de l'atteinte de son objectif
if ($cotation->prix >= $objectif->prix) {
// objectif atteint
$objectif->status_id = 2;
$objectif->goal_at = Carbon::now();
$objectif->goal_at = Carbon::now();
$objectif->save();
//envoi de message a l'agri
// envoi de message a l'agri
$this->sendMessageObjectif($objectif);
$counter += 1;
}
}
}
}//end foreach
return view('bo.cotations.checkgoals', compact('counter'));
}
protected function sendMessageObjectif($objectif)
{
//par défaut on va envoyer un mail, car on peut toujours
//envoi du mail d'alerte
Mail::to($objectif->user->email)->send(new AlertGoalAchieved($objectif));
$objectif->load('customer');
// par défaut on va envoyer un mail, car on peut toujours
// envoi du mail d'alerte
Mail::to($objectif->customer->email)->send(new AlertGoalAchieved($objectif));
//pour le moment on est pas sur de pouvoir envoyer un sms
// pour le moment on est pas sur de pouvoir envoyer un sms
$sendSms = false;
//il va nous falloir le num de téléphone
$toPhone = $objectif->user->apiData->phone;
// il va nous falloir le num de téléphone
$toPhone = $objectif->customer->apiData->phone;
//on ne garde que les numériques
// on ne garde que les numériques
$toPhone = preg_replace('/[^0-9+]/', '', $toPhone);
//on internationalise
// on internationalise
$toPhone = preg_replace('/^0/', '+33', $toPhone);
//vérification de format de téléphone français et mobile
// vérification de format de téléphone français et mobile
if (preg_match('/^\+33[67][0-9]{8}$/', $toPhone)) {
$sendSms = true;
}
//check si ce numéro est valide pour l'envoi de SMS
// check si ce numéro est valide pour l'envoi de SMS
if ($sendSms) {
$message = "Objectif " . $objectif->produit . " " . $objectif->echeance . " atteint. Contacter votre TC avant 17h45.";
/** @var \App\Lib\LDC\MailjetSms */
$mj = app('MailjetSms');
$mj = app('MailjetSms');
$mjResponse = $mj->send($message, $toPhone);
/** @var \GuzzleHttp\Psr7\Response $mjResponse */
$responseStatus = $mjResponse->getStatusCode(); //"200"
$responsePhrase = $mjResponse->getReasonPhrase(); //"OK"
$responseStatus = $mjResponse->getStatusCode();
// "200"
$responsePhrase = $mjResponse->getReasonPhrase();
// "OK"
if ($responseStatus == 200) {
$mjSmsResponse = $mjResponse->getBody()->getContents();
}
/* $format de la $mjSmsResponse
{"ID":"6302d3eb-b135-45ff-9aca-71513cf3d5a2",
"From":"Jeusselin",
"To":"+33682398703",
"Status":{
/*
$format de la $mjSmsResponse
{"ID":"6302d3eb-b135-45ff-9aca-71513cf3d5a2",
"From":"Jeusselin",
"To":"+33682398703",
"Status":{
"Code":1,
"Name":"sent_pending",
"Description":"Message is being sent"},
"Cost":{
"Cost":{
"Value":0.04,
"Currency":"EUR"},
"CreationTS":1617289400,
"Text":"Objectif Blé Avril 21 atteint. Contacter votre TC avant 17h45.",
"SmsCount":1}
"CreationTS":1617289400,
"Text":"Objectif Blé Avril 21 atteint. Contacter votre TC avant 17h45.",
"SmsCount":1}
*/
}
}//end if
}
}

View file

@ -0,0 +1,132 @@
<?php
namespace App\Http\Controllers\Bo;
use App\Enums\CustomerTypeEnum;
use App\Http\Controllers\Controller;
use App\Http\Requests\Bo\UpdateCustomerRequest;
use App\Http\Resources\CustomerCrmResource;
use App\Mail\InformProOpenAcess;
use App\Models\Customer;
use App\Models\Objectives;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
class CustomerController extends Controller
{
/**
* Display a listing of the resource.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
$query = Customer::where('role', '>=', Auth::user()->role);
if ($request->search) {
$this->searchQuery(
$query,
$request->search,
null,
'firstname',
'lastname',
'email',
);
} //end if
$this->sortQuery($query);
$customers = $query->paginate(25);
$searchFields = trans('Prénom,Nom,Email');
return view('bo.customers.index', compact('customers', 'searchFields'));
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
return view('bo.users.create');
}
/**
* Show the form for editing the specified resource.
*
* @param \App\Models\Customer $customer
* @return \Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
*/
public function edit(Customer $customer)
{
if (!$customer->existsInCrm()) {
return DB::transaction(function () use ($customer) {
Objectives::query()->where('customer_id', $customer->id)->delete();
$customer->delete();
return back()->with(
'error',
trans('Cet utilisateur n\'existe plus dans la CRM et a été supprimé localement.')
);
});
}
return view('bo.customers.edit', [
'customer' => $customer
]);
}
/**
* Update the specified resource in storage.
*
* @param \App\Http\Requests\Bo\UpdateCustomerRequest $request
* @param \App\Models\Customer $customer
* @return \Illuminate\Http\RedirectResponse
*/
public function update(UpdateCustomerRequest $request, Customer $customer)
{
return DB::transaction(function () use ($request, $customer) {
$customer->api_data->fill($request->validated());
$customer->fill(\array_intersect_key(
$request->validated(),
\array_flip($customer->getFillable()),
));
// * Theses props arent fillable
$customer->tc_id = \intval($request->post('tc_id'));
$customer->role = CustomerTypeEnum::make(\intval($request->post('role')));
$send_openaccess_mail = false;
if ($customer->role->equals(CustomerTypeEnum::professional)) {
// * if num client has been filled then il va falloir envoyer un mail d'information d'accès
$send_openaccess_mail = empty($customer->getOriginal('client_number')) &&
!empty($customer->client_number);
}
$customer->updateApiData(new CustomerCrmResource($customer));
$customer->saveOrFail();
// * envoi du mail d'ouverture.
if ($send_openaccess_mail) {
Mail::to($customer->email)->send(new InformProOpenAcess($customer));
}
if ($customer->saveOrFail()) {
return redirect()
->route(
'bo.customers.edit',
$customer
)
->with('success', trans(
':model a été mis à jour',
['model' => 'Client']
));
}
return back();
});
}
}

View file

@ -3,11 +3,14 @@
namespace App\Http\Controllers\Bo;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class DashboardController extends Controller
{
public function index(Request $request)
/**
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
return view('bo.dashboard.index');
}

View file

@ -18,8 +18,8 @@ class EmployeesController extends Controller
public function index()
{
$employees = Employees::orderBy('order', 'ASC')->get();
$sectors = BusinessSector::orderBy('order', 'ASC')->get();
return view('bo.employees.index',compact('employees','sectors'));
$sectors = BusinessSector::orderBy('order', 'ASC')->get();
return view('bo.employees.index', compact('employees', 'sectors'));
}
/**
@ -36,15 +36,15 @@ class EmployeesController extends Controller
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$lastname = $request->lastname;
$lastname = $request->lastname;
$firstname = $request->firstname;
$video = $request->video;
$photo = $request->photo;
$video = $request->video;
$photo = $request->photo;
$request->validate([
'lastname' => 'required|string|max:255',
@ -54,41 +54,38 @@ class EmployeesController extends Controller
'photo' => 'required|image|mimes:jpeg,png,jpg|max:2048|dimensions:width=100,height=100',
]);
$imageName = Str::slug($firstname."-".$lastname) . '-jeusselin.' . $photo->extension();
$photo->move(public_path('uploads/images/profiles/' . date('Y') . '/' . date('m')), $imageName);
$imageName = Str::slug($firstname . "-" . $lastname) . '-jeusselin.' . $photo->extension();
$photo->move(
storage_path(sprintf('app/public/modelfiles/profiles/%s/%s', date('Y'), date('m'))),
$imageName
);
$e = new Employees();
$e->civility = $request->civility;
$e->lastname = $lastname;
$e = new Employees();
$e->civility = $request->civility;
$e->lastname = $lastname;
$e->firstname = $firstname;
$e->job_title = $request->job_title;
$e->video = $video;
$e->photo = 'uploads/images/profiles/' . date('Y') . '/' . date('m') . '/' . $imageName;
$e->order = $this->getLastOrder();
$e->video = $video;
$e->photo = sprintf('storage/modelfiles/profiles/%s/%s/%s', date('Y'), date('m'), $imageName);
$e->order = $this->getLastOrder();
$e->save();
//prise en charge de la liaison avec les secteurs
// prise en charge de la liaison avec les secteurs
$associatedSectors = $request->associated_sectors;
$e->businessSectors()->sync($associatedSectors);
return redirect()->route('bo.employees.index');
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
return redirect()
->route('bo.employees.index')
->with('success', trans(
':model a été crée',
['model' => 'Employe']
));
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @param integer $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
@ -101,22 +98,22 @@ class EmployeesController extends Controller
$seIds[] = $sector_employee->id;
}
return view('bo.employees.edit', compact('e','s'))->with('seIds', $seIds);
return view('bo.employees.edit', compact('e', 's'))->with('seIds', $seIds);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @param \Illuminate\Http\Request $request
* @param integer $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$lastname = $request->lastname;
$lastname = $request->lastname;
$firstname = $request->firstname;
$video = $request->video;
$photo = $request->file('photo');
$video = $request->video;
$photo = $request->file('photo');
$request->validate([
'lastname' => 'required|string|max:255',
@ -125,7 +122,7 @@ class EmployeesController extends Controller
'video' => 'max:255',
]);
if($photo !== NULL) {
if ($photo !== null) {
$request->validate([
'photo' => 'image|mimes:jpeg,png,jpg|max:2048|dimensions:width=100,height=100',
]);
@ -133,63 +130,80 @@ class EmployeesController extends Controller
$e = Employees::findOrFail($id);
if($photo !== NULL) {
if(file_exists(public_path() . '/' . $e->photo))
unlink(public_path() . '/' . $e->photo);
$imageName = Str::slug($firstname."-".$lastname) . '-jeusselin.' . $photo->extension();
$photo->move(public_path('uploads/images/profiles/' . date('Y') . '/' . date('m')), $imageName);
if ($photo !== null) {
if (file_exists(storage_path(Str::replaceFirst('storage', 'app/public', $e->photo)))) {
unlink(storage_path(Str::replaceFirst('storage', 'app/public', $e->photo)));
}
$imageName = Str::slug($firstname . "-" . $lastname) . '-jeusselin.' . $photo->extension();
$photo->move(
storage_path(sprintf('app/public/modelfiles/profiles/%s/%s', date('Y'), date('m'))),
$imageName
);
}
$e->civility = $request->civility;
$e->lastname = $lastname;
$e->civility = $request->civility;
$e->lastname = $lastname;
$e->firstname = $firstname;
$e->job_title = $request->job_title;
$e->video = $video;
if($photo !== NULL) {
$e->photo = 'uploads/images/profiles/' . date('Y') . '/' . date('m') . '/' . $imageName;
$e->video = $video;
if ($photo !== null) {
$e->photo = sprintf('storage/modelfiles/profiles/%s/%s/%s', date('Y'), date('m'), $imageName);
}
$e->save();
$e->saveOrFail();
//prise en charge de la liaison avec les secteurs
// prise en charge de la liaison avec les secteurs
$associatedSectors = $request->associated_sectors;
$e->businessSectors()->sync($associatedSectors);
return redirect()->route('bo.employees.index');
return redirect()
->route('bo.employees.index')
->with('success', trans(
':model a été mis à jour',
['model' => 'Employee']
));
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @param integer $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$e = Employees::findOrFail($id);
if(file_exists(public_path() . '/' . $e->photo))
unlink(public_path() . '/' . $e->photo);
if (file_exists(storage_path(Str::replaceFirst('storage', 'app/public', $e->photo)))) {
unlink(storage_path(Str::replaceFirst('storage', 'app/public', $e->photo)));
}
//prise en charge de la liaison avec les secteurs
$e->businessSectors()->detach();
$e->delete();
return redirect()->route('bo.employees.index');
// prise en charge de la liaison avec les secteurs
if ($e->deleteOrFail()) {
return redirect()
->route('bo.employees.index')
->with('warning', trans(
':model a bien été supprimé',
['model' => 'Employe']
));
}
return back();
}
public function changeOrder($id, $action)
{
$current = Employees::findOrFail($id);
if ($action === 'up'){
$tmp = Employees::where('order', '<', $current->order)->orderBy('order', 'DESC')->first();
$newOrder = $tmp->order;
$tmp->order = $current->order;
if ($action === 'up') {
$tmp = Employees::where('order', '<', $current->order)->orderBy('order', 'DESC')->first();
$newOrder = $tmp->order;
$tmp->order = $current->order;
$current->order = $newOrder;
}else{
$tmp = Employees::where('order', '>', $current->order)->orderBy('order', 'ASC')->first();
$newOrder = $tmp->order;
$tmp->order = $current->order;
} else {
$tmp = Employees::where('order', '>', $current->order)->orderBy('order', 'ASC')->first();
$newOrder = $tmp->order;
$tmp->order = $current->order;
$current->order = $newOrder;
}
$tmp->save();
@ -201,8 +215,9 @@ class EmployeesController extends Controller
private function getLastOrder()
{
$order = Employees::select('order')->orderBy('order', 'DESC')->first();
if ($order === NULL)
if ($order === null) {
return 1;
}
return $order->order + 1;
}
}

View file

@ -0,0 +1,73 @@
<?php
namespace App\Http\Controllers\Bo;
use App\Http\Controllers\Controller;
use App\Models\GeneralConfig;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\View\View;
class GeneralConfigController extends Controller
{
/**
* Display the general configuration edit form.
*
* @return View
*/
public function edit(): View
{
return view('bo.general-config.edit', [
'config' => GeneralConfig::current(),
]);
}
/**
* Upload and store the "Nos métiers" page image.
*
* @param Request $request
* @return RedirectResponse
*/
public function upload(Request $request): RedirectResponse
{
$config = GeneralConfig::current();
$ancienne = $config->get('image');
$request->validate(
[
'image' => [$ancienne ? 'nullable' : 'required', 'image', 'mimes:jpeg,png,jpg', 'max:2048', 'dimensions:width=742,height=464'],
'image_alt' => ['required', 'string', 'min:5','max:50'],
'image_title' => ['required', 'string', 'min:5','max:50'],
],
['image.dimensions' => "L'image doit faire exactement 742 × 464 px."]
);
if ($request->hasFile('image')) {
$photo = $request->file('image');
$imageName = 'image-' . now()->format('YmdHis') . '.' . $photo->extension();
$path = $photo->storeAs(
sprintf('modelfiles/general-config/%s/%s', date('Y'), date('m')),
$imageName,
'public'
);
$config->put('image', $path);
}
$config
->put('image_alt', $request->input('image_alt'))
->put('image_title', $request->input('image_title'))
->save();
if ($request->hasFile('image') && $ancienne && $ancienne !== $config->get('image')) {
Storage::disk('public')->delete($ancienne);
}
return redirect()
->route('bo.general-config.edit')
->with('success', 'Configuration mise à jour.');
}
}

View file

@ -17,7 +17,7 @@ class HomeSlidersController extends Controller
public function index()
{
$slides = HomeSliders::orderBy('order', 'ASC')->get();
return view('bo.home-sliders.index',compact('slides'));
return view('bo.home-sliders.index', compact('slides'));
}
/**
@ -33,18 +33,18 @@ class HomeSlidersController extends Controller
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$title = $request->title;
$picture = $request->picture;
$text = $request->text;
$title = $request->title;
$picture = $request->picture;
$text = $request->text;
$linkLabel = $request->link_label;
$link = $request->link;
$newTab = $request->link_new_tab === null ? 0 : 1;
$status = 0;
$link = $request->link;
$newTab = $request->link_new_tab === null ? 0 : 1;
$status = 0;
$request->validate([
'title' => 'required|max:255',
@ -53,41 +53,40 @@ class HomeSlidersController extends Controller
'link' => 'sometimes|max:255',
]);
$imageName = Str::slug($title) .'-jeusselin.'.$picture->extension();
$picture->move(public_path('uploads/images/slider_accueil/' . date('Y') . '/' . date('m') . '/'), $imageName);
$imageName = Str::slug($title) . '-jeusselin.' . $picture->extension();
$picture->move(
storage_path(sprintf('app/public/modelfiles/slider_accueil/%s/%s', date('Y'), date('m'))),
$imageName
);
// $imageName_r = Str::slug($title) .'-jeusselin_r.'.$picture_r->extension();
// $picture_r->move(public_path('uploads/images/slider_accueil/' . date('Y') . '/' . date('m') . '/'), $imageName_r);
$hsp = new HomeSliders();
$hsp->title = $title;
$hsp->picture = 'uploads/images/slider_accueil/' . date('Y') . '/' . date('m') . '/' . $imageName;
//$hsp->picture_r = 'uploads/images/slider_accueil/' . date('Y') . '/' . date('m') . '/' . $imageName_r;
$hsp->text = $text;
$hsp->link_label = $linkLabel;
$hsp->link = $link;
// $picture_r->move(storage_path('modelfiles/slider_accueil/slider_accueil/' . date('Y') . '/' . date('m') . '/'), $imageName_r);
$hsp = new HomeSliders();
$hsp->title = $title;
$hsp->picture = sprintf('storage/modelfiles/slider_accueil/%s/%s/%s', date('Y'), date('m'), $imageName);
// $hsp->picture_r = 'storage/modelfiles/slider_accueil/' . date('Y') . '/' . date('m') . '/' . $imageName_r;
$hsp->text = $text;
$hsp->link_label = $linkLabel;
$hsp->link = $link;
$hsp->link_new_tab = $newTab;
$hsp->status = $status;
$hsp->order = $this->getLastOrder();
$hsp->status = $status;
$hsp->order = $this->getLastOrder();
$hsp->save();
return redirect()->route('bo.home-sliders.index');
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
if ($hsp->saveOrFail()) {
return redirect()
->route('bo.home-sliders.index')
->with('success', trans(
':model a été crée',
['model' => 'Slide']
));
}
return back();
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @param integer $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
@ -99,20 +98,21 @@ class HomeSlidersController extends Controller
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @param \Illuminate\Http\Request $request
* @param integer $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$title = $request->title;
$picture = $request->picture;
$picture_r = null; //$request->picture_r;
$text = $request->text;
$title = $request->title;
$picture = $request->picture;
$picture_r = null;
// $request->picture_r;
$text = $request->text;
$linkLabel = $request->link_label;
$link = $request->link;
$newTab = $request->link_new_tab === null ? 0 : 1;
$status = $request->status === null ? 0 : 1;
$link = $request->link;
$newTab = $request->link_new_tab === null ? 0 : 1;
$status = $request->status === null ? 0 : 1;
$request->validate([
'title' => 'required|max:255',
@ -120,16 +120,16 @@ class HomeSlidersController extends Controller
'link' => 'sometimes|max:255',
]);
if ($picture !== NULL && $picture_r !== NULL){
if ($picture !== null && $picture_r !== null) {
$request->validate([
'picture' => 'image|mimes:jpeg,png,jpg|max:2048|dimensions:max-width=300,max-height=300',
'picture_r' => 'image|mimes:jpeg,png,jpg|max:2048|dimensions:width=500,height=671',
]);
}elseif ($picture !== NULL && $picture_r === NULL){
} elseif ($picture !== null && $picture_r === null) {
$request->validate([
'picture' => 'required|image|mimes:jpeg,png,jpg|max:2048|dimensions:max-width=300,max-height=300'
]);
}elseif ($picture === NULL && $picture_r !== NULL){
} elseif ($picture === null && $picture_r !== null) {
$request->validate([
'picture_r' => 'required|image|mimes:jpeg,png,jpg|max:2048|dimensions:width=500,height=671'
]);
@ -137,70 +137,95 @@ class HomeSlidersController extends Controller
$hsp = HomeSliders::findOrFail($id);
if ($picture !== NULL){
if(file_exists(public_path() . '/' . $hsp->picture))
unlink(public_path() . '/' . $hsp->picture);
$imageName = Str::slug($title) .'-jeusselin.'.$picture->extension();
$picture->move(public_path('uploads/images/slider_accueil/' . date('Y') . '/' . date('m') . '/'), $imageName);
if ($picture !== null) {
if (file_exists(storage_path(Str::replaceFirst('storage', 'app/public', $hsp->picture)))) {
unlink(storage_path(Str::replaceFirst('storage', 'app/public', $hsp->picture)));
}
$imageName = Str::slug($title) . '-jeusselin.' . $picture->extension();
$picture->move(
storage_path(sprintf('app/public/modelfiles/slider_accueil/%s/%s', date('Y'), date('m'))),
$imageName
);
}
if ($picture_r !== NULL) {
if(file_exists(public_path() . '/' . $hsp->picture_r))
unlink(public_path() . '/' . $hsp->picture_r);
if ($picture_r !== null) {
if (file_exists(storage_path(Str::replaceFirst('storage', 'app/public', $hsp->picture_r)))) {
unlink(storage_path(Str::replaceFirst('storage', 'app/public', $hsp->picture_r)));
}
$imageName_r = Str::slug($title) . '-jeusselin_r.' . $picture_r->extension();
$picture_r->move(public_path('uploads/images/slider_accueil/' . date('Y') . '/' . date('m') . '/'), $imageName_r);
$picture_r->move(
storage_path(sprintf('app/public/modelfiles/slider_accueil/%s/%s', date('Y'), date('m'))),
$imageName_r
);
}
$hsp->title = $title;
if ($picture !== null)
$hsp->picture = 'uploads/images/slider_accueil/' . date('Y') . '/' . date('m') . '/' . $imageName;
if ($picture_r !== null)
$hsp->picture_r = 'uploads/images/slider_accueil/' . date('Y') . '/' . date('m') . '/' . $imageName_r;
$hsp->text = $text;
$hsp->link_label = $linkLabel;
$hsp->link = $link;
if ($picture !== null) {
$hsp->picture = sprintf('storage/modelfiles/slider_accueil/%s/%s/%s', date('Y'), date('m'), $imageName);
}
if ($picture_r !== null) {
$hsp->picture_r = sprintf('storage/modelfiles/slider_accueil/%s/%s/%s', date('Y'), date('m'), $imageName_r);
}
$hsp->text = $text;
$hsp->link_label = $linkLabel;
$hsp->link = $link;
$hsp->link_new_tab = $newTab;
$hsp->status = $status;
$hsp->save();
return redirect()->route('bo.home-sliders.edit', $hsp->id)->with('success', 'Enregistré !');
if ($hsp->saveOrFail()) {
return redirect()
->route('bo.home-sliders.index')
->with('success', trans(
':model a été mis à jour',
['model' => 'Slide']
));
}
return back();
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @param integer $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$h = HomeSliders::findOrFail($id);
if(file_exists(public_path() . '/' . $h->picture))
unlink(public_path() . '/' . $h->picture);
if(!is_null($h->picture_r)) {
if(file_exists(public_path() . '/' . $h->picture_r))
unlink(public_path() . '/' . $h->picture_r);
if (file_exists(storage_path(Str::replaceFirst('storage', 'app/public', $h->picture)))) {
unlink(storage_path(Str::replaceFirst('storage', 'app/public', $h->picture)));
}
if (!is_null($h->picture_r)) {
if (file_exists(storage_path(Str::replaceFirst('storage', 'app/public', $h->picture_r)))) {
unlink(storage_path(Str::replaceFirst('storage', 'app/public', $h->picture_r)));
}
}
$h->delete();
return redirect()->route('bo.home-sliders.index');
if ($h->deleteOrFail()) {
return redirect()
->route('bo.home-sliders.index')
->with('warning', trans(
':model a bien été supprimé',
['model' => 'Slide']
));
}
return back();
}
public function changeOrder($id, $action)
{
$current = HomeSliders::findOrFail($id);
if ($action === 'up'){
$tmp = HomeSliders::where('order', '<', $current->order)->orderBy('order', 'DESC')->first();
$newOrder = $tmp->order;
$tmp->order = $current->order;
if ($action === 'up') {
$tmp = HomeSliders::where('order', '<', $current->order)->orderBy('order', 'DESC')->first();
$newOrder = $tmp->order;
$tmp->order = $current->order;
$current->order = $newOrder;
}else{
$tmp = HomeSliders::where('order', '>', $current->order)->orderBy('order', 'ASC')->first();
$newOrder = $tmp->order;
$tmp->order = $current->order;
} else {
$tmp = HomeSliders::where('order', '>', $current->order)->orderBy('order', 'ASC')->first();
$newOrder = $tmp->order;
$tmp->order = $current->order;
$current->order = $newOrder;
}
$tmp->save();
@ -212,8 +237,9 @@ class HomeSlidersController extends Controller
private function getLastOrder()
{
$order = HomeSliders::select('order')->orderBy('order', 'DESC')->first();
if ($order === NULL)
if ($order === null) {
return 1;
}
return $order->order + 1;
}
}

View file

@ -10,7 +10,6 @@ use Illuminate\Support\Facades\Session;
class ObjectivesController extends Controller
{
/**
* Display a listing of the resource.
*
@ -18,16 +17,18 @@ class ObjectivesController extends Controller
*/
public function index(Request $request)
{
$filter_tc_id = $request->query('filter_tc_id');
$filter_tc_id = $request->query('filter_tc_id');
$objectives = $this->filterObjectives($request);
$objectives = $objectives->paginate(10);
$objectives->with(['customer', 'status']);
$objectives = $this->paginate($objectives);
return view('bo.objectives.index', compact('objectives','filter_tc_id'));
return view('bo.objectives.index', compact('objectives', 'filter_tc_id'));
}
protected function filterObjectives(Request $request) {
protected function filterObjectives(Request $request)
{
$objectives = Objectives::query();
@ -47,12 +48,12 @@ class ObjectivesController extends Controller
Session::put('objectives.sort_way', $request->sort_way);
Session::save();
}
if($request->filter_tc_id) {
if ($request->filter_tc_id) {
Session::put('objectives.filter_tc_id', $request->filter_tc_id);
Session::save();
}
if (Session::has('objectives.sort_col') and Session::has('objectives.sort_way')) {
if (Session::has('objectives.sort_col') && Session::has('objectives.sort_way')) {
switch (Session::get('objectives.sort_col')) {
case 'produit':
$objectives = $objectives->orderBy('produit', Session::get('objectives.sort_way'));
@ -75,28 +76,30 @@ class ObjectivesController extends Controller
case 'status_id':
$objectives = $objectives->orderBy('status_id', Session::get('objectives.sort_way'));
break;
case 'user_id':
$objectives = $objectives->orderBy('user_id', Session::get('objectives.sort_way'));
case 'customer_id':
$objectives = $objectives->orderBy('customer_id', Session::get('objectives.sort_way'));
break;
case 'tc_id':
$objectives = $objectives->select('objectives.*');
$objectives = $objectives->leftJoin('users', 'users.id', '=', 'objectives.user_id');
$objectives = $objectives->orderBy('users.tc_id', Session::get('objectives.sort_way'));
$objectives = $objectives->leftJoin('customers', 'customers.id', '=', 'objectives.customer_id');
$objectives = $objectives->orderBy('customers.tc_id', Session::get('objectives.sort_way'));
break;
}
}//end switch
if (Session::has('objectives.filter_tc_id')) {
if (Session::has('objectives.sort_col')
and Session::has('objectives.sort_way')
and Session::get('objectives.sort_col') == 'tc_id') {
$objectives = $objectives->where('users.tc_id', '=', Session::get('objectives.filter_tc_id'));
} else {
$objectives = $objectives->select('objectives.*');
$objectives = $objectives->leftJoin('users', 'users.id', '=', 'objectives.user_id');
$objectives = $objectives->where('users.tc_id', '=', Session::get('objectives.filter_tc_id'));
}
if (
Session::has('objectives.sort_col')
&& Session::has('objectives.sort_way')
&& Session::get('objectives.sort_col') == 'tc_id'
) {
$objectives = $objectives->where('customers.tc_id', '=', Session::get('objectives.filter_tc_id'));
} else {
$objectives = $objectives->select('objectives.*');
$objectives = $objectives->leftJoin('customers', 'customers.id', '=', 'objectives.customer_id');
$objectives = $objectives->where('customers.tc_id', '=', Session::get('objectives.filter_tc_id'));
}
}
}
}//end if
return $objectives;
}
@ -114,7 +117,7 @@ class ObjectivesController extends Controller
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
@ -125,31 +128,21 @@ class ObjectivesController extends Controller
/**
* Display the specified resource.
*
* @param int $id
* @param integer $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
$objectif = Objectives::findOrFail($id);
$objectif->load(['customer', 'status']);
return view('bo.objectives.show', compact('objectif'));
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
return view('bo.objectives.edit');
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @param \Illuminate\Http\Request $request
* @param integer $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
@ -160,7 +153,7 @@ class ObjectivesController extends Controller
/**
* Remove the specified resource from storage.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function destroy(Request $request)
@ -169,7 +162,7 @@ class ObjectivesController extends Controller
if ($request->id !== null) {
$objectif = Objectives::findOrFail($request->id);
if ($objectif->user_id == Auth::user()->id) {
if ($objectif->customer_id == Auth::guard('frontend')->user()->id) {
$objectif->delete();
} else {
$deleteOk = 3;
@ -180,52 +173,4 @@ class ObjectivesController extends Controller
return $deleteOk;
}
/**
* Store a newly created resource or update an existing one
* @param \Illuminate\Http\Request $request
* @return array $objectif
*/
public function saveProDatas(Request $request) {
//save data from Pro dashboard
$objectif = $request->objectif;
if (isset($objectif["id"])) {
$o = Objectives::findOrFail($objectif["id"]);
$o->produit = $objectif["produit"];
$o->qualite = $objectif["qualite"];
$o->quantite = $objectif["quantite"];
$o->campagne = $objectif["campagne"];
$o->prix = $objectif["prix"];
$o->echeance = $objectif["echeance"];
$o->volume_restant = $objectif["volume_restant"];
$o->observations = $objectif["observations"];
$o->save();
$objectif["status_id"] = $o->status_id;
$objectif["status"] = $o->status;
}
else {
$o = Objectives::updateOrCreate([
'produit' => $objectif["produit"],
'qualite' => $objectif["qualite"],
'quantite' => $objectif["quantite"],
'campagne' => $objectif["campagne"],
'prix' => $objectif["prix"],
'echeance' => $objectif["echeance"],
'volume_restant' => $objectif["volume_restant"],
'observations' => $objectif["observations"],
'user_id' => Auth::user()->id,
'status_id' => 1,
]);
$objectif["id"] = $o->id;
$objectif["status_id"] = $o->status_id;
$objectif["status"] = $o->status;
unset($objectif["user_id"]);
}
return $objectif;
}
}

View file

@ -13,7 +13,7 @@ class PublicPdfsController extends Controller
public function index(Request $request)
{
$publicpdfs = PublicPdfs::with('category')->get();
return view('bo.public-pdfs.index',compact('publicpdfs'));
return view('bo.public-pdfs.index', compact('publicpdfs'));
}
public function create()
@ -25,81 +25,109 @@ class PublicPdfsController extends Controller
public function store(Request $request)
{
$request->validate([
'pdffile' => ['required','mimes:application/pdf,pdf','max:2048'],
'pdffile' => ['required', 'mimes:application/pdf,pdf', 'max:2048'],
]);
$is_published = isset($request->is_published) ? true : false;
$pdffile = $request->pdffile;
$categoryId = $request->category;
$category = PdfCategories::findOrFail($categoryId);
$pdffile = $request->pdffile;
$categoryId = $request->category;
$category = PdfCategories::findOrFail($categoryId);
$fileName = Str::slug(pathinfo($pdffile->getClientOriginalName(),PATHINFO_FILENAME)).'.'.pathinfo($pdffile->getClientOriginalName(),PATHINFO_EXTENSION);
$pdffile->move(public_path('uploads/pdf/'. Str::slug($category->name) .'/' . date('Y') . '/' . date('m')), $fileName);
$fileName = Str::slug(pathinfo($pdffile->getClientOriginalName(), PATHINFO_FILENAME)) . '.' . pathinfo($pdffile->getClientOriginalName(), PATHINFO_EXTENSION);
$pdffile->move(
storage_path(sprintf('app/public/modelfiles/public_pdfs/%s/%s/%s', Str::slug($category->name), date('Y'), date('m'))),
$fileName
);
$pdf = new PublicPdfs();
$pdf = new PublicPdfs();
$pdf->file_name = $pdffile->getClientOriginalName();
$pdf->file_path = 'uploads/pdf/'. Str::slug($category->name) .'/' . date('Y') . '/' . date('m') . '/' . $fileName;
$pdf->is_published = $is_published;
$pdf->category_id = $categoryId;
$pdf->save();
$pdf->file_path = sprintf('storage/modelfiles/public_pdfs/%s/%s/%s/%s', Str::slug($category->name), date('Y'), date('m'), $fileName);
return redirect()->route('bo.public-pdfs.index');
$pdf->is_published = $is_published;
$pdf->category_id = $categoryId;
if ($pdf->saveOrFail()) {
return redirect()
->route('bo.public-pdfs.index')
->with('success', trans(
':model a été crée',
['model' => 'PDF']
));
}
return back();
}
public function edit($id)
{
$pdf = PublicPdfs::findOrFail($id);
$pc = PdfCategories::all();
$pc = PdfCategories::all();
return view('bo.public-pdfs.edit')
->with('pdf', $pdf)
->with('pc', $pc)
;
->with('pdf', $pdf)
->with('pc', $pc);
}
public function update(Request $request, $id)
{
$request->validate([
'pdffile' => ['mimes:application/pdf,pdf','max:2048'],
'pdffile' => ['mimes:application/pdf,pdf', 'max:2048'],
]);
$is_published = isset($request->is_published) ? true : false;
$pdffile = $request->pdffile;
$categoryId = $request->category;
$category = PdfCategories::findOrFail($categoryId);
$pdffile = $request->pdffile;
$categoryId = $request->category;
$category = PdfCategories::findOrFail($categoryId);
$pdf = PublicPdfs::findOrFail($id);
if ($pdffile !== NULL){
if(file_exists(public_path() . '/' . $pdf->file_path))
unlink(public_path() . '/' . $pdf->file_path);
$fileName = Str::slug(pathinfo($pdffile->getClientOriginalName(),PATHINFO_FILENAME)).'.'.pathinfo($pdffile->getClientOriginalName(),PATHINFO_EXTENSION);
$pdffile->move(public_path('uploads/pdf/'. Str::slug($category->name) .'/' . date('Y') . '/' . date('m')), $fileName);
if ($pdffile !== null) {
if (file_exists(storage_path(Str::replaceFirst('storage', 'app/public', $pdf->file_path)))) {
unlink(storage_path(Str::replaceFirst('storage', 'app/public', $pdf->file_path)));
}
$fileName = Str::slug(pathinfo($pdffile->getClientOriginalName(), PATHINFO_FILENAME)) . '.' . pathinfo($pdffile->getClientOriginalName(), PATHINFO_EXTENSION);
$pdffile->move(
storage_path(sprintf('app/public/modelfiles/public_pdfs/%s/%s/%s', Str::slug($category->name), date('Y'), date('m'))),
$fileName
);
$pdf->file_name = $pdffile->getClientOriginalName();
$pdf->file_path = 'uploads/pdf/'. Str::slug($category->name) .'/' . date('Y') . '/' . date('m') . '/' . $fileName;
$pdf->file_path = sprintf('storage/modelfiles/public_pdfs/%s/%s/%s/%s', Str::slug($category->name), date('Y'), date('m'), $fileName);
}
$pdf->is_published = $is_published;
$pdf->category_id = $categoryId;
$pdf->save();
$pdf->category_id = $categoryId;
return redirect()->route('bo.public-pdfs.edit', $pdf->id)->with('success', 'Enregistré !');
if ($pdf->saveOrFail()) {
return redirect()
->route('bo.public-pdfs.index')
->with('success', trans(
':model a été mis à jour',
['model' => 'PDF']
));
}
return back();
}
public function destroy($id)
{
$pdf = PublicPdfs::findOrFail($id);
if (file_exists(public_path() . '/' . $pdf->file_path))
unlink(public_path() . '/' . $pdf->file_path);
if (file_exists(storage_path(Str::replaceFirst('storage', 'app/public', $pdf->file_path)))) {
unlink(storage_path(Str::replaceFirst('storage', 'app/public', $pdf->file_path)));
}
$pdf->delete();
return redirect()->route('bo.public-pdfs.index');
if ($pdf->deleteOrFail()) {
return redirect()
->route('bo.public-pdfs.index')
->with('warning', trans(
':model a bien été supprimé',
['model' => 'PDF']
));
}
return back();
}
}

View file

@ -0,0 +1,84 @@
<?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
{
/**
* Display a listing of the resource.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Contracts\View\View
*/
public function index(Request $request): \Illuminate\Contracts\View\View
{
/** @var \Illuminate\Database\Eloquent\Builder $query */
$query = StaticPage::query();
/** @var string $search Search field */
$search = $request->search;
if ($search) {
$this->searchQuery(
$query,
$search,
null,
'title',
);
}
$searchFields = \implode(', ', [
trans('validation.attributes.title'),
]);
/** Sort columns with a query */
$this->sortQuery($query);
/** Custom pagination */
$staticPageModels = $this->paginate($query);
return view('bo.static_pages.index', compact('staticPageModels', 'search', 'searchFields'));
}
/**
* Show the form for editing the specified resource.
*
* @param \App\Models\StaticPage $static_page
* @return \Illuminate\Contracts\View\View
*/
public function edit(StaticPage $static_page): \Illuminate\Contracts\View\View
{
return view('bo.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))
]));
});
}
}

View file

@ -2,19 +2,25 @@
namespace App\Http\Controllers\Bo;
use App\Enums\UserRoleEnum;
use App\Http\Controllers\Controller;
use App\Http\Resources\UserCrmResource;
use App\Http\Requests\Bo\StoreUserRequest;
use App\Http\Requests\Bo\UpdateUserRequest;
use App\Models\User;
use App\Mail\InformProOpenAcess;
use Illuminate\Support\Facades\Mail;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Auth;
class UsersController extends Controller
{
/**
* UsersController
*
* @return void
*/
public function __construct()
{
$this->authorizeResource(User::class);
}
/**
* Display a listing of the resource.
*
@ -22,7 +28,10 @@ class UsersController extends Controller
*/
public function index()
{
$users = User::where('role', '>=', Auth::user()->role)->get();
/** @var \App\Models\User */
$loggedUser = Auth::guard('backend')->user();
$users = User::query()->where('role', '>=', $loggedUser->role)->paginate(20);
return view('bo.users.index', compact('users'));
}
@ -39,214 +48,83 @@ class UsersController extends Controller
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Http\Requests\Bo\StoreUserRequest $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
public function store(StoreUserRequest $request)
{
$request->validate([
'lastname' => 'required|string|max:255',
'firstname' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:8',
]);
/** @var \App\Models\User */
$loggedUser = Auth::guard('backend')->user();
$lastname = filter_var($request->lastname, FILTER_SANITIZE_STRING);
$firstname = filter_var($request->firstname, FILTER_SANITIZE_STRING);
$email = filter_var($request->email, FILTER_SANITIZE_EMAIL);
$password = $request->password;
$tokenMail = Str::uuid();
$role = $request->role;
$user = new User($request->validated());
$user->role = $loggedUser->role->equals(UserRoleEnum::superAdmin) ?
UserRoleEnum::make(\intval($request->role)) : $loggedUser->role;
$crmId = null;
$user = new User();
$user->crm_id = $crmId;
$user->firstname = $firstname;
$user->lastname = $lastname;
$user->email = $email;
$user->password = Hash::make($password);
$user->email_verify_token = $tokenMail;
$user->email_verified = 1;
if (Auth::user()->role < $role) {
$user->role = $role;
} else {
$user->role = Auth::user()->role;
if ($user->saveOrFail()) {
return redirect()
->route('bo.users.index')
->with('success', trans(
':model a été crée',
['model' => 'Utilisateur']
));
}
$user->save();
return redirect()->route('bo.users.index')
->with('success', "utilisateur créé.");
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
return back();
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @param \App\Models\User $user
* @return \Illuminate\Http\Response
*/
public function edit($id)
public function edit(User $user)
{
$user = User::findOrFail($id);
if ($user->role < Auth::user()->role) {
return redirect()->route('bo.users.index');
}
//infos CRM
if ($user->role >= 3) {
// on utilisera les apiData
return view('bo.users.edit_pro', compact('user'));
} else {
return view('bo.users.edit', compact('user'));
}
return view('bo.users.edit', ['user' => $user]);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
* @param \App\Http\Requests\Bo\UpdateUserRequest $request
* @param \App\Models\User $user
* @return \Illuminate\Http\RedirectResponse
*/
public function update(Request $request, $id)
public function update(UpdateUserRequest $request, User $user)
{
//basic information
$lastname = $request->lastname;
$firstname = $request->firstname;
$email = $request->email;
$password = $request->password;
$role = $request->role;
/** @var \App\Models\User */
$loggedUser = Auth::guard('backend')->user();
$request->validate([
'lastname' => 'required|string|max:255',
'firstname' => 'required|string|max:255',
]);
$user->fill($request->validated());
$user->role = $loggedUser->role->equals(UserRoleEnum::superAdmin) ?
UserRoleEnum::make(\intval($request->role)) : $loggedUser->role;
if (!empty($password)) {
$request->validate([
'password' => 'required|string|min:8'
]);
if ($user->saveOrFail()) {
return redirect()
->route('bo.users.index')
->with('success', trans(
':model a été mis à jour',
['model' => 'Utilisateur']
));
}
$user = User::findOrFail($id);
$user->lastname = $lastname;
$user->firstname = $firstname;
//check if mail has changed
if ($user->email != $email) {
//then validate
$request->validate([
'email' => 'required|string|email|max:255|unique:users',
]);
//and replace
$user->email = $email;
}
if (!empty($password)) {
$user->password = Hash::make($password);
}
if (Auth::user()->role < $role) {
$user->role = $role;
} else {
$user->role = Auth::user()->role;
}
$send_openaccess_mail = false;
if ($role == 3) {
//infos pro
$social_denomination = filter_var($request->social_denomination, FILTER_SANITIZE_STRING);
$tech_commercial = filter_var($request->tech_commercial, FILTER_SANITIZE_STRING);
$eleveur_volailles = isset($request->eleveur_volailles) ? true : false;
$eleveur_porcs = isset($request->eleveur_porcs) ? true : false;
$eleveur_bovins = isset($request->eleveur_bovins) ? true : false;
$capacite_stockage = filter_var($request->capacite_stockage, FILTER_SANITIZE_STRING);
$temps_chargement = filter_var($request->temps_chargement, FILTER_SANITIZE_STRING);
$stockage_aplat = isset($request->stockage_aplat) ? true : false;
$stockage_cellule = isset($request->stockage_cellule) ? true : false;
$adress_chargement = filter_var($request->adress_chargement, FILTER_SANITIZE_STRING);
$optional_contact = filter_var($request->optional_contact, FILTER_SANITIZE_STRING);
$num_client = filter_var($request->client_number, FILTER_SANITIZE_STRING);
$tc_id = $request->tc_id;
//check if num client has been filled
if (empty($user->client_number) && !empty($num_client)) {
//il va falloir envoyer un mail d'information d'accès
$send_openaccess_mail = true;
}
$user->social_denomination = $social_denomination;
$user->tech_commercial = $tech_commercial;
$user->eleveur_volailles = $eleveur_volailles;
$user->eleveur_porcs = $eleveur_porcs;
$user->eleveur_bovins = $eleveur_bovins;
$user->capacite_stockage = $capacite_stockage;
$user->temps_chargement = $temps_chargement;
$user->stockage_aplat = $stockage_aplat;
$user->stockage_cellule = $stockage_cellule;
$user->adress_chargement = $adress_chargement;
$user->optional_contact = $optional_contact;
$user->client_number = $num_client;
$user->tc_id = $tc_id;
$phone = $request->phone;
$user->apiData->phone = $phone;
$user->updateApiData(new UserCrmResource($user));
}
$user->save();
//envoi du mail d'ouverture
if ($send_openaccess_mail) {
Mail::to($email)->send(new InformProOpenAcess($user));
}
return redirect()->route('bo.users.edit', ['user' => $user->id])->with('success', 'Enregistré !');
return back();
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @param \App\Models\User $user
* @return \Illuminate\Http\Response
*/
public function destroy($id)
public function destroy(User $user)
{
$u = User::findOrFail($id);
//cannot delete self :
if (Auth::user()->id == $id) {
return redirect()
->route('bo.users.edit', ['user' => $id])
->withErrors('For security reasons you cannot delete yourself!');
}
if ($u->role < Auth::user()->role) {
//in theory you should never be here
if ($user->deleteOrFail()) {
return redirect()
->route('bo.users.index')
->withErrors('For security reasons you cannot delete this account!');
->with('warning', trans(
':model a bien été supprimé',
['model' => 'Utilisateur']
));
}
$u->delete();
return redirect()->route('bo.users.index');
return back();
}
}

View file

@ -1,13 +0,0 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class CSRController extends Controller
{
public function index(Request $request)
{
return view('front.csr');
}
}

View file

@ -1,13 +0,0 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ContactUsController extends Controller
{
public function index(Request $request)
{
return view('front.contactus');
}
}

View file

@ -5,9 +5,11 @@ namespace App\Http\Controllers;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
use Uwil\LaravelCommon\Controllers\Controller as BaseController;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
use AuthorizesRequests;
use DispatchesJobs;
use ValidatesRequests;
}

View file

@ -0,0 +1,17 @@
<?php
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
class AboutUsController extends Controller
{
/**
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
return view('fo.aboutus');
}
}

View file

@ -0,0 +1,35 @@
<?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;
/**
* Display the password confirmation view.
*
* @return \Illuminate\View\View
*/
public function showConfirmForm()
{
if (Auth::guard('frontend')->check()) {
return \response()->redirectToRoute('home');
}
return view('fo.auth.passwords.confirm');
}
/**
* Get the post register / login redirect path.
*
* @return string
*/
public function redirectPath()
{
return response()->redirectToRoute('fo.customer.dashboard')->getTargetUrl();
}
}

View file

@ -0,0 +1,83 @@
<?php
namespace App\Http\Controllers\Fo\Auth;
use App\Http\Controllers\Controller;
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
*/
private $message =
'Si votre compte existe vous devriez recevoir un message avec un lien pour réinitialiser votre mot de passe';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest:frontend');
$this->middleware('throttle:3,1')->only('sendResetLinkEmail');
}
/**
* Display the form to request a password reset link.
*
* @return \Illuminate\View\View
*/
public function showLinkRequestForm()
{
return view('fo.auth.passwords.email');
}
/**
* Get the broker to be used during password reset.
*
* @return \Illuminate\Contracts\Auth\PasswordBroker
*/
public function broker()
{
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)]);
}
}

View file

@ -0,0 +1,146 @@
<?php
namespace App\Http\Controllers\Fo\Auth;
use App\Http\Controllers\Controller;
use App\Models\Customer;
use App\Providers\RouteServiceProvider;
use Exception;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Session;
use LDC\LDCCRM\Models\Customer as CrmCustomer;
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()
{
return Auth::guard('frontend');
}
/**
* Show the application's login form.
*
* @return \Illuminate\View\View
*/
public function showLoginForm()
{
return view('fo.auth.login');
}
/**
* The user has been authenticated.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Database\Eloquent\Model $user
* @return mixed
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing, Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
*/
protected function authenticated(Request $request, Model $user)
{
$user->last_connection = \now();
$user->saveOrFail();
Session::flash('info', trans('Vous êtes à présent connecté'));
}
/**
* The user has logged out of the application.
*
* @param \Illuminate\Http\Request $request
* @return mixed
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
*/
protected function loggedOut(Request $request)
{
Session::flash('info', trans('Vous êtes à présent déconnecté'));
}
/**
* Get the post register / login redirect path.
*
* @return string
*/
public function redirectPath()
{
return response()->redirectToIntended()->getTargetUrl();
}
/**
* Attempt to log the user into the application.
*
* @param \Illuminate\Http\Request $request
* @return boolean
*/
protected function attemptLogin(Request $request): bool
{
$credentials = $this->credentials($request);
$customerModel = Customer::query()->where('email', Arr::get($credentials, 'email'))->first();
$crmCustomer = CrmCustomer::findWithEmail(Arr::get($credentials, 'email'));
// Check database customer.
if (!$customerModel) {
// Check crm customer.
if (!$crmCustomer) {
return false;
}
/** @var \App\Models\Customer $customerModel */
$customerModel = new Customer(Arr::only($crmCustomer->jsonSerialize(), [
'firstname',
'lastname',
'email',
]));
$customerModel->hashcode = $crmCustomer->hashcode;
if (!$customerModel->saveOrFail()) {
return false;
}
} else {
// Check crm customer.
if (!$crmCustomer) {
$customerModel->delete();
return false;
}
} //end if
try {
CrmCustomer::login(Arr::get($credentials, 'email'), Arr::get($credentials, 'password'));
} catch (Exception $ex) {
Log::error($ex);
return false;
}
$this->guard()->loginUsingId($customerModel->getKey());
return true;
}
}

View file

@ -0,0 +1,175 @@
<?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\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\Validation\ValidationException;
use LDC\LDCCRM\Enums\ApiError;
use LDC\LDCCRM\Enums\Country;
use LDC\LDCCRM\Exceptions\ApiErrorException;
use LDC\LDCCRM\Exceptions\ValidationException as ExceptionsValidationException;
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('fo.auth.register');
}
/**
* Get a validator for an incoming registration request.
*
* @param array $data
* @return \Illuminate\Contracts\Validation\Validator
* @throws \Illuminate\Validation\ValidationException If data is incorrect.
*/
protected function validator(array $data)
{
$data['ok_cgv'] = \request()->boolean('ok_cgv');
$data['phone'] = $data['phone'] ?? null;
$data['opt_in'] = ($data['opt_in'] ?? false) ? true : false;
return CreateAccountRequest::capture()->setContainer(app())->getValidator();
}
/**
* Create a new user instance after a valid registration.
*
* @param array $data
* @return \App\Models\Customer
* @throws \Illuminate\Validation\ValidationException If there are validation errors.
* @throws \RuntimeException On unhandled api Error.
*/
protected function create(array $data)
{
// * OK CGV has to be validated as true.
$data['country'] = Country::france;
$data['ok_cgv'] = \now();
$data['phone'] = Arr::get($data, 'phone');
$data['role'] = intval(Arr::get($data, 'user_cat'));
\collect([
'opt_in', 'eleveur.eleveur_porcs',
'eleveur.eleveur_volailles', 'stockage.stockage_aplat',
'eleveur.eleveur_bovins', 'stockage.stockage_cellule'
])->each(function (string $fieldName) use (&$data) {
$data[Arr::last(\explode('.', $fieldName))] = Arr::get($data, $fieldName) ? true : false;
});
try {
return DB::transaction(function () use ($data) {
$crmCustomer = new CrmCustomer($this->getOnlyCrmData($data));
// * Country Is forced to france
$crmCustomer->country = Country::france->value;
$crmCustomer->save();
// * Enregistrement du Hashcode
/** @var \App\Models\Customer $customer */
$customer = new Customer($data);
$customer->hashcode = $crmCustomer->hashcode;
$customer->role = $data['role'];
// * Customer will be logged in.
$customer->last_connection = \now();
$customer->saveOrFail();
if ($customer->saveOrFail()) {
// phpcs:ignore Generic.Files.LineLength.TooLong
Session::flash('success', trans('Votre compte à bien été crée, vous devez valider votre adresse email, un email de confirmation vous à été envoyé.'));
}
return $customer;
});
} catch (ApiErrorException $e) {
if ($e->getApiError()->equals(ApiError::customerExists)) {
throw ValidationException::withMessages([
'error' => 'Un compte est déjà associé à cette adresse email.'
]);
}
if ($e->getApiError()->equals(ApiError::validationFailed)) {
throw ValidationException::withMessages([
'error' => $e->getMessage()
]);
}
report($e);
Log::error(__CLASS__ . '::create reached end of possibilities.');
throw new \RuntimeException(__CLASS__ . '::create reached end of possibilities.');
} catch (ExceptionsValidationException $e) {
throw ValidationException::withMessages([
'error' => $e->getMessage()
]);
} //end try
}
/**
* Get the post register / login redirect path.
*
* @return string
*/
public function redirectPath()
{
return response()->redirectToRoute('fo.customer.dashboard')->getTargetUrl();
}
/**
* Get only data used in crm
*
* @param array $data
* @return array
*/
private function getOnlyCrmData(array $data): array
{
return \array_intersect_key(
$data,
[
'firstname' => '',
'lastname' => '',
'birth_date' => '',
'address' => '',
'postcode' => '',
'country' => '',
'city' => '',
'phone' => '',
'email' => '',
'password' => '',
'opt_in' => '',
]
);
}
}

View file

@ -0,0 +1,118 @@
<?php
namespace App\Http\Controllers\Fo\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Auth\Events\PasswordReset;
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');
}
/**
* Get the guard to be used during authentication.
*
* @return \Illuminate\Contracts\Auth\StatefulGuard
*/
protected function guard()
{
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\Factory|\Illuminate\View\View
*/
public function showResetForm(Request $request)
{
$token = $request->route()->parameter('token');
return view('fo.auth.passwords.reset')->with(
['token' => $token, 'email' => $request->email]
);
}
/**
* Reset the given user's password.
*
* @param mixed $customer
* @param mixed $password
* @return void
* @throws \Illuminate\Validation\ValidationException If something goes wrong.
*/
protected function resetPassword($customer, $password)
{
/** @var \LDC\LDCCRM\CrmApiV4 */
$crm = app('crmAPI');
try {
if (!($crmCustomer = $crm->getCustomer($customer->hashcode))) {
throw ValidationException::withMessages([
'error' => 'Changement impossible, compte inexistant.'
]);
}
$crmCustomer->password = $password;
$crmCustomer->save();
} catch (\TypeError | CrmException | ApiErrorException $e) {
report($e);
throw ValidationException::withMessages([
'error' => 'Une erreur est survenue, merci de réessayer ultérieurement.'
]);
} catch (ExceptionsValidationException $e) {
throw ValidationException::withMessages([
'error' => $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()
{
return response()->redirectToRoute('fo.customer.dashboard')->getTargetUrl();
}
/**
* Get the broker to be used during password reset.
*
* @return \Illuminate\Contracts\Auth\PasswordBroker
*/
public function broker()
{
return Password::broker('customers');
}
}

View file

@ -0,0 +1,47 @@
<?php
namespace App\Http\Controllers\Fo\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\VerifiesEmails;
use Illuminate\Http\Request;
class VerificationController extends Controller
{
use VerifiesEmails;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth:frontend');
$this->middleware('signed:relative')->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\View\View
*/
public function show(Request $request)
{
return $request->user()->hasVerifiedEmail()
? redirect($this->redirectPath())
: view('fo.auth.verify');
}
/**
* Get the post register / login redirect path.
*
* @return string
*/
public function redirectPath()
{
return response()->redirectToRoute('fo.customer.dashboard')->getTargetUrl();
}
}

View file

@ -0,0 +1,17 @@
<?php
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
class CSRController extends Controller
{
/**
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
return view('fo.csr');
}
}

View file

@ -0,0 +1,17 @@
<?php
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
class ContactUsController extends Controller
{
/**
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
return view('fo.contactus');
}
}

View file

@ -0,0 +1,25 @@
<?php
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
use App\Models\GeneralConfig;
use App\Models\HomeSliders;
class HomeController extends Controller
{
/**
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
$slides = HomeSliders::where([
['status', 1]
])->orderBy('order', 'ASC')->get();
$generalConfig = GeneralConfig::current();
return view('fo.home', compact('slides', 'generalConfig'));
}
}

View file

@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Fo;
use App\Enums\StaticPageType;
use App\Http\Controllers\Controller;
use App\Models\StaticPage;
class LegalNoticeController extends Controller
{
/**
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
$staticPageModel = StaticPage::query()->where('type', StaticPageType::legals)->first();
return view('fo.legalnotice', compact('staticPageModel'));
}
}

View file

@ -0,0 +1,35 @@
<?php
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
use App\Models\Articles;
class NewsController extends Controller
{
/**
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
$articles = Articles::where([
['status', 1],
['category_id', 1]
])->orderBy('created_at', 'ASC')->paginate(4);
return view('fo.news.index', compact('articles'));
}
/**
*
* @param string $slug
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function show(string $slug)
{
$article = Articles::where('slug', $slug)->firstOrFail();
return view('fo.news.article', compact('article'));
}
}

View file

@ -0,0 +1,32 @@
<?php
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
use App\Models\BusinessSector;
use App\Models\Employees;
use App\Models\GeneralConfig;
class OurTradeController extends Controller
{
/**
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
$secteurs_simples = BusinessSector::query()->orderBy('order', 'ASC')
->where('parent_id', null)->doesnthave('children')
->with('employees')->orderBy('order', 'ASC')->get();
$secteurs_complexes = BusinessSector::query()->orderBy('order', 'ASC')
->where('parent_id', null)->has('children')
->with('employees', 'children.employees')->orderBy('order', 'ASC')->get();
$nine_videos = Employees::query()->select('video', 'photo', 'firstname', 'lastname', 'job_title')
->whereNotNull('video')->inRandomOrder()->limit(9)->get();
$generalConfig = GeneralConfig::current();
return view('fo.ourtrade', compact('secteurs_simples', 'secteurs_complexes', 'nine_videos', 'generalConfig'));
}
}

View file

@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Fo;
use App\Enums\StaticPageType;
use App\Http\Controllers\Controller;
use App\Models\StaticPage;
class PrivacyPolicyController extends Controller
{
/**
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
$staticPageModel = StaticPage::query()->where('type', StaticPageType::confidentiality)->first();
return view('fo.privacypolicy', compact('staticPageModel'));
}
}

View file

@ -0,0 +1,164 @@
<?php
namespace App\Http\Controllers\Fo\Pro;
use App\Http\Controllers\Controller;
use App\Http\Requests\Fo\Customers\UpdateInfosRequest;
use App\Http\Requests\Fo\Customers\UpdatePasswordRequest;
use App\Http\Resources\CustomerCrmResource;
use App\Mail\InformProChangeInfos;
use App\Models\Customer;
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Illuminate\Validation\ValidationException;
use LDC\LDCCRM\Enums\ApiError;
use LDC\LDCCRM\Exceptions\ApiErrorException;
use LDC\LDCCRM\Exceptions\CrmException;
use LDC\LDCCRM\Exceptions\ValidationException as CrmValidationException;
class CustomerController extends Controller
{
/**
* CustomerController
*
* @return void
*/
public function __construct()
{
$this->authorizeResource(Customer::class);
}
/**
* Display a listing of the resource.
*
* @param \App\Models\Customer $customer
* @return \Illuminate\Http\Response
*/
public function edit(Customer $customer)
{
return view('fo.pro.customer.edit', [
'customer' => $customer
]);
}
/**
* Update the specified resource in storage.
*
* @param \App\Http\Requests\Fo\Customers\UpdateInfosRequest $request
* @param \App\Models\Customer $customer
* @return \Illuminate\Http\Response
*/
public function update(UpdateInfosRequest $request, Customer $customer)
{
return DB::transaction(function () use ($request, $customer) {
$data = \array_merge($request->validated(), ['tc_id' => $request->post('tc_id')]);
if ($this->updateCrmCustomerInfo($customer, $data)) {
// * envoi du mail de modification
$email = "contact.jeusselin@jeusselin.fr";
// TODO : should be an app setting.
Mail::to($email)->send(new InformProChangeInfos($customer));
return back()->with('success', trans('Vos informations ont bien été enregistrées.'));
}
return back()->withInput()->with(
'faillure',
trans(
'Une erreur est survenue, merci de réessayer ultérieurement.'
)
);
});
}
/**
* Customer change password view
*
* @param \App\Models\Customer $customer
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function password(Customer $customer)
{
$this->authorize('updatePassword', $customer);
return view('fo.pro.customer.change-mdp', ['customer' => $customer]);
}
/**
* Changement de mot de passe depuis le profil
*
* @param \App\Http\Requests\Fo\Customers\UpdatePasswordRequest $request
* @param \App\Models\Customer $customer
* @return \Illuminate\Http\RedirectResponse
*/
public function updatePassword(UpdatePasswordRequest $request, Customer $customer)
{
$this->authorize('updatePassword', $customer);
if ($this->updateCrmCustomerInfo($customer, ['password' => $request->post('password')])) {
event(new PasswordReset($customer));
return back()->with('success', trans('Vos informations ont bien été enregistrées.'));
}
return back()->withInput()->with(
'faillure',
trans('Une erreur est survenue, merci de réessayer ultérieurement.')
);
}
/**
* Updates user info
*
* @param \App\Models\Customer $customer
* @param array $data
* @return boolean
* @throws \Illuminate\Validation\ValidationException If something failed.
*/
private function updateCrmCustomerInfo(Customer $customer, array $data)
{
return DB::transaction(function () use ($customer, $data) {
try {
/** @var \LDC\LDCCRM\Models\Customer */
$crmCustomer = $customer->apiData;
if (\array_key_exists('email', $data)) {
$customer->email = $data['email'];
$customer->saveOrFail();
}
$crmCustomer->fill($data);
$saved = $crmCustomer->save();
$customer->api_data->fill($data);
$customer->fill(\array_intersect_key(
$data,
\array_flip($customer->getFillable()),
));
if (Arr::has($data, 'tc_id')) {
// * Theses props arent fillable
$customer->tc_id = \intval(Arr::get($data, 'tc_id'));
}
$customer->updateApiData(new CustomerCrmResource($customer));
$customer->saveOrFail();
return $saved;
} catch (CrmValidationException $e) {
throw ValidationException::withMessages([
'error' => $e->getMessage()
]);
} catch (CrmException $e) {
return false;
} catch (ApiErrorException $e) {
if ($e->getApiError()->equals(ApiError::validationFailed)) {
throw ValidationException::withMessages([
'error' => $e->getMessage()
]);
}
report($e);
return false;
} //end try
});
}
}

View file

@ -0,0 +1,165 @@
<?php
namespace App\Http\Controllers\Fo\Pro;
use App\Http\Controllers\Controller;
use App\Models\CotationsData;
use App\Models\Objectives;
use App\Models\PublicPdfs;
use App\Models\Articles;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Carbon;
class DashboardController extends Controller
{
/**
* AGRISPECTIVES
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index(Request $request)
{
// $cotations = CotationsData::whereNotNull('prix')->orderBy('produit')->orderBy('qualite')->orderBy('recolte')
$cotations = CotationsData::query()
->select('produit', 'qualite', 'recolte', DB::raw("GROUP_CONCAT(echeance,'::',COALESCE(prix,'--') SEPARATOR '|@|') AS prices"))
->whereNotNull('prix')
->groupBy('produit')
->groupBy('qualite')
->groupBy('recolte')
->orderBy('produit')
->get();
$mps = CotationsData::query()->select('produit')->distinct()->orderBy('produit')->get();
$dateMajCotations = CotationsData::query()->select('updated_at')->orderBy('id', 'DESC')->first();
$dbobjectif = new Objectives();
// * capte les nouvelles colonnes éventuelles
$nullData = array_combine(
$dbobjectif->getFillable(),
array_fill(0, count($dbobjectif->getFillable()), null)
);
$dbobjectif->fill($nullData);
$dbobjectif->produit = '--';
$dbobjectif->qualite = '--';
$dbobjectif->campagne = '--';
$dbobjectif->quantite = 0;
// $dbobjectif->prix = 0;
$dbobjectif->echeance = '--';
$dbobjectif->volume_restant = 0;
// $dbobjectif->observations = '';
$dbmyObjectives = Objectives::query()->with('status')->whereHas('customer', function (Builder $q) {
$q->where('id', Auth::guard('frontend')->user()->id);
})->orderBy('updated_at', 'DESC')->get();
$formEnums = $this->getObjectivesFormEnums();
$pdfsAnalyse = PublicPdfs::query()->where('category_id', 1)
->where('is_published', true)->orderBy('created_at', 'DESC')->get();
$pdfsMarches = PublicPdfs::query()->where('category_id', 2)
->where('is_published', true)->orderBy('created_at', 'DESC')->get();
// * par défaut le marché est fermé
// * si on est (un jour de semaine) après 11h ou avant 17h45 alors ouvert
$market_closed = true;
// * Current time
$time = Carbon::now();
// * set time to 11:00
$start = Carbon::create($time->year, $time->month, $time->day, 11, 0, 0);
// * set time to 17:45
$end = Carbon::create($time->year, $time->month, $time->day, 17, 45, 0);
if ($time->isWeekday()) {
if ($time->between($start, $end, true)) {
$market_closed = false;
}
}
if (!$dateMajCotations) {
$noCotationsYet = true;
} else {
$dayMaj = Carbon::createFromFormat('Y-m-d H:i:s', $dateMajCotations->updated_at)->startOfDay();
$today = Carbon::now()->startOfDay();
// * we suppose we have cotations today
$noCotationsYet = false;
if ($today > $dayMaj) {
// * we don't have the cotations yet
$noCotationsYet = true;
}
}
$articles = Articles::where([
['status', 1],
['category_id', 2]
])->orderBy('created_at', 'ASC')->paginate(4);
$objectivesData = [
'dbobjectif' => $dbobjectif,
'dbmyObjectives' => $dbmyObjectives,
'formEnums' => $formEnums,
];
return view(
'fo.pro.dashboard.index',
compact(
'cotations',
'mps',
'objectivesData',
'pdfsAnalyse',
'pdfsMarches',
'dateMajCotations',
'market_closed',
'noCotationsYet',
'articles'
)
);
}
public function waiting(Request $request)
{
/** @var \App\Models\Customer */
$customer = Auth::guard('frontend')->user();
if ($customer->is_validated_pro) {
return \response()->redirectToRoute('fo.pro.dashboard');
}
return view('fo.pro.dashboard.waiting');
}
private function getObjectivesFormEnums()
{
$enums = array();
/** @var \Illuminate\Database\Eloquent\Collection<integer,\App\Models\CotationsData> */
$produitEnum = CotationsData::query()->select('produit AS value')->distinct()->get();
$enums['produit'] = $produitEnum;
$qualiteEnum = array();
foreach ($produitEnum as $produit) {
$qualiteEnum[$produit->value] = CotationsData::query()
->select('qualite AS value')->distinct()->where('produit', $produit->value)->get();
}
$enums['qualite'] = $qualiteEnum;
$campagneEnum = array();
foreach ($produitEnum as $produit) {
$campagneEnum[$produit->value] = CotationsData::query()
->select('recolte AS value')->distinct()->where('produit', $produit->value)->get();
}
$enums['campagne'] = $campagneEnum;
$echeanceEnum = array();
foreach ($produitEnum as $produit) {
foreach ($campagneEnum[$produit->value] as $campagne) {
$echeanceEnum[$produit->value][$campagne->value] = CotationsData::query()
->select('echeance AS value')->distinct()
->where('produit', $produit->value)
->where('recolte', $campagne->value)
->whereNotNull('prix')
->get();
}
}
$enums['echeance'] = $echeanceEnum;
return $enums;
}
}

View file

@ -0,0 +1,82 @@
<?php
namespace App\Http\Controllers\Fo\Pro;
use App\Http\Controllers\Controller;
use App\Models\Objectives;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class ObjectivesController extends Controller
{
/**
* Remove the specified resource from storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function destroy(Request $request)
{
$deleteOk = 0;
if ($request->id !== null) {
$objectif = Objectives::findOrFail($request->id);
if ($objectif->customer_id == Auth::guard('frontend')->user()->id) {
$objectif->delete();
} else {
$deleteOk = 3;
}
} else {
$deleteOk = 2;
}
return $deleteOk;
}
/**
* Store a newly created resource or update an existing one
* @param \Illuminate\Http\Request $request
* @return array $objectif
*/
public function saveProDatas(Request $request)
{
// save data from Pro dashboard
$objectif = $request->objectif;
if (isset($objectif["id"])) {
$o = Objectives::findOrFail($objectif["id"]);
$o->produit = $objectif["produit"];
$o->qualite = $objectif["qualite"];
$o->quantite = $objectif["quantite"];
$o->campagne = $objectif["campagne"];
$o->prix = $objectif["prix"];
$o->echeance = $objectif["echeance"];
$o->volume_restant = $objectif["volume_restant"];
$o->observations = $objectif["observations"];
$o->save();
$objectif["status_id"] = $o->status_id;
$objectif["status"] = $o->status;
} else {
$o = Objectives::updateOrCreate([
'produit' => $objectif["produit"],
'qualite' => $objectif["qualite"],
'quantite' => $objectif["quantite"],
'campagne' => $objectif["campagne"],
'prix' => $objectif["prix"],
'echeance' => $objectif["echeance"],
'volume_restant' => $objectif["volume_restant"],
'observations' => $objectif["observations"],
'customer_id' => Auth::guard('frontend')->user()->id,
'status_id' => 1,
]);
$objectif["id"] = $o->id;
$objectif["status_id"] = $o->status_id;
$objectif["status"] = $o->status;
unset($objectif["customer_id"]);
} //end if
return $objectif;
}
}

View file

@ -0,0 +1,17 @@
<?php
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
class SearchController extends Controller
{
/**
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
return view('fo.search');
}
}

View file

@ -1,18 +0,0 @@
<?php
namespace App\Http\Controllers;
use App\Models\HomeSliders;
use Illuminate\Http\Request;
class HomeController extends Controller
{
public function index(Request $request)
{
$slides = HomeSliders::where([
['status', 1]
])->orderBy('order', 'ASC')->get();
return view('home', compact('slides'));
}
}

View file

@ -1,13 +0,0 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class LegalNoticeController extends Controller
{
public function index(Request $request)
{
return view('front.legalnotice');
}
}

View file

@ -1,28 +0,0 @@
<?php
namespace App\Http\Controllers;
use App\Models\Articles;
use Illuminate\Http\Request;
class NewsController extends Controller
{
public function index(Request $request)
{
$articles = Articles::where([
['status', 1],
['category_id', 1]
])->orderBy('created_at', 'ASC')->paginate(4);
//$articles = $articles->paginate();
return view('front.news.index', compact('articles'));
}
public function show($slug)
{
$article = Articles::where('slug', $slug)->first();
return view('front.news.article', compact('article'));
}
}

View file

@ -1,21 +0,0 @@
<?php
namespace App\Http\Controllers;
use App\Models\BusinessSector;
use App\Models\Employees;
use Illuminate\Http\Request;
class OurTradeController extends Controller
{
public function index(Request $request)
{
$secteurs_simples = BusinessSector::orderBy('order', 'ASC')->where('parent_id', null)->doesnthave('children')->with('employees')->orderBy('order', 'ASC')->get();
$secteurs_complexes = BusinessSector::orderBy('order', 'ASC')->where('parent_id', null)->has('children')->with('employees','children.employees')->orderBy('order', 'ASC')->get();
//$secteurs->employees->sortBy('order');
$nine_videos = Employees::select('video','photo','firstname','lastname','job_title')->whereNotNull('video')->inRandomOrder()->limit(9)->get();
return view('front.ourtrade', compact('secteurs_simples','secteurs_complexes','nine_videos'));
}
}

View file

@ -1,13 +0,0 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PrivacyPolicyController extends Controller
{
public function index(Request $request)
{
return view('front.privacypolicy');
}
}

View file

@ -1,140 +0,0 @@
<?php
namespace App\Http\Controllers\Pro;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use App\Http\Requests\UpdateInfosRequest;
use App\Http\Resources\UserCrmResource;
use Illuminate\Support\Facades\Mail;
use App\Mail\InformProChangeInfos;
use Illuminate\Http\Request;
class CustomerController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function mesInfos()
{
//récupérer les infos
$user = User::findOrFail(Auth::user()->id);
return view('pro.customer.infos', compact('user'));
}
/**
* Update the specified resource in storage.
*
* @param UpdateInfosRequest $request
* @return \Illuminate\Http\Response
*/
public function updateInfos(UpdateInfosRequest $request)
{
//basic information
$lastname = $request->lastname;
$firstname = $request->firstname;
$email = $request->email;
$password = $request->password;
$role = $request->role;
$user = User::findOrFail(Auth::user()->id);
$user->lastname = $lastname;
$user->firstname = $firstname;
//check if mail has changed
if ($user->email != $email) {
//then validate
$request->validate([
'email' => 'required|string|email|max:255|unique:users',
]);
//and replace
$user->email = $email;
}
if ($user->role == 3) {
//infos pro
$social_denomination = filter_var($request->social_denomination, FILTER_SANITIZE_STRING);
$tech_commercial = filter_var($request->tech_commercial, FILTER_SANITIZE_STRING);
$eleveur_volailles = isset($request->eleveur_volailles) ? true : false;
$eleveur_porcs = isset($request->eleveur_porcs) ? true : false;
$eleveur_bovins = isset($request->eleveur_bovins) ? true : false;
$capacite_stockage = filter_var($request->capacite_stockage, FILTER_SANITIZE_STRING);
$temps_chargement = filter_var($request->temps_chargement, FILTER_SANITIZE_STRING);
$stockage_aplat = isset($request->stockage_aplat) ? true : false;
$stockage_cellule = isset($request->stockage_cellule) ? true : false;
$adress_chargement = filter_var($request->adress_chargement, FILTER_SANITIZE_STRING);
$optional_contact = filter_var($request->optional_contact, FILTER_SANITIZE_STRING);
$user->social_denomination = $social_denomination;
$user->tech_commercial = $tech_commercial;
$user->eleveur_volailles = $eleveur_volailles;
$user->eleveur_porcs = $eleveur_porcs;
$user->eleveur_bovins = $eleveur_bovins;
$user->capacite_stockage = $capacite_stockage;
$user->temps_chargement = $temps_chargement;
$user->stockage_aplat = $stockage_aplat;
$user->stockage_cellule = $stockage_cellule;
$user->adress_chargement = $adress_chargement;
$user->optional_contact = $optional_contact;
$phone = $request->phone;
$birth_date = $request->birth_date;
$address = $request->address;
$city = $request->city;
$postcode = $request->postcode;
$optin = $request->news !== null ? 1 : 0;
$user->apiData->firstname = $firstname;
$user->apiData->lastname = $lastname;
$user->apiData->email = $email;
$user->apiData->birth_date = $birth_date;
$user->apiData->phone = $phone;
$user->apiData->address = $address;
$user->apiData->city = $city;
$user->apiData->postcode = $postcode;
$user->apiData->opt_in = $optin;
$user->updateApiData(new UserCrmResource($user));
}
$user->save();
//envoi du mail de modification
$email = "contact.jeusselin@jeusselin.fr"; // TODO : should be an app setting
Mail::to($email)->send(new InformProChangeInfos($user));
return redirect()->route('pro.mes-infos')->with('success', 'Enregistré !');
}
public function changePassword() {
return view('pro.customer.change-mdp');
}
/**
* changement de mot de passe depuis le profil
*/
public function changePasswordWhenAuthenticated(Request $request)
{
$request->validate([
'password' => 'required|min:8|confirmed|max:255'
]);
$crm = app('crmApi');
$customer = $crm->changePwdCustomer(Auth::guard('web')->user()->crm_id, $request->password);
if ($customer->status === "OK") {
return back()->with('success', __("Modifications enregistrées !"));
} else {
return back()->withErrors(__("Une erreur est survenue, merci de réessayer ultérieurement."));
}
}
}

View file

@ -1,120 +0,0 @@
<?php
namespace App\Http\Controllers\Pro;
use App\Http\Controllers\Controller;
use App\Models\Cotations;
use App\Models\CotationsData;
use App\Models\Objectives;
use App\Models\PublicPdfs;
use App\Models\Articles;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Carbon;
class DashboardController extends Controller
{
public function index(Request $request)
{
//$cotations = CotationsData::whereNotNull('prix')->orderBy('produit')->orderBy('qualite')->orderBy('recolte')
$cotations = CotationsData::select('produit','qualite','recolte', DB::raw("GROUP_CONCAT(echeance,'::',COALESCE(prix,'--') SEPARATOR '|@|') AS prices"))
->whereNotNull('prix')
->groupBy('produit')
->groupBy('qualite')
->groupBy('recolte')
->orderBy('produit')
->get();
$mps = CotationsData::select('produit')->distinct()->orderBy('produit')->get();
setlocale(LC_TIME, config('app.locale'));
$dateMajCotations = CotationsData::select('updated_at')->orderBy('id','DESC')->first();
$dbobjectif = new Objectives();
//capte les nouvelles colonnes éventuelles
$nullData= array_combine(
$dbobjectif->getFillable(),
array_fill(0, count($dbobjectif->getFillable()), null)
);
$dbobjectif->fill($nullData);
$dbobjectif->produit = '--';
$dbobjectif->qualite = '--';
$dbobjectif->campagne = '--';
$dbobjectif->quantite = 0;
//$dbobjectif->prix = 0;
$dbobjectif->echeance = '--';
$dbobjectif->volume_restant = 0;
//$dbobjectif->observations = '';
$dbmyObjectives = Objectives::with('status')->where('user_id',Auth::user()->id)->orderBy('updated_at','DESC')->get();
$formEnums = $this->getObjectivesFormEnums();
$pdfsAnalyse = PublicPdfs::where('category_id',1)->where('is_published',1)->orderBy('created_at','DESC')->get();
$pdfsMarches = PublicPdfs::where('category_id',2)->where('is_published',1)->orderBy('created_at','DESC')->get();
//par défaut le marché est fermé
$market_closed = true;
//si on est (un jour de semaine) après 11h ou avant 17h45 alors ouvert
$time = Carbon::now(); // Current time
$start = Carbon::create($time->year, $time->month, $time->day, 11, 0, 0); //set time to 11:00
$end = Carbon::create($time->year, $time->month, $time->day, 17, 45, 0); //set time to 17:45
if ($time->isWeekday()) {
if ($time->between($start, $end, true)) {
$market_closed = false;
}
}
$dayMaj = Carbon::createFromFormat('Y-m-d H:i:s', $dateMajCotations->updated_at)->startOfDay();
$today = Carbon::now()->startOfDay();
$noCotationsYet = false; //we suppose we have cotations today
if ($today > $dayMaj) {
$noCotationsYet = true; //we don't have the cotations yet
}
$articles = Articles::where([
['status', 1],
['category_id', 2]
])->orderBy('created_at', 'ASC')->paginate(4);
return view('pro.dashboard.index', compact('cotations', 'mps', 'dbobjectif', 'dbmyObjectives', 'formEnums', 'pdfsAnalyse', 'pdfsMarches', 'dateMajCotations', 'market_closed', 'noCotationsYet' ,'articles'));
}
public function waiting(Request $request)
{
return view('pro.dashboard.waiting');
}
private function getObjectivesFormEnums() {
$enums = array();
$produitEnum = CotationsData::select('produit AS value')->distinct()->get();
$enums['produit'] = $produitEnum;
$qualiteEnum = array();
foreach ($produitEnum as $produit) {
$qualiteEnum[$produit->value] = CotationsData::select('qualite AS value')->distinct()->where('produit',$produit->value)->get();
}
$enums['qualite'] = $qualiteEnum;
$campagneEnum = array();
foreach ($produitEnum as $produit) {
$campagneEnum[$produit->value] = CotationsData::select('recolte AS value')->distinct()->where('produit',$produit->value)->get();
}
$enums['campagne'] = $campagneEnum;
$echeanceEnum = array();
foreach ($produitEnum as $produit) {
foreach($campagneEnum[$produit->value] as $campagne) {
$echeanceEnum[$produit->value][$campagne->value] = CotationsData::select('echeance AS value')->distinct()
->where('produit',$produit->value)
->where('recolte',$campagne->value)
->whereNotNull('prix')
->get();
}
}
$enums['echeance'] = $echeanceEnum;
return $enums;
}
}

View file

@ -1,13 +0,0 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class SearchController extends Controller
{
public function index(Request $request)
{
return view('front.search');
}
}

View file

@ -14,9 +14,9 @@ class Kernel extends HttpKernel
* @var array
*/
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Fruitcake\Cors\HandleCors::class,
\Illuminate\Http\Middleware\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
@ -30,17 +30,25 @@ class Kernel extends HttpKernel
*/
protected $middlewareGroups = [
'web' => [
'htmlsanitize',
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\SecureHeaders::class
],
'saml' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
],
'api' => [
'throttle:api',
'throttle:40,1',
\Illuminate\Routing\Middleware\ThrottleRequests::class . ':api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
@ -55,16 +63,18 @@ class Kernel extends HttpKernel
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::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,
'admin' => \App\Http\Middleware\Admin::class,
// * Filter only role CustomerTypeEnum::professional()
'pro' => \App\Http\Middleware\Pro::class,
// * Filter has client_number
'valid-pro' => \App\Http\Middleware\ValidPro::class,
'secu-bo' => \App\Http\Middleware\LdcSecureBo::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'htmlsanitize' => \Uwil\LaravelCommon\Middlewares\HtmlSanitizer::class,
];
}

View file

@ -1,25 +0,0 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class Admin
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
$role = Auth::user()->role;
if ($role <= 2)
return $next($request);
abort(404, "Cette page n'existe pas.");
}
}

View file

@ -3,19 +3,36 @@
namespace App\Http\Middleware;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
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 mixed $request
* @return string|null
*/
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
$logins = [
'frontend' => route('login'),
'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('login');
}
abort(401);
}
}

View file

@ -12,6 +12,5 @@ class EncryptCookies extends Middleware
* @var array
*/
protected $except = [
//
];
];
}

View file

@ -0,0 +1,63 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Uwil\LaravelCommon\Helpers\ToolboxHelper as ToolboxHelper;
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
): \Symfony\Component\HttpFoundation\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);
}
}

View file

@ -1,22 +0,0 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class LdcSecureBo
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
//check if user for bo is within trusted network
return $next($request);
}
}

View file

@ -0,0 +1,28 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class LogoutUnpublishedUsers
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
/** @var \App\Models\User|null $userModel */
$userModel = Auth::user();
if (!is_null($userModel) && !$userModel->published) {
Auth::logout();
return redirect()->route('bo.login')->with('warning', trans('auth.unpublished_user'));
}
return $next($request);
}
}

View file

@ -12,6 +12,5 @@ class PreventRequestsDuringMaintenance extends Middleware
* @var array
*/
protected $except = [
//
];
];
}

View file

@ -2,7 +2,7 @@
namespace App\Http\Middleware;
use Closure;
use App\Enums\CustomerTypeEnum;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
@ -11,14 +11,15 @@ class Pro
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
public function handle(Request $request, \Closure $next)
{
$role = Auth::user()->role;
if ($role == 3) {
/** @var \App\Models\Customer|null */
$customer = Auth::guard('frontend')->user();
if ($customer and $customer->role->equals(CustomerTypeEnum::professional)) {
return $next($request);
}

View file

@ -2,8 +2,6 @@
namespace App\Http\Middleware;
use App\Providers\RouteServiceProvider;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
@ -12,18 +10,28 @@ class RedirectIfAuthenticated
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null ...$guards
* @return mixed
* @phpcs:disable Generic.Files.LineLength.TooLong
* @param \Illuminate\Http\Request $request
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @param string|null ...$guards
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
* @throws \RuntimeException If guard is unhandled.
* @phpcs:enable
*/
public function handle(Request $request, Closure $next, ...$guards)
public function handle(Request $request, \Closure $next, ...$guards)
{
$guards = empty($guards) ? [null] : $guards;
foreach ($guards as $guard) {
if (Auth::guard($guard)->check()) {
return redirect(RouteServiceProvider::HOME);
switch ($guard) {
case 'frontend':
return \redirect()->route('fo.home');
case 'backend':
return \redirect()->route('bo.dashboard');
default:
throw new \RuntimeException("Unhandled guard `{$guard}` .");
}
}
}

View file

@ -0,0 +1,121 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\View;
use Illuminate\Support\Facades\Vite;
class SecureHeaders
{
/**
* Enumerate headers which you do not want in your application's responses.
* Great starting point would be to go check out @Scott_Helme's:
* https://securityheaders.com/
*
* @var array
*/
private $unwantedHeaderList = [
'X-Powered-By',
'Server',
];
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return \Symfony\Component\HttpFoundation\Response
*/
public function handle(Request $request, \Closure $next): \Symfony\Component\HttpFoundation\Response
{
// * For Vite DEV
$host = \parse_url(\config('app.url'), \PHP_URL_HOST);
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;');
$cspPolicies = [
"default-src 'none';",
"manifest-src 'self';",
// * CKEDITOR Specific https://ckeditor.com/docs/ckeditor5/latest/installation/advanced/csp.html
"connect-src 'self' blob: " . implode(' ', [
// * VITE DEV
config('app.debug') ? "wss://{$host}:4443" : '',
config('app.debug') ? "https://{$host}:4443" : '',
'https://yl.s-web.fr'
]) . ';',
"img-src 'self' data: blob: " . implode(' ', [
// * VITE DEV
config('app.debug') ? "https://{$host}:4443" : '',
]) . ';',
"object-src 'self' " . implode(' ', []) . ';',
"frame-src 'self' " . implode(' ', [
'https://www.google.com/recaptcha/',
'https://recaptcha.google.com/recaptcha/',
'https://www.google.com/maps/',
'https://maps.google.com/',
'https://www.youtube.com',
'https://player.vimeo.com',
'blob:'
]) . ';',
"font-src 'self' data: " . \implode(' ', [
// * VITE DEV
config('app.debug') ? "https://{$host}:4443" : '',
'https://fonts.gstatic.com;'
]) . ';',
// ! Using CKEditor will must have unsafe-inline style
// phpcs:ignore Generic.Files.LineLength.TooLong
"style-src 'self' 'unsafe-inline' " . \implode(' ', [
'https://cdnjs.cloudflare.com',
// * File Manager
'https://fonts.googleapis.com',
'https://cdn.jsdelivr.net',
'https://use.fontawesome.com',
'https://fonts.googleapis.com',
// * VITE DEV
config('app.debug') ? "https://{$host}:4443" : ''
]) . ';',
// ! If you dont use ckeditor use this
// "style-src 'self' 'nonce-$nonce';",
// phpcs:ignore Generic.Files.LineLength.TooLong
"script-src 'self' {$jsDev} " . \implode(' ', [
'https: blob:',
'https://www.googletagmanager.com',
'https://cdnjs.cloudflare.com',
"$scheme://www.google-analytics.com",
// * VITE DEV
config('app.debug') ? "https://{$host}:4443" : '',
]) . ';'
];
$response->headers->set(
'Content-Security-Policy',
implode(' ', $cspPolicies) . $reportUri
);
$response->headers->set('Feature-Policy', 'fullscreen=(self \'https://www.youtube.com\');');
return $response;
}
/**
* Remove unwanted headers.
*
* @param array $headerList
* @return void
*/
private function removeUnwantedHeaders(array $headerList): void
{
foreach ($headerList as $header) {
header_remove($header);
}
}
}

View file

@ -2,7 +2,7 @@
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
@ -10,14 +10,18 @@ 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_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO | Request::HEADER_X_FORWARDED_AWS_ELB;
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;
}

View file

@ -2,7 +2,6 @@
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
@ -11,16 +10,17 @@ class ValidPro
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
public function handle(Request $request, \Closure $next)
{
$client_num = Auth::user()->client_number;
if (!empty($client_num)) {
/** @var \App\Models\Customer|null */
$customer = Auth::guard('frontend')->user();
if ($customer and $customer->is_validated_pro) {
return $next($request);
}
return redirect()->route('pro.pending-validation');
return redirect()->route('fo.pro.pending-validation');
}
}

View file

@ -12,6 +12,5 @@ class VerifyCsrfToken extends Middleware
* @var array
*/
protected $except = [
//
];
];
}

View file

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

View file

@ -0,0 +1,36 @@
<?php
namespace App\Http\Requests\Bo;
use App\Enums\UserRoleEnum;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rules\Enum;
class StoreUserRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return boolean
*/
public function authorize()
{
return \auth('backend')->check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'lastname' => 'required|string|max:255',
'firstname' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:8',
'role' => new Enum(UserRoleEnum::class)
];
}
}

View file

@ -0,0 +1,38 @@
<?php
namespace App\Http\Requests\Bo;
use App\Enums\CustomerTypeEnum;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rules\Enum;
class UpdateCustomerRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return boolean
*/
public function authorize()
{
return auth('backend')->check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'tc_id' => 'nullable|digits_between:1,16',
'client_number' => [
!empty($this->customer->client_number) ? 'required' : 'nullable',
'digits_between:1,16'
],
'phone' => 'nullable|string|max:15',
'role' => ['required', new Enum(CustomerTypeEnum::class)]
];
}
}

View file

@ -0,0 +1,42 @@
<?php
namespace App\Http\Requests\Bo;
use Illuminate\Validation\Rule;
class UpdateUserRequest extends StoreUserRequest
{
/**
* Prepare the data for validation.
*
* @return void
*/
public function prepareForValidation()
{
if (empty($this->post('password'))) {
$this->offsetUnset('password');
}
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return \array_merge(
parent::rules(),
[
'password' => 'sometimes|string|min:8',
'email' => [
'required',
'string',
'email',
'max:255',
(new Rule())->unique('users')->ignore($this->user->id)
]
]
);
}
}

View file

@ -0,0 +1,167 @@
<?php
namespace App\Http\Requests\Fo\Customers;
use App\Enums\CustomerTypeEnum;
use App\Rules\Adult;
use BadMethodCallException;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rules\Enum;
use Illuminate\Validation\Rules\Password;
use LDC\LDCCRM\Enums\Country;
class CreateAccountRequest extends FormRequest
{
/**
* Get the validator
*
* @return \Illuminate\Contracts\Validation\Validator
*/
public function getValidator(): Validator
{
$this->prepareForValidation();
return $this->getValidatorInstance();
}
/**
* Determine if the user is authorized to make this request.
*
* @return boolean
*/
public function authorize()
{
return true;
}
/**
* Prepare the data for validation.
*
* @return void
*/
protected function prepareForValidation()
{
$this->merge([
'phone' => $this->phone,
'opt_in' => $this->opt_in ? true : false,
'eleveur_porcs' => $this->boolean('eleveur.eleveur_porcs') ? true : false,
'eleveur_volailles' => $this->boolean('eleveur.eleveur_volailles') ? true : false,
'eleveur_bovins' => $this->boolean('eleveur.eleveur_bovins') ? true : false,
'stockage_aplat' => $this->boolean('stockage.stockage_aplat') ? true : false,
'stockage_cellule' => $this->boolean('stockage.stockage_cellule') ? true : false,
'role' => \ctype_digit($this->user_cat) ? \intval($this->user_cat) : $this->user_cat,
]);
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$requiredIfRoleIsPro = 'sometimes';
try {
$role = $this->customer ? $this->customer->role : CustomerTypeEnum::make($this->role);
if ($role->equals(CustomerTypeEnum::professional)) {
$requiredIfRoleIsPro = 'required';
}
} catch (BadMethodCallException | \TypeError $e) {
$requiredIfRoleIsPro = 'sometimes';
}
return [
'lastname' => 'required|string|max:255',
'firstname' => 'required|string|max:255',
'phone' => 'nullable|max:255',
'address' => 'required|string|min:1|max:255',
'postcode' => 'required|string|min:1',
'city' => 'required|string|min:1|max:255',
'birth_date' => ['required', new Adult(trans('Vous devez être majeur pour vous inscrire.'))],
'email' => [
'required', 'email:rfc,dns,spoof', 'max:255',
'unique:customers,email',
],
'password' => [
'required', 'confirmed', Password::min(8)->mixedCase()->numbers()->symbols()
],
'ok_cgv' => 'accepted',
'opt_in' => 'required|boolean',
// * Spécific jeusselin
'role' => ['required', new Enum(CustomerTypeEnum::class)],
'social_denomination' => "{$requiredIfRoleIsPro}|max:255",
'tech_commercial' => "{$requiredIfRoleIsPro}|string|max:255",
'siret' => "{$requiredIfRoleIsPro}|string|max:255",
'numtva' => "{$requiredIfRoleIsPro}|string|max:255",
'certiphyto' => "{$requiredIfRoleIsPro}|string|max:255",
'certiphyto_date' => "{$requiredIfRoleIsPro}|string|max:255",
'eleveur' => "{$requiredIfRoleIsPro}|array|min:1",
'eleveur_porcs' => "required_with:eleveur|boolean",
'eleveur_volailles' => "required_with:eleveur|boolean",
'eleveur_bovins' => "required_with:eleveur|boolean",
'capacite_stockage' => "{$requiredIfRoleIsPro}|string|max:255",
'temps_chargement' => "{$requiredIfRoleIsPro}|string|max:255",
'stockage' => "{$requiredIfRoleIsPro}|array|min:1",
'stockage_aplat' => "required_with:stockage|boolean",
'stockage_cellule' => "required_with:stockage|boolean",
'adress_chargement' => "present|nullable|string|max:255",
'optional_contact' => "present|nullable|string|max:255",
];
}
/**
* Get custom attributes for validator errors.
* @return array
*/
public function attributes()
{
return [
'lastname' => trans('nom'),
'firstname' => trans('prénom'),
'phone' => trans('téléphone'),
'address' => trans('adresse'),
'postcode' => trans('code postal'),
'city' => trans('ville'),
'birth_date' => trans('date de naissance'),
'email' => trans('email'),
'password' => trans('mot de passe'),
'ok_cgv' => trans('conditions d\'utilisation'),
'opt_in' => trans('newsletter'),
'role' => trans('êtes-vous un agriculteur'),
'social_denomination' => trans('dénomination sociale'),
'tech_commercial' => trans('technico commercial'),
'siret' => trans('siret'),
'certiphyto_date' => trans('date de validité'),
'numtva' => trans('numéro de tva'),
'certiphyto' => trans('numéro de certiphyto'),
'certiphyto_date' => trans('numéro de certiphyto'),
'eleveur' => trans('éleveur de'),
'capacite_stockage' => trans('capacité de stockage'),
'temps_chargement' => trans('temps de chargement'),
'stockage' => trans('type de stockage'),
'adress_chargement' => trans('adresse de chargement'),
'optional_contact' => trans('contact à joindre'),
];
}
/**
* Get custom messages for validator errors.
*
* @return array
*/
public function messages()
{
return [
'phone.phone' => trans('Le champ :attribute est invalide, il accepte les numéros des
pays suivants :countries.', ['countries' => Country::france->label()]),
'country.in' => trans('Le champ :attribute est invalide, il accepte les pays
suivants :countries.', ['countries' => Country::france->label()]),
'email.unique' => trans('Un compte existe déjà avec cette adresse.'),
'ok_cgv.accepted' => trans('Vous devez accepter les conditions d\'utilisation du site pour continuer.')
];
}
}

View file

@ -0,0 +1,33 @@
<?php
namespace App\Http\Requests\Fo\Customers;
use Illuminate\Support\Facades\Auth;
class UpdateInfosRequest extends CreateAccountRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return boolean
*/
public function authorize()
{
return Auth::guard('frontend')->check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$rules = parent::rules();
unset($rules['email']);
unset($rules['password']);
unset($rules['role']);
unset($rules['ok_cgv']);
return $rules;
}
}

View file

@ -0,0 +1,54 @@
<?php
namespace App\Http\Requests\Fo\Customers;
use App\Rules\CrmCustomerPassword;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rules\Password;
class UpdatePasswordRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return boolean
*/
public function authorize()
{
return auth('frontend')->check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
/** @var \Ldc\LDCCRM\Models\Customer */
$crmCustomer = \auth('frontend')->user()->api_data;
return [
'old_password' => [
'required',
new CrmCustomerPassword($crmCustomer)
],
'password' => [
'required', 'string', 'max:255', 'confirmed',
Password::min(8)->mixedCase()->letters()->numbers()->uncompromised()
]
];
}
/**
* Get custom attributes for validator errors.
*
* @return array
*/
public function attributes()
{
return [
'old_password' => trans('ancien mot de passe'),
'password' => trans('mot de passe'),
];
}
}

View file

@ -1,42 +0,0 @@
<?php
namespace App\Http\Requests;
use Carbon\Carbon;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
class UpdateInfosRequest extends FormRequest
{
public function __construct()
{
}
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return Auth::guard('web')->check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'firstname' => 'required|string|max:255',
'lastname' => 'required|string|max:255',
'birth_date' => 'required|date|before_or_equal:' . Carbon::now()->subYears(18)->toDateString(),
'address' => 'max:255',
'phone' => 'max:255',
'city' => 'required|string|max:255',
'postcode' => 'required'
];
}
}

View file

@ -0,0 +1,46 @@
<?php
namespace App\Http\Resources;
use App\Models\Customer;
use Illuminate\Http\Resources\Json\JsonResource;
class CustomerCrmResource extends JsonResource
{
/** @var \App\Models\Customer */
private $customer;
/**
* CustomerCrmResource
*
* @param \App\Models\Customer $customer
*/
public function __construct(Customer $customer)
{
$this->customer = $customer;
}
/**
* Transform the resource into an array.
*
* @param mixed $request
* @return array
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
*/
public function toArray($request)
{
/** @var \LDC\LDCCRM\Models\Customer */
$crmCustomer = $this->customer->api_data;
return [
'hashcode' => $this->customer->hashcode,
'firstname' => $crmCustomer->firstname,
'lastname' => $crmCustomer->lastname,
'opt_in' => $crmCustomer->opt_in,
'birthdate' => $crmCustomer->birth_date,
'phone' => $crmCustomer->phone,
'address' => $crmCustomer->address,
'address2' => $crmCustomer->address2,
'city' => $crmCustomer->city,
'postcode' => $crmCustomer->postcode
];
}
}

View file

@ -1,40 +0,0 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
use App\Models\User;
class UserCrmResource extends JsonResource
{
/** @var User */
private $user;
public function __construct(User $user)
{
$this->user = $user;
}
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
$crmUser = (object)$this->user->apiData;
return [
'crm_id' => $this->user->crm_id,
'firstname' => $crmUser->firstname,
'lastname' => $crmUser->lastname,
'optin' => $crmUser->opt_in,
'birthdate' => $crmUser->birth_date,
'phone' => $crmUser->phone,
'address' => $crmUser->address,
'address2' => null,
'city' => $crmUser->city,
'postcode' => $crmUser->postcode
];
}
}

View file

@ -1,387 +0,0 @@
<?php
namespace App\Jobs;
use App\Models\Articles;
use Exception;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Routing\Route as RoutingRoute;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Schema;
use Kwaadpepper\Enum\BaseEnum;
use ReflectionClass;
use Spatie\Sitemap\Sitemap;
use Spatie\Sitemap\Tags\Url;
class RefreshSiteMap implements ShouldQueue
{
use Dispatchable;
use InteractsWithQueue;
use Queueable;
use SerializesModels;
/**
* Uri that start with something in
* this table will be ignored
*
* @var array
*/
protected $ignoreRoutes = [
'/login',
'/confirmation-email',
'/mot-de-passe-oublie',
'/home',
'/_debugbar' // Hack ignore laravel debug bar
];
/**
* liste des routes à binder
*
* @var array
*/
protected $routesBinder = [
'news.show' => [
'slug' => [Articles::class, 'slug']
],
];
/**
* Execute the job.
*
*! Ici c'est du sale !!
* TODO: mettre tout ça dans un package pour le rendre plus générique
*
* @return void
*/
public function handle()
{
$this->assertRouteBinderIsCorrect();
$siteMap = [];
$routeCollection = Route::getRoutes();
/** @var \Illuminate\Routing\Route $route */
foreach ($routeCollection as $route) {
if ($this->routeShouldBeIgnored($route)) {
continue;
}
if (!$this->routeHandlesGetMethod($route)) {
continue;
}
/** @var array to be populated with models from DB to generate a route */
$rParams = [];
/** @var \array [lluminate\Routing\Route::signatureParameters] parameters signature from the controller */
$params = $route->signatureParameters();
/** @var \array [Illuminate\Routing\Route::parameterNames] parameters name from the registered route */
$pNames = $route->parameterNames();
$hasModels = false;
foreach ($params as $param) {
/** @var ReflectionClass|null $name */
$name = $param->getType() && !$param->getType()->isBuiltin()
? new ReflectionClass($param->getType()->getName())
: null;
/** @var string $pName $parameter name on route uri */
$pName = '';
// If the route has parameters and the controller accepts it
if (count($pNames) and \array_key_exists($param->getPosition(), $pNames)) {
// Get the controller parameter name for the route
$pName = $pNames[$param->getPosition()];
}
// If We have a custom binder for this route
if ($this->hasRouteBinderParam($route, $pName)) {
$hasModels = true;
$this->processWithRouteBinderParam($rParams, $route, $pName);
continue;
}
// If This route takes a model as param
if ($name and $name->isSubclassOf(Model::class)) {
$hasModels = true;
/** @var \string */
$modelClassName = $name->getName();
$this->setParamsForModel($rParams, $modelClassName, $pName);
continue;
}
}
// If the route has no dynamic models as parameters
if (!count($params) or !$hasModels) {
$siteMap[] = [
route($route->getName()),
Url::CHANGE_FREQUENCY_MONTHLY,
0.1
];
} else { // If the route has dynamic models as parameters
$this->genRoute($route, $siteMap, $rParams);
}
}
$sm = Sitemap::create();
foreach ($siteMap as $smRules) {
$sm->add(Url::create($smRules[0])
->setLastModificationDate(Carbon::yesterday())
->setChangeFrequency($smRules[1])
->setPriority($smRules[2]));
}
$sm->writeToFile(\public_path('sitemap.xml'));
}
/**
* Process route with binderParam
*
* @param RoutingRoute $route
* @param string $pName
* @return void
*/
private function processWithRouteBinderParam(array &$rParams, RoutingRoute $route, string $pName)
{
$o = $this->getRouteBinderParam($route, $pName);
/** @var \string */
$modelClassName = $o[0];
/** @var \string */
$routeParamName = $o[1];
$rfLCls = (new ReflectionClass($modelClassName));
switch (true) {
case $rfLCls->isSubclassOf(Model::class):
$this->setParamsForModel($rParams, $modelClassName, $pName, $routeParamName);
break;
case $rfLCls->isSubclassOf(BaseEnum::class):
$this->setParamForEnum($rParams, $rfLCls->getName(), $pName);
break;
default:
throw new Exception(sprintf('Unhandled class type %s', $rfLCls->getName()));
}
}
/**
* Set route param Array for Enums
*
* @param array $rParams
* @param string $enumClassName
* @param string $pName
* @return void
*/
private function setParamForEnum(array &$rParams, string $enumClassName, string $pName)
{
foreach (forward_static_call(sprintf('%s::toArray', $enumClassName)) as $enum) {
if (!array_key_exists($pName, $rParams)) {
$rParams[$pName] = [];
}
$rParams[$pName][] = $enum->value;
}
}
/**
* Set route param Array for Models
*
* @param array $rParams
* @param string $modelClassName
* @param string $pName
* @param string $routeParamName
* @return void
*/
private function setParamsForModel(
array &$rParams,
string $modelClassName,
string $pName,
string $routeParamName = null
) {
$i = 0;
$limit = 10;
$modelTable = (new ReflectionClass($modelClassName))->newInstanceWithoutConstructor()->getTable();
$q = $modelClassName::query();
$q = Schema::hasColumn($modelTable, 'status') ? $q->where('status', true) : $q; //to get models with a active status
$q = Schema::hasColumn($modelTable, 'category_id') ? $q->where('category_id', 1) : $q; //to not include only public Actus
do {
$results = $q->offset($i * $limit)->limit($limit)->get();
$length = count($results);
$results->map(function (Model $model) use (&$rParams, $pName, $routeParamName) {
if (!array_key_exists($pName, $rParams)) {
$rParams[$pName] = [];
}
if ($routeParamName) {
$rParams[$pName][] = $model[$routeParamName];
} else {
$rParams[$pName][] = $model;
}
});
$i++;
} while ($length);
}
/**
* Recursively generate routes for all params
*
* @param RoutingRoute $route
* @param array $siteMap
* @param array $params
* @return void
*/
private function genRoute(RoutingRoute $route, array &$siteMap, array $params)
{
$filtered = false;
foreach ($params as $pName => $param) {
if (is_array($param)) {
collect($param)->map(function ($p) use ($route, &$siteMap, $params, $pName) {
$this->genRoute($route, $siteMap, array_merge($params, [$pName => $p]));
});
return;
}
$filtered = array_key_last($params) === $pName ? true : false;
}
if ($filtered) {
$siteMap[] = [
route($route->getName(), $params),
Url::CHANGE_FREQUENCY_DAILY,
0.1
];
}
}
/**
* Check if $route exists in routesBinder
*
* @param RoutingRoute $route
* @return boolean
*/
private function hasRouteBinder(RoutingRoute $route): bool
{
return array_key_exists($route->getName(), $this->routesBinder);
}
/**
* Check if $route exists in routesBinder and has $param
*
* @param RoutingRoute $route
* @param string $param
* @return boolean
*/
private function hasRouteBinderParam(RoutingRoute $route, string $param): bool
{
if ($this->hasRouteBinder($route)) {
return array_key_exists($param, $this->getRouteBinder($route));
}
return false;
}
/**
* Get the routeBinder
*
* @param RoutingRoute $route
* @return array
*/
private function getRouteBinder(RoutingRoute $route): array
{
return $this->routesBinder[$route->getName()];
}
/**
* Get the routeBinder param
*
* @param RoutingRoute $route
* @param string $param
* @return array
*/
private function getRouteBinderParam(RoutingRoute $route, string $param): array
{
return $this->routesBinder[$route->getName()][$param];
}
/**
* Assert that routeBinder is correct
*
* @throws Exception
* @return void
*/
private function assertRouteBinderIsCorrect()
{
/** @var \Illuminate\Routing\RouteCollection */
$routeCollection = Route::getRoutes();
foreach ($this->routesBinder as $routeName => $params) {
if (!$routeCollection->hasNamedRoute($routeName)) {
throw new Exception(sprintf('Route %s does not exists', $routeName));
}
foreach ($params as $pName => $p) {
if (count($p) != 2) {
throw new Exception(sprintf(
'Route %s parameter %s does not have Model classname and parameter name',
$routeName,
$pName
));
}
$rfCls = (new ReflectionClass($p[0]))->newInstanceWithoutConstructor();
if (is_subclass_of($rfCls, BaseEnum::class)) {
return;
}
if (!is_subclass_of($rfCls, Model::class)) {
throw new Exception(sprintf(
'Route "%s" parameter "%s" first element must be a child of "%s"',
$routeName,
$pName,
Model::class
));
}
if (!Schema::hasColumn($rfCls->getTable(), $p[1])) {
throw new Exception(sprintf(
'"%s" parameter "%s" second element "%s" must refer to and existing database column of "%s"',
$routeName,
$pName,
$p[1],
$p[0]
));
}
}
}
}
/**
* Check if the route handles the HTTP GET method
*
* @param RoutingRoute $route
* @return boolean
*/
private function routeHandlesGetMethod(RoutingRoute $route): bool
{
return in_array('GET', $route->methods());
}
/**
* Check if the actual route uri start with
* a partial uri from the table
* Check also if it uses middleware auth
*
* @param RoutingRoute $route
* @return boolean
*/
private function routeShouldBeIgnored(RoutingRoute $route): bool
{
foreach ($this->ignoreRoutes as $iRoute) {
if (strpos($route->uri(), ltrim($iRoute, '/')) === 0) {
return true;
}
}
foreach ($route->middleware() as $middleware) {
if (strpos($middleware, 'auth') === 0) {
return true;
}
}
return false;
}
}

View file

@ -4,12 +4,14 @@ namespace App\Lib\LDC;
use GuzzleHttp\Client;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Facades\Log;
use Psr\Http\Message\ResponseInterface;
class MailjetSms
{
/** @var Application $app */
protected $app;
/** @var array $config */
protected $config = [];
@ -43,7 +45,7 @@ class MailjetSms
public function send(string $message, string $to, $from = null): ResponseInterface
{
$from = $from ?? $this->config['sms_from'];
$from = $from ?? $this->config['sms_from'];
$client = $this->buildHttpClient();
try {
@ -55,8 +57,8 @@ class MailjetSms
]
]);
} catch (\GuzzleHttp\Exception\RequestException $ex) {
\Log::debug('error');
\Log::debug((string) $ex->getResponse()->getBody());
Log::debug('error');
Log::debug((string)$ex->getResponse()->getBody());
throw $ex;
}

View file

@ -3,14 +3,13 @@
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use App\Models\Objectives;
class AlertGoalAchieved extends Mailable
{
use Queueable, SerializesModels;
use Queueable;
use SerializesModels;
protected $objectif;
@ -32,6 +31,8 @@ class AlertGoalAchieved extends Mailable
public function build()
{
/** @var App\Models\Objectives $this->objectif */
return $this->subject("Objectif Atteint! - ". config('app.name', 'Jeusselin'))->view('front.mail.alertgoalachieved')->with('objectif', $this->objectif);
return $this->subject("Objectif Atteint! - " . config('app.name', 'Jeusselin'))
->view('fo.mail.alertgoalachieved')
->with('objectif', $this->objectif);
}
}

View file

@ -3,13 +3,13 @@
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class InformProChangeInfos extends Mailable
{
use Queueable, SerializesModels;
use Queueable;
use SerializesModels;
/**
* Create a new message instance.
@ -28,6 +28,6 @@ class InformProChangeInfos extends Mailable
*/
public function build()
{
return $this->subject("L'utilisateur à modifié ses informations")->view('front.mail.pro-infos-change')->with('user', $this->user);
return $this->subject("L'utilisateur à modifié ses informations")->view('fo.mail.pro-infos-change')->with('user', $this->user);
}
}

View file

@ -3,13 +3,13 @@
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class InformProOpenAcess extends Mailable
{
use Queueable, SerializesModels;
use Queueable;
use SerializesModels;
/**
* Create a new message instance.
@ -28,6 +28,6 @@ class InformProOpenAcess extends Mailable
*/
public function build()
{
return $this->subject("Ouverture de votre accès")->view('front.mail.openpro')->with('user', $this->user);
return $this->subject("Ouverture de votre accès")->view('fo.mail.openpro')->with('user', $this->user);
}
}

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