diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..14eaf4c --- /dev/null +++ b/.babelrc @@ -0,0 +1,14 @@ +{ + "presets": [ + ["@babel/preset-env", { + "targets": { + "node": "6" + } + }] + ], + "plugins": [ + ["@babel/plugin-proposal-object-rest-spread", { + "useBuiltIns": true + }] + ] +} diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..81d9a54 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,32 @@ +**/*.log +**/*.md +**/*.php~ +**/._* +**/.dockerignore +**/.DS_Store +**/.git/ +**/.gitattributes +**/.github +**/.gitignore +**/.gitkeep +**/.gitmodules +**/.idea +**/Dockerfile +**/Thumbs.db +**/docker-compose*.yaml +**/docker-compose*.yml +.editorconfig +.php_cs.cache +.travis.yml +composer.phar +docker/mysql/data/ +etc/build/* +node_modules/ +var/* +vendor/ +public/assets/ +public/build/ +public/bundles/ +public/css/ +public/js/ +public/media/ diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..8c5a7e8 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,88 @@ +# 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 + +[*.feature] +indent_style = space +indent_size = 4 + +[*.js] +indent_style = space +indent_size = 2 + +[*.json] +indent_style = space +indent_size = 2 + +[*.md] +indent_style = space +indent_size = 4 +trim_trailing_whitespace = false + +[*.neon] +indent_style = space +indent_size = 4 + +[*.php] +indent_style = space +indent_size = 4 + +[*.sh] +indent_style = space +indent_size = 4 + +[*.{yaml,yml}] +indent_style = space +indent_size = 4 +trim_trailing_whitespace = false + +[docker-compose.{yaml,yml}] +indent_size = 2 + +[docker-compose.*.{yaml,yml}] +indent_size = 2 + +[.babelrc] +indent_style = space +indent_size = 2 + +[.gitmodules] +indent_style = tab +indent_size = 4 + +[.php_cs{,.dist}] +indent_style = space +indent_size = 4 + +[composer.json] +indent_style = space +indent_size = 4 + +[package.json] +indent_style = space +indent_size = 2 + +[phpspec.yml{,.dist}] +indent_style = space +indent_size = 4 + +[phpstan.neon] +indent_style = space +indent_size = 4 + +[phpunit.xml{,.dist}] +indent_style = space +indent_size = 4 diff --git a/.env b/.env new file mode 100644 index 0000000..0379e65 --- /dev/null +++ b/.env @@ -0,0 +1,36 @@ +# This file is a "template" of which env vars needs to be defined in your configuration or in an .env file +# Set variables here that may be different on each deployment target of the app, e.g. development, staging, production. +# https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration + +###> symfony/framework-bundle ### +APP_ENV=dev +APP_DEBUG=1 +APP_SECRET=EDITME +###< symfony/framework-bundle ### + +###> doctrine/doctrine-bundle ### +# Choose one of the following DBMS, adjust the server version and charset if needed +DATABASE_URL=mysql://root@127.0.0.1/sylius_%kernel.environment%?serverVersion=8&charset=utf8mb4 +#DATABASE_URL=pgsql://postgres:postgres@127.0.0.1/sylius_%kernel.environment%?serverVersion=15&charset=utf8 +###< doctrine/doctrine-bundle ### + +###> symfony/messenger ### +# Choose one of the transports below +# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages +# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages +MESSENGER_TRANSPORT_DSN=doctrine://default +SYLIUS_MESSENGER_TRANSPORT_MAIN_DSN=doctrine://default +SYLIUS_MESSENGER_TRANSPORT_MAIN_FAILED_DSN=doctrine://default?queue_name=main_failed +SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_DSN=doctrine://default?queue_name=catalog_promotion_removal +SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_FAILED_DSN=doctrine://default?queue_name=catalog_promotion_removal_failed +###< symfony/messenger ### + +###> lexik/jwt-authentication-bundle ### +JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem +JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem +JWT_PASSPHRASE=e7c5fca1060bdf6ad23c33e4c236081f +###< lexik/jwt-authentication-bundle ### + +###> symfony/mailer ### +MAILER_DSN=null://null +###< symfony/mailer ### diff --git a/.env.prod b/.env.prod new file mode 100644 index 0000000..caab7ca --- /dev/null +++ b/.env.prod @@ -0,0 +1,3 @@ +APP_ENV=prod +APP_DEBUG=0 +APP_SECRET='s$cretf0rt3st' diff --git a/.env.test b/.env.test new file mode 100644 index 0000000..ddc27a6 --- /dev/null +++ b/.env.test @@ -0,0 +1,18 @@ +APP_SECRET='s$cretf0rt3st' + +KERNEL_CLASS='App\Kernel' + +###> lexik/jwt-authentication-bundle ### +JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private-test.pem +JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public-test.pem +JWT_PASSPHRASE=ALL_THAT_IS_GOLD_DOES_NOT_GLITTER_NOT_ALL_THOSE_WHO_WANDER_ARE_LOST +###< lexik/jwt-authentication-bundle ### + +###> symfony/messenger ### +# Sync transport turned for testing env for the ease of testing +MESSENGER_TRANSPORT_DSN=sync:// +SYLIUS_MESSENGER_TRANSPORT_MAIN_DSN=sync:// +SYLIUS_MESSENGER_TRANSPORT_MAIN_FAILED_DSN=sync:// +SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_DSN=sync:// +SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_FAILED_DSN=sync:// +###< symfony/messenger ### diff --git a/.env.test_cached b/.env.test_cached new file mode 100644 index 0000000..ace50d7 --- /dev/null +++ b/.env.test_cached @@ -0,0 +1,19 @@ +APP_DEBUG=0 +APP_SECRET='s$cretf0rt3st' + +KERNEL_CLASS='App\Kernel' + +###> lexik/jwt-authentication-bundle ### +JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private-test.pem +JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public-test.pem +JWT_PASSPHRASE=ALL_THAT_IS_GOLD_DOES_NOT_GLITTER_NOT_ALL_THOSE_WHO_WANDER_ARE_LOST +###< lexik/jwt-authentication-bundle ### + +###> symfony/messenger ### +# Sync transport turned for testing env for the ease of testing +MESSENGER_TRANSPORT_DSN=sync:// +SYLIUS_MESSENGER_TRANSPORT_MAIN_DSN=sync:// +SYLIUS_MESSENGER_TRANSPORT_MAIN_FAILED_DSN=sync:// +SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_DSN=sync:// +SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_FAILED_DSN=sync:// +###< symfony/messenger ### diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..dfddb25 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,20 @@ +module.exports = { + extends: 'airbnb-base', + env: { + node: true, + }, + rules: { + 'object-shorthand': ['error', 'always', { + avoidQuotes: true, + avoidExplicitReturnArrows: true, + }], + 'function-paren-newline': ['error', 'consistent'], + 'max-len': ['warn', 120, 2, { + ignoreUrls: true, + ignoreComments: false, + ignoreRegExpLiterals: true, + ignoreStrings: true, + ignoreTemplateLiterals: true, + }], + }, +}; diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..92faea2 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @Sylius/core-team diff --git a/.github/autolabeler.yml b/.github/autolabeler.yml new file mode 100644 index 0000000..86c9218 --- /dev/null +++ b/.github/autolabeler.yml @@ -0,0 +1,2 @@ +Maintenance: ['etc/', '.github/', '*.md'] +Docker: ['docker/', '.docker/', 'Dockerfile', 'docker-compose.*'] diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..e91abb6 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,34 @@ +version: 2 +updates: +- package-ecosystem: composer + directory: "/" + schedule: + interval: daily + time: "10:00" + open-pull-requests-limit: 10 + ignore: + - dependency-name: stripe/stripe-php + versions: + - 7.69.0 + - 7.70.0 + - 7.72.0 + - 7.73.0 + - 7.74.0 + - 7.75.0 + - 7.76.0 + - dependency-name: sylius-labs/coding-standard + versions: + - 4.0.1 + - dependency-name: sylius/sylius + versions: + - 1.9.0 + - dependency-name: phpstan/phpstan + versions: + - 0.12.70 + - 0.12.71 + - 0.12.73 + - dependency-name: phpstan/phpstan-webmozart-assert + versions: + - 0.12.10 + - 0.12.11 + - 0.12.9 diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml new file mode 100644 index 0000000..e5fc0ec --- /dev/null +++ b/.github/workflows/auto-merge.yml @@ -0,0 +1,22 @@ +name: Auto-merge + +on: + pull_request: ~ + +jobs: + auto-merge: + runs-on: ubuntu-20.04 + steps: + - + name: Checkout repository + uses: actions/checkout@v2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - + name: Auto-merge minor dependencies upgrades + uses: ahmadnassri/action-dependabot-auto-merge@v2 + with: + target: minor + github-token: ${{ secrets.GITHUB_TOKEN }} + config: .github/dependabot.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..ca0b583 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,209 @@ +name: Build + +on: + push: + branches-ignore: + - "dependabot/**" + paths-ignore: + - "*.md" + pull_request: + paths-ignore: + - "*.md" + release: + types: [created] + schedule: + - + cron: "0 1 * * 6" # Run at 1am every Saturday + workflow_dispatch: ~ + +jobs: + tests: + runs-on: ubuntu-20.04 + + name: "PHP ${{ matrix.php }}, Symfony ${{ matrix.symfony }}, MySQL ${{ matrix.mysql }}, Node ${{ matrix.node }}" + + timeout-minutes: 50 + + strategy: + fail-fast: false + matrix: + php: ["8.0", "8.1"] + symfony: ["^5.4", "^6.0"] + node: ["16.x"] + mysql: ["5.7", "8.0"] + + env: + APP_ENV: test_cached + DATABASE_URL: "mysql://root:root@127.0.0.1/sylius?serverVersion=${{ matrix.mysql }}" + + steps: + - + uses: actions/checkout@v2 + + - + name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "${{ matrix.php }}" + extensions: intl, mbstring + tools: symfony + coverage: none + + - + name: Restrict Symfony version + if: matrix.symfony != '' + run: | + composer global config --no-plugins allow-plugins.symfony/flex true + composer global require --no-progress --no-scripts --no-plugins "symfony/flex:1.18.5" + composer config extra.symfony.require "${{ matrix.symfony }}" + + - + name: Setup Node + uses: actions/setup-node@v2 + with: + node-version: "${{ matrix.node }}" + + - + name: Shutdown default MySQL + run: sudo service mysql stop + + - + name: Setup MySQL + uses: mirromutth/mysql-action@v1.1 + with: + mysql version: "${{ matrix.mysql }}" + mysql root password: "root" + + - + name: Output PHP version for Symfony CLI + run: php -v | head -n 1 | awk '{ print $2 }' > .php-version + + - + name: Install certificates + run: symfony server:ca:install + + - + name: Run Chrome Headless + run: google-chrome-stable --enable-automation --disable-background-networking --no-default-browser-check --no-first-run --disable-popup-blocking --disable-default-apps --allow-insecure-localhost --disable-translate --disable-extensions --no-sandbox --enable-features=Metal --headless --remote-debugging-port=9222 --window-size=2880,1800 --proxy-server='direct://' --proxy-bypass-list='*' http://127.0.0.1 > /dev/null 2>&1 & + + - + name: Run webserver + run: symfony server:start --port=8080 --dir=public --daemon + + - + name: Restrict Symfony version + if: matrix.symfony != '' + run: composer config extra.symfony.require "${{ matrix.symfony }}" + + - + name: Get Composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - + name: Cache Composer + uses: actions/cache@v2 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-php-${{ matrix.php }}-composer-${{ hashFiles('**/composer.json **/composer.lock') }} + restore-keys: | + ${{ runner.os }}-php-${{ matrix.php }}-composer- + + - + name: Install PHP dependencies + run: composer install --no-interaction + + - + name: Get Yarn cache directory + id: yarn-cache + run: echo "::set-output name=dir::$(yarn cache dir)" + + - + name: Cache Yarn + uses: actions/cache@v2 + with: + path: ${{ steps.yarn-cache.outputs.dir }} + key: ${{ runner.os }}-node-${{ matrix.node }}-yarn-${{ hashFiles('**/package.json **/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-node-${{ matrix.node }}-yarn- + + - + name: Install JS dependencies + run: yarn install + + - + name: Prepare test application database + run: | + APP_DEBUG=1 bin/console doctrine:database:create -vvv + bin/console doctrine:migrations:migrate -n -vvv + + - + name: Prepare test application assets + run: | + bin/console assets:install public -vvv + yarn encore production + + - + name: Prepare test application cache + run: bin/console cache:warmup -vvv + + - + name: Prepare Messenger transport (Doctrine) + run: bin/console messenger:setup-transports -vvv + + - + name: Load fixtures + run: bin/console sylius:fixtures:load -n + + - + name: Validate composer.json + run: composer validate --ansi --strict --no-check-publish + + - + name: Run security check + run: symfony security:check + + - + name: Check coding standard + run: vendor/bin/ecs check src + + - + name: Run PHPStan + run: vendor/bin/phpstan analyse -c phpstan.neon -l max src/ + + - + name: Validate database schema + run: bin/console doctrine:schema:validate + + - + name: Run PHPSpec + run: vendor/bin/phpspec run --ansi -f progress --no-interaction + + - + name: Run PHPUnit + run: vendor/bin/phpunit --colors=always + + - + name: Run managing catalog promotion scenarios + run: vendor/bin/behat --colors --strict --no-interaction -vvv -f progress --tags="~@javascript&&~@todo&&~@cli&&@managing_catalog_promotions" + + - + name: Run managing exchange rates scenarios + run: vendor/bin/behat --colors --strict --no-interaction -vvv -f progress --tags="~@javascript&&~@todo&&~@cli&&@managing_exchange_rates" + + - + name: Run non-JS Behat (without managing catalog promotion scenarios and exchange rates) + run: vendor/bin/behat --colors --strict --no-interaction -vvv -f progress --tags="~@javascript&&~@todo&&~@cli&&~@managing_catalog_promotions&&~@managing_exchange_rates" + + - + name: Run JS Behat + run: vendor/bin/behat --colors --strict --no-interaction -vvv -f progress --tags="@javascript&&~@todo&&~@cli" || vendor/bin/behat --colors --strict --no-interaction -vvv -f progress --tags="@javascript&&~@todo&&~@cli" --rerun || vendor/bin/behat --colors --strict --no-interaction -vvv -f progress --tags="@javascript&&~@todo&&~@cli" --rerun + + - + name: Upload Behat logs + uses: actions/upload-artifact@v2 + if: failure() + with: + name: "Behat logs (PHP ${{ matrix.php }}, Symfony ${{ matrix.symfony }}, MySQL ${{ matrix.mysql }})" + path: etc/build/ + if-no-files-found: ignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..18f8948 --- /dev/null +++ b/.gitignore @@ -0,0 +1,49 @@ +/public/assets +/public/build +/public/css +/public/js +/public/media +!/public/media/image/.gitkeep + +/etc/build/* +!/etc/build/.gitignore + +/behat.yml +/phpspec.yml + +/docker-compose.override.yaml +/docker-compose.override.yml +/docker/mysql/data/ + +###> symfony/framework-bundle ### +/composer.lock +/.env.*.local +/.env.local +/.env.local.php +/public/bundles +/var/ +/vendor/ +###< symfony/framework-bundle ### + +###> friendsofphp/php-cs-fixer ### +/.php_cs +/.php_cs.cache +###< friendsofphp/php-cs-fixer ### + +###> phpunit/phpunit ### +/.phpunit.result.cache +/phpunit.xml +###< phpunit/phpunit ### + +###> lexik/jwt-authentication-bundle ### +/config/jwt/*.pem +!/config/jwt/*-test.pem +###< lexik/jwt-authentication-bundle ### + +###> symfony/webpack-encore-bundle ### +/node_modules/ +/public/build/ +/npm-debug.log +/yarn-error.log +/yarn.lock +###< symfony/webpack-encore-bundle ### diff --git a/CONFLICTS.md b/CONFLICTS.md new file mode 100644 index 0000000..dab299f --- /dev/null +++ b/CONFLICTS.md @@ -0,0 +1,9 @@ +# CONFLICTS + +This document explains why certain conflicts were added to `composer.json` and +references related issues. + +- `symfony/framework-bundle:6.2.8`: + + This version is missing the service alias `validator.expression` + which causes ValidatorException exception to be thrown when using `Expression` constraint. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..63b9f8d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,171 @@ +# the different stages of this Dockerfile are meant to be built into separate images +# https://docs.docker.com/compose/compose-file/#target + +ARG PHP_VERSION=8.1 +ARG NODE_VERSION=16 +ARG NGINX_VERSION=1.21 +ARG ALPINE_VERSION=3.15 +ARG COMPOSER_VERSION=2.4 +ARG PHP_EXTENSION_INSTALLER_VERSION=latest + +FROM composer:${COMPOSER_VERSION} AS composer + +FROM mlocati/php-extension-installer:${PHP_EXTENSION_INSTALLER_VERSION} AS php_extension_installer + +FROM php:${PHP_VERSION}-fpm-alpine${ALPINE_VERSION} AS base + +# persistent / runtime deps +RUN apk add --no-cache \ + acl \ + file \ + gettext \ + unzip \ + ; + +COPY --from=php_extension_installer /usr/bin/install-php-extensions /usr/local/bin/ + +# default PHP image extensions +# ctype curl date dom fileinfo filter ftp hash iconv json libxml mbstring mysqlnd openssl pcre PDO pdo_sqlite Phar +# posix readline Reflection session SimpleXML sodium SPL sqlite3 standard tokenizer xml xmlreader xmlwriter zlib +RUN install-php-extensions apcu exif gd intl pdo_mysql opcache zip + +COPY --from=composer /usr/bin/composer /usr/bin/composer +COPY docker/php/prod/php.ini $PHP_INI_DIR/php.ini +COPY docker/php/prod/opcache.ini $PHP_INI_DIR/conf.d/opcache.ini + +# copy file required by opcache preloading +COPY config/preload.php /srv/sylius/config/preload.php + +# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser +ENV COMPOSER_ALLOW_SUPERUSER=1 +RUN set -eux; \ + composer clear-cache +ENV PATH="${PATH}:/root/.composer/vendor/bin" + +WORKDIR /srv/sylius + +# build for production +ENV APP_ENV=prod + +# prevent the reinstallation of vendors at every changes in the source code +COPY composer.* symfony.lock ./ +RUN set -eux; \ + composer install --prefer-dist --no-autoloader --no-interaction --no-scripts --no-progress --no-dev; \ + composer clear-cache + +# copy only specifically what we need +COPY .env .env.prod ./ +COPY assets assets/ +COPY bin bin/ +COPY config config/ +COPY public public/ +COPY src src/ +COPY templates templates/ +COPY translations translations/ + +RUN set -eux; \ + mkdir -p var/cache var/log; \ + composer dump-autoload --classmap-authoritative; \ + APP_SECRET='' composer run-script post-install-cmd; \ + chmod +x bin/console; sync; \ + bin/console sylius:install:assets --no-interaction; \ + bin/console sylius:theme:assets:install public --no-interaction + +VOLUME /srv/sylius/var + +VOLUME /srv/sylius/public/media + +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"] + +FROM node:${NODE_VERSION}-alpine${ALPINE_VERSION} AS sylius_node + +WORKDIR /srv/sylius + +RUN set -eux; \ + apk add --no-cache --virtual .build-deps \ + g++ \ + gcc \ + make \ + ; + +# prevent the reinstallation of vendors at every changes in the source code +COPY package.json yarn.* ./ +RUN set -eux; \ + yarn install; \ + yarn cache clean + +COPY --from=base /srv/sylius/vendor/sylius/sylius/src/Sylius/Bundle/UiBundle/Resources/private vendor/sylius/sylius/src/Sylius/Bundle/UiBundle/Resources/private/ +COPY --from=base /srv/sylius/vendor/sylius/sylius/src/Sylius/Bundle/AdminBundle/Resources/private vendor/sylius/sylius/src/Sylius/Bundle/AdminBundle/Resources/private/ +COPY --from=base /srv/sylius/vendor/sylius/sylius/src/Sylius/Bundle/ShopBundle/Resources/private vendor/sylius/sylius/src/Sylius/Bundle/ShopBundle/Resources/private/ +COPY --from=base /srv/sylius/assets ./assets + +COPY webpack.config.js ./ +RUN yarn build:prod + +COPY docker/node/docker-entrypoint.sh /usr/local/bin/docker-entrypoint +RUN chmod +x /usr/local/bin/docker-entrypoint + +ENTRYPOINT ["docker-entrypoint"] +CMD ["yarn", "build:prod"] + +FROM base AS sylius_php_prod + +COPY --from=sylius_node /srv/sylius/public/build public/build + +FROM nginx:${NGINX_VERSION}-alpine AS sylius_nginx + +COPY docker/nginx/conf.d/default.conf /etc/nginx/conf.d/ + +WORKDIR /srv/sylius + +COPY --from=base /srv/sylius/public public/ +COPY --from=sylius_node /srv/sylius/public public/ + +FROM sylius_php_prod AS sylius_php_dev + +COPY docker/php/dev/php.ini $PHP_INI_DIR/php.ini +COPY docker/php/dev/opcache.ini $PHP_INI_DIR/conf.d/opcache.ini + +WORKDIR /srv/sylius + +ENV APP_ENV=dev + +COPY .env.test .env.test_cached ./ + +RUN set -eux; \ + composer install --prefer-dist --no-autoloader --no-interaction --no-scripts --no-progress; \ + composer clear-cache + +FROM sylius_php_prod AS sylius_cron + +RUN set -eux; \ + apk add --no-cache --virtual .build-deps \ + apk-cron \ + ; + +COPY docker/cron/crontab /etc/crontabs/root +COPY docker/cron/docker-entrypoint.sh /usr/local/bin/docker-entrypoint +RUN chmod +x /usr/local/bin/docker-entrypoint + +ENTRYPOINT ["docker-entrypoint"] +CMD ["crond", "-f"] + +FROM sylius_php_prod AS sylius_migrations_prod + +COPY docker/migrations/docker-entrypoint.sh /usr/local/bin/docker-entrypoint +RUN chmod +x /usr/local/bin/docker-entrypoint + +ENTRYPOINT ["docker-entrypoint"] + +FROM sylius_php_dev AS sylius_migrations_dev + +COPY docker/migrations/docker-entrypoint.sh /usr/local/bin/docker-entrypoint +RUN chmod +x /usr/local/bin/docker-entrypoint + +RUN composer dump-autoload --classmap-authoritative + +ENTRYPOINT ["docker-entrypoint"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..92d58bf --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2011-2020 Paweł Jędrzejewski + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..7151acb --- /dev/null +++ b/README.md @@ -0,0 +1,101 @@ +
+ + + +
+ +This is Sylius Standard Edition repository for starting new projects.
+ +## About + +Sylius is the first decoupled eCommerce framework based on [**Symfony**](http://symfony.com) and [**Doctrine**](http://doctrine-project.org). +The highest quality of code, strong testing culture, built-in Agile (BDD) workflow and exceptional flexibility make it the best solution for application tailored to your business requirements. +Enjoy being an eCommerce Developer again! + +Powerful REST API allows for easy integrations and creating unique customer experience on any device. + +We're using full-stack Behavior-Driven-Development, with [phpspec](http://phpspec.net) and [Behat](http://behat.org) + +## Documentation + +Documentation is available at [docs.sylius.com](http://docs.sylius.com). + +## Installation + +### Traditional +```bash +$ wget http://getcomposer.org/composer.phar +$ php composer.phar create-project sylius/sylius-standard project +$ cd project +$ yarn install +$ yarn build +$ php bin/console sylius:install +$ symfony serve +$ open http://localhost:8000/ +``` + +For more detailed instruction please visit [installation chapter in our docs](https://docs.sylius.com/en/1.10/book/installation/installation.html). + +### Docker + +#### Development + +Make sure you have installed [Docker](https://docs.docker.com/get-docker/) on your local machine. +Execute `docker compose up -d` in your favorite terminal and wait some time until the services will be ready. You might want to see docker logs. +Then enter `localhost` in your browser or execute `open localhost` in your terminal. + +#### Production + +The simplest way to deploy your Sylius store via Docker is via `docker-compose.prod.yml` configuration file. +To do that you need to install [Docker](https://docs.docker.com/get-docker/) on your VPS and define `MYSQL_PASSWORD` environment. +Then execute `docker compose -f docker-compose.prod.yml up -d` command in your terminal. The `MYSQL_PASSWORD` env will be automatically +applied to the rest of the config. + +> When using a Virtual Private Server (VPS) we recommend having at least 2GB of RAM memory + +**Quick deploy:** +```bash +curl -fsSL https://get.docker.com -o get-docker.sh +sudo sh get-docker.sh + +export MYSQL_PASSWORD=SLyPJLaye7 + +docker compose -f docker-compose.prod.yml up -d +docker compose -f docker-compose.prod.yml exec php bin/console sylius:fixtures:load --no-interaction +``` + +## Troubleshooting + +If something goes wrong, errors & exceptions are logged at the application level: + +```bash +$ tail -f var/log/prod.log +$ tail -f var/log/dev.log +``` + +## Contributing + +Would like to help us and build the most developer-friendly eCommerce framework? Start from reading our [Contribution Guide](https://docs.sylius.com/en/latest/contributing/)! + +## Stay Updated + +If you want to keep up with the updates, [follow the official Sylius account on Twitter](http://twitter.com/Sylius) and [like us on Facebook](https://www.facebook.com/SyliusEcommerce/). + +## Bug Tracking + +If you want to report a bug or suggest an idea, please use [GitHub issues](https://github.com/Sylius/Sylius/issues). + +## Community Support + +Get Sylius support on [Slack](https://sylius.com/slack), [Forum](https://forum.sylius.com/) or [Stack Overflow](https://stackoverflow.com/questions/tagged/sylius). + +## MIT License + +Sylius is completely free and released under the [MIT License](https://github.com/Sylius/Sylius/blob/master/LICENSE). + +## Authors + +Sylius was originally created by [Paweł Jędrzejewski](http://pjedrzejewski.com). +See the list of [contributors from our awesome community](https://github.com/Sylius/Sylius/contributors). diff --git a/assets/admin/entry.js b/assets/admin/entry.js new file mode 100644 index 0000000..8acf2c2 --- /dev/null +++ b/assets/admin/entry.js @@ -0,0 +1 @@ +// In this file you can import assets like images or stylesheets diff --git a/assets/shop/entry.js b/assets/shop/entry.js new file mode 100644 index 0000000..8acf2c2 --- /dev/null +++ b/assets/shop/entry.js @@ -0,0 +1 @@ +// In this file you can import assets like images or stylesheets diff --git a/behat.yml.dist b/behat.yml.dist new file mode 100644 index 0000000..49d5309 --- /dev/null +++ b/behat.yml.dist @@ -0,0 +1,66 @@ +imports: + - vendor/sylius/sylius/src/Sylius/Behat/Resources/config/suites.yml + +default: + formatters: + pretty: + verbose: true + paths: false + snippets: false + + extensions: + DMore\ChromeExtension\Behat\ServiceContainer\ChromeExtension: ~ + + FriendsOfBehat\MinkDebugExtension: + directory: etc/build + clean_start: false + screenshot: true + + Behat\MinkExtension: + files_path: "%paths.base%/vendor/sylius/sylius/src/Sylius/Behat/Resources/fixtures/" + base_url: "https://127.0.0.1:8080/" + default_session: symfony + javascript_session: chrome_headless + sessions: + symfony: + symfony: ~ + chrome_headless: + chrome: + api_url: http://127.0.0.1:9222 + validate_certificate: false + chrome_headless_second_session: + chrome: + api_url: http://127.0.0.1:9222 + validate_certificate: false + chrome: + selenium2: + browser: chrome + capabilities: + browserName: chrome + browser: chrome + version: "" + marionette: null # https://github.com/Behat/MinkExtension/pull/311 + chrome: + switches: + - "start-fullscreen" + - "start-maximized" + - "no-sandbox" + extra_capabilities: + unexpectedAlertBehaviour: accept + firefox: + selenium2: + browser: firefox + show_auto: false + + FriendsOfBehat\SymfonyExtension: ~ + + FriendsOfBehat\VariadicExtension: ~ + + FriendsOfBehat\SuiteSettingsExtension: + paths: + - "vendor/sylius/sylius/features" + - "features" + + gherkin: + filters: + tags: "~@todo&&~@cli" # CLI is excluded as it registers an error handler that mutes fatal errors diff --git a/bin/console b/bin/console new file mode 100755 index 0000000..313dc90 --- /dev/null +++ b/bin/console @@ -0,0 +1,15 @@ +#!/usr/bin/env php +=1.2) +if (is_array($env = @include dirname(__DIR__).'/.env.local.php')) { + $_SERVER += $env; + $_ENV += $env; +} elseif (!class_exists(Dotenv::class)) { + throw new RuntimeException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.'); +} elseif (method_exists(Dotenv::class, 'bootEnv')) { + (new Dotenv())->bootEnv(dirname(__DIR__) . '/.env'); + + return; +} else { + // load all the .env files + (new Dotenv(true))->loadEnv(dirname(__DIR__).'/.env'); +} + +$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?: 'dev'; +$_SERVER['APP_DEBUG'] = $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV']; +$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], FILTER_VALIDATE_BOOLEAN) ? '1' : '0'; diff --git a/config/bundles.php b/config/bundles.php new file mode 100644 index 0000000..08f9762 --- /dev/null +++ b/config/bundles.php @@ -0,0 +1,63 @@ + ['all' => true], + Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], + Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], + Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], + Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], + Sylius\Calendar\SyliusCalendarBundle::class => ['all' => true], + Sylius\Bundle\OrderBundle\SyliusOrderBundle::class => ['all' => true], + Sylius\Bundle\MoneyBundle\SyliusMoneyBundle::class => ['all' => true], + Sylius\Bundle\CurrencyBundle\SyliusCurrencyBundle::class => ['all' => true], + Sylius\Bundle\LocaleBundle\SyliusLocaleBundle::class => ['all' => true], + Sylius\Bundle\ProductBundle\SyliusProductBundle::class => ['all' => true], + Sylius\Bundle\ChannelBundle\SyliusChannelBundle::class => ['all' => true], + Sylius\Bundle\AttributeBundle\SyliusAttributeBundle::class => ['all' => true], + Sylius\Bundle\TaxationBundle\SyliusTaxationBundle::class => ['all' => true], + Sylius\Bundle\ShippingBundle\SyliusShippingBundle::class => ['all' => true], + Sylius\Bundle\PaymentBundle\SyliusPaymentBundle::class => ['all' => true], + Sylius\Bundle\MailerBundle\SyliusMailerBundle::class => ['all' => true], + Sylius\Bundle\PromotionBundle\SyliusPromotionBundle::class => ['all' => true], + Sylius\Bundle\AddressingBundle\SyliusAddressingBundle::class => ['all' => true], + Sylius\Bundle\InventoryBundle\SyliusInventoryBundle::class => ['all' => true], + Sylius\Bundle\TaxonomyBundle\SyliusTaxonomyBundle::class => ['all' => true], + Sylius\Bundle\UserBundle\SyliusUserBundle::class => ['all' => true], + Sylius\Bundle\CustomerBundle\SyliusCustomerBundle::class => ['all' => true], + Sylius\Bundle\UiBundle\SyliusUiBundle::class => ['all' => true], + Sylius\Bundle\ReviewBundle\SyliusReviewBundle::class => ['all' => true], + Sylius\Bundle\CoreBundle\SyliusCoreBundle::class => ['all' => true], + Sylius\Bundle\ResourceBundle\SyliusResourceBundle::class => ['all' => true], + Sylius\Bundle\GridBundle\SyliusGridBundle::class => ['all' => true], + winzou\Bundle\StateMachineBundle\winzouStateMachineBundle::class => ['all' => true], + Sonata\BlockBundle\SonataBlockBundle::class => ['all' => true], + Bazinga\Bundle\HateoasBundle\BazingaHateoasBundle::class => ['all' => true], + JMS\SerializerBundle\JMSSerializerBundle::class => ['all' => true], + FOS\RestBundle\FOSRestBundle::class => ['all' => true], + Knp\Bundle\GaufretteBundle\KnpGaufretteBundle::class => ['all' => true], + Knp\Bundle\MenuBundle\KnpMenuBundle::class => ['all' => true], + Liip\ImagineBundle\LiipImagineBundle::class => ['all' => true], + Payum\Bundle\PayumBundle\PayumBundle::class => ['all' => true], + Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true], + BabDev\PagerfantaBundle\BabDevPagerfantaBundle::class => ['all' => true], + Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true], + Sylius\Bundle\FixturesBundle\SyliusFixturesBundle::class => ['all' => true], + Sylius\Bundle\PayumBundle\SyliusPayumBundle::class => ['all' => true], + Sylius\Bundle\ThemeBundle\SyliusThemeBundle::class => ['all' => true], + Sylius\Bundle\AdminBundle\SyliusAdminBundle::class => ['all' => true], + Sylius\Bundle\ShopBundle\SyliusShopBundle::class => ['all' => true], + Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true, 'test' => true, 'test_cached' => true], + Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true, 'test_cached' => true], + Fidry\AliceDataFixtures\Bridge\Symfony\FidryAliceDataFixturesBundle::class => ['dev' => true, 'test' => true, 'test_cached' => true], + Nelmio\Alice\Bridge\Symfony\NelmioAliceBundle::class => ['dev' => true, 'test' => true, 'test_cached' => true], + FriendsOfBehat\SymfonyExtension\Bundle\FriendsOfBehatSymfonyExtensionBundle::class => ['test' => true, 'test_cached' => true], + Sylius\Behat\Application\SyliusTestPlugin\SyliusTestPlugin::class => ['test' => true, 'test_cached' => true], + ApiPlatform\Core\Bridge\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true], + Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true], + Sylius\Bundle\ApiBundle\SyliusApiBundle::class => ['all' => true], + SyliusLabs\DoctrineMigrationsExtraBundle\SyliusLabsDoctrineMigrationsExtraBundle::class => ['all' => true], + Sylius\PayPalPlugin\SyliusPayPalPlugin::class => ['all' => true], + SyliusLabs\Polyfill\Symfony\Security\Bundle\SyliusLabsPolyfillSymfonySecurityBundle::class => ['all' => true], + League\FlysystemBundle\FlysystemBundle::class => ['all' => true], + Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true], +]; diff --git a/config/jwt/.gitkeep b/config/jwt/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/config/jwt/private-test.pem b/config/jwt/private-test.pem new file mode 100644 index 0000000..d2ff3d0 --- /dev/null +++ b/config/jwt/private-test.pem @@ -0,0 +1,30 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIhNMtc+21vO0CAggA +MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECJ3pCz5BZ5wBBIIEyKx/OW6jYrrN +ZfcQn40CON3st4lO16QGaY3nwhtMfS3M0VBQWRXjGSTrUU72H3PEhqtM7v4av1ED +Vf1hkIm2gGPb/qxctapG33aw0Ean1AhHtqVtiEN0C3tK8Jpx6ARYbFees1xkHd4R +lIkl715D2K9eqZCWK5sljChGWPK97Jm2zTudLQImvzLDJLDDDd8T7HamG/GvDROc +lzZeNEg3oO2DzYwu3yI3oHYORM7pWxaJr0hSe+147U/hHwRq7n0vWP3JnsJlmxoy +gpN/ZG8qh+MdWaEdg9NmfjQSZK/N4ckIN3y/5ZeDXFxr5sQkLJk/V0ZU1j2qe6cj +TG4DX3pAkNwPw0PrMdas0V9FwL9wIH/65uQg9HdlXQ5FoaaNk4i+OULhpkcQ9znn ++tArQcnEyHY+/ZC8flnnOGRiZLyjVf+L2zHp4eiEd+ftiT5uv6UAGtUYVd/ulSZm +4do66tFRij6D5gkeS7KvSY952Ueq/3XqhCmJNbs3Hv9V9pCfdE420m9ntEbziZiM +5YU+jrLcLe0B5WYZyX3koIWLD09GXC+JB0735q+o0RMYbVGHNIMh0y9PSBPNZj6X +3ke2pHzigPhU4iuCUdt/KZHFN8UyiJH7EPYXRSTbGRTilvwe7ULEwiAZgqEng4qy +UCpKlokZynI7q0uhE537hn/zafpqcjHrdrfuO9jRyQOLmDq1ockP842+QBxhCtDU +N3A0hm03slIgGFikr4NsRki8osweDHSg0LaWyGBklQY0QHPh/e9XURfiqKI4LpkJ +REr7Lo4S2J+D4jgnADnrRc+R7a6jiN/562e6B4JiVCt28m5qJCeiiUpErp07J/ks +cpQ1i3TUpDoFFivmKkcJfneHKiaPaNjjcwUJf1szVp0I/rQ8zfe2zxqVW6ARUULp +fD65fgZZsigkPEbk4eqgvbcqu7hLFddHzdgi4TXcI0QSrYx8JHJ6L9aaiUyHmiih +W1gJ2jtn087ssN+yQ81bbs8tf3t+Efj7gge4kn7nye9r62adEpwrB3syT2uSt3yr +qf/j8ycf6R8lvD0AZPQ0aLQu1hOKloduk5OkuPTZToHNuvvYR9wpyMhCQFOBGD1P +trXGcAATIKDF4skG5A5ia36TcD07X+Nqb5obukQmbj3dMuPe3C4u1tFdykz5B4I9 +PJgiChRQ5J5Qg4xWXZdzmsuRC2YZT1SIIATnZ6PRnIlovhjBCtGKRVNjtljRqoIA +opzPolaxCX6Cuo15zVO8HgGB4fPht+VD6Muann8cRBx7RCvR8QZhym/HVJxnu9OL +mt+hYNUGgt+Kx5CKeDB98Vq7YOKjt9r0ocwnB/RzwgzwlXRoJ/m0Ra1VOmOJzAss +Ib78x/tTt9C3YMzfGXHxNHy9XWU28xOW8SjghOgJFlW8JWRzjRQ0TYNtLYnw+i3B +UpOhcdKiORmRew5gtjJd09Fu59U/YiDjAcCyauzTny8mNaseKgIWSUUviAexhbJL +FsIjqjEI1OxdD9/mKdyEA2nk3AmjrPtY3exvaWtx5QFsQM+RSWxD3oZ0Ht0Wg3J1 +q5IW5YvyyjgGIVW2gtThpzUjsn68G9dPQ8fVdC99HY5aNwmZtX/uWZKx+cmbJQbP +q3yyvW3b+6iYFIse6P/4Hg== +-----END ENCRYPTED PRIVATE KEY----- diff --git a/config/jwt/public-test.pem b/config/jwt/public-test.pem new file mode 100644 index 0000000..0635bfb --- /dev/null +++ b/config/jwt/public-test.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApehy09MSecsyPhR8Ylkb +WCzXZxSup/1TfAeOJEpQCm/D1bcJVwoUZFFgrWcVvwFtXOngSXwIq0jhTdQqS0No +aeMR/lIvYK6ZBnz1+c3UU/rV2BvG4gSc07tVjyuaPuD1NBSBtIR5NY2gz2SatL9A +ZfKMJBZhaVb1yMVbDfwa4WgQQ9rd7F/D2fqblPIPARaBzGbkKuMSXbb6kWurW2GJ +1O8SyyHAv47Gr3PaB7MZxNMgsxJPBbIh8RZvpUBOvzvq0aAWlXTxNYp9iV5liPUA +/aXhx+p4CqtD87BLJ+Iim/Vu6xBVom/+Yahl8yZsSIebQy2Y0JlSjhgQ27E5Q4zQ +lwIDAQAB +-----END PUBLIC KEY----- diff --git a/config/packages/_sylius.yaml b/config/packages/_sylius.yaml new file mode 100644 index 0000000..ce751d0 --- /dev/null +++ b/config/packages/_sylius.yaml @@ -0,0 +1,254 @@ +imports: + - { resource: "@SyliusCoreBundle/Resources/config/app/config.yml" } + + - { resource: "@SyliusAdminBundle/Resources/config/app/config.yml" } + - { resource: "@SyliusApiBundle/Resources/config/app/config.yaml" } + + - { resource: "@SyliusShopBundle/Resources/config/app/config.yml" } + - { resource: "@SyliusPayPalPlugin/Resources/config/config.yaml" } + +parameters: + sylius_core.public_dir: '%kernel.project_dir%/public' + +when@dev: + sylius_api: + enabled: true + +sylius_addressing: + resources: + address: + classes: + model: App\Entity\Addressing\Address + country: + classes: + model: App\Entity\Addressing\Country + province: + classes: + model: App\Entity\Addressing\Province + zone: + classes: + model: App\Entity\Addressing\Zone + zone_member: + classes: + model: App\Entity\Addressing\ZoneMember + +sylius_attribute: + resources: + product: + attribute: + classes: + model: App\Entity\Product\ProductAttribute + translation: + classes: + model: App\Entity\Product\ProductAttributeTranslation + attribute_value: + classes: + model: App\Entity\Product\ProductAttributeValue + +sylius_channel: + resources: + channel: + classes: + model: App\Entity\Channel\Channel +sylius_core: + resources: + product_image: + classes: + model: App\Entity\Product\ProductImage + taxon_image: + classes: + model: App\Entity\Taxonomy\TaxonImage + product_taxon: + classes: + model: App\Entity\Product\ProductTaxon + channel_pricing: + classes: + model: App\Entity\Channel\ChannelPricing + +sylius_currency: + resources: + currency: + classes: + model: App\Entity\Currency\Currency + exchange_rate: + classes: + model: App\Entity\Currency\ExchangeRate + +sylius_customer: + resources: + customer: + classes: + model: App\Entity\Customer\Customer + customer_group: + classes: + model: App\Entity\Customer\CustomerGroup + +sylius_locale: + resources: + locale: + classes: + model: App\Entity\Locale\Locale + +sylius_order: + resources: + order: + classes: + model: App\Entity\Order\Order + order_item: + classes: + model: App\Entity\Order\OrderItem + order_item_unit: + classes: + model: App\Entity\Order\OrderItemUnit + adjustment: + classes: + model: App\Entity\Order\Adjustment + order_sequence: + classes: + model: App\Entity\Order\OrderSequence + +sylius_payment: + resources: + payment_method: + classes: + model: App\Entity\Payment\PaymentMethod + translation: + classes: + model: App\Entity\Payment\PaymentMethodTranslation + payment: + classes: + model: App\Entity\Payment\Payment + +sylius_payum: + resources: + payment_security_token: + classes: + model: App\Entity\Payment\PaymentSecurityToken + gateway_config: + classes: + model: App\Entity\Payment\GatewayConfig + +sylius_product: + resources: + product: + classes: + model: App\Entity\Product\Product + translation: + classes: + model: App\Entity\Product\ProductTranslation + product_variant: + classes: + model: App\Entity\Product\ProductVariant + translation: + classes: + model: App\Entity\Product\ProductVariantTranslation + product_option: + classes: + model: App\Entity\Product\ProductOption + translation: + classes: + model: App\Entity\Product\ProductOptionTranslation + product_option_value: + classes: + model: App\Entity\Product\ProductOptionValue + translation: + classes: + model: App\Entity\Product\ProductOptionValueTranslation + product_association: + classes: + model: App\Entity\Product\ProductAssociation + product_association_type: + classes: + model: App\Entity\Product\ProductAssociationType + translation: + classes: + model: App\Entity\Product\ProductAssociationTypeTranslation + +sylius_promotion: + resources: + catalog_promotion: + classes: + model: App\Entity\Promotion\CatalogPromotion + catalog_promotion_action: + classes: + model: App\Entity\Promotion\CatalogPromotionAction + catalog_promotion_scope: + classes: + model: App\Entity\Promotion\CatalogPromotionScope + promotion: + classes: + model: App\Entity\Promotion\Promotion + promotion_rule: + classes: + model: App\Entity\Promotion\PromotionRule + promotion_action: + classes: + model: App\Entity\Promotion\PromotionAction + promotion_coupon: + classes: + model: App\Entity\Promotion\PromotionCoupon + +sylius_review: + resources: + product: + review: + classes: + model: App\Entity\Product\ProductReview + +sylius_shipping: + resources: + shipment: + classes: + model: App\Entity\Shipping\Shipment + shipping_method: + classes: + model: App\Entity\Shipping\ShippingMethod + translation: + classes: + model: App\Entity\Shipping\ShippingMethodTranslation + shipping_category: + classes: + model: App\Entity\Shipping\ShippingCategory + +sylius_taxation: + resources: + tax_category: + classes: + model: App\Entity\Taxation\TaxCategory + tax_rate: + classes: + model: App\Entity\Taxation\TaxRate + +sylius_taxonomy: + resources: + taxon: + classes: + model: App\Entity\Taxonomy\Taxon + translation: + classes: + model: App\Entity\Taxonomy\TaxonTranslation +sylius_user: + resources: + admin: + user: + classes: + model: App\Entity\User\AdminUser + shop: + user: + classes: + model: App\Entity\User\ShopUser + oauth: + user: + classes: + model: App\Entity\User\UserOAuth + +sylius_shop: + product_grid: + include_all_descendants: true + +sylius_theme: + sources: + filesystem: + scan_depth: 1 + directories: + - "%kernel.project_dir%/themes" diff --git a/config/packages/api_platform.yaml b/config/packages/api_platform.yaml new file mode 100644 index 0000000..b0351e5 --- /dev/null +++ b/config/packages/api_platform.yaml @@ -0,0 +1,9 @@ +api_platform: + mapping: + paths: + - '%kernel.project_dir%/config/api_platform' + - '%kernel.project_dir%/src/Entity' + patch_formats: + json: ['application/merge-patch+json'] + swagger: + versions: [3] diff --git a/config/packages/assets.yaml b/config/packages/assets.yaml new file mode 100644 index 0000000..5382769 --- /dev/null +++ b/config/packages/assets.yaml @@ -0,0 +1,11 @@ +framework: + assets: + packages: + admin: + json_manifest_path: '%kernel.project_dir%/public/build/admin/manifest.json' + shop: + json_manifest_path: '%kernel.project_dir%/public/build/shop/manifest.json' + app.admin: + json_manifest_path: '%kernel.project_dir%/public/build/app/admin/manifest.json' + app.shop: + json_manifest_path: '%kernel.project_dir%/public/build/app/shop/manifest.json' diff --git a/config/packages/dev/jms_serializer.yaml b/config/packages/dev/jms_serializer.yaml new file mode 100644 index 0000000..2f32a9b --- /dev/null +++ b/config/packages/dev/jms_serializer.yaml @@ -0,0 +1,12 @@ +jms_serializer: + visitors: + json_serialization: + options: + - JSON_PRETTY_PRINT + - JSON_UNESCAPED_SLASHES + - JSON_PRESERVE_ZERO_FRACTION + json_deserialization: + options: + - JSON_PRETTY_PRINT + - JSON_UNESCAPED_SLASHES + - JSON_PRESERVE_ZERO_FRACTION diff --git a/config/packages/dev/monolog.yaml b/config/packages/dev/monolog.yaml new file mode 100644 index 0000000..da2b092 --- /dev/null +++ b/config/packages/dev/monolog.yaml @@ -0,0 +1,9 @@ +monolog: + handlers: + main: + type: stream + path: "%kernel.logs_dir%/%kernel.environment%.log" + level: debug + firephp: + type: firephp + level: info diff --git a/config/packages/dev/nelmio_alice.yaml b/config/packages/dev/nelmio_alice.yaml new file mode 100644 index 0000000..e2ae069 --- /dev/null +++ b/config/packages/dev/nelmio_alice.yaml @@ -0,0 +1,3 @@ +nelmio_alice: + functions_blacklist: + - 'current' diff --git a/config/packages/doctrine.yaml b/config/packages/doctrine.yaml new file mode 100644 index 0000000..bd8c393 --- /dev/null +++ b/config/packages/doctrine.yaml @@ -0,0 +1,23 @@ +parameters: + # Adds a fallback DATABASE_URL if the env var is not set. + # This allows you to run cache:warmup even if your + # environment variables are not available yet. + # You should not need to change this value. + env(DATABASE_URL): '' + +doctrine: + dbal: + url: '%env(resolve:DATABASE_URL)%' + + orm: + auto_generate_proxy_classes: '%kernel.debug%' + entity_managers: + default: + auto_mapping: true + mappings: + App: + is_bundle: false + type: annotation + dir: '%kernel.project_dir%/src/Entity' + prefix: 'App\Entity' + alias: App diff --git a/config/packages/doctrine_migrations.yaml b/config/packages/doctrine_migrations.yaml new file mode 100644 index 0000000..765b5c5 --- /dev/null +++ b/config/packages/doctrine_migrations.yaml @@ -0,0 +1,6 @@ +doctrine_migrations: + storage: + table_storage: + table_name: sylius_migrations + migrations_paths: + 'App\Migrations': "%kernel.project_dir%/src/Migrations" diff --git a/config/packages/flysystem.yaml b/config/packages/flysystem.yaml new file mode 100644 index 0000000..2447c23 --- /dev/null +++ b/config/packages/flysystem.yaml @@ -0,0 +1,6 @@ +flysystem: + storages: + sylius.storage: + adapter: 'local' + options: + directory: '%sylius_core.images_dir%' diff --git a/config/packages/fos_rest.yaml b/config/packages/fos_rest.yaml new file mode 100644 index 0000000..eaebb27 --- /dev/null +++ b/config/packages/fos_rest.yaml @@ -0,0 +1,11 @@ +fos_rest: + exception: true + view: + formats: + json: true + xml: true + empty_content: 204 + format_listener: + rules: + - { path: '^/api/v1/.*', priorities: ['json', 'xml'], fallback_format: json, prefer_extension: true } + - { path: '^/', stop: true } diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml new file mode 100644 index 0000000..2904743 --- /dev/null +++ b/config/packages/framework.yaml @@ -0,0 +1,24 @@ +framework: + translator: { fallbacks: ["%locale%"] } + secret: '%env(APP_SECRET)%' + form: + enabled: true + legacy_error_messages: false + csrf_protection: true + session: + handler_id: ~ + serializer: + mapping: + paths: [ '%kernel.project_dir%/config/serialization' ] + +when@dev: + framework: + profiler: { only_exceptions: false } + +when@test: &framework_test + framework: + test: true + session: + storage_factory_id: session.storage.factory.mock_file + +when@test_cached: *framework_test diff --git a/config/packages/jms_serializer.yaml b/config/packages/jms_serializer.yaml new file mode 100644 index 0000000..ed7bc61 --- /dev/null +++ b/config/packages/jms_serializer.yaml @@ -0,0 +1,4 @@ +jms_serializer: + visitors: + xml_serialization: + format_output: '%kernel.debug%' diff --git a/config/packages/lexik_jwt_authentication.yaml b/config/packages/lexik_jwt_authentication.yaml new file mode 100644 index 0000000..edfb69d --- /dev/null +++ b/config/packages/lexik_jwt_authentication.yaml @@ -0,0 +1,4 @@ +lexik_jwt_authentication: + secret_key: '%env(resolve:JWT_SECRET_KEY)%' + public_key: '%env(resolve:JWT_PUBLIC_KEY)%' + pass_phrase: '%env(JWT_PASSPHRASE)%' diff --git a/config/packages/liip_imagine.yaml b/config/packages/liip_imagine.yaml new file mode 100644 index 0000000..bb2e7ce --- /dev/null +++ b/config/packages/liip_imagine.yaml @@ -0,0 +1,6 @@ +liip_imagine: + resolvers: + default: + web_path: + web_root: "%kernel.project_dir%/public" + cache_prefix: "media/cache" diff --git a/config/packages/mailer.yaml b/config/packages/mailer.yaml new file mode 100644 index 0000000..7acef57 --- /dev/null +++ b/config/packages/mailer.yaml @@ -0,0 +1,12 @@ +framework: + mailer: + dsn: '%env(MAILER_DSN)%' + +when@test: &mailer_test + framework: + cache: + pools: + test.mailer_pool: + adapter: cache.adapter.filesystem + +when@test_cached: *mailer_test diff --git a/config/packages/prod/doctrine.yaml b/config/packages/prod/doctrine.yaml new file mode 100644 index 0000000..55ea750 --- /dev/null +++ b/config/packages/prod/doctrine.yaml @@ -0,0 +1,35 @@ +doctrine: + orm: + entity_managers: + default: + metadata_cache_driver: + type: service + id: doctrine.system_cache_provider + query_cache_driver: + type: service + id: doctrine.system_cache_provider + result_cache_driver: + type: service + id: doctrine.result_cache_provider + +services: + doctrine.result_cache_provider: + class: Doctrine\Common\Cache\Psr6\DoctrineProvider + public: false + factory: ['Doctrine\Common\Cache\Psr6\DoctrineProvider', 'wrap'] + arguments: + - '@doctrine.result_cache_pool' + doctrine.system_cache_provider: + class: Doctrine\Common\Cache\Psr6\DoctrineProvider + public: false + factory: [ 'Doctrine\Common\Cache\Psr6\DoctrineProvider', 'wrap' ] + arguments: + - '@doctrine.system_cache_pool' + +framework: + cache: + pools: + doctrine.result_cache_pool: + adapter: cache.app + doctrine.system_cache_pool: + adapter: cache.system diff --git a/config/packages/prod/jms_serializer.yaml b/config/packages/prod/jms_serializer.yaml new file mode 100644 index 0000000..c288182 --- /dev/null +++ b/config/packages/prod/jms_serializer.yaml @@ -0,0 +1,10 @@ +jms_serializer: + visitors: + json_serialization: + options: + - JSON_UNESCAPED_SLASHES + - JSON_PRESERVE_ZERO_FRACTION + json_deserialization: + options: + - JSON_UNESCAPED_SLASHES + - JSON_PRESERVE_ZERO_FRACTION diff --git a/config/packages/prod/monolog.yaml b/config/packages/prod/monolog.yaml new file mode 100644 index 0000000..6461211 --- /dev/null +++ b/config/packages/prod/monolog.yaml @@ -0,0 +1,10 @@ +monolog: + handlers: + main: + type: fingers_crossed + action_level: error + handler: nested + nested: + type: stream + path: "%kernel.logs_dir%/%kernel.environment%.log" + level: debug diff --git a/config/packages/routing.yaml b/config/packages/routing.yaml new file mode 100644 index 0000000..4116679 --- /dev/null +++ b/config/packages/routing.yaml @@ -0,0 +1,3 @@ +framework: + router: + strict_requirements: true diff --git a/config/packages/security.yaml b/config/packages/security.yaml new file mode 100644 index 0000000..ed1698c --- /dev/null +++ b/config/packages/security.yaml @@ -0,0 +1,121 @@ +security: + enable_authenticator_manager: true + providers: + sylius_admin_user_provider: + id: sylius.admin_user_provider.email_or_name_based + sylius_api_admin_user_provider: + id: sylius.admin_user_provider.email_or_name_based + sylius_shop_user_provider: + id: sylius.shop_user_provider.email_or_name_based + sylius_api_shop_user_provider: + id: sylius.shop_user_provider.email_or_name_based + password_hashers: + Sylius\Component\User\Model\UserInterface: argon2i + firewalls: + admin: + switch_user: true + context: admin + pattern: "%sylius.security.admin_regex%" + provider: sylius_admin_user_provider + form_login: + provider: sylius_admin_user_provider + login_path: sylius_admin_login + check_path: sylius_admin_login_check + failure_path: sylius_admin_login + default_target_path: sylius_admin_dashboard + use_forward: false + use_referer: true + enable_csrf: true + csrf_parameter: _csrf_admin_security_token + csrf_token_id: admin_authenticate + remember_me: + secret: "%env(APP_SECRET)%" + path: "/%sylius_admin.path_name%" + name: APP_ADMIN_REMEMBER_ME + lifetime: 31536000 + remember_me_parameter: _remember_me + logout: + path: sylius_admin_logout + target: sylius_admin_login + + new_api_admin_user: + pattern: "%sylius.security.new_api_admin_regex%/.*" + provider: sylius_api_admin_user_provider + stateless: true + entry_point: jwt + json_login: + check_path: "%sylius.security.new_api_admin_route%/authentication-token" + username_path: email + password_path: password + success_handler: lexik_jwt_authentication.handler.authentication_success + failure_handler: lexik_jwt_authentication.handler.authentication_failure + jwt: true + + new_api_shop_user: + pattern: "%sylius.security.new_api_shop_regex%/.*" + provider: sylius_api_shop_user_provider + stateless: true + entry_point: jwt + json_login: + check_path: "%sylius.security.new_api_shop_route%/authentication-token" + username_path: email + password_path: password + success_handler: lexik_jwt_authentication.handler.authentication_success + failure_handler: lexik_jwt_authentication.handler.authentication_failure + jwt: true + + shop: + switch_user: { role: ROLE_ALLOWED_TO_SWITCH } + context: shop + pattern: "%sylius.security.shop_regex%" + provider: sylius_shop_user_provider + form_login: + success_handler: sylius.authentication.success_handler + failure_handler: sylius.authentication.failure_handler + provider: sylius_shop_user_provider + login_path: sylius_shop_login + check_path: sylius_shop_login_check + failure_path: sylius_shop_login + default_target_path: sylius_shop_homepage + use_forward: false + use_referer: true + enable_csrf: true + csrf_parameter: _csrf_shop_security_token + csrf_token_id: shop_authenticate + remember_me: + secret: "%env(APP_SECRET)%" + name: APP_SHOP_REMEMBER_ME + lifetime: 31536000 + remember_me_parameter: _remember_me + logout: + path: sylius_shop_logout + target: sylius_shop_homepage + invalidate_session: false + + dev: + pattern: ^/(_(profiler|wdt)|css|images|js)/ + security: false + + access_control: + - { path: "%sylius.security.admin_regex%/_partial", role: PUBLIC_ACCESS, ips: [127.0.0.1, ::1] } + - { path: "%sylius.security.admin_regex%/_partial", role: ROLE_NO_ACCESS } + - { path: "%sylius.security.shop_regex%/_partial", role: PUBLIC_ACCESS, ips: [127.0.0.1, ::1] } + - { path: "%sylius.security.shop_regex%/_partial", role: ROLE_NO_ACCESS } + + - { path: "%sylius.security.admin_regex%/forgotten-password", role: PUBLIC_ACCESS } + + - { path: "%sylius.security.admin_regex%/login", role: PUBLIC_ACCESS } + - { path: "%sylius.security.shop_regex%/login", role: PUBLIC_ACCESS } + + - { path: "%sylius.security.shop_regex%/register", role: PUBLIC_ACCESS } + - { path: "%sylius.security.shop_regex%/verify", role: PUBLIC_ACCESS } + + - { path: "%sylius.security.admin_regex%", role: ROLE_ADMINISTRATION_ACCESS } + - { path: "%sylius.security.shop_regex%/account", role: ROLE_USER } + + - { path: "%sylius.security.new_api_admin_route%/reset-password-requests", role: PUBLIC_ACCESS } + - { path: "%sylius.security.new_api_admin_regex%/.*", role: ROLE_API_ACCESS } + - { path: "%sylius.security.new_api_admin_route%/authentication-token", role: PUBLIC_ACCESS } + - { path: "%sylius.security.new_api_user_account_regex%/.*", role: ROLE_USER } + - { path: "%sylius.security.new_api_shop_route%/authentication-token", role: PUBLIC_ACCESS } + - { path: "%sylius.security.new_api_shop_regex%/.*", role: PUBLIC_ACCESS } diff --git a/config/packages/stof_doctrine_extensions.yaml b/config/packages/stof_doctrine_extensions.yaml new file mode 100644 index 0000000..7770f74 --- /dev/null +++ b/config/packages/stof_doctrine_extensions.yaml @@ -0,0 +1,4 @@ +# Read the documentation: https://symfony.com/doc/current/bundles/StofDoctrineExtensionsBundle/index.html +# See the official DoctrineExtensions documentation for more details: https://github.com/Atlantic18/DoctrineExtensions/tree/master/doc/ +stof_doctrine_extensions: + default_locale: '%locale%' diff --git a/config/packages/sylius_labs_doctrine_migrations_extra.yaml b/config/packages/sylius_labs_doctrine_migrations_extra.yaml new file mode 100644 index 0000000..3150dd9 --- /dev/null +++ b/config/packages/sylius_labs_doctrine_migrations_extra.yaml @@ -0,0 +1,3 @@ +sylius_labs_doctrine_migrations_extra: + migrations: + 'App\Migrations': ~ diff --git a/config/packages/test/fidry_alice_data_fixtures.yaml b/config/packages/test/fidry_alice_data_fixtures.yaml new file mode 100644 index 0000000..ae4e694 --- /dev/null +++ b/config/packages/test/fidry_alice_data_fixtures.yaml @@ -0,0 +1,2 @@ +fidry_alice_data_fixtures: + default_purge_mode: no_purge diff --git a/config/packages/test/monolog.yaml b/config/packages/test/monolog.yaml new file mode 100644 index 0000000..7e2b9e3 --- /dev/null +++ b/config/packages/test/monolog.yaml @@ -0,0 +1,6 @@ +monolog: + handlers: + main: + type: stream + path: "%kernel.logs_dir%/%kernel.environment%.log" + level: error diff --git a/config/packages/test/nelmio_alice.yaml b/config/packages/test/nelmio_alice.yaml new file mode 100644 index 0000000..caec543 --- /dev/null +++ b/config/packages/test/nelmio_alice.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: ../dev/nelmio_alice.yaml } diff --git a/config/packages/test/security.yaml b/config/packages/test/security.yaml new file mode 100644 index 0000000..4071d31 --- /dev/null +++ b/config/packages/test/security.yaml @@ -0,0 +1,6 @@ +security: + password_hashers: + Sylius\Component\User\Model\UserInterface: + algorithm: argon2i + time_cost: 3 + memory_cost: 10 diff --git a/config/packages/test/sylius_theme.yaml b/config/packages/test/sylius_theme.yaml new file mode 100644 index 0000000..4d34199 --- /dev/null +++ b/config/packages/test/sylius_theme.yaml @@ -0,0 +1,3 @@ +sylius_theme: + sources: + test: ~ diff --git a/config/packages/test/sylius_uploader.yaml b/config/packages/test/sylius_uploader.yaml new file mode 100644 index 0000000..ab9d6ca --- /dev/null +++ b/config/packages/test/sylius_uploader.yaml @@ -0,0 +1,3 @@ +services: + Sylius\Component\Core\Generator\ImagePathGeneratorInterface: + class: Sylius\Behat\Service\Generator\UploadedImagePathGenerator diff --git a/config/packages/test_cached/doctrine.yaml b/config/packages/test_cached/doctrine.yaml new file mode 100644 index 0000000..55ea750 --- /dev/null +++ b/config/packages/test_cached/doctrine.yaml @@ -0,0 +1,35 @@ +doctrine: + orm: + entity_managers: + default: + metadata_cache_driver: + type: service + id: doctrine.system_cache_provider + query_cache_driver: + type: service + id: doctrine.system_cache_provider + result_cache_driver: + type: service + id: doctrine.result_cache_provider + +services: + doctrine.result_cache_provider: + class: Doctrine\Common\Cache\Psr6\DoctrineProvider + public: false + factory: ['Doctrine\Common\Cache\Psr6\DoctrineProvider', 'wrap'] + arguments: + - '@doctrine.result_cache_pool' + doctrine.system_cache_provider: + class: Doctrine\Common\Cache\Psr6\DoctrineProvider + public: false + factory: [ 'Doctrine\Common\Cache\Psr6\DoctrineProvider', 'wrap' ] + arguments: + - '@doctrine.system_cache_pool' + +framework: + cache: + pools: + doctrine.result_cache_pool: + adapter: cache.app + doctrine.system_cache_pool: + adapter: cache.system diff --git a/config/packages/test_cached/fidry_alice_data_fixtures.yaml b/config/packages/test_cached/fidry_alice_data_fixtures.yaml new file mode 100644 index 0000000..f5c8649 --- /dev/null +++ b/config/packages/test_cached/fidry_alice_data_fixtures.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: "../test/fidry_alice_data_fixtures.yaml" } diff --git a/config/packages/test_cached/fos_rest.yaml b/config/packages/test_cached/fos_rest.yaml new file mode 100644 index 0000000..2b4189d --- /dev/null +++ b/config/packages/test_cached/fos_rest.yaml @@ -0,0 +1,3 @@ +fos_rest: + exception: + debug: true diff --git a/config/packages/test_cached/monolog.yaml b/config/packages/test_cached/monolog.yaml new file mode 100644 index 0000000..71bef59 --- /dev/null +++ b/config/packages/test_cached/monolog.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: "../test/monolog.yaml" } diff --git a/config/packages/test_cached/security.yaml b/config/packages/test_cached/security.yaml new file mode 100644 index 0000000..f487c5a --- /dev/null +++ b/config/packages/test_cached/security.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: '../test/security.yaml' } diff --git a/config/packages/test_cached/sylius_channel.yaml b/config/packages/test_cached/sylius_channel.yaml new file mode 100644 index 0000000..bab83ef --- /dev/null +++ b/config/packages/test_cached/sylius_channel.yaml @@ -0,0 +1,2 @@ +sylius_channel: + debug: true diff --git a/config/packages/test_cached/sylius_theme.yaml b/config/packages/test_cached/sylius_theme.yaml new file mode 100644 index 0000000..9fb4c94 --- /dev/null +++ b/config/packages/test_cached/sylius_theme.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: "../test/sylius_theme.yaml" } diff --git a/config/packages/test_cached/sylius_uploader.yaml b/config/packages/test_cached/sylius_uploader.yaml new file mode 100644 index 0000000..cfa727e --- /dev/null +++ b/config/packages/test_cached/sylius_uploader.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: "../test/sylius_uploader.yaml" } diff --git a/config/packages/translation.yaml b/config/packages/translation.yaml new file mode 100644 index 0000000..1f4f966 --- /dev/null +++ b/config/packages/translation.yaml @@ -0,0 +1,8 @@ +framework: + default_locale: '%locale%' + translator: + paths: + - '%kernel.project_dir%/translations' + fallbacks: + - '%locale%' + - 'en' diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml new file mode 100644 index 0000000..18af2f4 --- /dev/null +++ b/config/packages/twig.yaml @@ -0,0 +1,16 @@ +twig: + paths: ['%kernel.project_dir%/templates'] + debug: '%kernel.debug%' + strict_variables: '%kernel.debug%' + +services: + _defaults: + public: false + autowire: true + autoconfigure: true + + Twig\Extra\Intl\IntlExtension: ~ + +when@test_cached: + twig: + strict_variables: true diff --git a/config/packages/validator.yaml b/config/packages/validator.yaml new file mode 100644 index 0000000..61807db --- /dev/null +++ b/config/packages/validator.yaml @@ -0,0 +1,3 @@ +framework: + validation: + enable_annotations: true diff --git a/config/packages/web_profiler.yaml b/config/packages/web_profiler.yaml new file mode 100644 index 0000000..7732441 --- /dev/null +++ b/config/packages/web_profiler.yaml @@ -0,0 +1,14 @@ +when@dev: + web_profiler: + toolbar: true + intercept_redirects: false + +when@test: &web_profiler_test + web_profiler: + toolbar: false + intercept_redirects: false + + framework: + profiler: { collect: false } + +when@test_cached: *web_profiler_test diff --git a/config/packages/webpack_encore.yaml b/config/packages/webpack_encore.yaml new file mode 100644 index 0000000..fe1b0b7 --- /dev/null +++ b/config/packages/webpack_encore.yaml @@ -0,0 +1,7 @@ +webpack_encore: + output_path: '%kernel.project_dir%/public/build/default' + builds: + admin: '%kernel.project_dir%/public/build/admin' + shop: '%kernel.project_dir%/public/build/shop' + app.admin: '%kernel.project_dir%/public/build/app/admin' + app.shop: '%kernel.project_dir%/public/build/app/shop' diff --git a/config/preload.php b/config/preload.php new file mode 100644 index 0000000..5ebcdb2 --- /dev/null +++ b/config/preload.php @@ -0,0 +1,5 @@ +get() won't work + public: false + + _instanceof: + Sylius\Bundle\ResourceBundle\Controller\ResourceController: + autowire: false + Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType: + autowire: false + + # Makes classes in src/ available to be used as services; + # this creates a service per class whose id is the fully-qualified class name + App\: + resource: '../src/*' + exclude: '../src/{Entity,Migrations,Tests,Kernel.php}' + + # Controllers are imported separately to make sure services can be injected + # as action arguments even if you don't extend any base controller class + App\Controller\: + resource: '../src/Controller' + tags: ['controller.service_arguments'] diff --git a/config/services_test.yaml b/config/services_test.yaml new file mode 100644 index 0000000..c02bef9 --- /dev/null +++ b/config/services_test.yaml @@ -0,0 +1,5 @@ +imports: + - { resource: "../vendor/sylius/sylius/src/Sylius/Behat/Resources/config/services.xml" } + +sylius_api: + enabled: true diff --git a/config/services_test_cached.yaml b/config/services_test_cached.yaml new file mode 100644 index 0000000..0de380e --- /dev/null +++ b/config/services_test_cached.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: "services_test.yaml" } diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..02d5b87 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,118 @@ +services: + php: + container_name: php + build: + context: . + target: sylius_php_prod + depends_on: + - migrations + environment: + APP_DEBUG: 0 + APP_ENV: prod + APP_SECRET: EDITME + DATABASE_URL: mysql://sylius:${MYSQL_PASSWORD}@mysql/sylius_prod + MAILER_URL: smtp://localhost + MESSENGER_TRANSPORT_DSN: doctrine://default + SYLIUS_MESSENGER_TRANSPORT_MAIN_DSN: doctrine://default + SYLIUS_MESSENGER_TRANSPORT_MAIN_FAILED_DSN: doctrine://default?queue_name=main_failed + SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_DSN: doctrine://default?queue_name=catalog_promotion_removal + SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_FAILED_DSN: doctrine://default?queue_name=catalog_promotion_removal_failed + PHP_DATE_TIMEZONE: ${PHP_DATE_TIMEZONE:-UTC} + volumes: + # use a bind-mounted host directory, as we want to keep the sessions + - ./var/sessions:/srv/sylius/var/sessions:rw + # use a bind-mounted host directory, as we want to keep the media + - ./public/media:/srv/sylius/public/media:rw + networks: + - sylius + + cron: + container_name: cron + build: + context: . + target: sylius_cron + depends_on: + - migrations + environment: + APP_ENV: prod + APP_DEBUG: 0 + APP_SECRET: EDITME + DATABASE_URL: mysql://sylius:${MYSQL_PASSWORD}@mysql/sylius_prod + PHP_DATE_TIMEZONE: ${PHP_DATE_TIMEZONE:-UTC} + networks: + - sylius + + worker: + container_name: worker + command: ["php", "bin/console", "messenger:consume", "main", "catalog_promotion_removal", "--limit=5", "--memory-limit=256M", "--time-limit=600"] + restart: always + build: + context: . + target: sylius_php_prod + depends_on: + - migrations + environment: + APP_ENV: prod + APP_DEBUG: 0 + APP_SECRET: EDITME + DATABASE_URL: mysql://sylius:${MYSQL_PASSWORD}@mysql/sylius_prod + MESSENGER_TRANSPORT_DSN: doctrine://default + SYLIUS_MESSENGER_TRANSPORT_MAIN_DSN: doctrine://default + SYLIUS_MESSENGER_TRANSPORT_MAIN_FAILED_DSN: doctrine://default?queue_name=main_failed + SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_DSN: doctrine://default?queue_name=catalog_promotion_removal + SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_FAILED_DSN: doctrine://default?queue_name=catalog_promotion_removal_failed + PHP_DATE_TIMEZONE: ${PHP_DATE_TIMEZONE:-UTC} + networks: + - sylius + + migrations: + container_name: migrations + build: + context: . + target: sylius_migrations_prod + depends_on: + - mysql + environment: + APP_ENV: prod + APP_DEBUG: 0 + APP_SECRET: EDITME + DATABASE_URL: mysql://sylius:${MYSQL_PASSWORD}@mysql/sylius_prod + LOAD_FIXTURES: ${LOAD_FIXTURES:-0} + PHP_DATE_TIMEZONE: ${PHP_DATE_TIMEZONE:-UTC} + networks: + - sylius + + mysql: + container_name: mysql + # in production, we may want to use a managed database service + image: mysql:5.7 # Sylius is fully working on mysql 8.0 version + environment: + MYSQL_RANDOM_ROOT_PASSWORD: true + MYSQL_DATABASE: sylius_prod + MYSQL_USER: sylius + MYSQL_PASSWORD: ${MYSQL_PASSWORD:?MYSQL_PASSWORD is not set or empty} + volumes: + # use a bind-mounted host directory, because we never want to lose our data! + - ./docker/mysql/data:/var/lib/mysql:rw,delegated + networks: + - sylius + + nginx: + container_name: nginx + # in production, we may want to use a static website hosting service + build: + context: . + target: sylius_nginx + depends_on: + - php + volumes: + # use a bind-mounted host directory, as we want to keep the media + - ./public/media:/srv/sylius/public/media:ro + networks: + - sylius + ports: + - 80:80 + +networks: + sylius: + driver: bridge diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..ddcdec2 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,104 @@ +services: + php: + container_name: php + build: + context: . + target: sylius_php_dev + depends_on: + - migrations + environment: + - APP_ENV=dev + - APP_DEBUG=1 + - APP_SECRET=EDITME + - DATABASE_URL=mysql://sylius:${MYSQL_PASSWORD:-nopassword}@mysql/sylius + - MAILER_DSN=smtp://mailhog:1025 + - PHP_DATE_TIMEZONE=${PHP_DATE_TIMEZONE:-UTC} + volumes: + - .:/srv/sylius:rw,cached + # if you develop on Linux, you may use a bind-mounted host directory instead + # - ./var:/srv/sylius/var:rw + - ./public:/srv/sylius/public:rw,delegated + # if you develop on Linux, you may use a bind-mounted host directory instead + # - ./public/media:/srv/sylius/public/media:rw + - public-media:/srv/sylius/public/media:rw + + migrations: + container_name: migrations + build: + context: . + target: sylius_migrations_dev + depends_on: + - mysql + environment: + - APP_ENV=dev + - APP_DEBUG=1 + - APP_SECRET=EDITME + - DATABASE_URL=mysql://sylius:${MYSQL_PASSWORD:-nopassword}@mysql/sylius + - LOAD_FIXTURES=1 + - PHP_DATE_TIMEZONE=${PHP_DATE_TIMEZONE:-UTC} + + mysql: + container_name: mysql + image: mysql:5.7 # Sylius is fully working on mysql 8.0 version + platform: linux/amd64 + environment: + - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:-nopassword} + - MYSQL_DATABASE=sylius + - MYSQL_USER=sylius + - MYSQL_PASSWORD=${MYSQL_PASSWORD:-nopassword} + volumes: + - mysql-data:/var/lib/mysql:rw + # you may use a bind-mounted host directory instead, so that it is harder to accidentally remove the volume and lose all your data! + # - ./docker/mysql/data:/var/lib/mysql:rw,delegated + ports: + - "${MYSQL_PORT:-3306}:3306" + cap_add: + - SYS_NICE # prevent "mbind: Operation not permitted" errors + + node: + container_name: node + build: + context: . + target: sylius_node + command: ["yarn", "watch"] + depends_on: + - php + environment: + - GULP_ENV=dev + - PHP_HOST=php + - PHP_PORT=9000 + volumes: + - .:/srv/sylius:rw,cached + - ./public:/srv/sylius/public:rw,delegated + ports: + - "${NODE_PORT:-35729}:35729" + + nginx: + container_name: nginx + build: + context: . + target: sylius_nginx + depends_on: + - php + - node # to ensure correct build order + volumes: + - ./public:/srv/sylius/public:ro + # if you develop on Linux, you may use a bind-mounted host directory instead + # - ./public/media:/srv/sylius/public/media:ro + - public-media:/srv/sylius/public/media:ro,nocopy + ports: + - "${HTTP_PORT:-80}:80" + + mailhog: + # do not use in production! + image: mailhog/mailhog:latest + environment: + - MH_STORAGE=maildir + # volumes: + # - ./docker/mailhog/maildir:/maildir:rw,delegated + ports: + - "${MAILHOG_PORT:-8025}:8025" + +volumes: + mysql-data: + public-media: diff --git a/docker/cron/crontab b/docker/cron/crontab new file mode 100644 index 0000000..c8fe77b --- /dev/null +++ b/docker/cron/crontab @@ -0,0 +1,2 @@ +* * * * * php /srv/sylius/bin/console sylius:remove-expired-carts +* * * * * php /srv/sylius/bin/console sylius:cancel-unpaid-orders diff --git a/docker/cron/docker-entrypoint.sh b/docker/cron/docker-entrypoint.sh new file mode 100755 index 0000000..360a4f9 --- /dev/null +++ b/docker/cron/docker-entrypoint.sh @@ -0,0 +1,12 @@ +#!/bin/sh +set -e + +while ping -c1 migrations >/dev/null 2>&1; +do + (>&2 echo "Waiting for Migrations container to finish") + sleep 1; +done; + +(>&2 echo "Migrations container finished. Starting Cron process.") + +exec docker-php-entrypoint "$@" diff --git a/docker/migrations/docker-entrypoint.sh b/docker/migrations/docker-entrypoint.sh new file mode 100755 index 0000000..6f3311c --- /dev/null +++ b/docker/migrations/docker-entrypoint.sh @@ -0,0 +1,25 @@ +#!/bin/sh +set -e + +attempt_left=20 + +until php bin/console doctrine:query:sql "select 1" >/dev/null 2>&1; +do + attempt_left=$((attempt_left-1)) + + if [ "${attempt_left}" -eq "0" ]; then + + (>&2 echo "MySQL did not answer. Aborting migrations.") + exit 1 + else + (>&2 echo "Waiting for MySQL to be ready...") + fi + + sleep 1 +done + +php bin/console doctrine:migrations:migrate --no-interaction + +if [ "$LOAD_FIXTURES" = "1" ]; then + php bin/console sylius:fixtures:load --no-interaction +fi diff --git a/docker/nginx/conf.d/default.conf b/docker/nginx/conf.d/default.conf new file mode 100644 index 0000000..c2565c7 --- /dev/null +++ b/docker/nginx/conf.d/default.conf @@ -0,0 +1,43 @@ +server { + root /srv/sylius/public; + listen *:80; + + location / { + # try to serve file directly, fallback to index.php + try_files $uri /index.php$is_args$args; + } + + location ~ ^/index\.php(/|$) { + resolver 127.0.0.11 valid=10s ipv6=off; + set $backendfpm "php:9000"; + # Comment the next line and uncomment the next to enable dynamic resolution (incompatible with Kubernetes); + fastcgi_pass $backendfpm; + #resolver 127.0.0.11; + #set $upstream_host php; + #fastcgi_pass $upstream_host:9000; + + fastcgi_split_path_info ^(.+\.php)(/.*)$; + include fastcgi_params; + # When you are using symlinks to link the document root to the + # current version of your application, you should pass the real + # application path instead of the path to the symlink to PHP + # FPM. + # Otherwise, PHP's OPcache may not properly detect changes to + # your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126 + # for more information). + fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; + fastcgi_param DOCUMENT_ROOT $realpath_root; + # Prevents URIs that include the front controller. This will 404: + # http://domain.tld/index.php/some-path + # Remove the internal directive to allow URIs like this + internal; + } + + # return 404 for all other php files not matching the front controller + # this prevents access to other php files you don't want to be accessible. + location ~ \.php$ { + return 404; + } + + client_max_body_size 6m; +} diff --git a/docker/node/docker-entrypoint.sh b/docker/node/docker-entrypoint.sh new file mode 100755 index 0000000..ecd73af --- /dev/null +++ b/docker/node/docker-entrypoint.sh @@ -0,0 +1,18 @@ +#!/bin/sh +set -e + +# first arg is `-f` or `--some-option` +if [ "${1#-}" != "$1" ]; then + set -- node "$@" +fi + +if [ "$1" = 'node' ] || [ "$1" = 'yarn' ]; then + yarn install + + >&2 echo "Waiting for PHP to be ready..." + until nc -z "$PHP_HOST" "$PHP_PORT"; do + sleep 1 + done +fi + +exec "$@" diff --git a/docker/php/dev/opcache.ini b/docker/php/dev/opcache.ini new file mode 100644 index 0000000..b6a356a --- /dev/null +++ b/docker/php/dev/opcache.ini @@ -0,0 +1,10 @@ +[opcache] +opcache.enable=1 +opcache.enable_cli=1 +opcache.memory_consumption=256 +opcache.max_accelerated_files=20000 +opcache.validate_timestamps=1 +opcache.revalidate_freq=0 +opcache.jit=1255 +opcache.jit_buffer_size=128M +opcache.interned_strings_buffer=16 diff --git a/docker/php/dev/php.ini b/docker/php/dev/php.ini new file mode 100644 index 0000000..fc1acf9 --- /dev/null +++ b/docker/php/dev/php.ini @@ -0,0 +1,7 @@ +memory_limit=3G +post_max_size=6M +upload_max_filesize=5M +realpath_cache_size=4096K +realpath_cache_ttl=600 + +date.timezone=${PHP_DATE_TIMEZONE} diff --git a/docker/php/docker-entrypoint.sh b/docker/php/docker-entrypoint.sh new file mode 100755 index 0000000..54b400a --- /dev/null +++ b/docker/php/docker-entrypoint.sh @@ -0,0 +1,27 @@ +#!/bin/sh +set -e + +# first arg is `-f` or `--some-option` +if [ "${1#-}" != "$1" ]; then + set -- php-fpm "$@" +fi + +if [ "$1" = 'php-fpm' ] || [ "$1" = 'bin/console' ]; then + mkdir -p var/cache var/log var/sessions public/media + setfacl -R -m u:www-data:rwX -m u:"$(whoami)":rwX var public/media + setfacl -dR -m u:www-data:rwX -m u:"$(whoami)":rwX var public/media + + if [ "$APP_ENV" != 'prod' ]; then + composer install --prefer-dist --no-progress --no-interaction + bin/console assets:install --no-interaction + bin/console sylius:theme:assets:install public --no-interaction + fi + + while ping -c1 migrations >/dev/null 2>&1; + do + (>&2 echo "Waiting for Migrations container to finish") + sleep 1; + done; +fi + +exec docker-php-entrypoint "$@" diff --git a/docker/php/prod/opcache.ini b/docker/php/prod/opcache.ini new file mode 100644 index 0000000..58be9e0 --- /dev/null +++ b/docker/php/prod/opcache.ini @@ -0,0 +1,9 @@ +[opcache] +opcache.enable=1 +opcache.enable_cli=1 +opcache.memory_consumption=256 +opcache.max_accelerated_files=20000 +opcache.validate_timestamps=0 +opcache.jit=1255 +opcache.jit_buffer_size=128M +opcache.interned_strings_buffer=16 diff --git a/docker/php/prod/php.ini b/docker/php/prod/php.ini new file mode 100644 index 0000000..31170a7 --- /dev/null +++ b/docker/php/prod/php.ini @@ -0,0 +1,7 @@ +memory_limit=256M +post_max_size=6M +upload_max_filesize=5M +realpath_cache_size=4096K +realpath_cache_ttl=600 + +date.timezone=${PHP_DATE_TIMEZONE} diff --git a/docker/test.sh b/docker/test.sh new file mode 100755 index 0000000..29dddcb --- /dev/null +++ b/docker/test.sh @@ -0,0 +1,24 @@ +#!/bin/sh +set -e + +readonly timeout=100 +readonly sleep_time=5 + +i=1 +time=$((timeout * sleep_time)) + +until curl -L --fail http://localhost:80 2>/dev/null +do + i=$((i+1)) + + if [ "${i}" -gt "${timeout}" ]; then + + echo "Sylius Store was never created, aborting due to ${time}s timeout!" + curl -L http://localhost:80 -H Accept:application/json + exit 1 + else + echo "Sylius Store did not response" + fi + + sleep $sleep_time +done diff --git a/ecs.php b/ecs.php new file mode 100644 index 0000000..8bf3677 --- /dev/null +++ b/ecs.php @@ -0,0 +1,18 @@ +import('vendor/sylius-labs/coding-standard/ecs.php'); + $config->paths(['src']); + + $config->skip([ + VisibilityRequiredFixer::class => ['*Spec.php'], + ]); + + $config->ruleWithConfiguration(BinaryOperatorSpacesFixer::class, []); + $config->ruleWithConfiguration(PhpdocSeparationFixer::class, ['groups' => [['ORM\\*']]]); +}; diff --git a/etc/build/.gitignore b/etc/build/.gitignore new file mode 100755 index 0000000..e69de29 diff --git a/features/.gitignore b/features/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/gulpfile.babel.js b/gulpfile.babel.js new file mode 100644 index 0000000..6a3c4e4 --- /dev/null +++ b/gulpfile.babel.js @@ -0,0 +1,63 @@ +import chug from 'gulp-chug'; +import gulp from 'gulp'; +import yargs from 'yargs'; + +const { argv } = yargs + .options({ + rootPath: { + description: '{{ method.description }}
+