First commit of project EBS
This commit is contained in:
parent
b160346ee1
commit
e533ba1f15
989 changed files with 74032 additions and 662 deletions
34
.dockerignore
Normal file
34
.dockerignore
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
**/*.log
|
||||
**/*.md
|
||||
**/*.php~
|
||||
**/*.dist.php
|
||||
**/*.dist
|
||||
**/*.cache
|
||||
**/._*
|
||||
**/.dockerignore
|
||||
**/.DS_Store
|
||||
**/.git/
|
||||
**/.gitattributes
|
||||
**/.gitignore
|
||||
**/.gitmodules
|
||||
**/docker-compose.*.yaml
|
||||
**/docker-compose.*.yml
|
||||
**/docker-compose.yaml
|
||||
**/docker-compose.yml
|
||||
**/Dockerfile
|
||||
**/Thumbs.db
|
||||
.github/
|
||||
docs/
|
||||
helm/
|
||||
Makefile
|
||||
node_modules/
|
||||
public/build/
|
||||
public/bundles/
|
||||
tests/
|
||||
var/
|
||||
vendor/
|
||||
.editorconfig
|
||||
.env.*.local
|
||||
.env.local
|
||||
.env.local.php
|
||||
.env.test
|
||||
72
.editorconfig
Normal file
72
.editorconfig
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# EditorConfig helps developers define and maintain consistent
|
||||
# coding styles between different editors and IDEs
|
||||
# editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
# Change these settings to your own preference
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
# We recommend you to keep these unchanged
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{js,html,ts,tsx}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.json]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.php]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.sh]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[*.xml{,.dist}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.{yaml,yml}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[.github/workflows/*.yml]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[.gitmodules]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[.php_cs{,.dist}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[.travis.yml]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[composer.json]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[docker-compose{,.*}.{yaml,yml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[Dockerfile]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
108
.env
Normal file
108
.env
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
# In all environments, the following files are loaded if they exist,
|
||||
# the latter taking precedence over the former:
|
||||
#
|
||||
# * .env contains default values for the environment variables needed by the app
|
||||
# * .env.local uncommitted file with local overrides
|
||||
# * .env.$APP_ENV committed environment-specific defaults
|
||||
# * .env.$APP_ENV.local uncommitted environment-specific overrides
|
||||
#
|
||||
# Real environment variables win over .env files.
|
||||
#
|
||||
# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
|
||||
# https://symfony.com/doc/current/configuration/secrets.html
|
||||
#
|
||||
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
|
||||
# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration
|
||||
|
||||
###> symfony/framework-bundle ###
|
||||
APP_ENV=dev
|
||||
APP_DEBUG=1
|
||||
APP_SECRET=fd8e6e32f64b1dddcfe849f88de35019
|
||||
###< symfony/framework-bundle ###
|
||||
|
||||
###> doctrine/doctrine-bundle ###
|
||||
# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
|
||||
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
|
||||
#
|
||||
# DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db"
|
||||
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8&charset=utf8mb4"
|
||||
DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=14&charset=utf8"
|
||||
###< doctrine/doctrine-bundle ###
|
||||
|
||||
###> nelmio/cors-bundle ###
|
||||
CORS_ALLOW_ORIGIN='^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$'
|
||||
###< nelmio/cors-bundle ###
|
||||
|
||||
###> symfony/messenger ###
|
||||
# Choose one of the transports below
|
||||
MESSENGER_TRANSPORT_DSN=doctrine://default
|
||||
# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages
|
||||
# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages
|
||||
###< symfony/messenger ###
|
||||
|
||||
###> symfony/mercure-bundle ###
|
||||
# See https://symfony.com/doc/current/mercure.html#configuration
|
||||
# The URL of the Mercure hub, used by the app to publish updates (can be a local URL)
|
||||
MERCURE_URL=https://example.com/.well-known/mercure
|
||||
# The public URL of the Mercure hub, used by the browser to connect
|
||||
MERCURE_PUBLIC_URL=https://example.com/.well-known/mercure
|
||||
# The secret used to sign the JWTs
|
||||
MERCURE_JWT_SECRET="!ChangeThisMercureHubJWTSecretKey!"
|
||||
###< symfony/mercure-bundle ###
|
||||
|
||||
###> symfony/mailer ###
|
||||
MAILER_DSN=null://null
|
||||
# MAILER_DSN=smtp://mailer:1025
|
||||
# MAILER_DSN=null://null
|
||||
###< symfony/mailer ###
|
||||
|
||||
###> symfony/google-mailer ###
|
||||
# Gmail SHOULD NOT be used on production, use it in development only.
|
||||
# It can be used with an application password, see https://support.google.com/accounts/answer/185833?visit_id=638042796580302159-1820620508&p=InvalidSecondFactor&rd=1
|
||||
# MAILER_DSN=gmail://USERNAME:PASSWORD@default
|
||||
###< symfony/google-mailer ###
|
||||
|
||||
###> symfony/twilio-notifier ###
|
||||
# SMS_DSN=twilio://SID:TOKEN@default?from=FROM
|
||||
###< symfony/twilio-notifier ###
|
||||
|
||||
###> symfony/ovh-cloud-notifier ###
|
||||
# SMS_DSN=ovhcloud://APPLICATION_KEY:APPLICATION_SECRET@default?consumer_key=CONSUMER_KEY&service_name=SERVICE_NAME
|
||||
###< symfony/ovh-cloud-notifier ###
|
||||
|
||||
###> symfony/notifier ###
|
||||
# This is main the DNS that is used by the notifier component
|
||||
# the other below are just example for two different third party vendors
|
||||
#SMS_DSN=twilio://SID:TOKEN@default?from=FROM
|
||||
SMS_DSN=null://null
|
||||
###< symfony/notifier ###
|
||||
|
||||
###> symfony/fake-sms-notifier ###
|
||||
FAKE_SMS_DSN=fakesms+email://mailer?to=admin&from=PlateformCoop
|
||||
###< symfony/fake-sms-notifier ###
|
||||
|
||||
###> snc/redis-bundle ###
|
||||
# passwords that contain special characters (@, %, :, +) must be urlencoded
|
||||
REDIS_URL=redis://redis
|
||||
###< snc/redis-bundle ###
|
||||
|
||||
###> meilisearch/meilisearch-symfony ###
|
||||
MEILISEARCH_URL=http://meilisearch:7700
|
||||
MEILISEARCH_API_KEY=ms
|
||||
###< meilisearch/meilisearch-symfony ###
|
||||
|
||||
###> payum/payum-bundle ###
|
||||
# @see https://my.mollie.com/dashboard/org_XXXXXXXX/developers/api-keys
|
||||
# even it's a fake key it must start with 'test_' or 'live_' and must be at least 30 characters long
|
||||
PAYUM_APIKEY=test_FRabcdefghijklmnopqrstuvwxyzab
|
||||
PAYUM_GATEWAY=mollie
|
||||
###< payum/payum-bundle ###
|
||||
|
||||
###> league/flysystem-bundle ###
|
||||
STORAGE_BUCKET=images
|
||||
STORAGE_ENDPOINT=http://storage:9000
|
||||
STORAGE_REGION=us-east-1
|
||||
STORAGE_USE_PATH_STYLE_ENDPOINT=true
|
||||
STORAGE_KEY=app
|
||||
STORAGE_SECRET=!ChangeMe!
|
||||
###< league/flysystem-bundle ###
|
||||
7
.env.test
Normal file
7
.env.test
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# define your env variables for the test env here
|
||||
KERNEL_CLASS='App\Kernel'
|
||||
APP_SECRET='$ecretf0rt3st'
|
||||
SYMFONY_DEPRECATIONS_HELPER=999999
|
||||
PANTHER_APP_ENV=test
|
||||
PANTHER_ERROR_SCREENSHOT_DIR=./var/error-screenshots
|
||||
PAYUM_GATEWAY=offline
|
||||
33
.eslintrc.json
Normal file
33
.eslintrc.json
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es2021": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"overrides": [
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": "latest",
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
"indent": [
|
||||
"error",
|
||||
2,
|
||||
{ "ignoreComments": true }
|
||||
],
|
||||
"linebreak-style": [
|
||||
"error",
|
||||
"unix"
|
||||
],
|
||||
"quotes": [
|
||||
"error",
|
||||
"single"
|
||||
],
|
||||
"semi": [
|
||||
"error",
|
||||
"never"
|
||||
]
|
||||
}
|
||||
}
|
||||
16
.gitattributes
vendored
Normal file
16
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
* text=auto eol=lf
|
||||
|
||||
*.conf text eol=lf
|
||||
*.html text eol=lf
|
||||
*.ini text eol=lf
|
||||
*.js text eol=lf
|
||||
*.json text eol=lf
|
||||
*.md text eol=lf
|
||||
*.php text eol=lf
|
||||
*.sh text eol=lf
|
||||
*.yaml text eol=lf
|
||||
*.yml text eol=lf
|
||||
bin/console text eol=lf
|
||||
|
||||
*.ico binary
|
||||
*.png binary
|
||||
45
.github/pull_request_template.md
vendored
Normal file
45
.github/pull_request_template.md
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
# Description
|
||||
|
||||
Please include a summary of the changes and the related issue.
|
||||
Please also include relevant motivation and context.
|
||||
|
||||
Related to # (issue)
|
||||
|
||||
## Type of change
|
||||
|
||||
Please delete options that are not relevant.
|
||||
|
||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||
- [ ] Cleanup/refactoring of an existing feature (code quality change without feature modification)
|
||||
- [ ] Improvment of an existing feature (minor tweak)
|
||||
- [ ] Documentation (no code)
|
||||
|
||||
# How Has This Been Tested?
|
||||
|
||||
Please describe the tests that you ran to verify your changes. Put below at least a file
|
||||
that was modified/added for the tests of this feature/bugfix.
|
||||
|
||||
- [ ] Test A
|
||||
|
||||
# Checklist:
|
||||
|
||||
- [ ] I have assigned myself to the related ticket
|
||||
- [ ] I have read the ticket carefully and the code addresses exactly what is described in it
|
||||
- [ ] I have added tests that prove my fix is effective or that my feature works
|
||||
- [ ] Tests pass locally (`make test-complete`)
|
||||
- [ ] Code coverage is still at 100% (`make coverage`)
|
||||
- [ ] My code follows the style guidelines of this project, `make ci` should run without error
|
||||
- [ ] Translations have been added, I didn't put raw text in PHP files or Twig templates
|
||||
- [ ] I have performed a self-review of my code
|
||||
- [ ] I have commented my code, particularly in hard-to-understand areas
|
||||
- [ ] I have made corresponding changes to the documentation
|
||||
- [ ] Git rebase have been made, and the PR can be merged without conflict
|
||||
- [ ] All CI checks are ✅
|
||||
- [ ] I have removed the draft status of the PR
|
||||
- [ ] I have removed the WIP tag on the PR and also in the title
|
||||
- [ ] I have added the RFR (ready for review) tag on the PR
|
||||
- [ ] I have added the DEPLOY tag and the feature/fix can be tested on the dedicated environment
|
||||
- [ ] I have assigned someone to review the PR
|
||||
|
||||
56
.github/workflows/ci.yml
vendored
Normal file
56
.github/workflows/ci.yml
vendored
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Docker build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Pull images
|
||||
run: docker compose pull
|
||||
- name: Start services
|
||||
run: docker compose up --build -d
|
||||
- name: Wait for services
|
||||
run: |
|
||||
while status="$(docker inspect --format="{{if .Config.Healthcheck}}{{print .State.Health.Status}}{{end}}" "$(docker compose ps -q php)")"; do
|
||||
case $status in
|
||||
starting) sleep 1;;
|
||||
healthy) exit 0;;
|
||||
unhealthy) exit 1;;
|
||||
esac
|
||||
done
|
||||
exit 1
|
||||
- name: Check HTTP reachability
|
||||
run: curl http://localhost
|
||||
- name: Check HTTPS reachability
|
||||
run: curl -k https://localhost
|
||||
- name: Test manifest file
|
||||
run: mkdir -p public/build; docker compose exec -T php echo "{}" > public/build/manifest.json
|
||||
- name: Create test database
|
||||
run: docker compose exec -T php bin/console -e test doctrine:database:create
|
||||
- name: Create database schema
|
||||
run: docker compose exec -T php bin/console -e test doctrine:schema:create
|
||||
- name: Setup Messenger
|
||||
run: docker compose exec -T php bin/console -e test messenger:setup-transports
|
||||
- name: Initializing Fixtures
|
||||
run: docker compose exec -T php bin/console -e test hautelook:fixtures:load --no-interaction --no-bundles
|
||||
- name: Meilisearch indexation
|
||||
run: docker compose exec -T php bin/console -e test app:index-products
|
||||
- name: PHPUnit
|
||||
run: docker compose exec -T php bin/phpunit
|
||||
- name: Doctrine Schema Validator
|
||||
run: docker compose exec -T php bin/console doctrine:schema:validate --skip-sync
|
||||
- name: PHP CS Fixer
|
||||
run: docker compose exec -T php sh -c './vendor/bin/php-cs-fixer fix --allow-risky=yes --dry-run --format=checkstyle | ./vendor/bin/cs2pr'
|
||||
- name: PHPStan
|
||||
run: docker compose exec -T php ./vendor/bin/phpstan analyse --memory-limit=-1 --error-format=github
|
||||
- name: Twig Linter
|
||||
run: docker compose exec -T php ./vendor/bin/twigcs templates/ --exclude vendor
|
||||
- name: Install eslint
|
||||
run: docker run --rm -w "/usr/app" -v "${PWD}":/usr/app gmolaire/yarn yarn add eslint
|
||||
- name: Run eslint on javascript files
|
||||
run: docker run --rm -w "/usr/app" -v "${PWD}":/usr/app gmolaire/yarn yarn lint
|
||||
33
.github/workflows/cleanup.yml
vendored
Normal file
33
.github/workflows/cleanup.yml
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
name: Cleanup
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [ closed ]
|
||||
|
||||
jobs:
|
||||
cleanup:
|
||||
name: Cleanup
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set KUBECONFIG
|
||||
run: |
|
||||
mkdir ~/.kube
|
||||
echo ${{ secrets.KUBECONFIG }} | base64 -d > ~/.kube/config
|
||||
kubectl config view
|
||||
|
||||
- name: Uninstall helm release
|
||||
id: uninstall_helm_release
|
||||
run: |
|
||||
export RELEASE_NAME=pr-$(jq --raw-output .pull_request.number $GITHUB_EVENT_PATH)
|
||||
echo "Uninstalling release ${RELEASE_NAME}"
|
||||
if ! helm uninstall ${RELEASE_NAME} --kube-context nonprod --wait ; then
|
||||
echo "HELM Uninstall has failed !"
|
||||
echo "Please ask the SRE team to manually clean remaining objects"
|
||||
exit 1
|
||||
fi
|
||||
echo "HELM uninstall successfull"
|
||||
echo "Cleaning remaining PVC..."
|
||||
kubectl delete pvc -l app.kubernetes.io/instance=$RELEASE_NAME
|
||||
35
.gitignore
vendored
Normal file
35
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
###> symfony/framework-bundle ###
|
||||
/.env.local
|
||||
/.env.local.php
|
||||
/.env.*.local
|
||||
/config/secrets/prod/prod.decrypt.private.php
|
||||
/public/bundles/
|
||||
/var/
|
||||
/vendor/
|
||||
###< symfony/framework-bundle ###
|
||||
|
||||
###> friendsofphp/php-cs-fixer ###
|
||||
/.php-cs-fixer.php
|
||||
/.php-cs-fixer.cache
|
||||
###< friendsofphp/php-cs-fixer ###
|
||||
|
||||
###> symfony/phpunit-bridge ###
|
||||
###< symfony/phpunit-bridge ###
|
||||
|
||||
###> phpunit/phpunit ###
|
||||
/phpunit.xml
|
||||
.phpunit.result.cache
|
||||
docs/coverage
|
||||
###< phpunit/phpunit ###
|
||||
|
||||
###> symfony/webpack-encore-bundle ###
|
||||
/node_modules/
|
||||
/public/build/
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
###< symfony/webpack-encore-bundle ###
|
||||
|
||||
###> league/flysystem-bundle ###
|
||||
storage
|
||||
###< league/flysystem-bundle ###
|
||||
27
.php-cs-fixer.dist.php
Normal file
27
.php-cs-fixer.dist.php
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
// https://cs.symfony.com/
|
||||
|
||||
$finder = PhpCsFixer\Finder::create()
|
||||
->in(__DIR__)
|
||||
->exclude('var')
|
||||
->exclude('tmp')
|
||||
->exclude('node_modules')
|
||||
;
|
||||
|
||||
return (new PhpCsFixer\Config())->setRules([
|
||||
'@Symfony' => true,
|
||||
'array_syntax' => ['syntax' => 'short'], // https://cs.symfony.com/doc/rules/array_notation/array_syntax.html
|
||||
'declare_strict_types' => true, // https://cs.symfony.com/doc/rules/strict/declare_strict_types.html
|
||||
'php_unit_fqcn_annotation' => false, // https://cs.symfony.com/doc/rules/php_unit/php_unit_fqcn_annotation.html
|
||||
'yoda_style' => false, // https://cs.symfony.com/doc/rules/control_structure/yoda_style.html
|
||||
'phpdoc_to_comment' => false, // https://cs.symfony.com/doc/rules/phpdoc/phpdoc_to_comment.html # Needed for PHPStan @var annotations
|
||||
'native_function_invocation' => [ // https://cs.symfony.com/doc/rules/function_notation/native_function_invocation.html
|
||||
'include' => ['@compiler_optimized'], // https://cs.symfony.com/doc/rules/function_notation/native_function_invocation.html#include
|
||||
'scope' => 'namespaced', // https://cs.symfony.com/doc/rules/function_notation/native_function_invocation.html#scope
|
||||
'strict' => true // https://cs.symfony.com/doc/rules/function_notation/native_function_invocation.html#strict
|
||||
],
|
||||
])
|
||||
->setFinder($finder);
|
||||
0
.trivyignore
Normal file
0
.trivyignore
Normal file
213
Dockerfile
Normal file
213
Dockerfile
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
# the different stages of this Dockerfile are meant to be built into separate images
|
||||
# https://docs.docker.com/develop/develop-images/multistage-build/#stop-at-a-specific-build-stage
|
||||
# https://docs.docker.com/compose/compose-file/#target
|
||||
|
||||
|
||||
# https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact
|
||||
ARG PHP_VERSION=8.1
|
||||
ARG CADDY_VERSION=2
|
||||
|
||||
# yarn build
|
||||
FROM gmolaire/yarn AS yarn_build
|
||||
WORKDIR /usr/app
|
||||
RUN apt-get update && apt-get install tar
|
||||
RUN mkdir -p /usr/app/vendor/symfony
|
||||
RUN curl -L https://github.com/symfony/ux-autocomplete/archive/v2.7.1.tar.gz -o ux-autocomplete.tar.gz
|
||||
RUN tar -xzvf ux-autocomplete.tar.gz --directory /usr/app/vendor/symfony
|
||||
RUN mv /usr/app/vendor/symfony/ux-autocomplete-2.7.1 /usr/app/vendor/symfony/ux-autocomplete
|
||||
COPY package.json yarn.lock .
|
||||
RUN yarn install
|
||||
COPY . .
|
||||
RUN yarn build
|
||||
|
||||
# Prod image
|
||||
FROM php:${PHP_VERSION}-fpm-alpine AS app_php
|
||||
|
||||
# needed for security update until base image is updated
|
||||
RUN apk upgrade libcurl curl openssl openssl-dev libressl libcrypto3 libssl3
|
||||
|
||||
# Allow to use development versions of Symfony
|
||||
ARG STABILITY="stable"
|
||||
ENV STABILITY ${STABILITY}
|
||||
|
||||
# Allow to select Symfony version
|
||||
ARG SYMFONY_VERSION=""
|
||||
ENV SYMFONY_VERSION ${SYMFONY_VERSION}
|
||||
|
||||
ENV APP_ENV=prod
|
||||
|
||||
WORKDIR /srv/app
|
||||
|
||||
# php extensions installer: https://github.com/mlocati/docker-php-extension-installer
|
||||
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
|
||||
RUN chmod +x /usr/local/bin/install-php-extensions
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN apk add --no-cache \
|
||||
acl \
|
||||
fcgi \
|
||||
file \
|
||||
gettext \
|
||||
git \
|
||||
nghttp2 \
|
||||
libcrypto3 \
|
||||
libssl3 \
|
||||
;
|
||||
|
||||
RUN set -eux; \
|
||||
install-php-extensions \
|
||||
intl \
|
||||
zip \
|
||||
apcu \
|
||||
opcache \
|
||||
xsl \
|
||||
redis \
|
||||
bcmath \
|
||||
;
|
||||
|
||||
###> doctrine/doctrine-bundle ###
|
||||
RUN apk add --no-cache --virtual .pgsql-deps postgresql-dev; \
|
||||
docker-php-ext-install -j$(nproc) pdo_pgsql; \
|
||||
apk add --no-cache --virtual .pgsql-rundeps so:libpq.so.5; \
|
||||
apk del .pgsql-deps
|
||||
###< doctrine/doctrine-bundle ###
|
||||
###< recipes ###
|
||||
|
||||
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
|
||||
COPY docker/php/conf.d/app.ini $PHP_INI_DIR/conf.d/
|
||||
COPY docker/php/conf.d/app.prod.ini $PHP_INI_DIR/conf.d/
|
||||
|
||||
COPY docker/php/php-fpm.d/zz-docker.conf /usr/local/etc/php-fpm.d/zz-docker.conf
|
||||
RUN mkdir -p /var/run/php
|
||||
|
||||
COPY docker/php/docker-healthcheck.sh /usr/local/bin/docker-healthcheck
|
||||
RUN chmod +x /usr/local/bin/docker-healthcheck
|
||||
|
||||
HEALTHCHECK --interval=10s --timeout=3s --retries=3 CMD ["docker-healthcheck"]
|
||||
|
||||
COPY docker/php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint
|
||||
RUN chmod +x /usr/local/bin/docker-entrypoint
|
||||
|
||||
ENTRYPOINT ["docker-entrypoint"]
|
||||
CMD ["php-fpm"]
|
||||
|
||||
# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser
|
||||
ENV COMPOSER_ALLOW_SUPERUSER=1
|
||||
ENV PATH="${PATH}:/root/.composer/vendor/bin"
|
||||
|
||||
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
|
||||
|
||||
RUN chown -R www-data: /srv/app/ /var/run/php/
|
||||
|
||||
# prevent the reinstallation of vendors at every changes in the source code
|
||||
USER www-data
|
||||
COPY --chown=www-data:www-data composer.* symfony.* ./
|
||||
RUN set -eux; \
|
||||
if [ -f composer.json ]; then \
|
||||
composer install --prefer-dist --no-dev --no-autoloader --no-scripts --no-progress; \
|
||||
composer clear-cache; \
|
||||
fi
|
||||
|
||||
# copy sources
|
||||
COPY --chown=www-data:www-data . .
|
||||
RUN rm -Rf docker/
|
||||
|
||||
RUN set -eux; \
|
||||
mkdir -p var/cache var/log; \
|
||||
if [ -f composer.json ]; then \
|
||||
composer dump-autoload --classmap-authoritative --no-dev; \
|
||||
composer dump-env prod; \
|
||||
COMPOSER_MEMORY_LIMIT=-1 composer run-script --no-dev post-install-cmd; \
|
||||
chmod +x bin/console; sync; \
|
||||
fi;
|
||||
|
||||
# copy yarn build output
|
||||
COPY --from=yarn_build --chown=www-data:www-data /usr/app/public/build/ public/build/
|
||||
|
||||
# Dev image
|
||||
FROM app_php AS app_php_dev
|
||||
|
||||
USER root
|
||||
|
||||
###> recipes ###
|
||||
###> symfony/panther ###
|
||||
# Chromium and ChromeDriver
|
||||
ENV PANTHER_NO_SANDBOX 1
|
||||
# Not mandatory, but recommended
|
||||
ENV PANTHER_CHROME_ARGUMENTS='--disable-dev-shm-usage'
|
||||
RUN apk add --no-cache chromium chromium-chromedriver
|
||||
|
||||
# Firefox and geckodriver
|
||||
#ARG GECKODRIVER_VERSION=0.29.0
|
||||
#RUN apk add --no-cache firefox
|
||||
#RUN wget -q https://github.com/mozilla/geckodriver/releases/download/v$GECKODRIVER_VERSION/geckodriver-v$GECKODRIVER_VERSION-linux64.tar.gz; \
|
||||
# tar -zxf geckodriver-v$GECKODRIVER_VERSION-linux64.tar.gz -C /usr/bin; \
|
||||
# rm geckodriver-v$GECKODRIVER_VERSION-linux64.tar.gz
|
||||
###< symfony/panther ###
|
||||
|
||||
|
||||
# Additional dev tools (graphviz is to have the dot program to generate the workflows' graphs)
|
||||
RUN apk add --no-cache \
|
||||
make \
|
||||
nano \
|
||||
vim \
|
||||
neovim \
|
||||
graphviz \
|
||||
;
|
||||
|
||||
# Load aliases at interactive shell (sh -l)
|
||||
ENV ENV="/etc/profile"
|
||||
|
||||
ENV APP_ENV=dev XDEBUG_MODE=off
|
||||
USER www-data
|
||||
# We must create directories to avoid problems with EasyAdmin which checks rights
|
||||
# even a cloud storgae is used (thoses directories will stay empty when a cloud
|
||||
# storage is used).
|
||||
RUN mkdir -p /srv/app/public/storage/uploads/category
|
||||
RUN mkdir -p /srv/app/public/storage/uploads/menu
|
||||
RUN mkdir -p /srv/app/public/storage/uploads/product
|
||||
RUN mkdir -p /srv/app/public/storage/uploads/user
|
||||
|
||||
USER root
|
||||
VOLUME /srv/app/var/
|
||||
|
||||
RUN rm $PHP_INI_DIR/conf.d/app.prod.ini; \
|
||||
mv "$PHP_INI_DIR/php.ini" "$PHP_INI_DIR/php.ini-production"; \
|
||||
mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"
|
||||
|
||||
COPY docker/php/conf.d/app.dev.ini $PHP_INI_DIR/conf.d/
|
||||
|
||||
RUN set -eux; \
|
||||
install-php-extensions xdebug
|
||||
|
||||
RUN rm -f .env.local.php
|
||||
|
||||
# Build Caddy with the Mercure and Vulcain modules
|
||||
# FROM caddy:${CADDY_VERSION}-builder-alpine AS app_caddy_builder
|
||||
|
||||
# Temporary fix for https://github.com/dunglas/mercure/issues/770
|
||||
# https://github.com/dunglas/symfony-docker/pull/407/files
|
||||
|
||||
FROM caddy:2.7-builder-alpine AS app_caddy_builder
|
||||
|
||||
# RUN xcaddy build \
|
||||
# --with github.com/dunglas/mercure \
|
||||
# --with github.com/dunglas/mercure/caddy \
|
||||
# --with github.com/dunglas/vulcain \
|
||||
# --with github.com/dunglas/vulcain/caddy
|
||||
|
||||
RUN xcaddy build \
|
||||
--with github.com/dunglas/mercure/caddy \
|
||||
--with github.com/dunglas/vulcain/caddy
|
||||
|
||||
# Caddy image
|
||||
FROM caddy:${CADDY_VERSION} AS app_caddy
|
||||
|
||||
# needed for security update until base image is updated
|
||||
RUN apk upgrade libcurl curl openssl openssl-dev libressl libcrypto1.1 libssl1.1 libcrypto3 libssl3
|
||||
|
||||
WORKDIR /srv/app
|
||||
|
||||
COPY --from=app_caddy_builder /usr/bin/caddy /usr/bin/caddy
|
||||
COPY --from=app_php /srv/app/public public/
|
||||
COPY docker/caddy/Caddyfile /etc/caddy/Caddyfile
|
||||
180
ERRORS.md
Normal file
180
ERRORS.md
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
# Errors
|
||||
|
||||
This documention gives solutions for some errors occuring in the project.
|
||||
|
||||
## 1. Makefile
|
||||
|
||||
### Error 1.1
|
||||
|
||||
plateformcoop-ebs$ docker compose exec php ./vendor/bin/php-cs-fixer fix --allow-risky=yes
|
||||
OCI runtime exec failed: exec failed: unable to start container process: exec: "./vendor/bin/php-cs-fixer": permission denied: unknown
|
||||
|
||||
### Solution 1.1
|
||||
|
||||
Verify that the executables in `vendor/bin`have the executblale right:
|
||||
|
||||
cd /srv/app/vendor/bin; chmod +x *
|
||||
|
||||
|
||||
## 2. PHPStan
|
||||
|
||||
### Error 2.1
|
||||
|
||||
tests/Integration/Translator/NotranslatorTest.php
|
||||
---------------------------------------------------------------------------
|
||||
Service "App\Translator\NoTranslator" is not registered in the container.
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
### Solution 2.1
|
||||
|
||||
To resolve this error, run:
|
||||
|
||||
make stan-cc
|
||||
|
||||
|
||||
## 3. PHPUnit
|
||||
|
||||
### Error 3.1
|
||||
|
||||
..........................................make: *** [Makefile:159: test] Error 137
|
||||
|
||||
### Solution 3.1
|
||||
|
||||
Check if there is no `dump()` in a loop.
|
||||
|
||||
### Error 3.2
|
||||
|
||||
..................make: *** [test] Error 139
|
||||
|
||||
### Solution 3.2
|
||||
|
||||
It seems to be a temporary Docker error. Run again the tests. Try the debug mode
|
||||
`make test-debug` if the error is still there to find the faulty tests.
|
||||
|
||||
|
||||
### Error 3.3
|
||||
|
||||
```
|
||||
1) App\Tests\Functional\Controller\User\ServiceRequest\ServiceRequestStatusWorkflowControllerRefuseTest::testTransitionRefuseSuccess
|
||||
|
||||
LogicException: The selected node does not have a form ancestor.
|
||||
|
||||
/srv/app/vendor/symfony/dom-crawler/Form.php:372
|
||||
/srv/app/vendor/symfony/dom-crawler/AbstractUriElement.php:45
|
||||
/srv/app/vendor/symfony/dom-crawler/Form.php:38
|
||||
/srv/app/vendor/symfony/dom-crawler/Crawler.php:838
|
||||
/srv/app/tests/Functional/Controller/User/ServiceRequest/ServiceRequestStatusWorkflowControllerRefuseTest.php:35
|
||||
```
|
||||
|
||||
It's because we have the same traduction in two places.
|
||||
|
||||
```
|
||||
<div class="d-grid col mt-2">
|
||||
<button type="button" class="btn btn-danger"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#refuseModal">
|
||||
<i class="bi bi-x"></i>
|
||||
{{ (i18n_prefix ~ '.link.refuse')|trans }} <== HERE
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<button type="submit"
|
||||
class="btn btn-danger">
|
||||
{{ (i18n_prefix ~ '.link.refuse')|trans }} <== AND HERE
|
||||
</button>
|
||||
```
|
||||
|
||||
### Solution 3.2
|
||||
|
||||
```
|
||||
<div class="d-grid col mt-2">
|
||||
<button type="button" class="btn btn-danger"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#refuseModal">
|
||||
<i class="bi bi-x"></i>
|
||||
{{ (i18n_prefix ~ '.link.refuse_modal')|trans }} <== CHANGE FIRST KEY TRADE
|
||||
</button>
|
||||
</div>
|
||||
```
|
||||
|
||||
Change the traduction key for the first button
|
||||
|
||||
|
||||
## 4. Geocoding/Nominatim
|
||||
|
||||
### Error 4.1
|
||||
|
||||
Error for all the geocoding tests (poc or modify my address):
|
||||
|
||||
ErrorException: Handling "App\Message\Query\Admin\User\UserAddressQuery" failed: Serialization of 'Closure' is not allowed
|
||||
in /srv/app/vendor/symfony/messenger/Middleware/HandleMessageMiddleware.php:129
|
||||
|
||||
It is because the Nominatim service is down (error 502, bad gateway).
|
||||
Disable the cache in `config/packages/bazinga_geocoder.yaml` to see the real error:
|
||||
|
||||
The geocoder server returned an invalid response (502) for query "https://nominatim.openstreetmap.org/search?format=jsonv2&q=Timipi%2C%20Fives%2C%20france&addressdetails=1&extratags=1&limit=3&accept-language=fr".
|
||||
We could not parse it.
|
||||
|
||||
https://nominatim.openstreetmap.org/search?format=jsonv2&q=Timipi%2C%20Fives%2C%20france&addressdetails=1&extratags=1&limit=3&accept-language=fr"
|
||||
|
||||
502 Bad Gateway
|
||||
nginx
|
||||
|
||||
### Solution 4.1
|
||||
|
||||
Wait.
|
||||
|
||||
It would be nice if the bundle could hande this error correclty and at least return
|
||||
an empty results array if there is such an error.
|
||||
As it is made now, we can't catch this error, which is quite problematic.
|
||||
Create a new issue on the bundle to see what can be done.
|
||||
|
||||
### Todo for 4.1
|
||||
|
||||
Use mocks for the test env.
|
||||
|
||||
|
||||
## 5. Docker
|
||||
|
||||
### Error 5.1
|
||||
|
||||
When running a command with make like `make cs` we have he error:
|
||||
|
||||
OCI runtime exec failed: exec failed: unable to start container process: read init-p: connection reset by peer: unknown
|
||||
|
||||
### Solution 5.1
|
||||
|
||||
Restart Docker.
|
||||
|
||||
|
||||
## 6. Symfony
|
||||
|
||||
### Error 6.1
|
||||
|
||||
When trying to access a controller we just created:
|
||||
|
||||
Could not resolve argument $productId of "App\Controller\User\Product\DeleteProductAction::__invoke()", maybe you forgot to register the controller as a service or missed tagging it with the "controller.service_arguments"?
|
||||
|
||||
### Solution 6.1
|
||||
|
||||
There is a mismatch between the arguments of the controller action and the route
|
||||
requirements, fix them (eg: `productId` instead of `id`.
|
||||
|
||||
|
||||
|
||||
## 7. Meilisearch
|
||||
|
||||
### Error 7.1
|
||||
|
||||
When indexing a document:
|
||||
|
||||
The primary key inference failed as the engine found 2 fields ending with `id` in their names: 'id' and 'ownerId'.
|
||||
Please specify the primary key manually using the `primaryKey` query parameter?
|
||||
|
||||
### Solution 6.1
|
||||
|
||||
The primary key must specified to avoid confusion. It can be set using the second
|
||||
argument of the `addDocument()` functions.
|
||||
|
||||
$this->getIndex()->addDocuments([$this->normalizeProduct($product)], self::PRIMARY_KEY);
|
||||
680
LICENSE
680
LICENSE
|
|
@ -1,661 +1,19 @@
|
|||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
Copyright (c) Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
|
|
|||
233
Makefile
Normal file
233
Makefile
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
# Config
|
||||
CURRENT_UID := $(shell id -u)
|
||||
CURRENT_GID := $(shell id -g)
|
||||
|
||||
SHELL = sh
|
||||
REDIS_PORT = 6389
|
||||
|
||||
# Executables (local)
|
||||
DOCKER = docker
|
||||
DOCKER_COMP = docker compose
|
||||
REDIS = redis-cli
|
||||
|
||||
# Docker containers
|
||||
PHP_CONT = $(DOCKER_COMP) exec php
|
||||
|
||||
# see https://hub.docker.com/r/gmolaire/yarn
|
||||
YARN_CONT = $(DOCKER) run -it --rm -w "/usr/app" -v "${PWD}":/usr/app gmolaire/yarn yarn
|
||||
|
||||
# Main executables
|
||||
PHP = $(PHP_CONT) php
|
||||
COMPOSER = $(PHP_CONT) composer
|
||||
SYMFONY = $(PHP_CONT) bin/console
|
||||
PHPUNIT = $(PHP_CONT) bin/phpunit
|
||||
|
||||
# Vendors executables
|
||||
PHPSTAN = $(PHP_CONT) ./vendor/bin/phpstan
|
||||
PHP_CS_FIXER = $(PHP_CONT) ./vendor/bin/php-cs-fixer
|
||||
TWIGCS = $(PHP_CONT) ./vendor/bin/twigcs
|
||||
RECTOR = $(PHP_CONT) ./vendor/bin/rector
|
||||
|
||||
# Misc
|
||||
.DEFAULT_GOAL = help
|
||||
.PHONY = help build up start down logs sh composer vendor sf cc ci cs lint-twigcs
|
||||
|
||||
## —— 🎵 🐳 The Symfony Docker Makefile 🐳 🎵 —————————————————————————————————
|
||||
help: ## Outputs this help screen
|
||||
@grep -E '(^[a-zA-Z0-9_-]+:.*?##.*$$)|(^##)' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}{printf "\033[32m%-30s\033[0m %s\n", $$1, $$2}' | sed -e 's/\[32m##/[33m/'
|
||||
|
||||
## —— Docker 🐳 ————————————————————————————————————————————————————————————————
|
||||
build: ## Builds the Docker images
|
||||
@$(DOCKER_COMP) build --pull
|
||||
|
||||
up: ## Start the docker hub in detached mode (no logs)
|
||||
@$(DOCKER_COMP) up -d
|
||||
|
||||
wait: ## Waits for all containers to be ready
|
||||
@$(DOCKER_COMP) up --wait
|
||||
|
||||
start: ## Starts the main containers (load-fixtures must be done so the caddy service can be healthy)
|
||||
start: up yarn-install load-fixtures yarn-dev wait
|
||||
|
||||
start-dev: ## Start additional and optional dev tools in the docker-compose.override.yml.dist file
|
||||
@$(DOCKER_COMP) -f docker-compose.override.yml.dist up --wait
|
||||
|
||||
stop: ## Stop and remove the docker containers (and volumes) of the project
|
||||
@$(DOCKER_COMP) down -v --remove-orphans
|
||||
|
||||
logs: ## Show live logs
|
||||
@$(DOCKER_COMP) logs --tail=0 --follow
|
||||
|
||||
sh: ## Connect to the PHP FPM container
|
||||
@$(PHP_CONT) sh -l
|
||||
|
||||
linux-fix-perms: ## Fix permissions on Linux
|
||||
$(PHP_CONT) chown -R $(CURRENT_UID):$(CURRENT_GID) .
|
||||
|
||||
## —— Composer 🧙 ——————————————————————————————————————————————————————————————
|
||||
composer: ## Run composer, pass the parameter "c=" to run a given command, example: make composer c='req symfony/orm-pack'
|
||||
@$(eval c ?=)
|
||||
@$(COMPOSER) $(c)
|
||||
|
||||
vendor: composer.lock ## Install vendors according to the current composer.lock file
|
||||
vendor: c=install --prefer-dist --no-progress --no-scripts --no-interaction
|
||||
vendor: composer
|
||||
|
||||
## —— Symfony 🎵 ———————————————————————————————————————————————————————————————
|
||||
sf: ## List all Symfony commands or pass the parameter "c=" to run a given command, example: make sf c=about
|
||||
@$(eval env ?= 'dev')
|
||||
@$(eval c ?=)
|
||||
@$(SYMFONY) $(c) --env=$(env)
|
||||
|
||||
cc: c=c:c ## Clear the cache
|
||||
cc: sf
|
||||
|
||||
purge: ## Purge the all vars files manually
|
||||
@$(PHP_CONT) sh -c "rm -rf /srv/app/var/*"
|
||||
|
||||
## —— Coding standards ✨ ——————————————————————————————————————————————————————
|
||||
stan: ## Run PHPStan. Use the 'path' parameter to check a given file only: make stan path=src/Services/ControllerHelper.php
|
||||
$(eval path ?= )
|
||||
@$(PHPSTAN) analyse -c phpstan.neon --memory-limit 1G -vvv $(path)
|
||||
|
||||
stan-cc: ## Clear manually the PHPStan result cache
|
||||
@$(PHPSTAN) clear-result-cache
|
||||
|
||||
lint-php: ## Lint files with php-cs-fixer (just use fix-php)
|
||||
$(PHP_CS_FIXER) fix --dry-run --allow-risky=yes
|
||||
|
||||
lint-twig: ## Lint Twig files to check they are well formatted (no parse error)
|
||||
@$(SYMFONY) lint:twig --env=dev
|
||||
|
||||
lint-twigcs: ## Check Twig coding style
|
||||
@$(TWIGCS) templates/ --exclude vendor
|
||||
|
||||
lint-container: ## Check there is no problem with the container
|
||||
@$(SYMFONY) lint:container
|
||||
|
||||
lint-yaml: ## Check all YAML files are well formatted
|
||||
@$(SYMFONY) lint:yaml --parse-tags config/ translations/ templates/
|
||||
|
||||
fix-php: ## Fix files with php-cs-fixer
|
||||
@$(PHP_CS_FIXER) fix --allow-risky=yes
|
||||
|
||||
rector: ## Run rector with current rules in rector.php
|
||||
@$(RECTOR) process src/
|
||||
|
||||
ci: ## Run pre-commit checks to ensure the CI will be green
|
||||
ci: cs lint-yaml lint-container lint-twig lint-twigcs yarn-lint doctrine-validate test-complete
|
||||
|
||||
cs: ## Run PHPStan and php-cs-fixer only
|
||||
cs: fix-php stan
|
||||
|
||||
## —— Project ——————————————————————————————————————————————————————————————————
|
||||
load-fixtures: drop-db ## Build the DB, control the schema validity, load fixtures and check the migration status (deb)
|
||||
$(eval env ?= 'dev')
|
||||
@$(SYMFONY) doctrine:database:create --if-not-exists --env=$(env)
|
||||
@$(SYMFONY) doctrine:schema:create --env=$(env)
|
||||
@$(SYMFONY) doctrine:schema:validate --env=$(env)
|
||||
@$(SYMFONY) doctrine:migrations:migrate --env=$(env) --no-interaction
|
||||
@$(SYMFONY) messenger:setup-transports --env=$(env)
|
||||
@$(SYMFONY) hautelook:fixtures:load --no-interaction -vv --no-bundles --env=$(env)
|
||||
@$(SYMFONY) app:index-products --env=$(env)
|
||||
|
||||
drop-db: ## Delete the whole database, useful when having integrity problems for data or constraints
|
||||
$(eval env ?= 'dev')
|
||||
@$(SYMFONY) doctrine:database:drop --env=$(env) --if-exists --force
|
||||
|
||||
load-test-fixtures: env=test ## Allows to use the test fixtures to debug problems
|
||||
load-test-fixtures: load-fixtures
|
||||
|
||||
load-prod-fixtures: env=prod
|
||||
load-prod-fixtures: load-fixtures ## Same than load-fixtures but with only minimum data
|
||||
|
||||
cache-clear: ## Clear the application cache (used for tests)
|
||||
$(eval env ?= 'dev')
|
||||
@$(SYMFONY) c:c --env=$(env)
|
||||
@$(SYMFONY) cache:pool:clear cache.app --env=$(env)
|
||||
|
||||
doctrine-validate: ## Validate the doctrine schema
|
||||
$(eval env ?= 'dev')
|
||||
@$(SYMFONY) doctrine:schema:validate --env=$(env)
|
||||
|
||||
doctrine-migrate: ## Run all the available Doctrine migrations
|
||||
@$(SYMFONY) doctrine:migrations:migrate --no-interaction
|
||||
|
||||
meilisearch-index:
|
||||
$(eval env ?= 'dev')
|
||||
@$(SYMFONY) app:index-products --env=$(env)
|
||||
|
||||
|
||||
## —— Tests ✅ —————————————————————————————————————————————————————————————————
|
||||
test: ## Run tests with optional suite, filter and options
|
||||
@$(eval testsuite ?= 'all')
|
||||
@$(eval filter ?= '.')
|
||||
@$(eval options ?= '--stop-on-failure')
|
||||
@$(PHPUNIT) --testsuite=$(testsuite) --filter=$(filter) $(options)
|
||||
|
||||
test-complete: ## Run all tests without stopping on the first error
|
||||
test-complete: env=test
|
||||
test-complete: options=
|
||||
test-complete: cc load-fixtures test
|
||||
|
||||
test-debug: ## Run all tests in debug mode
|
||||
test-debug: env=test
|
||||
test-debug: options=--debug --stop-on-failure
|
||||
test-debug: cc load-fixtures test
|
||||
|
||||
test-unit: ## Run unit tests only
|
||||
test-unit: env=test
|
||||
test-unit: testsuite=unit
|
||||
test-unit: test
|
||||
|
||||
test-api: ## Run API tests only
|
||||
test-api: env=test
|
||||
test-api: testsuite=api
|
||||
test-api: test
|
||||
|
||||
test-integration: ## Run integration tests only
|
||||
test-integration: env=test
|
||||
test-integration: testsuite=integration
|
||||
test-integration: load-test-fixtures test
|
||||
|
||||
test-functional: ## Run functional tests only
|
||||
test-functional: env=test
|
||||
test-functional: testsuite=functional
|
||||
test-functional: load-test-fixtures test
|
||||
|
||||
test-e2e: ## Run E2E tests only
|
||||
test-e2e: env=test
|
||||
test-e2e: load-test-fixtures test
|
||||
|
||||
coverage: ## Generate the HTML PHPUnit code coverage report locally
|
||||
coverage: env=test
|
||||
coverage: load-test-fixtures
|
||||
# Cache must be generated by PHPUnit so it can run compiler passes
|
||||
@$(PHP_CONT) sh -c "rm -rf /srv/app/var/cache/test"
|
||||
@$(DOCKER_COMP) exec -e XDEBUG_MODE=coverage php php -d xdebug.enable=1 -d memory_limit=-1 bin/phpunit --coverage-html=docs/coverage
|
||||
|
||||
## —— Debug 🐞——————————————————————————————————————————————————————————————————
|
||||
redis: ## Connect to redis with CLI (redis-cli must be installed locally)
|
||||
@$(REDIS) -p $(REDIS_PORT)
|
||||
|
||||
redis-cc: ## Flush all Redis cache
|
||||
@$(REDIS) -p $(REDIS_PORT) flushall
|
||||
|
||||
## —— Yarn 🐱 / JavaScript —————————————————————————————————————————————————————
|
||||
yarn-install: ## Install node dependencies with Yarn
|
||||
@$(YARN_CONT) install
|
||||
|
||||
yarn-dev: ## Build the assets for the dev env
|
||||
@$(YARN_CONT) dev
|
||||
|
||||
yarn-lint: ## Lint JS files
|
||||
@$(YARN_CONT) lint
|
||||
|
||||
yarn-cmd: ## Run a given command
|
||||
@$(eval cmd ?= 'help')
|
||||
@$(YARN_CONT) $(cmd)
|
||||
|
||||
## —— Doc 📚 ———————————————————————————————————————————————————————————————————
|
||||
workflows: ## Generate and update the graphs of all available workflows
|
||||
@$(PHP_CONT) bin/console workflow:dump service_request_status | dot -Tpng -o docs/service_request_status_workflow.png
|
||||
@echo "Done!"
|
||||
|
|
@ -205,4 +205,4 @@ La page en question bénéficiera de l’accès au reste du framework, à la bas
|
|||
|
||||
|
||||
# Installation et documentation technique
|
||||
La documentation d'installation et configuration technique de la plateforme est disponible sur [cette page]().
|
||||
La documentation d'installation et configuration technique de la plateforme est disponible sur [cette page](docs/README.md).
|
||||
|
|
|
|||
18
assets/app.js
Normal file
18
assets/app.js
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
/*
|
||||
* Welcome to your app's main JavaScript file!
|
||||
*
|
||||
* We recommend including the built version of this JavaScript file
|
||||
* (and its CSS file) in your base layout (base.html.twig).
|
||||
*/
|
||||
|
||||
// any CSS you import will output into a single css file (app.css in this case)
|
||||
import './styles/global.scss'
|
||||
|
||||
// start the Stimulus application
|
||||
import './stimulus'
|
||||
|
||||
import '@fortawesome/fontawesome-free/js/fontawesome'
|
||||
import '@fortawesome/fontawesome-free/js/solid'
|
||||
import '@fortawesome/fontawesome-free/js/regular'
|
||||
import '@fortawesome/fontawesome-free/js/brands'
|
||||
15
assets/controllers.json
Normal file
15
assets/controllers.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"controllers": {
|
||||
"@symfony/ux-autocomplete": {
|
||||
"autocomplete": {
|
||||
"enabled": true,
|
||||
"fetch": "eager",
|
||||
"autoimport": {
|
||||
"tom-select/dist/css/tom-select.default.css": true,
|
||||
"tom-select/dist/css/tom-select.bootstrap5.css": false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"entrypoints": []
|
||||
}
|
||||
9
assets/controllers/accordion_controller.js
Normal file
9
assets/controllers/accordion_controller.js
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import { Controller } from '@hotwired/stimulus'
|
||||
|
||||
export default class extends Controller {
|
||||
toggle() {
|
||||
const accordionList = this.element.nextElementSibling
|
||||
this.element.lastElementChild.classList.toggle('rotate-180')
|
||||
accordionList.classList.toggle('opened')
|
||||
}
|
||||
}
|
||||
65
assets/controllers/account_controller.js
Normal file
65
assets/controllers/account_controller.js
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
import { Controller } from '@hotwired/stimulus'
|
||||
|
||||
export default class extends Controller {
|
||||
|
||||
hiddenUserInput () {
|
||||
const divUserInput = document.querySelector('.user-input')
|
||||
divUserInput.classList.add('hidden')
|
||||
}
|
||||
|
||||
hiddenPlaceInput() {
|
||||
const divUserInput = document.querySelector('.place-input')
|
||||
divUserInput.classList.add('hidden')
|
||||
}
|
||||
connect () {
|
||||
const userInput = this.element.value === 'user'
|
||||
const placeInput = this.element.value === 'place'
|
||||
const inputUserLastname = document.querySelector('.input-lastname')
|
||||
const inputUserFirstname = document.querySelector('.input-firstname')
|
||||
const inputPlaceName = document.querySelector('.input-name')
|
||||
|
||||
const userInputChecked = userInput && this.element.checked
|
||||
const placeInputChecked = placeInput && this.element.checked
|
||||
|
||||
if (userInputChecked) {
|
||||
inputUserFirstname.required = true
|
||||
inputUserLastname.required = true
|
||||
this.hiddenPlaceInput()
|
||||
}
|
||||
|
||||
if (placeInputChecked) {
|
||||
inputPlaceName.required = true
|
||||
this.hiddenUserInput()
|
||||
}
|
||||
}
|
||||
|
||||
choosenType() {
|
||||
const placeInput = this.element.value === 'place'
|
||||
const inputUserLastname = document.querySelector('.input-lastname')
|
||||
const inputUserFirstname = document.querySelector('.input-firstname')
|
||||
const inputPlaceName = document.querySelector('.input-name')
|
||||
|
||||
const divUserInput = document.querySelector('.user-input')
|
||||
const divPlaceInput = document.querySelector('.place-input')
|
||||
|
||||
const placeInputChecked = placeInput && this.element.checked
|
||||
|
||||
if (placeInputChecked) {
|
||||
inputUserFirstname.removeAttribute('required')
|
||||
inputUserLastname.removeAttribute('required')
|
||||
|
||||
inputPlaceName.setAttribute('required', '')
|
||||
|
||||
divPlaceInput.classList.remove('hidden')
|
||||
divUserInput.classList.add('hidden')
|
||||
} else {
|
||||
inputPlaceName.removeAttribute('required')
|
||||
|
||||
inputUserFirstname.setAttribute('required', '')
|
||||
inputUserLastname.setAttribute('required', '')
|
||||
|
||||
divUserInput.classList.remove('hidden')
|
||||
divPlaceInput.classList.add('hidden')
|
||||
}
|
||||
}
|
||||
}
|
||||
114
assets/controllers/calendar_controller.js
Normal file
114
assets/controllers/calendar_controller.js
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
import { Controller} from '@hotwired/stimulus'
|
||||
import flatpickr from 'flatpickr'
|
||||
import rangePlugin from 'flatpickr/dist/plugins/rangePlugin'
|
||||
import { French } from 'flatpickr/dist/l10n/fr'
|
||||
export default class extends Controller {
|
||||
static values = {
|
||||
unavailabilities: String
|
||||
}
|
||||
|
||||
initialize() {
|
||||
this.fp
|
||||
this.fpProductOwner
|
||||
}
|
||||
|
||||
connect() {
|
||||
const unavailabilities = this.unavailabilitiesValue.split(',')
|
||||
|
||||
const selector = this.element.querySelector('#calendar-start-day')
|
||||
|
||||
const commonOptions = {
|
||||
locale: {
|
||||
...French,
|
||||
weekdays: {
|
||||
shorthand: ['D', 'L', 'M', 'M', 'J', 'V', 'S'], // Override shorthand because it is initially in the "lun", "mar", "mer" (etc) format
|
||||
longhand: French.weekdays.longhand,
|
||||
}
|
||||
},
|
||||
inline: true,
|
||||
disable: unavailabilities,
|
||||
monthSelectorType: 'static',
|
||||
minDate: 'today',
|
||||
}
|
||||
|
||||
if (!selector) {
|
||||
// This flatpickr instance is meant for when a user visits its own product page
|
||||
this.fpProductOwner = flatpickr('#product-owner-calendar', commonOptions)
|
||||
|
||||
// This prevents owner from selecting days
|
||||
this.fpProductOwner.daysContainer.addEventListener('click', (event) => {
|
||||
event.stopPropagation()
|
||||
}, true)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
this.fp = flatpickr(selector, {
|
||||
...commonOptions,
|
||||
allowInput: true,
|
||||
mode: 'range',
|
||||
plugins: [new rangePlugin({ input: '#calendar-end-day'})],
|
||||
onReady(_, __, instance) {
|
||||
let params = (new URL(location)).searchParams
|
||||
const startAt = params.get('startAt')
|
||||
const endAt = params.get('endAt')
|
||||
|
||||
const dates = []
|
||||
|
||||
if (startAt) dates.push(startAt)
|
||||
if (endAt) dates.push(endAt)
|
||||
|
||||
if (dates.length) {
|
||||
instance.setDate(dates, true)
|
||||
return
|
||||
}
|
||||
|
||||
const buttonServiceRequestPage = document.querySelector('#create_service_request_submit')
|
||||
|
||||
if (!buttonServiceRequestPage) return
|
||||
|
||||
buttonServiceRequestPage.setAttribute('disabled', '')
|
||||
},
|
||||
onChange() {
|
||||
const startAtInput = document.querySelector('#calendar-start-day')
|
||||
const endAtInput = document.querySelector('#calendar-end-day')
|
||||
const startAt = startAtInput.value
|
||||
const endAt = endAtInput.value
|
||||
|
||||
const buttonProductPage = document.querySelector('#service-request')
|
||||
const buttonServiceRequestPage = document.querySelector('#create_service_request_submit')
|
||||
|
||||
if (buttonProductPage) {
|
||||
startAt && endAt
|
||||
? buttonProductPage.removeAttribute('disabled')
|
||||
: buttonProductPage.setAttribute('disabled', '')
|
||||
}
|
||||
|
||||
if (buttonServiceRequestPage) {
|
||||
startAt && endAt
|
||||
? buttonServiceRequestPage.removeAttribute('disabled')
|
||||
: buttonServiceRequestPage.setAttribute('disabled', '')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
resetDates() {
|
||||
this.fp.clear()
|
||||
}
|
||||
|
||||
serviceRequest() {
|
||||
const button = this.element.querySelector('#service-request')
|
||||
const path = button.dataset.path
|
||||
const startAtInput = this.element.querySelector('#calendar-start-day')
|
||||
const endAtInput = this.element.querySelector('#calendar-end-day')
|
||||
const startAt = startAtInput.value
|
||||
const endAt = endAtInput.value
|
||||
|
||||
const url = new URL(path, window.location.origin)
|
||||
url.searchParams.set('startAt', startAt)
|
||||
url.searchParams.set('endAt', endAt)
|
||||
|
||||
location.href = url
|
||||
}
|
||||
}
|
||||
8
assets/controllers/menu_controller.js
Normal file
8
assets/controllers/menu_controller.js
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import {Controller} from '@hotwired/stimulus'
|
||||
|
||||
export default class extends Controller {
|
||||
toggle() {
|
||||
const menu = document.querySelector('.menu')
|
||||
menu.classList.toggle('hide')
|
||||
}
|
||||
}
|
||||
34
assets/controllers/product_controller.js
Normal file
34
assets/controllers/product_controller.js
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import { Controller} from '@hotwired/stimulus'
|
||||
import { Toast } from 'bootstrap'
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = [ 'activeButton', 'pausedButton', 'activeTag', 'pausedTag' ]
|
||||
|
||||
static values = {
|
||||
route: String,
|
||||
}
|
||||
|
||||
async switchStatus() {
|
||||
const response = await fetch(this.routeValue, { method: 'PATCH' })
|
||||
|
||||
if (!response.ok) {
|
||||
const toastElement = document.querySelector('[data-notification=error]')
|
||||
const toast = new Toast(toastElement)
|
||||
toast.show()
|
||||
return
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
const { status } = data
|
||||
|
||||
const toastElement = document.querySelector(`[data-notification=${status}StatusSuccess]`)
|
||||
const toast = new Toast(toastElement)
|
||||
toast.show()
|
||||
|
||||
this.activeButtonTarget.classList.toggle('d-none')
|
||||
this.pausedButtonTarget.classList.toggle('d-none')
|
||||
|
||||
this.activeTagTarget.classList.toggle('d-none')
|
||||
this.pausedTagTarget.classList.toggle('d-none')
|
||||
}
|
||||
}
|
||||
40
assets/controllers/productupload_controller.js
Normal file
40
assets/controllers/productupload_controller.js
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import { Controller} from '@hotwired/stimulus'
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ['input', 'feedback']
|
||||
|
||||
static values = {
|
||||
uploadMaxsizeByFile: Number, // max size by image allowed
|
||||
uploadMaxItems: Number, // max number of images allowed
|
||||
currentImagesCount: Number, // number of images already uploaded
|
||||
feedbackMessage: String, // image too too big feedback
|
||||
maxImagesError: String, // count threshold reached error
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Check the size of each file. Remove the selected files if one is incorrect.
|
||||
* 2. Check the number of images uploaded.
|
||||
*/
|
||||
checkUpload() {
|
||||
const maxAllowedImages = this.uploadMaxItemsValue - this.currentImagesCountValue
|
||||
if (maxAllowedImages < this.inputTarget.files.length) {
|
||||
this.feedbackTarget.innerHTML = this.maxImagesErrorValue
|
||||
this.inputTarget.value = ''
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
const uploadMaxsizeByFile = 1048576 * this.uploadMaxsizeByFileValue
|
||||
let feedback = []
|
||||
for (let file of this.inputTarget.files) {
|
||||
if (file.size > uploadMaxsizeByFile) {
|
||||
feedback.push(this.feedbackMessageValue.replace('%file%', file.name))
|
||||
}
|
||||
}
|
||||
|
||||
if (feedback.length > 0) {
|
||||
this.feedbackTarget.innerHTML = feedback.join('<br/>')
|
||||
this.inputTarget.value = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
18
assets/controllers/productvisibility_controller.js
Normal file
18
assets/controllers/productvisibility_controller.js
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import { Controller} from '@hotwired/stimulus'
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ['public', 'groups']
|
||||
|
||||
connect () {
|
||||
if (this.publicTarget.checked) {
|
||||
this.hideGroups()
|
||||
}
|
||||
}
|
||||
|
||||
hideGroups() {
|
||||
this.groupsTarget.classList.add('hidden')
|
||||
}
|
||||
showGroups() {
|
||||
this.groupsTarget.classList.remove('hidden')
|
||||
}
|
||||
}
|
||||
14
assets/controllers/read-more_controller.js
Normal file
14
assets/controllers/read-more_controller.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import {Controller} from '@hotwired/stimulus'
|
||||
|
||||
export default class extends Controller {
|
||||
toggle() {
|
||||
const readMoreContainer = document.querySelector('.read')
|
||||
const buttonToggle = this.element
|
||||
const opened = readMoreContainer.classList.contains('less')
|
||||
|
||||
readMoreContainer.classList.toggle('less')
|
||||
readMoreContainer.classList.toggle('more')
|
||||
|
||||
buttonToggle.innerHTML = opened ? 'Voir plus' : 'Voir moins'
|
||||
}
|
||||
}
|
||||
16
assets/controllers/search_controller.js
Normal file
16
assets/controllers/search_controller.js
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { Controller} from '@hotwired/stimulus'
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = [ 'form' ]
|
||||
|
||||
/**
|
||||
* Reset the form to blank values (input reset doesn't work with prefilled values).
|
||||
*/
|
||||
reset() {
|
||||
this.formTarget.elements['p[q]'].value = ''
|
||||
this.formTarget.elements['p[category]'].value = ''
|
||||
this.formTarget.elements['p[place]'].value = ''
|
||||
this.formTarget.elements['p[city]'].value = ''
|
||||
this.formTarget.elements['p[distance]'].forEach(radio => radio.checked = false)
|
||||
}
|
||||
}
|
||||
11
assets/controllers/tooltips_controller.js
Normal file
11
assets/controllers/tooltips_controller.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { Controller } from '@hotwired/stimulus'
|
||||
import { Tooltip } from 'bootstrap'
|
||||
|
||||
export default class extends Controller {
|
||||
connect() {
|
||||
const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
|
||||
tooltipTriggerList.map(function (tooltipTriggerEl) {
|
||||
return new Tooltip(tooltipTriggerEl)
|
||||
})
|
||||
}
|
||||
}
|
||||
21
assets/stimulus.js
Normal file
21
assets/stimulus.js
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import { startStimulusApp } from '@symfony/stimulus-bridge'
|
||||
import { Application } from '@hotwired/stimulus'
|
||||
|
||||
import PasswordVisibility from 'stimulus-password-visibility'
|
||||
import Carousel from 'stimulus-carousel'
|
||||
import 'swiper/swiper-bundle.css'
|
||||
|
||||
// Registers Stimulus controllers from controllers.json and in the controllers/ directory
|
||||
export const app = startStimulusApp(require.context(
|
||||
'@symfony/stimulus-bridge/lazy-controller-loader!./controllers',
|
||||
true,
|
||||
/\.[jt]sx?$/
|
||||
))
|
||||
|
||||
// register any custom, 3rd party controllers here
|
||||
// app.register('some_controller_name', SomeImportedController);
|
||||
|
||||
const application = Application.start()
|
||||
application.register('carousel', Carousel)
|
||||
application.register('password-visibility', PasswordVisibility)
|
||||
|
||||
18
assets/styles/_accordion.scss
Normal file
18
assets/styles/_accordion.scss
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
.accordion.rotate-180 {
|
||||
transition: transform .3s ease-in-out;
|
||||
}
|
||||
|
||||
.accordion {
|
||||
transition: transform .3s ease-in-out;
|
||||
}
|
||||
|
||||
.accordion-list {
|
||||
max-height: 0;
|
||||
transition: max-height .3s ease-out;
|
||||
overflow: hidden;
|
||||
|
||||
&.opened {
|
||||
max-height: 500px;
|
||||
transition: max-height .3s ease-in;
|
||||
}
|
||||
}
|
||||
18
assets/styles/_address.scss
Normal file
18
assets/styles/_address.scss
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
.address-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&-checkbox {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
&-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
> p {
|
||||
margin: 0;
|
||||
color: $heading-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
73
assets/styles/_calendar.scss
Normal file
73
assets/styles/_calendar.scss
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
.flatpickr-calendar {
|
||||
align-self: center;
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.cur-month,
|
||||
.cur-year {
|
||||
font-size: $font-size-base !important;
|
||||
font-weight: $font-weight-normal !important;
|
||||
}
|
||||
|
||||
.cur-month {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.cur-year {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.arrowUp,
|
||||
.arrowDown {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.flatpickr-current-month {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.flatpickr-weekdays {
|
||||
margin-top: $spacer;
|
||||
}
|
||||
|
||||
.flatpickr-weekday {
|
||||
font-weight: $font-weight-normal !important;
|
||||
color: $gray-600 !important;
|
||||
}
|
||||
|
||||
.flatpickr-day {
|
||||
color: $primary !important;
|
||||
|
||||
&.selected {
|
||||
border: none;
|
||||
border-radius: 4px !important;
|
||||
background: $primary;
|
||||
color: $white !important;
|
||||
}
|
||||
|
||||
&.inRange {
|
||||
color: $black !important;
|
||||
}
|
||||
|
||||
&.prevMonthDay,
|
||||
&.nextMonthDay {
|
||||
color: rgba($gray-600, .5) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.flatpickr-disabled {
|
||||
color: $gray-600 !important;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.flatpickr-prev-month,
|
||||
.flatpickr-next-month {
|
||||
svg {
|
||||
fill: $primary;
|
||||
}
|
||||
}
|
||||
|
||||
22
assets/styles/_card.scss
Normal file
22
assets/styles/_card.scss
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
.card {
|
||||
.img-container {
|
||||
@media (min-width: 1200px) {
|
||||
height: 310px;
|
||||
}
|
||||
@media (max-width: 1025px) {
|
||||
height: 235px;
|
||||
}
|
||||
@media (max-width: 700px) {
|
||||
height: 180px;
|
||||
}
|
||||
}
|
||||
.img {
|
||||
object-fit: contain;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.img-default {
|
||||
object-fit: cover;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
36
assets/styles/_chat.scss
Normal file
36
assets/styles/_chat.scss
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
.chat-content {
|
||||
margin-bottom: 200px;
|
||||
}
|
||||
|
||||
.chat-action {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 992px) {
|
||||
.chat-container {
|
||||
max-height: 800px;
|
||||
overflow-y: auto;
|
||||
position: relative;
|
||||
|
||||
.chat-content {
|
||||
margin-bottom: 150px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.chat-action {
|
||||
width: 75%;
|
||||
}
|
||||
.conversation-textarea {
|
||||
height: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 992px) and (max-width: 1199px) {
|
||||
.chat-content {
|
||||
margin-bottom: 150px;
|
||||
}
|
||||
.chat-action {
|
||||
width: 66.6%;
|
||||
}
|
||||
}
|
||||
81
assets/styles/_connexion.scss
Normal file
81
assets/styles/_connexion.scss
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
#account_create_step2_form_type,
|
||||
#create_group_form_type
|
||||
{
|
||||
display: flex;
|
||||
|
||||
> .form-check {
|
||||
margin-right: 10px;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
label.required:after,
|
||||
legend.required:after
|
||||
{
|
||||
content: "*" !important;
|
||||
color: #B02A37;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
label.form-check-label.required:after {
|
||||
content: '' !important;
|
||||
}
|
||||
|
||||
#account_create_step2_form_plainPassword_first:invalid,
|
||||
#account_create_step2_form_plainPassword_second:invalid,
|
||||
#login-password:invalid {
|
||||
background-image: none !important;
|
||||
}
|
||||
|
||||
#account_create_step2_form_plainPassword_first:valid,
|
||||
#account_create_step2_form_plainPassword_second:valid,
|
||||
#login-password:valid {
|
||||
background-image: none !important;
|
||||
}
|
||||
|
||||
.password-visibility {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
> input {
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
> .eye {
|
||||
background-color: transparent;
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: var(--bs-border-radius-sm) !important;
|
||||
border-top-right-radius: var(--bs-border-radius-sm) !important;
|
||||
height: fit-content;
|
||||
padding: 4px 8px 1.2px 4px;
|
||||
}
|
||||
|
||||
> input.is-invalid ~ .eye {
|
||||
border: 1px solid #B02A37;
|
||||
}
|
||||
|
||||
> input.is-invalid ~ span {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.was-validated {
|
||||
> .password {
|
||||
> .password-visibility {
|
||||
> input:invalid ~ .eye {
|
||||
border: 1px solid #B02A37;
|
||||
}
|
||||
|
||||
> input:valid ~ .eye {
|
||||
border: 1px solid #198754;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
59
assets/styles/_conversations.scss
Normal file
59
assets/styles/_conversations.scss
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
.conversations {
|
||||
&-link {
|
||||
transition: background .3s;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background: rgba($gray-300, 0.3);
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
&-img {
|
||||
width: 74px;
|
||||
aspect-ratio: 1/1;
|
||||
}
|
||||
}
|
||||
|
||||
.conversation {
|
||||
&-message {
|
||||
border-radius: 4px;
|
||||
|
||||
&.system {
|
||||
border: 1px solid $gray-400;
|
||||
}
|
||||
|
||||
&.from_recipient,
|
||||
&.from_owner {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
&.from_recipient {
|
||||
background: $blue-100;
|
||||
}
|
||||
|
||||
&.from_owner {
|
||||
margin-left: auto;
|
||||
background: $blue-500;
|
||||
color: $white;
|
||||
|
||||
.conversation-messageValue {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&-messageValue {
|
||||
color: $black;
|
||||
}
|
||||
|
||||
&-textarea {
|
||||
height: calc(1.5em + 0.75rem + 2px);
|
||||
}
|
||||
}
|
||||
|
||||
.label-modal-width.col-sm-2 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
23
assets/styles/_custom-variables.scss
Normal file
23
assets/styles/_custom-variables.scss
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
$white: #FFFFFF;
|
||||
$gray: #D4D9DF;
|
||||
$gray-100: #F8F9FA;
|
||||
$gray-900: #667080;
|
||||
$blue-100: #CCE5FF;
|
||||
$blue-200: #B8DAFF;
|
||||
$blue-500: #0D6EFD;
|
||||
$blue-900: #031633;
|
||||
$red: #B02A37;
|
||||
$green: #198754;
|
||||
$yellow: #FFC107;
|
||||
$gray-border: #CED4DA;
|
||||
|
||||
$dark: $blue-900;
|
||||
$light: $gray-100;
|
||||
$primary: $blue-500;
|
||||
|
||||
$heading-color: #152536;
|
||||
$body-color: #6c757d;
|
||||
|
||||
//FONT
|
||||
$bolder: 600;
|
||||
$font-weight-bolder: $bolder;
|
||||
51
assets/styles/_grid.scss
Normal file
51
assets/styles/_grid.scss
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
// GRID PAGE LOAN
|
||||
.grid-template-loans {
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"product calendar"
|
||||
"message calendar";
|
||||
column-gap: 2rem;
|
||||
grid-template-rows: 100px auto;
|
||||
}
|
||||
|
||||
// GRID PAGE PRODUCT
|
||||
.grid-template-product {
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"info lender"
|
||||
"info calendar";
|
||||
grid-template-columns: 45rem 3fr;
|
||||
column-gap: 100px;
|
||||
}
|
||||
|
||||
.grid {
|
||||
&-lender {
|
||||
grid-area: lender;
|
||||
}
|
||||
|
||||
&-product {
|
||||
grid-area: product;
|
||||
}
|
||||
|
||||
&-message {
|
||||
grid-area: message;
|
||||
}
|
||||
|
||||
&-calendar {
|
||||
grid-area: calendar;
|
||||
}
|
||||
|
||||
&-info {
|
||||
grid-area: info;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 992px) {
|
||||
.grid-template-loans, .grid-template-product, .grid-template-conversation {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.lender {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
21
assets/styles/_group.scss
Normal file
21
assets/styles/_group.scss
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
.card-group {
|
||||
width: 100%;
|
||||
|
||||
div {
|
||||
span.badge {
|
||||
width: fit-content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 991px) {
|
||||
.group-list {
|
||||
li {
|
||||
border-bottom: 1px solid $gray;
|
||||
|
||||
&:last-child {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
34
assets/styles/_headings.scss
Normal file
34
assets/styles/_headings.scss
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
h1, h2, h3, h4, h5, h6 {
|
||||
color: $heading-color;
|
||||
font-weight: $font-weight-semibold;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 40px;
|
||||
font-weight: 600;
|
||||
line-height: 48.41px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
line-height: 38.73px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
line-height: 33.89px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
line-height: 29.05px;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
line-height: 24.2px;
|
||||
}
|
||||
11
assets/styles/_lender.scss
Normal file
11
assets/styles/_lender.scss
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
.avatar {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
font-size: 24px;
|
||||
|
||||
&-icon {
|
||||
&::before {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
39
assets/styles/_my-account.scss
Normal file
39
assets/styles/_my-account.scss
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
.myAccount{
|
||||
border-bottom: 1px solid $gray-border;
|
||||
> .myAccount-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
> svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 10px;
|
||||
font-weight: 400;
|
||||
> path {
|
||||
fill: $secondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.myAccount-body {
|
||||
> div {
|
||||
> svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
> path {
|
||||
fill: $secondary;
|
||||
font-weight: lighter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-switch {
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
.myAccount {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
41
assets/styles/_pagination.scss
Normal file
41
assets/styles/_pagination.scss
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
._pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
> .pagination-items {
|
||||
padding: 8px 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(102, 112, 128, 0.25) !important;
|
||||
}
|
||||
}
|
||||
|
||||
> .pagination-list {
|
||||
> ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: inline-flex;
|
||||
> li {
|
||||
padding: 8px 16px;
|
||||
margin-right: 8px;
|
||||
list-style: none;
|
||||
|
||||
&.current {
|
||||
background-color: rgba(102, 112, 128, 0.25) !important;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(102, 112, 128, 0.25) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
33
assets/styles/_product-list.scss
Normal file
33
assets/styles/_product-list.scss
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
.product-type {
|
||||
border-radius: 4px 0 0 4px !important;
|
||||
border: 1px solid $primary !important;
|
||||
|
||||
&:last-child {
|
||||
border-radius: 0 4px 4px 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
#p_distance {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
|
||||
.form-check {
|
||||
.form-check-label {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.input-search {
|
||||
> input {
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
.search {
|
||||
background-color: transparent;
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: var(--bs-border-radius-sm) !important;
|
||||
border-top-right-radius: var(--bs-border-radius-sm) !important;
|
||||
}
|
||||
}
|
||||
85
assets/styles/_product.scss
Normal file
85
assets/styles/_product.scss
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
.color-svg-secondary {
|
||||
> svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
path {
|
||||
fill: $secondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.product-img{
|
||||
max-width: 100%;
|
||||
max-height: 300px;
|
||||
}
|
||||
|
||||
.swiper-wrapper {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.swiper-slide {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.swiper-button-next,
|
||||
.swiper-button-prev {
|
||||
background: rgba($black, .5);
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
|
||||
&:after {
|
||||
font-size: 14px;
|
||||
font-weight: 900;
|
||||
line-height: 0;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.read {
|
||||
overflow: hidden;
|
||||
|
||||
&.more {
|
||||
max-height: 80px;
|
||||
transition: max-height .3s ease-in-out;
|
||||
}
|
||||
|
||||
&.less {
|
||||
max-height: 500px;
|
||||
transition: max-height .3s ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
.read-toggle {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
> svg {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.loan-application {
|
||||
padding: 8px 12px;
|
||||
background-color: $secondary;
|
||||
width: fit-content;
|
||||
> p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.comment {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
> .comment-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
> p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
10
assets/styles/_reset.scss
Normal file
10
assets/styles/_reset.scss
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-top: 0;
|
||||
padding: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
15
assets/styles/_upload.scss
Normal file
15
assets/styles/_upload.scss
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
.upload {
|
||||
width: fit-content;
|
||||
.upload-input {
|
||||
padding: 62px;
|
||||
border: 1px solid $blue-200;
|
||||
background-color: $blue-100;
|
||||
|
||||
}
|
||||
|
||||
input[type=file] {
|
||||
visibility: hidden;
|
||||
width: 0;
|
||||
height: 0
|
||||
}
|
||||
}
|
||||
112
assets/styles/_utilities.scss
Normal file
112
assets/styles/_utilities.scss
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
.hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.rotate-180 {
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
|
||||
.-rotate-90 {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
.rotate-90 {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.text-gray {
|
||||
color: $gray-900;
|
||||
}
|
||||
|
||||
.text-blue-500 {
|
||||
color: $blue-500;
|
||||
}
|
||||
|
||||
.fit-content {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.fs-7 {
|
||||
font-size: $font-size-base * .75;
|
||||
}
|
||||
|
||||
.lh-0 {
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
.bg-primary-100 {
|
||||
background-color: $blue-100;
|
||||
}
|
||||
|
||||
.border-primary-200 {
|
||||
border: 1px solid $blue-200;
|
||||
}
|
||||
|
||||
.text-bg-blue-custom {
|
||||
color: $blue-500;
|
||||
border: 1px solid $blue-200;
|
||||
background-color: $blue-100;
|
||||
}
|
||||
|
||||
.featured-image {
|
||||
width: 74px;
|
||||
height: 74px;
|
||||
border-radius: 4px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.user-image {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.img-avatar {
|
||||
display: inline-block;
|
||||
background-size: cover;
|
||||
background-position: center center;
|
||||
border-radius: 50%
|
||||
}
|
||||
.bg-secondary-subtle {
|
||||
background: $gray-100;
|
||||
}
|
||||
|
||||
.fw-medium {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.default-user-avatar {
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
.fit-content {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.white-space-normal{
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
> input {
|
||||
border-right: 0;
|
||||
}
|
||||
&-button {
|
||||
border: 1px solid #ced4da;
|
||||
border-left: none;
|
||||
background-color: $white;
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: var(--bs-border-radius-sm) !important;
|
||||
border-top-right-radius: var(--bs-border-radius-sm) !important;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 992px) {
|
||||
.img-funding {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
46
assets/styles/global.scss
Normal file
46
assets/styles/global.scss
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
// customize some Bootstrap variables
|
||||
// $primary: darken(#428bca, 20%); // muse rebuild to see the change
|
||||
|
||||
@import "custom-variables";
|
||||
|
||||
// the ~ allows you to reference things in node_modules
|
||||
@import "~bootstrap/scss/bootstrap";
|
||||
@import "~bootstrap-icons/font/bootstrap-icons";
|
||||
@import "~flatpickr/dist/flatpickr.min.css";
|
||||
|
||||
@import "reset";
|
||||
@import "product-list";
|
||||
@import "card";
|
||||
@import "pagination";
|
||||
@import "product";
|
||||
@import "utilities";
|
||||
@import "my-account";
|
||||
@import "connexion";
|
||||
@import "conversations";
|
||||
@import "accordion";
|
||||
@import "calendar";
|
||||
@import "headings";
|
||||
@import "lender";
|
||||
@import "grid";
|
||||
@import "upload";
|
||||
@import "address";
|
||||
@import "chat";
|
||||
@import "group";
|
||||
|
||||
html,
|
||||
body {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
// Hack to force footer in the bottom of the page
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: 'Inter', sans-serif;
|
||||
}
|
||||
17
bin/console
Executable file
17
bin/console
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
use App\Kernel;
|
||||
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
||||
|
||||
if (!is_file(dirname(__DIR__).'/vendor/autoload_runtime.php')) {
|
||||
throw new LogicException('Symfony Runtime is missing. Try running "composer require symfony/runtime".');
|
||||
}
|
||||
|
||||
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
|
||||
|
||||
return function (array $context) {
|
||||
$kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
|
||||
|
||||
return new Application($kernel);
|
||||
};
|
||||
19
bin/phpunit
Executable file
19
bin/phpunit
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
if (!ini_get('date.timezone')) {
|
||||
ini_set('date.timezone', 'UTC');
|
||||
}
|
||||
|
||||
if (is_file(dirname(__DIR__).'/vendor/phpunit/phpunit/phpunit')) {
|
||||
define('PHPUNIT_COMPOSER_INSTALL', dirname(__DIR__).'/vendor/autoload.php');
|
||||
require PHPUNIT_COMPOSER_INSTALL;
|
||||
PHPUnit\TextUI\Command::main();
|
||||
} else {
|
||||
if (!is_file(dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php')) {
|
||||
echo "Unable to find the `simple-phpunit.php` script in `vendor/symfony/phpunit-bridge/bin/`.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php';
|
||||
}
|
||||
180
composer.json
Normal file
180
composer.json
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
{
|
||||
"name": "platformcoop/ebs",
|
||||
"type": "project",
|
||||
"license": "MIT",
|
||||
"description": "APES : Platforme d'échange de services et de biens",
|
||||
"minimum-stability": "stable",
|
||||
"prefer-stable": true,
|
||||
"repositories": {
|
||||
"coopTilleuls/payum-mollie": {
|
||||
"type": "vcs",
|
||||
"url": "git@github.com:coopTilleuls/payum-mollie.git"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1.11",
|
||||
"ext-apcu": "*",
|
||||
"ext-ctype": "*",
|
||||
"ext-iconv": "*",
|
||||
"ext-intl": "*",
|
||||
"ext-xsl": "*",
|
||||
"ext-zip": "*",
|
||||
"api-platform/core": "^3.1",
|
||||
"craue/formflow-bundle": "^3.6",
|
||||
"doctrine/annotations": "^1.0",
|
||||
"doctrine/doctrine-bundle": "^2.7",
|
||||
"doctrine/doctrine-migrations-bundle": "^3.2",
|
||||
"doctrine/orm": "^2.13",
|
||||
"easycorp/easyadmin-bundle": "v4.5.1",
|
||||
"friendsofsymfony/ckeditor-bundle": "^2.4",
|
||||
"geocoder-php/nominatim-provider": "^5.6",
|
||||
"handcraftedinthealps/goodby-csv": "^1.4",
|
||||
"hautelook/alice-bundle": "^2.11",
|
||||
"knplabs/knp-paginator-bundle": "^6.1",
|
||||
"league/commonmark": "^2.3",
|
||||
"league/flysystem-aws-s3-v3": "^3.15",
|
||||
"league/flysystem-bundle": "^3.0",
|
||||
"league/flysystem-google-cloud-storage": "^3.15",
|
||||
"league/flysystem-memory": "^3.10",
|
||||
"meilisearch/meilisearch-php": "^1.0",
|
||||
"moneyphp/money": "^3.3",
|
||||
"nelmio/cors-bundle": "^2.2",
|
||||
"nesbot/carbon": "^2.66",
|
||||
"nyholm/psr7": "^1.0",
|
||||
"odolbeau/phone-number-bundle": "^3.9",
|
||||
"payum/offline": "^1.7",
|
||||
"payum/payum-bundle": "^2.5",
|
||||
"phpdocumentor/reflection-docblock": "^5.3",
|
||||
"phpstan/phpdoc-parser": "^1.11",
|
||||
"sensio/framework-extra-bundle": "^6.2",
|
||||
"snc/redis-bundle": "^4.3",
|
||||
"stof/doctrine-extensions-bundle": "^1.7",
|
||||
"symfony/asset": "6.2.*",
|
||||
"symfony/cache": "6.2.*",
|
||||
"symfony/clock": "6.2.*",
|
||||
"symfony/console": "6.2.*",
|
||||
"symfony/doctrine-messenger": "6.2.*",
|
||||
"symfony/dotenv": "6.2.*",
|
||||
"symfony/expression-language": "6.2.*",
|
||||
"symfony/fake-sms-notifier": "6.2.*",
|
||||
"symfony/flex": "^2",
|
||||
"symfony/form": "6.2.*",
|
||||
"symfony/framework-bundle": "6.2.*",
|
||||
"symfony/google-mailer": "6.2.*",
|
||||
"symfony/html-sanitizer": "6.2.*",
|
||||
"symfony/http-client": "6.2.*",
|
||||
"symfony/mailer": "6.2.*",
|
||||
"symfony/mercure-bundle": "^0.3.5",
|
||||
"symfony/messenger": "6.2.*",
|
||||
"symfony/mime": "6.2.*",
|
||||
"symfony/monolog-bundle": "^3.8",
|
||||
"symfony/notifier": "6.2.*",
|
||||
"symfony/ovh-cloud-notifier": "6.2.*",
|
||||
"symfony/property-access": "6.2.*",
|
||||
"symfony/property-info": "6.2.*",
|
||||
"symfony/proxy-manager-bridge": "6.2.*",
|
||||
"symfony/rate-limiter": "6.2.*",
|
||||
"symfony/requirements-checker": "^2.0",
|
||||
"symfony/runtime": "6.2.*",
|
||||
"symfony/security-bundle": "6.2.*",
|
||||
"symfony/serializer": "6.2.*",
|
||||
"symfony/translation-contracts": "^3.2",
|
||||
"symfony/twig-bridge": "6.2.*",
|
||||
"symfony/twig-bundle": "6.2.*",
|
||||
"symfony/twilio-notifier": "6.2.*",
|
||||
"symfony/uid": "6.2.*",
|
||||
"symfony/ux-autocomplete": "^2.7",
|
||||
"symfony/validator": "6.2.*",
|
||||
"symfony/webpack-encore-bundle": "^1.16",
|
||||
"symfony/workflow": "6.2.*",
|
||||
"symfony/yaml": "6.2.*",
|
||||
"twig/cssinliner-extra": "^3.4",
|
||||
"twig/extra-bundle": "^3.4",
|
||||
"twig/inky-extra": "^3.4",
|
||||
"twig/intl-extra": "^3.5",
|
||||
"twig/markdown-extra": "^3.4",
|
||||
"twig/twig": "^2.12|^3.0",
|
||||
"webbaard/payum-mollie": "^1.0",
|
||||
"webmozart/assert": "^1.11",
|
||||
"willdurand/geocoder-bundle": "^5.18"
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"composer/package-versions-deprecated": true,
|
||||
"symfony/flex": true,
|
||||
"symfony/runtime": true,
|
||||
"phpstan/extension-installer": true,
|
||||
"php-http/discovery": true
|
||||
},
|
||||
"optimize-autoloader": true,
|
||||
"preferred-install": {
|
||||
"*": "dist"
|
||||
},
|
||||
"sort-packages": true
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"App\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"App\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"replace": {
|
||||
"symfony/polyfill-ctype": "*",
|
||||
"symfony/polyfill-iconv": "*",
|
||||
"symfony/polyfill-php72": "*",
|
||||
"symfony/polyfill-php73": "*",
|
||||
"symfony/polyfill-php74": "*",
|
||||
"symfony/polyfill-php80": "*",
|
||||
"symfony/polyfill-php81": "*"
|
||||
},
|
||||
"scripts": {
|
||||
"auto-scripts": {
|
||||
"cache:clear": "symfony-cmd",
|
||||
"ckeditor:install --tag=4.22.1": "symfony-cmd",
|
||||
"assets:install %PUBLIC_DIR%": "symfony-cmd",
|
||||
"requirements-checker": "script"
|
||||
},
|
||||
"post-install-cmd": [
|
||||
"@auto-scripts"
|
||||
],
|
||||
"post-update-cmd": [
|
||||
"@auto-scripts"
|
||||
]
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/symfony": "*"
|
||||
},
|
||||
"extra": {
|
||||
"symfony": {
|
||||
"allow-contrib": false,
|
||||
"require": "6.2.*",
|
||||
"docker": true
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"ekino/phpstan-banned-code": "^1.0",
|
||||
"friendsofphp/php-cs-fixer": "^3.12",
|
||||
"friendsoftwig/twigcs": "^6.1",
|
||||
"phpstan/extension-installer": "^1.1",
|
||||
"phpstan/phpstan-deprecation-rules": "^1.0",
|
||||
"phpstan/phpstan-doctrine": "^1.3",
|
||||
"phpstan/phpstan-strict-rules": "^1.4",
|
||||
"phpstan/phpstan-symfony": "^1.2",
|
||||
"phpstan/phpstan-webmozart-assert": "^1.2",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"rector/rector": "^0.14.5",
|
||||
"staabm/annotate-pull-request-from-checkstyle": "^1.8",
|
||||
"symfony/browser-kit": "6.2.*",
|
||||
"symfony/css-selector": "6.2.*",
|
||||
"symfony/debug-bundle": "6.2.*",
|
||||
"symfony/maker-bundle": "^1.47",
|
||||
"symfony/panther": "^2.0",
|
||||
"symfony/phpunit-bridge": "^6.1",
|
||||
"symfony/web-profiler-bundle": "6.2.*",
|
||||
"zenstruck/messenger-test": "^1.5"
|
||||
}
|
||||
}
|
||||
18594
composer.lock
generated
Normal file
18594
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
23
composer.md
Normal file
23
composer.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# Note regarding composer.json
|
||||
|
||||
## Meilisearch
|
||||
|
||||
meilisearch/meilisearch-php
|
||||
|
||||
Is locked to `v0.26.0` to prevent this error:
|
||||
|
||||
Executing script cache:clear [KO]
|
||||
[KO]
|
||||
Script cache:clear returned with error code 1
|
||||
!!
|
||||
!! In DebugClassLoader.php line 327:
|
||||
!!
|
||||
!! Case mismatch between loaded and declared class names: "MeiliSearch\Client"
|
||||
!! vs "Meilisearch\Client".
|
||||
!!
|
||||
!!
|
||||
!!
|
||||
Script @auto-scripts was called via post-update-cmd
|
||||
|
||||
|
||||
I have opened a ticket https://github.com/meilisearch/meilisearch-php/issues/452.
|
||||
36
config/bundles.php
Normal file
36
config/bundles.php
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
|
||||
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
|
||||
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
|
||||
Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true],
|
||||
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
|
||||
Bazinga\GeocoderBundle\BazingaGeocoderBundle::class => ['all' => true],
|
||||
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
|
||||
Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
|
||||
Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
|
||||
Nelmio\Alice\Bridge\Symfony\NelmioAliceBundle::class => ['all' => true],
|
||||
Fidry\AliceDataFixtures\Bridge\Symfony\FidryAliceDataFixturesBundle::class => ['all' => true],
|
||||
Hautelook\AliceBundle\HautelookAliceBundle::class => ['all' => true],
|
||||
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
|
||||
Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true],
|
||||
ApiPlatform\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true],
|
||||
Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true],
|
||||
Symfony\Bundle\MercureBundle\MercureBundle::class => ['all' => true],
|
||||
Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
|
||||
EasyCorp\Bundle\EasyAdminBundle\EasyAdminBundle::class => ['all' => true],
|
||||
Craue\FormFlowBundle\CraueFormFlowBundle::class => ['all' => true],
|
||||
Zenstruck\Messenger\Test\ZenstruckMessengerTestBundle::class => ['dev' => true, 'test' => true],
|
||||
Snc\RedisBundle\SncRedisBundle::class => ['all' => true],
|
||||
Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true],
|
||||
League\FlysystemBundle\FlysystemBundle::class => ['all' => true],
|
||||
Knp\Bundle\PaginatorBundle\KnpPaginatorBundle::class => ['all' => true],
|
||||
Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true],
|
||||
Symfony\UX\Autocomplete\AutocompleteBundle::class => ['all' => true],
|
||||
Payum\Bundle\PayumBundle\PayumBundle::class => ['all' => true],
|
||||
FOS\CKEditorBundle\FOSCKEditorBundle::class => ['all' => true],
|
||||
Misd\PhoneNumberBundle\MisdPhoneNumberBundle::class => ['all' => true],
|
||||
];
|
||||
24
config/packages/api_platform.yaml
Normal file
24
config/packages/api_platform.yaml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
api_platform:
|
||||
title: 'PlateformCoop API'
|
||||
description: 'List of PlateformCoop API endpoints. Most of them require to be logged.'
|
||||
|
||||
# The version of the API.
|
||||
version: '%app_version%'
|
||||
|
||||
openapi:
|
||||
# The contact information for the exposed API.
|
||||
contact:
|
||||
# The identifying name of the contact person/organization.
|
||||
name: APES
|
||||
# The URL pointing to the contact information. MUST be in the format of a URL.
|
||||
url: http://www.apes-hdf.org/page-96-0-0.html
|
||||
# The email address of the contact person/organization. MUST be in the format of an email address.
|
||||
email: contact@apes-hdf.org
|
||||
# A URL to the Terms of Service for the API. MUST be in the format of a URL.
|
||||
termsOfService: https://github.com/ApesHDF/EBS/blob/main/LICENSE
|
||||
# The license information for the exposed API.
|
||||
license:
|
||||
# The license name used for the API.
|
||||
name: MIT
|
||||
# URL to the license used for the API. MUST be in the format of a URL.
|
||||
url: https://github.com/ApesHDF/EBS/blob/main/LICENSE
|
||||
24
config/packages/bazinga_geocoder.yaml
Normal file
24
config/packages/bazinga_geocoder.yaml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
services:
|
||||
_defaults:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
# we need a PSR16 cache for bazinga_geoloc
|
||||
cache.geoloc.psr16:
|
||||
class: Symfony\Component\Cache\Psr16Cache
|
||||
arguments: ['@cache.geoloc']
|
||||
|
||||
# See the docs at https://github.com/geocoder-php/BazingaGeocoderBundle
|
||||
bazinga_geocoder:
|
||||
# The local IP (127.0.0.1) will be replaced by the fake_ip
|
||||
# see https://github.com/geocoder-php/BazingaGeocoderBundle/blob/5.0.0/Resources/doc/index.md#fake-local-ip
|
||||
fake_ip: 92.159.11.105 # Lomme
|
||||
providers:
|
||||
nominatim:
|
||||
# https://github.com/geocoder-php/nominatim-provider
|
||||
factory: Bazinga\GeocoderBundle\ProviderFactory\NominatimFactory
|
||||
|
||||
# https://github.com/geocoder-php/BazingaGeocoderBundle/blob/master/doc/cache.md
|
||||
cache: 'cache.geoloc.psr16'
|
||||
cache_lifetime: 86400
|
||||
cache_precision: ~
|
||||
23
config/packages/cache.yaml
Normal file
23
config/packages/cache.yaml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
framework:
|
||||
cache:
|
||||
# Unique name of your app: used to compute stable namespaces for cache keys.
|
||||
prefix_seed: platformecoop/ebs
|
||||
|
||||
# The "app" cache stores to the filesystem by default.
|
||||
# The data in this cache should persist between deploys.
|
||||
# app: cache.adapter.filesystem
|
||||
|
||||
# Other options include:
|
||||
# Redis
|
||||
app: cache.adapter.redis
|
||||
default_redis_provider: "%env(REDIS_URL)%"
|
||||
|
||||
# APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
|
||||
#app: cache.adapter.apcu
|
||||
|
||||
# Namespaced pools use the above "app" backend by default
|
||||
pools:
|
||||
# Specific pool for Geolocation stuff
|
||||
cache.geoloc:
|
||||
adapter: cache.app
|
||||
default_lifetime: 3600
|
||||
5
config/packages/debug.yaml
Normal file
5
config/packages/debug.yaml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
when@dev:
|
||||
debug:
|
||||
# Forwards VarDumper Data clones to a centralized server allowing to inspect dumps on CLI or in your browser.
|
||||
# See the "server:dump" command to start a new server.
|
||||
dump_destination: "tcp://%env(VAR_DUMPER_SERVER)%"
|
||||
44
config/packages/doctrine.yaml
Normal file
44
config/packages/doctrine.yaml
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
doctrine:
|
||||
dbal:
|
||||
url: '%env(resolve:DATABASE_URL)%'
|
||||
|
||||
# IMPORTANT: You MUST configure your server version,
|
||||
# either here or in the DATABASE_URL env var (see .env file)
|
||||
server_version: '14' # to synchronize with docker-compose.yml
|
||||
|
||||
orm:
|
||||
auto_generate_proxy_classes: true
|
||||
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
|
||||
auto_mapping: true
|
||||
mappings:
|
||||
App:
|
||||
is_bundle: false
|
||||
dir: '%kernel.project_dir%/src/Entity'
|
||||
prefix: 'App\Entity'
|
||||
alias: App
|
||||
|
||||
when@test:
|
||||
doctrine:
|
||||
dbal:
|
||||
# "TEST_TOKEN" is typically set by ParaTest
|
||||
dbname_suffix: '_test%env(default::TEST_TOKEN)%'
|
||||
logging: false
|
||||
|
||||
when@prod:
|
||||
doctrine:
|
||||
orm:
|
||||
auto_generate_proxy_classes: false
|
||||
query_cache_driver:
|
||||
type: pool
|
||||
pool: doctrine.system_cache_pool
|
||||
result_cache_driver:
|
||||
type: pool
|
||||
pool: doctrine.result_cache_pool
|
||||
|
||||
framework:
|
||||
cache:
|
||||
pools:
|
||||
doctrine.result_cache_pool:
|
||||
adapter: cache.app
|
||||
doctrine.system_cache_pool:
|
||||
adapter: cache.system
|
||||
7
config/packages/doctrine_migrations.yaml
Normal file
7
config/packages/doctrine_migrations.yaml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
doctrine_migrations:
|
||||
migrations_paths:
|
||||
# namespace is arbitrary but should be different from App\Migrations
|
||||
# as migrations classes should NOT be autoloaded
|
||||
'DoctrineMigrations': '%kernel.project_dir%/migrations'
|
||||
enable_profiler: false
|
||||
organize_migrations: BY_YEAR
|
||||
100
config/packages/flysystem.yaml
Normal file
100
config/packages/flysystem.yaml
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
parameters:
|
||||
# physical storage path
|
||||
upload_dir: '%kernel.project_dir%/public/storage/uploads'
|
||||
category_upload_dir: '%upload_dir%/category'
|
||||
user_upload_dir: '%upload_dir%/user'
|
||||
product_upload_dir: '%upload_dir%/product'
|
||||
|
||||
# relative URL path
|
||||
base_path: '/storage/uploads'
|
||||
category_base_path: '%base_path%/category'
|
||||
user_base_path: '%base_path%/user'
|
||||
product_base_path: '%base_path%/product'
|
||||
|
||||
# S3 Bucket config
|
||||
storage_bucket: '%env(resolve:STORAGE_BUCKET)%'
|
||||
|
||||
# Read the documentation at https://github.com/thephpleague/flysystem-bundle/blob/master/docs/1-getting-started.md
|
||||
flysystem:
|
||||
storages:
|
||||
category.storage:
|
||||
adapter: 'local'
|
||||
options:
|
||||
directory: '%category_upload_dir%'
|
||||
public_url: '%category_base_path%'
|
||||
|
||||
# local
|
||||
user.storage:
|
||||
adapter: 'local'
|
||||
options:
|
||||
directory: '%user_upload_dir%'
|
||||
public_url: '%user_base_path%'
|
||||
|
||||
# Test S3 config locally with the min.io service (@see the docker compose files)
|
||||
# user.storage:
|
||||
# adapter: 'aws'
|
||||
# visibility: public
|
||||
# options:
|
||||
# bucket: '%storage_bucket%'
|
||||
# prefix: 'user'
|
||||
# client: 'Aws\S3\S3Client'
|
||||
|
||||
product.storage:
|
||||
adapter: 'local'
|
||||
options:
|
||||
directory: '%product_upload_dir%'
|
||||
public_url: '%product_base_path%'
|
||||
default.storage:
|
||||
adapter: 'local'
|
||||
options:
|
||||
directory: '%upload_dir%'
|
||||
public_url: '%base_path%'
|
||||
|
||||
# memory storage in the test env so we don't have to manipulate actual files
|
||||
when@test:
|
||||
flysystem:
|
||||
storages:
|
||||
category.storage:
|
||||
adapter: 'memory'
|
||||
public_url: '%category_base_path%'
|
||||
user.storage:
|
||||
adapter: 'memory'
|
||||
public_url: '%user_base_path%'
|
||||
product.storage:
|
||||
adapter: 'memory'
|
||||
public_url: '%product_base_path%'
|
||||
default.storage:
|
||||
adapter: 'memory'
|
||||
public_url: '%base_path%'
|
||||
|
||||
# S3 compatible bucket in the production environment
|
||||
when@prod:
|
||||
flysystem:
|
||||
storages:
|
||||
category.storage:
|
||||
adapter: 'aws'
|
||||
visibility: public
|
||||
options:
|
||||
bucket: '%storage_bucket%'
|
||||
prefix: 'category'
|
||||
client: 'Aws\S3\S3Client'
|
||||
user.storage:
|
||||
adapter: 'aws'
|
||||
visibility: public
|
||||
options:
|
||||
bucket: '%storage_bucket%'
|
||||
prefix: 'user'
|
||||
client: 'Aws\S3\S3Client'
|
||||
product.storage:
|
||||
adapter: 'aws'
|
||||
visibility: public
|
||||
options:
|
||||
bucket: '%storage_bucket%'
|
||||
prefix: 'product'
|
||||
client: 'Aws\S3\S3Client'
|
||||
default.storage:
|
||||
adapter: 'aws'
|
||||
visibility: public
|
||||
options:
|
||||
bucket: '%storage_bucket%'
|
||||
client: 'Aws\S3\S3Client'
|
||||
10
config/packages/fos_ckeditor.yaml
Normal file
10
config/packages/fos_ckeditor.yaml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# Read the documentation: https://symfony.com/doc/current/bundles/FOSCKEditorBundle/index.html
|
||||
|
||||
twig:
|
||||
form_themes:
|
||||
- '@FOSCKEditor/Form/ckeditor_widget.html.twig'
|
||||
|
||||
fos_ck_editor:
|
||||
configs:
|
||||
main_config:
|
||||
toolbar: full
|
||||
29
config/packages/framework.yaml
Normal file
29
config/packages/framework.yaml
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# see https://symfony.com/doc/current/reference/configuration/framework.html
|
||||
framework:
|
||||
secret: '%env(APP_SECRET)%'
|
||||
csrf_protection: true
|
||||
http_method_override: false
|
||||
|
||||
# Enables session support. Note that the session will ONLY be started if you read or write from it.
|
||||
# Remove or comment this section to explicitly disable session support.
|
||||
session:
|
||||
# handler_id: null # native session handler
|
||||
handler_id: Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler
|
||||
cookie_secure: auto
|
||||
cookie_samesite: lax
|
||||
storage_factory_id: session.storage.factory.native
|
||||
|
||||
#esi: true
|
||||
#fragments: true
|
||||
php_errors:
|
||||
log: true
|
||||
|
||||
# i18n
|
||||
# this parameter with allowed routing prefix, @see LocalesCompilerPass
|
||||
enabled_locales: ['fr']
|
||||
|
||||
when@test:
|
||||
framework:
|
||||
test: true
|
||||
session:
|
||||
storage_factory_id: session.storage.factory.mock_file
|
||||
13
config/packages/hautelook_alice.yaml
Normal file
13
config/packages/hautelook_alice.yaml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
hautelook_alice:
|
||||
fixtures_path: 'fixtures' # Path to which to look for fixtures relative to the project directory or the bundle path. May be a string or an array of strings.
|
||||
root_dirs:
|
||||
- '%kernel.project_dir%'
|
||||
|
||||
when@dev: &dev
|
||||
hautelook_alice:
|
||||
fixtures_path: 'fixtures'
|
||||
|
||||
when@test: *dev
|
||||
|
||||
# An instance can be initialized thanks to the prod fixtures
|
||||
when@prod: *dev
|
||||
10
config/packages/http_discovery.yaml
Normal file
10
config/packages/http_discovery.yaml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
services:
|
||||
Psr\Http\Message\RequestFactoryInterface: '@http_discovery.psr17_factory'
|
||||
Psr\Http\Message\ResponseFactoryInterface: '@http_discovery.psr17_factory'
|
||||
Psr\Http\Message\ServerRequestFactoryInterface: '@http_discovery.psr17_factory'
|
||||
Psr\Http\Message\StreamFactoryInterface: '@http_discovery.psr17_factory'
|
||||
Psr\Http\Message\UploadedFileFactoryInterface: '@http_discovery.psr17_factory'
|
||||
Psr\Http\Message\UriFactoryInterface: '@http_discovery.psr17_factory'
|
||||
|
||||
http_discovery.psr17_factory:
|
||||
class: Http\Discovery\Psr17Factory
|
||||
4
config/packages/knp_paginator.yaml
Normal file
4
config/packages/knp_paginator.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# https://github.com/KnpLabs/KnpPaginatorBundle#configuration-example
|
||||
knp_paginator:
|
||||
template:
|
||||
pagination: '@KnpPaginator/Pagination/bootstrap_v5_pagination.html.twig'
|
||||
10
config/packages/mailer.yaml
Normal file
10
config/packages/mailer.yaml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
framework:
|
||||
mailer:
|
||||
dsn: '%env(MAILER_DSN)%'
|
||||
envelope:
|
||||
sender: 'notifications@example.com'
|
||||
|
||||
when@test:
|
||||
framework:
|
||||
mailer:
|
||||
dsn: 'null://null'
|
||||
9
config/packages/meilisearch.yaml
Normal file
9
config/packages/meilisearch.yaml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# Meilisearch
|
||||
parameters:
|
||||
meilisearchUrl: '%env(string:MEILISEARCH_URL)%'
|
||||
meilisearchApiKey: '%env(string:MEILISEARCH_API_KEY)%'
|
||||
|
||||
services:
|
||||
_defaults:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
8
config/packages/mercure.yaml
Normal file
8
config/packages/mercure.yaml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
mercure:
|
||||
hubs:
|
||||
default:
|
||||
url: '%env(MERCURE_URL)%'
|
||||
public_url: '%env(MERCURE_PUBLIC_URL)%'
|
||||
jwt:
|
||||
secret: '%env(MERCURE_JWT_SECRET)%'
|
||||
publish: '*'
|
||||
33
config/packages/messenger.yaml
Normal file
33
config/packages/messenger.yaml
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
framework:
|
||||
messenger:
|
||||
# https://symfony.com/doc/current/messenger/multiple_buses.html
|
||||
default_bus: command.bus
|
||||
buses:
|
||||
query.bus: # $queryBus
|
||||
command.bus: # $commandBus
|
||||
|
||||
# Uncomment this (and the failed transport below) to send failed messages to this transport for later handling.
|
||||
failure_transport: failed
|
||||
|
||||
transports:
|
||||
# https://symfony.com/doc/current/messenger.html#transport-configuration
|
||||
sync: 'sync://'
|
||||
async: '%env(MESSENGER_TRANSPORT_DSN)%'
|
||||
failed: '%env(MESSENGER_TRANSPORT_DSN)%?queue_name=failed'
|
||||
|
||||
routing:
|
||||
# Sync
|
||||
'*': sync # default routing for all messages until not changed
|
||||
|
||||
# Route your messages to the transports
|
||||
# Async
|
||||
# 'App\Message\YourMessage': async
|
||||
|
||||
when@test:
|
||||
framework:
|
||||
messenger:
|
||||
transports:
|
||||
# replace with your transport name here (e.g., my_transport: 'in-memory://')
|
||||
# For more Messenger testing tools, see https://github.com/zenstruck/messenger-test
|
||||
async: 'test://'
|
||||
# sync: 'test://'
|
||||
6
config/packages/misd_phone_number.yaml
Normal file
6
config/packages/misd_phone_number.yaml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# To persist libphonenumber\PhoneNumber objects, add the Misd\PhoneNumberBundle\Doctrine\DBAL\Types\PhoneNumberType mapping to your application's config.
|
||||
# This requires: doctrine/doctrine-bundle
|
||||
doctrine:
|
||||
dbal:
|
||||
types:
|
||||
phone_number: Misd\PhoneNumberBundle\Doctrine\DBAL\Types\PhoneNumberType
|
||||
11
config/packages/mollie.yaml
Normal file
11
config/packages/mollie.yaml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
services:
|
||||
_defaults:
|
||||
autowire: true # Automatically injects dependencies in your services.
|
||||
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
|
||||
|
||||
# @see https://github.com/webbaard/payum-mollie#symfony-integration
|
||||
app.payum.mollie.factory:
|
||||
class: Payum\Core\Bridge\Symfony\Builder\GatewayFactoryBuilder
|
||||
arguments: [PayHelper\Payum\Mollie\MollieGatewayFactory]
|
||||
tags:
|
||||
- { name: payum.gateway_factory_builder, factory: mollie }
|
||||
61
config/packages/monolog.yaml
Normal file
61
config/packages/monolog.yaml
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
monolog:
|
||||
channels:
|
||||
- deprecation # Deprecations are logged in the dedicated "deprecation" channel when it exists
|
||||
|
||||
when@dev:
|
||||
monolog:
|
||||
handlers:
|
||||
main:
|
||||
type: stream
|
||||
path: "%kernel.logs_dir%/%kernel.environment%.log"
|
||||
level: debug
|
||||
channels: ["!event"]
|
||||
# uncomment to get logging in your browser
|
||||
# you may have to allow bigger header sizes in your Web server configuration
|
||||
#firephp:
|
||||
# type: firephp
|
||||
# level: info
|
||||
#chromephp:
|
||||
# type: chromephp
|
||||
# level: info
|
||||
console:
|
||||
type: console
|
||||
process_psr_3_messages: false
|
||||
channels: ["!event", "!doctrine", "!console"]
|
||||
|
||||
when@test:
|
||||
monolog:
|
||||
handlers:
|
||||
main:
|
||||
type: fingers_crossed
|
||||
action_level: error
|
||||
handler: nested
|
||||
excluded_http_codes: [404, 405]
|
||||
channels: ["!event"]
|
||||
nested:
|
||||
type: stream
|
||||
path: "%kernel.logs_dir%/%kernel.environment%.log"
|
||||
level: debug
|
||||
|
||||
when@prod:
|
||||
monolog:
|
||||
handlers:
|
||||
main:
|
||||
type: fingers_crossed
|
||||
action_level: error
|
||||
handler: nested
|
||||
excluded_http_codes: [404, 405]
|
||||
buffer_size: 50 # How many messages should be saved? Prevent memory leaks
|
||||
nested:
|
||||
type: stream
|
||||
path: php://stderr
|
||||
level: debug
|
||||
formatter: monolog.formatter.json
|
||||
console:
|
||||
type: console
|
||||
process_psr_3_messages: false
|
||||
channels: ["!event", "!doctrine"]
|
||||
deprecation:
|
||||
type: stream
|
||||
channels: [deprecation]
|
||||
path: php://stderr
|
||||
15
config/packages/nelmio_alice.yaml
Normal file
15
config/packages/nelmio_alice.yaml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
hautelook_alice:
|
||||
root_dirs:
|
||||
|
||||
when@dev: &dev
|
||||
nelmio_alice:
|
||||
functions_blacklist:
|
||||
- 'current'
|
||||
- 'shuffle'
|
||||
- 'date'
|
||||
- 'time'
|
||||
- 'file'
|
||||
- 'md5'
|
||||
- 'sha1'
|
||||
|
||||
when@test: *dev
|
||||
10
config/packages/nelmio_cors.yaml
Normal file
10
config/packages/nelmio_cors.yaml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
nelmio_cors:
|
||||
defaults:
|
||||
origin_regex: true
|
||||
allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
|
||||
allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
|
||||
allow_headers: ['Content-Type', 'Authorization']
|
||||
expose_headers: ['Link']
|
||||
max_age: 3600
|
||||
paths:
|
||||
'^/': null
|
||||
29
config/packages/notifier.yaml
Normal file
29
config/packages/notifier.yaml
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
framework:
|
||||
notifier:
|
||||
texter_transports:
|
||||
sms_service: '%env(SMS_DSN)%' # change in your .env.local to test with a real API key
|
||||
# sms_service: 'null://null' # use this to deactivate totally SMS
|
||||
|
||||
channel_policy:
|
||||
# use chat/slack, chat/telegram, sms/twilio or sms/nexmo
|
||||
urgent: ['email']
|
||||
high: ['email']
|
||||
medium: ['email']
|
||||
low: ['email']
|
||||
|
||||
admin_recipients:
|
||||
- { email: admin@example.com }
|
||||
|
||||
when@dev:
|
||||
framework:
|
||||
notifier:
|
||||
texter_transports:
|
||||
fakesms: 'fakesms+email://mailer?to=TO&from=FROM'
|
||||
|
||||
# don't send real SMS in test env, but we are still able to check that the code
|
||||
# tried to send something with the AssertCount assertions (@see tests)
|
||||
when@test:
|
||||
framework:
|
||||
notifier:
|
||||
texter_transports:
|
||||
sms_service: 'null://null'
|
||||
21
config/packages/nyholm_psr7.yaml
Normal file
21
config/packages/nyholm_psr7.yaml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
services:
|
||||
# Register nyholm/psr7 services for autowiring with PSR-17 (HTTP factories)
|
||||
Psr\Http\Message\RequestFactoryInterface: '@nyholm.psr7.psr17_factory'
|
||||
Psr\Http\Message\ResponseFactoryInterface: '@nyholm.psr7.psr17_factory'
|
||||
Psr\Http\Message\ServerRequestFactoryInterface: '@nyholm.psr7.psr17_factory'
|
||||
Psr\Http\Message\StreamFactoryInterface: '@nyholm.psr7.psr17_factory'
|
||||
Psr\Http\Message\UploadedFileFactoryInterface: '@nyholm.psr7.psr17_factory'
|
||||
Psr\Http\Message\UriFactoryInterface: '@nyholm.psr7.psr17_factory'
|
||||
|
||||
# Register nyholm/psr7 services for autowiring with HTTPlug factories
|
||||
Http\Message\MessageFactory: '@nyholm.psr7.httplug_factory'
|
||||
Http\Message\RequestFactory: '@nyholm.psr7.httplug_factory'
|
||||
Http\Message\ResponseFactory: '@nyholm.psr7.httplug_factory'
|
||||
Http\Message\StreamFactory: '@nyholm.psr7.httplug_factory'
|
||||
Http\Message\UriFactory: '@nyholm.psr7.httplug_factory'
|
||||
|
||||
nyholm.psr7.psr17_factory:
|
||||
class: Nyholm\Psr7\Factory\Psr17Factory
|
||||
|
||||
nyholm.psr7.httplug_factory:
|
||||
class: Nyholm\Psr7\Factory\HttplugFactory
|
||||
21
config/packages/payum.yaml
Normal file
21
config/packages/payum.yaml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# https://github.com/Payum/PayumBundle
|
||||
payum:
|
||||
security:
|
||||
token_storage:
|
||||
App\Entity\PaymentToken: { doctrine: orm }
|
||||
|
||||
storages:
|
||||
App\Entity\Payment: { doctrine: orm }
|
||||
|
||||
gateways:
|
||||
# For tests but can also be used for offline payments like cash.
|
||||
offline:
|
||||
factory: offline
|
||||
|
||||
# https://github.com/webbaard/payum-mollie
|
||||
# fork for PHP 8.0+
|
||||
# see config/packages/mollie.yaml
|
||||
mollie:
|
||||
factory: mollie
|
||||
apiKey: '%env(string:PAYUM_APIKEY)%'
|
||||
method: creditcard # one of directdebit, creditcard or directdebit_oneoff
|
||||
12
config/packages/routing.yaml
Normal file
12
config/packages/routing.yaml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
framework:
|
||||
router:
|
||||
utf8: true
|
||||
|
||||
# Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
|
||||
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
|
||||
#default_uri: http://localhost
|
||||
|
||||
when@prod:
|
||||
framework:
|
||||
router:
|
||||
strict_requirements: null
|
||||
67
config/packages/security.yaml
Normal file
67
config/packages/security.yaml
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
security:
|
||||
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
|
||||
password_hashers:
|
||||
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
|
||||
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
|
||||
providers:
|
||||
# used to reload user from session & other features (e.g. switch_user)
|
||||
app_user_provider:
|
||||
entity:
|
||||
class: App\Entity\User
|
||||
property: email
|
||||
firewalls:
|
||||
dev:
|
||||
pattern: ^/(_(profiler|wdt)|css|images|js)/
|
||||
security: false
|
||||
main:
|
||||
lazy: true
|
||||
provider: app_user_provider
|
||||
# checkers are in src/Security/Checker
|
||||
user_checker: security.user_checker.chain.main
|
||||
|
||||
# activate different ways to authenticate
|
||||
# https://symfony.com/doc/current/security.html#the-firewall
|
||||
|
||||
# https://symfony.com/doc/current/security/impersonating_user.html
|
||||
switch_user:
|
||||
parameter: _switch_user
|
||||
|
||||
form_login:
|
||||
login_path: app_login
|
||||
check_path: app_login
|
||||
enable_csrf: true
|
||||
default_target_path: app_user_my_account
|
||||
|
||||
# https://symfony.com/doc/current/security.html#logging-out
|
||||
logout:
|
||||
path: app_logout
|
||||
target: app_login
|
||||
|
||||
entry_point: App\Security\EntryPoint\AuthenticationEntryPoint
|
||||
|
||||
login_throttling:
|
||||
max_attempts: 2
|
||||
|
||||
# Easy way to control access for large sections of your site
|
||||
# Note: Only the *first* access control that matches will be used
|
||||
access_control:
|
||||
- { path: ^/admin, roles: [ROLE_ADMIN, ROLE_GROUP_ADMIN] }
|
||||
# to synchronize with MyAccountAction
|
||||
- { path: ^/en/my-account/, roles: ROLE_USER }
|
||||
- { path: ^/fr/mon-compte/, roles: ROLE_USER }
|
||||
|
||||
role_hierarchy:
|
||||
ROLE_ADMIN: [ROLE_USER, ROLE_ALLOWED_TO_SWITCH, ROLE_GROUP_ADMIN]
|
||||
|
||||
when@test:
|
||||
security:
|
||||
password_hashers:
|
||||
# By default, password hashers are resource intensive and take time. This is
|
||||
# important to generate secure password hashes. In tests however, secure hashes
|
||||
# are not important, waste resources and increase test times. The following
|
||||
# reduces the work factor to the lowest possible values.
|
||||
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
|
||||
algorithm: auto
|
||||
cost: 4 # Lowest possible value for bcrypt
|
||||
time_cost: 3 # Lowest possible value for argon
|
||||
memory_cost: 10 # Lowest possible value for argon
|
||||
7
config/packages/sensio_framework_extra.yaml
Normal file
7
config/packages/sensio_framework_extra.yaml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# https://stackoverflow.com/q/69809320/633864
|
||||
sensio_framework_extra:
|
||||
router:
|
||||
annotations: false
|
||||
request:
|
||||
converters: false
|
||||
auto_convert: false
|
||||
27
config/packages/snc_redis.yaml
Normal file
27
config/packages/snc_redis.yaml
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
services:
|
||||
_defaults:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler:
|
||||
arguments:
|
||||
- '@snc_redis.session'
|
||||
- { 'ttl': 3600 }
|
||||
|
||||
# Define your clients here. The example below connects to database 0 of the default Redis server.
|
||||
#
|
||||
# See https://github.com/snc/SncRedisBundle/blob/master/docs/README.md for instructions on
|
||||
# how to configure the bundle.
|
||||
snc_redis:
|
||||
clients:
|
||||
default:
|
||||
type: phpredis
|
||||
alias: default
|
||||
dsn: "%env(REDIS_URL)%"
|
||||
logging: '%kernel.debug%'
|
||||
|
||||
# use in framework.
|
||||
session:
|
||||
type: phpredis
|
||||
alias: session
|
||||
dsn: "%env(REDIS_URL)%/1"
|
||||
logging: '%kernel.debug%'
|
||||
10
config/packages/stof_doctrine_extensions.yaml
Normal file
10
config/packages/stof_doctrine_extensions.yaml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# Read the documentation: https://symfony.com/doc/current/bundles/StofDoctrineExtensionsBundle/index.html
|
||||
# See the official DoctrineExtensions documentation for more details: https://github.com/doctrine-extensions/DoctrineExtensions/tree/main/doc
|
||||
stof_doctrine_extensions:
|
||||
default_locale: fr_FR
|
||||
orm:
|
||||
default:
|
||||
timestampable: true
|
||||
sluggable: true
|
||||
sortable: true
|
||||
tree: true
|
||||
16
config/packages/translation.yaml
Normal file
16
config/packages/translation.yaml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
parameters:
|
||||
requirements_locales: null # @see LocalesCompilerPass
|
||||
|
||||
framework:
|
||||
default_locale: fr
|
||||
translator:
|
||||
default_path: '%kernel.project_dir%/translations'
|
||||
fallbacks:
|
||||
- fr
|
||||
# providers:
|
||||
# crowdin:
|
||||
# dsn: '%env(CROWDIN_DSN)%'
|
||||
# loco:
|
||||
# dsn: '%env(LOCO_DSN)%'
|
||||
# lokalise:
|
||||
# dsn: '%env(LOKALISE_DSN)%'
|
||||
16
config/packages/twig.yaml
Normal file
16
config/packages/twig.yaml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
twig:
|
||||
default_path: '%kernel.project_dir%/templates'
|
||||
form_themes: ['bootstrap_5_horizontal_layout.html.twig'] # bootstrap_5_layout.html.twig
|
||||
globals:
|
||||
app_version: '%app_version%'
|
||||
upload_images_allowed_extensions: '%upload_maxsize_by_file%'
|
||||
upload_maxsize_by_file: '%upload_maxsize_by_file%'
|
||||
upload_maxsize_total: '%upload_maxsize_total%'
|
||||
upload_max_images: '%upload_max_images%'
|
||||
brand: '%brand%'
|
||||
role_user: !php/const App\Entity\User::ROLE_USER
|
||||
role_admin: !php/const App\Entity\User::ROLE_ADMIN
|
||||
|
||||
when@test:
|
||||
twig:
|
||||
strict_variables: true
|
||||
4
config/packages/uid.yaml
Normal file
4
config/packages/uid.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
framework:
|
||||
uid:
|
||||
# default_uuid_version: 7
|
||||
# time_based_uuid_version: 7
|
||||
13
config/packages/validator.yaml
Normal file
13
config/packages/validator.yaml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
framework:
|
||||
validation:
|
||||
email_validation_mode: html5
|
||||
|
||||
# Enables validator auto-mapping support.
|
||||
# For instance, basic validation constraints will be inferred from Doctrine's metadata.
|
||||
#auto_mapping:
|
||||
# App\Entity\: []
|
||||
|
||||
when@test:
|
||||
framework:
|
||||
validation:
|
||||
not_compromised_password: false
|
||||
17
config/packages/web_profiler.yaml
Normal file
17
config/packages/web_profiler.yaml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
when@dev:
|
||||
web_profiler:
|
||||
toolbar: '%kernel.debug%'
|
||||
intercept_redirects: false
|
||||
|
||||
framework:
|
||||
profiler:
|
||||
only_exceptions: false
|
||||
collect_serializer_data: true
|
||||
|
||||
when@test:
|
||||
web_profiler:
|
||||
toolbar: false
|
||||
intercept_redirects: false
|
||||
|
||||
framework:
|
||||
profiler: { collect: false }
|
||||
50
config/packages/webpack_encore.yaml
Normal file
50
config/packages/webpack_encore.yaml
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
webpack_encore:
|
||||
# The path where Encore is building the assets - i.e. Encore.setOutputPath()
|
||||
output_path: '%kernel.project_dir%/public/build'
|
||||
# If multiple builds are defined (as shown below), you can disable the default build:
|
||||
# output_path: false
|
||||
|
||||
# Set attributes that will be rendered on all script and link tags
|
||||
script_attributes:
|
||||
defer: true
|
||||
# Uncomment (also under link_attributes) if using Turbo Drive
|
||||
# https://turbo.hotwired.dev/handbook/drive#reloading-when-assets-change
|
||||
# 'data-turbo-track': reload
|
||||
# link_attributes:
|
||||
# Uncomment if using Turbo Drive
|
||||
# 'data-turbo-track': reload
|
||||
|
||||
# If using Encore.enableIntegrityHashes() and need the crossorigin attribute (default: false, or use 'anonymous' or 'use-credentials')
|
||||
# crossorigin: 'anonymous'
|
||||
|
||||
# Preload all rendered script and link tags automatically via the HTTP/2 Link header
|
||||
# preload: true
|
||||
|
||||
# Throw an exception if the entrypoints.json file is missing or an entry is missing from the data
|
||||
strict_mode: false
|
||||
|
||||
# If you have multiple builds:
|
||||
# builds:
|
||||
# pass "frontend" as the 3rg arg to the Twig functions
|
||||
# {{ encore_entry_script_tags('entry1', null, 'frontend') }}
|
||||
|
||||
# frontend: '%kernel.project_dir%/public/frontend/build'
|
||||
|
||||
# Cache the entrypoints.json (rebuild Symfony's cache when entrypoints.json changes)
|
||||
# Put in config/packages/prod/webpack_encore.yaml
|
||||
# cache: true
|
||||
|
||||
framework:
|
||||
assets:
|
||||
json_manifest_path: '%kernel.project_dir%/public/build/manifest.json'
|
||||
|
||||
when@prod:
|
||||
webpack_encore:
|
||||
# Cache the entrypoints.json (rebuild Symfony's cache when entrypoints.json changes)
|
||||
# Available in version 1.2
|
||||
cache: true
|
||||
strict_mode: true
|
||||
|
||||
when@test:
|
||||
webpack_encore:
|
||||
strict_mode: false
|
||||
56
config/packages/workflow.yaml
Normal file
56
config/packages/workflow.yaml
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
# https://symfony.com/doc/current/workflow.html#configuration
|
||||
# Get the generated services :
|
||||
# $ php bin/console debug:autowiring workflow
|
||||
# Generate the graphs in "/docs":
|
||||
# $ make workflows
|
||||
framework:
|
||||
workflows:
|
||||
service_request_status:
|
||||
type: 'state_machine'
|
||||
audit_trail:
|
||||
enabled: true
|
||||
marking_store:
|
||||
type: 'method'
|
||||
# for now workflow uses strings not enums
|
||||
# @see https://github.com/symfony/symfony/issues/44211
|
||||
property: 'statusRaw'
|
||||
supports:
|
||||
- App\Entity\ServiceRequest
|
||||
initial_marking: new
|
||||
# @see ServiceRequestStatus
|
||||
places:
|
||||
- new
|
||||
- to_confirm
|
||||
- confirmed
|
||||
- refused
|
||||
- finished
|
||||
# @see ServiceRequestStatusWorkflow
|
||||
transitions:
|
||||
# owner confirmation
|
||||
accept:
|
||||
from: new
|
||||
to: to_confirm
|
||||
# the owner modifies the dates and accept the request
|
||||
modifyOwner:
|
||||
from: new
|
||||
to: to_confirm
|
||||
# the recipient modifies the dates and ask the owner to validate again
|
||||
modifyRecipient:
|
||||
from: to_confirm
|
||||
to: new
|
||||
# recipient confirmation
|
||||
confirm:
|
||||
from: to_confirm
|
||||
to: confirmed
|
||||
# transaction manually finalized by the owner
|
||||
finalize:
|
||||
from: confirmed
|
||||
to: finished
|
||||
# transaction auto-finalized by the system
|
||||
autoFinalize:
|
||||
from: confirmed
|
||||
to: finished
|
||||
# refusal from the owner or recipient
|
||||
refuse:
|
||||
from: [new, to_confirm, confirmed]
|
||||
to: refused
|
||||
11
config/packages_extra/doctrine.yaml
Normal file
11
config/packages_extra/doctrine.yaml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# additional services related to Doctrine
|
||||
services:
|
||||
_defaults:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
# Needed to activate autowiring for the Doctrine listener
|
||||
App\Doctrine\Listener\:
|
||||
resource: '../../src/Doctrine/Listener'
|
||||
tags:
|
||||
- { name: doctrine.orm.entity_listener }
|
||||
53
config/packages_extra/flysystem.yaml
Normal file
53
config/packages_extra/flysystem.yaml
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
# additional services related to Flysystem
|
||||
parameters:
|
||||
# Allowed extensions for images
|
||||
upload_images_allowed_extensions: ['png', 'jpg', 'jpeg']
|
||||
|
||||
# Allowed maxsize by file (mb)
|
||||
upload_maxsize_by_file: 1
|
||||
|
||||
# Allowed maxsize for multiple uploads (mb)
|
||||
upload_maxsize_total: 5
|
||||
|
||||
# Max number of photos/images by product
|
||||
upload_max_images: 5
|
||||
|
||||
# S3 Bucket config
|
||||
storage_endpoint: '%env(string:STORAGE_ENDPOINT)%'
|
||||
storage_region: '%env(string:STORAGE_REGION)%'
|
||||
storage_use_path_style_endpoint: '%env(bool:STORAGE_USE_PATH_STYLE_ENDPOINT)%'
|
||||
storage_key: '%env(string:STORAGE_KEY)%'
|
||||
storage_secret: '%env(string:STORAGE_SECRET)%'
|
||||
|
||||
services:
|
||||
_defaults:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
_instanceof:
|
||||
App\Twig\FlysystemImageInterface:
|
||||
tags: [app.flysystem_image_extension]
|
||||
|
||||
App\Twig\FlysystemImagesInterface:
|
||||
tags: [app.flysystem_images_extension]
|
||||
|
||||
App\Twig\:
|
||||
resource: '../../src/Twig/'
|
||||
|
||||
App\Twig\ImageExtensionCollection:
|
||||
arguments:
|
||||
- !tagged_iterator app.flysystem_image_extension
|
||||
|
||||
App\Twig\ImagesExtensionCollection:
|
||||
arguments:
|
||||
- !tagged_iterator app.flysystem_images_extension
|
||||
|
||||
Aws\S3\S3Client:
|
||||
arguments:
|
||||
- endpoint: '%storage_endpoint%'
|
||||
version: 'latest'
|
||||
region: '%storage_region%'
|
||||
use_path_style_endpoint: '%storage_use_path_style_endpoint%'
|
||||
credentials:
|
||||
key: '%storage_key%'
|
||||
secret: '%storage_secret%'
|
||||
17
config/packages_extra/mailer.yaml
Normal file
17
config/packages_extra/mailer.yaml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# additional services related to the mailer
|
||||
services:
|
||||
_defaults:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
_instanceof:
|
||||
App\Mailer\Email\EmailInterface:
|
||||
tags: ['app.email']
|
||||
|
||||
# we need to reload EmailInterface objects here so the correct tag is applied
|
||||
App\Mailer\Email\:
|
||||
resource: '../../src/Mailer/Email/'
|
||||
|
||||
App\Mailer\EmailCollection:
|
||||
arguments:
|
||||
- !tagged_iterator app.email
|
||||
11
config/packages_extra/uuid.yaml
Normal file
11
config/packages_extra/uuid.yaml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# additional services related to the uuid component
|
||||
services:
|
||||
_defaults:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
# Activate these commands
|
||||
Symfony\Component\Uid\Command\GenerateUlidCommand: ~
|
||||
Symfony\Component\Uid\Command\GenerateUuidCommand: ~
|
||||
Symfony\Component\Uid\Command\InspectUlidCommand: ~
|
||||
Symfony\Component\Uid\Command\InspectUuidCommand: ~
|
||||
7
config/preload.php
Normal file
7
config/preload.php
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
if (file_exists(dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php')) {
|
||||
require dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php';
|
||||
}
|
||||
13
config/routes.yaml
Normal file
13
config/routes.yaml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# load everyting in Controller and use attributes
|
||||
controllers:
|
||||
resource: ../src/Controller/
|
||||
type: attribute
|
||||
|
||||
# avoid to have an empty and not used function in SecurityController
|
||||
app_logout:
|
||||
path: /logout
|
||||
|
||||
# Payoum:
|
||||
# @see https://github.com/Payum/Payum/blob/master/docs/symfony/get-it-started.md#payum-bundle-get-it-started"
|
||||
payum_all:
|
||||
resource: "@PayumBundle/Resources/config/routing/all.xml"
|
||||
12
config/routes/annotations.yaml
Normal file
12
config/routes/annotations.yaml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
controllers:
|
||||
resource: '../../src/Controller/'
|
||||
type: annotation
|
||||
# the prefix is only used when i18n are not explicitly defined
|
||||
# allowed prefixes are defined by the "kernel.enabled_locales" parameter
|
||||
# @see config/packages/framework.yaml
|
||||
prefix: /{_locale}
|
||||
|
||||
# No prefix for the root route :) it handles "/" and redirects
|
||||
root:
|
||||
resource: '../../src/Controller/AppController.php'
|
||||
type: annotation
|
||||
4
config/routes/api_platform.yaml
Normal file
4
config/routes/api_platform.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
api_platform:
|
||||
resource: .
|
||||
type: api_platform
|
||||
prefix: /api
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue