diff --git a/.github/workflows/recipe.yaml b/.github/workflows/recipe.yaml new file mode 100644 index 0000000..ac678fd --- /dev/null +++ b/.github/workflows/recipe.yaml @@ -0,0 +1,80 @@ +name: Flex Recipe + +on: + push: + branches: [ master ] + pull_request: + +jobs: + + recipe: + + name: Flex recipe (PHP ${{ matrix.php }}, Sylius ${{ matrix.sylius }}) + + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + php: ['8.1', '8.2', '8.3'] + sylius: ["~1.12.0"] + + steps: + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: gd, intl, json + ini-values: date.timezone=UTC + + - name: Set project php-version + run: | + echo ${{ matrix.php }} > .php-version + - uses: actions/checkout@v3 + with: + path: plugin + + - name: Determine composer cache directory + id: composer-cache-directory + working-directory: plugin + run: echo "directory=$(composer config cache-dir)" >> $GITHUB_OUTPUT + + - name: Cache dependencies installed with composer + uses: actions/cache@v3 + id: cache-composer + with: + path: ${{ steps.composer-cache-directory.outputs.directory }} + key: composer2-php:${{ matrix.php }}-sylius:${{ matrix.sylius }}-${{ hashFiles('**/composer.json') }} + restore-keys: composer2-php:${{ matrix.php }}-sylius:${{ matrix.sylius }}- + + - name: Ensure that composer cache directory exists + run: mkdir -p ${{ steps.composer-cache-directory.outputs.directory }} + + - name: Composer Github Auth + run: composer config -g github-oauth.github.com ${{ github.token }} + + - name: Create Sylius-Standard project without install + run: | + composer create-project --prefer-dist --no-scripts --no-progress --no-install sylius/sylius-standard sylius "${{ matrix.sylius }}" + + # Because the sylius-standard has a soft constraint + - name: Make sure to install the required version of Sylius + working-directory: ./sylius + run: | + composer require --no-install --no-scripts --no-progress sylius/sylius="${{ matrix.sylius }}" + + - name: Setup some requirements + working-directory: ./sylius + run: | + composer config --no-plugins allow-plugins true + composer config --no-plugins extra.symfony.allow-contrib true + composer config --no-plugins secure-http false + composer config --no-plugins --unset platform.php + composer config --no-plugins extra.symfony.docker false + composer config --no-plugins --json extra.symfony.endpoint '["https://api.github.com/repos/monsieurbiz/symfony-recipes/contents/index.json?ref=flex/master","flex://defaults"]' + composer config repositories.plugin '{"type": "path", "url": "../plugin/"}' + + - name: Require plugin & install all dependencies + working-directory: ./sylius + run: | + composer require monsieurbiz/sylius-scipts-plugin="*@dev" diff --git a/.github/workflows/security.yaml b/.github/workflows/security.yaml new file mode 100644 index 0000000..1d24ddb --- /dev/null +++ b/.github/workflows/security.yaml @@ -0,0 +1,59 @@ +name: Security + +on: + push: + branches: [ master ] + pull_request: + schedule: + - cron: '0 0 * * *' + +jobs: + + security: + + name: Security check (PHP ${{ matrix.php }}) + + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + php: ['8.1', '8.2', '8.3'] + + env: + COMPOSER_ARGS: --prefer-dist + + steps: + - uses: actions/checkout@v3 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + ini-values: date.timezone=UTC + + - name: Set project php-version + run: | + echo ${{ matrix.php }} > .php-version + - name: Determine composer cache directory + id: composer-cache-directory + run: echo "directory=$(composer config cache-dir)" >> $GITHUB_OUTPUT + + - name: Cache dependencies installed with composer + uses: actions/cache@v3 + id: cache-composer + with: + path: ${{ steps.composer-cache-directory.outputs.directory }} + key: composer2-php:${{ matrix.php }}-${{ hashFiles('**/composer.json') }} + restore-keys: composer2-php:${{ matrix.php }}- + + - name: Ensure that composer cache directory exists + run: mkdir -p ${{ steps.composer-cache-directory.outputs.directory }} + + - name: Composer Github Auth + run: composer config -g github-oauth.github.com ${{ github.token }} + + - name: Install PHP dependencies + run: composer install + + - uses: symfonycorp/security-checker-action@v5 diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml new file mode 100644 index 0000000..d548059 --- /dev/null +++ b/.github/workflows/tests.yaml @@ -0,0 +1,80 @@ +name: Tests + +on: + push: + branches: [ master ] + pull_request: + +jobs: + + php: + + name: Quality tests (PHP ${{ matrix.php }}) + + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + php: ['8.1', '8.2', '8.3'] + + env: + SYMFONY_ARGS: --no-tls + COMPOSER_ARGS: --prefer-dist + DOCKER_INTERACTIVE_ARGS: -t + + steps: + - uses: actions/checkout@v3 + + - uses: actions/setup-node@v3 + with: + node-version: '16' + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + ini-values: date.timezone=UTC + + - name: Set project php-version + run: | + echo ${{ matrix.php }} > .php-version + - name: Install symfony CLI + run: | + curl -1sLf 'https://dl.cloudsmith.io/public/symfony/stable/setup.deb.sh' | sudo -E bash + sudo apt install symfony-cli + - name: Determine composer cache directory + id: composer-cache-directory + run: echo "directory=$(composer config cache-dir)" >> $GITHUB_OUTPUT + + - name: Cache dependencies installed with composer + uses: actions/cache@v3 + id: cache-composer + with: + path: ${{ steps.composer-cache-directory.outputs.directory }} + key: composer2-php:${{ matrix.php }}-${{ hashFiles('**/composer.json') }} + restore-keys: composer2-php:${{ matrix.php }}- + + - name: Ensure that composer cache directory exists + run: mkdir -p ${{ steps.composer-cache-directory.outputs.directory }} + + - name: Composer Github Auth + run: composer config -g github-oauth.github.com ${{ github.token }} + + - run: make install + + - run: make test.composer + + - run: make test.phpcs + + - run: make test.phpstan + + - run: make test.phpmd + + - run: make test.yaml + + - run: make test.twig + + - run: make test.schema + + - run: make test.container diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..964680f --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +/vendor/ +/composer.lock + +/tests/Application + +/behat.yml +/phpspec.yml + +/var +/public +/bin +/.php-version +/php.ini +/.phpunit.result.cache +/node_modules +/yarn.lock +/.php-cs-fixer.cache diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..da3ccc8 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,268 @@ + + * + * For the full copyright and license information, please view the LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +$header = <<<'HEADER' +This file is part of Monsieur Biz' Scripts plugin for Sylius. +(c) Monsieur Biz +For the full copyright and license information, please view the LICENSE.txt +file that was distributed with this source code. +HEADER; + +$finder = PhpCsFixer\Finder::create() + ->in(__DIR__) + ->exclude( + [ + 'tests/Application', + ] + ) +; + +$config = new PhpCsFixer\Config(); +$config + ->setRiskyAllowed(true) + ->setRules([ + '@DoctrineAnnotation' => true, + '@PHP71Migration' => true, + '@PHP71Migration:risky' => true, + '@PHPUnit60Migration:risky' => true, + '@Symfony' => true, + '@Symfony:risky' => true, + 'align_multiline_comment' => [ + 'comment_type' => 'phpdocs_like', + ], + 'array_indentation' => true, + 'array_syntax' => [ + 'syntax' => 'short', + ], + 'binary_operator_spaces' => true, + 'blank_line_after_opening_tag' => true, + 'blank_line_after_namespace' => true, + 'blank_lines_before_namespace' => true, + 'blank_line_before_statement' => true, + 'cast_spaces' => true, + 'class_attributes_separation' => true, + 'class_definition' => [ + 'single_item_single_line' => true, + 'multi_line_extends_each_single_line' => true, + ], + 'combine_consecutive_issets' => true, + 'combine_consecutive_unsets' => true, + 'comment_to_phpdoc' => true, + 'compact_nullable_typehint' => true, + 'concat_space' => [ + 'spacing' => 'one', + ], + 'constant_case' => [ + 'case' => 'lower', + ], + 'declare_equal_normalize' => true, + 'dir_constant' => true, + 'declare_strict_types' => true, + 'doctrine_annotation_array_assignment' => [ + 'operator' => '=', + ], + 'doctrine_annotation_spaces' => [ + 'after_array_assignments_equals' => false, + 'before_array_assignments_equals' => false, + ], + 'elseif' => true, + 'encoding' => true, + 'ereg_to_preg' => true, + 'error_suppression' => true, + 'explicit_indirect_variable' => true, + 'full_opening_tag' => true, + 'fully_qualified_strict_types' => true, + 'function_declaration' => true, + 'function_to_constant' => true, + 'general_phpdoc_tag_rename' => true, + 'global_namespace_import' => [ + 'import_classes' => true, + 'import_constants' => false, + 'import_functions' => false, + ], + 'header_comment' => [ + 'header' => $header, + 'location' => 'after_open', + ], + 'include' => true, + 'increment_style' => [ + 'style' => 'pre', + ], + 'indentation_type' => true, + 'is_null' => true, + 'line_ending' => true, + 'list_syntax' => [ + 'syntax' => 'short', + ], + 'logical_operators' => true, + 'lowercase_cast' => true, + 'lowercase_keywords' => true, + 'lowercase_static_reference' => true, + 'magic_constant_casing' => true, + 'method_argument_space' => true, + 'modernize_strpos' => false, + 'modernize_types_casting' => true, + 'multiline_comment_opening_closing' => true, + 'multiline_whitespace_before_semicolons' => [ + 'strategy' => 'new_line_for_chained_calls', + ], + 'native_constant_invocation' => true, + 'native_function_casing' => true, + 'new_with_braces' => true, + 'no_alias_functions' => true, + 'no_alternative_syntax' => true, + 'no_blank_lines_after_class_opening' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_break_comment' => true, + 'no_closing_tag' => true, + 'no_empty_comment' => true, + 'no_empty_phpdoc' => true, + 'no_empty_statement' => true, + 'no_extra_blank_lines' => [ + 'tokens' => [ + 'break', + 'case', + 'continue', + 'curly_brace_block', + 'default', + 'extra', + 'parenthesis_brace_block', + 'return', + 'square_brace_block', + 'switch', + 'throw', + 'use', + ], + ], + 'no_homoglyph_names' => true, + 'no_leading_import_slash' => true, + 'no_leading_namespace_whitespace' => true, + 'no_mixed_echo_print' => [ + 'use' => 'echo', + ], + 'no_multiline_whitespace_around_double_arrow' => true, + 'no_null_property_initialization' => true, + 'no_php4_constructor' => true, + 'no_singleline_whitespace_before_semicolons' => true, + 'no_short_bool_cast' => true, + 'no_spaces_after_function_name' => true, + 'no_spaces_around_offset' => true, + 'no_spaces_inside_parenthesis' => true, + 'no_superfluous_elseif' => true, + 'no_superfluous_phpdoc_tags' => [ + 'allow_mixed' => true, + ], + 'no_unset_cast' => true, + 'no_unneeded_control_parentheses' => true, + 'no_unneeded_curly_braces' => true, + 'no_unneeded_final_method' => true, + 'no_unset_on_property' => true, + 'no_unused_imports' => true, + 'no_useless_else' => true, + 'no_useless_return' => true, + 'no_trailing_comma_in_singleline' => true, + 'no_trailing_whitespace' => true, + 'no_trailing_whitespace_in_comment' => true, + 'no_whitespace_before_comma_in_array' => true, + 'no_whitespace_in_blank_line' => true, + 'non_printable_character' => true, + 'normalize_index_brace' => true, + 'nullable_type_declaration_for_default_null_value' => false, + 'object_operator_without_whitespace' => true, + 'ordered_imports' => [ + 'imports_order' => [ + 'class', + 'function', + 'const', + ], + 'sort_algorithm' => 'alpha', + ], + 'php_unit_dedicate_assert' => true, + 'php_unit_fqcn_annotation' => true, + 'php_unit_method_casing' => [ + 'case' => 'camel_case', + ], + 'php_unit_set_up_tear_down_visibility' => true, + 'php_unit_test_annotation' => [ + 'style' => 'prefix', + ], + 'phpdoc_align' => [ + 'align' => 'left', + ], + 'phpdoc_add_missing_param_annotation' => [ + 'only_untyped' => true, + ], + 'phpdoc_indent' => true, + 'phpdoc_inline_tag_normalizer' => true, + 'phpdoc_no_access' => true, + 'phpdoc_no_alias_tag' => true, + 'phpdoc_no_empty_return' => true, + 'phpdoc_no_package' => true, + 'phpdoc_no_useless_inheritdoc' => true, + 'phpdoc_order' => true, + 'phpdoc_return_self_reference' => true, + 'phpdoc_scalar' => true, + 'phpdoc_separation' => ['groups' => [ + ['ORM\\*'], ['Assert\\*'], + ]], + 'phpdoc_single_line_var_spacing' => true, + 'phpdoc_tag_type' => true, + 'phpdoc_to_comment' => false, + 'phpdoc_trim' => true, + 'phpdoc_trim_consecutive_blank_line_separation' => true, + 'phpdoc_types' => true, + 'phpdoc_types_order' => [ + 'null_adjustment' => 'always_last', + 'sort_algorithm' => 'none', + ], + 'phpdoc_var_annotation_correct_order' => true, + 'phpdoc_var_without_name' => true, + 'pow_to_exponentiation' => true, + 'protected_to_private' => true, + 'return_assignment' => true, + 'return_type_declaration' => true, + 'self_accessor' => true, + 'short_scalar_cast' => true, + 'single_blank_line_at_eof' => true, + 'single_class_element_per_statement' => true, + 'single_import_per_statement' => true, + 'single_line_after_imports' => true, + 'single_line_comment_style' => true, + 'single_quote' => true, + 'space_after_semicolon' => true, + 'standardize_not_equals' => true, + 'strict_param' => true, + 'switch_case_semicolon_to_colon' => true, + 'switch_case_space' => true, + 'ternary_operator_spaces' => true, + 'ternary_to_null_coalescing' => true, + 'trailing_comma_in_multiline' => [ + 'elements' => ['arrays'], + ], + 'trim_array_spaces' => true, + 'type_declaration_spaces' => true, + 'unary_operator_spaces' => true, + 'visibility_required' => [ + 'elements' => [ + 'const', + 'property', + 'method', + ], + ], + 'void_return' => true, + 'whitespace_after_comma_in_array' => true, // alerady in symfony set + ]) + ->setFinder($finder) +; + +return $config; diff --git a/.php-version.dist b/.php-version.dist new file mode 100644 index 0000000..2983cad --- /dev/null +++ b/.php-version.dist @@ -0,0 +1 @@ +8.2 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..da87eab --- /dev/null +++ b/Makefile @@ -0,0 +1,218 @@ +.DEFAULT_GOAL := help +SHELL=/bin/bash +APP_DIR=tests/Application +SYLIUS_VERSION=1.12.0 +SYMFONY=cd ${APP_DIR} && symfony +COMPOSER=symfony composer +CONSOLE=${SYMFONY} console +export COMPOSE_PROJECT_NAME=scripts +PLUGIN_NAME=sylius-${COMPOSE_PROJECT_NAME}-plugin +COMPOSE=docker-compose +YARN=yarn +DOCTRINE_MIGRATIONS_NAMESPACE=MonsieurBiz\SyliusScriptsPlugin\Migrations + + +### +### DEVELOPMENT +### ¯¯¯¯¯¯¯¯¯¯¯ + +install: application platform sylius ## Install the plugin +.PHONY: install + +up: docker.up server.start ## Up the project (start docker, start symfony server) +stop: server.stop docker.stop ## Stop the project (stop docker, stop symfony server) +down: server.stop docker.down ## Down the project (removes docker containers, stop symfony server) + +reset: ## Stop docker and remove dependencies + ${MAKE} docker.down || true + rm -rf ${APP_DIR} + rm -rf vendor composer.lock +.PHONY: reset + +dependencies: composer.lock node_modules ## Setup the dependencies +.PHONY: dependencies + +.php-version: .php-version.dist + rm -f .php-version + ln -s .php-version.dist .php-version + +php.ini: php.ini.dist + rm -f php.ini + ln -s php.ini.dist php.ini + +composer.lock: composer.json + ${COMPOSER} install --no-scripts --no-plugins + +yarn.install: ${APP_DIR}/yarn.lock + +${APP_DIR}/yarn.lock: + ln -sf ${APP_DIR}/node_modules node_modules + cd ${APP_DIR} && ${YARN} install && ${YARN} build +# No CSS and JS on this plugin yet +# ${YARN} install +# ${YARN} encore prod + +node_modules: ${APP_DIR}/node_modules ## Install the Node dependencies using yarn + +${APP_DIR}/node_modules: yarn.install + +### +### TEST APPLICATION +### ¯¯¯¯¯ + +application: .php-version php.ini ${APP_DIR} setup_application ${APP_DIR}/docker-compose.yaml + +${APP_DIR}: + (${COMPOSER} create-project --no-interaction --prefer-dist --no-scripts --no-progress --no-install sylius/sylius-standard="~${SYLIUS_VERSION}" ${APP_DIR}) + +setup_application: + rm -f ${APP_DIR}/yarn.lock + (cd ${APP_DIR} && ${COMPOSER} config repositories.plugin '{"type": "path", "url": "../../"}') + (cd ${APP_DIR} && ${COMPOSER} config extra.symfony.allow-contrib true) + (cd ${APP_DIR} && ${COMPOSER} config minimum-stability dev) + (cd ${APP_DIR} && ${COMPOSER} config --no-plugins allow-plugins true) + (cd ${APP_DIR} && ${COMPOSER} config --no-plugins --json extra.symfony.endpoint '["https://api.github.com/repos/monsieurbiz/symfony-recipes/contents/index.json?ref=flex/master","flex://defaults"]') + (cd ${APP_DIR} && ${COMPOSER} require --no-install --no-scripts --no-progress sylius/sylius="~${SYLIUS_VERSION}") # Make sure to install the required version of sylius because the sylius-standard has a soft constraint + $(MAKE) ${APP_DIR}/.php-version + $(MAKE) ${APP_DIR}/php.ini + (cd ${APP_DIR} && ${COMPOSER} install --no-interaction) + $(MAKE) apply_dist + (cd ${APP_DIR} && ${COMPOSER} require --no-progress monsieurbiz/${PLUGIN_NAME}="*@dev") + rm -rf ${APP_DIR}/var/cache + + +${APP_DIR}/docker-compose.yaml: + rm -f ${APP_DIR}/docker-compose.yml + rm -f ${APP_DIR}/docker-compose.yaml + ln -s ../../docker-compose.yaml.dist ${APP_DIR}/docker-compose.yaml +.PHONY: ${APP_DIR}/docker-compose.yaml + +${APP_DIR}/.php-version: .php-version + (cd ${APP_DIR} && ln -sf ../../.php-version) + +${APP_DIR}/php.ini: php.ini + (cd ${APP_DIR} && ln -sf ../../php.ini) + +apply_dist: + ROOT_DIR=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))); \ + for i in `cd dist && find . -type f`; do \ + FILE_PATH=`echo $$i | sed 's|./||'`; \ + FOLDER_PATH=`dirname $$FILE_PATH`; \ + echo $$FILE_PATH; \ + (cd ${APP_DIR} && rm -f $$FILE_PATH); \ + (cd ${APP_DIR} && mkdir -p $$FOLDER_PATH); \ + (cd ${APP_DIR} && ln -s $$ROOT_DIR/dist/$$FILE_PATH $$FILE_PATH); \ + done + +### +### TESTS +### ¯¯¯¯¯ + +test.all: test.composer test.phpstan test.phpmd test.phpcs test.yaml test.schema test.twig test.container ## Run all tests in once + +test.composer: ## Validate composer.json + ${COMPOSER} validate --strict + +test.phpstan: ## Run PHPStan + ${COMPOSER} phpstan + +test.phpmd: ## Run PHPMD + ${COMPOSER} phpmd + +test.phpcs: ## Run PHP CS Fixer in dry-run + ${COMPOSER} run -- phpcs --dry-run -v + +test.phpcs.fix: ## Run PHP CS Fixer and fix issues if possible + ${COMPOSER} run -- phpcs -v + +test.container: ## Lint the symfony container + ${CONSOLE} lint:container + +test.yaml: ## Lint the symfony Yaml files + ${CONSOLE} lint:yaml ../../recipes ../../src/Resources/config + +test.schema: ## Validate MySQL Schema + ${CONSOLE} doctrine:schema:validate + +test.twig: ## Validate Twig templates + ${CONSOLE} lint:twig --no-debug templates/ ../../src/Resources/views/ + +### +### MIGRATIONS +### ¯¯¯¯¯¯¯¯¯¯ + +doctrine.migration.diff: ## create a diff migration file for the plugin + ${CONSOLE} doctrine:migrations:diff --namespace="${DOCTRINE_MIGRATIONS_NAMESPACE}" +.PHONY: doctrine.migration.diff + +### +### SYLIUS +### ¯¯¯¯¯¯ + +sylius: dependencies sylius.database sylius.fixtures sylius.assets messenger.setup ## Install Sylius +.PHONY: sylius + +sylius.database: ## Setup the database + ${CONSOLE} doctrine:database:drop --if-exists --force + ${CONSOLE} doctrine:database:create --if-not-exists + ${CONSOLE} doctrine:migration:migrate -n + +sylius.fixtures: ## Run the fixtures + ${CONSOLE} sylius:fixtures:load -n default + +sylius.assets: ## Install all assets with symlinks + ${CONSOLE} assets:install --symlink + ${CONSOLE} sylius:install:assets + ${CONSOLE} sylius:theme:assets:install --symlink + +messenger.setup: ## Setup Messenger transports + ${CONSOLE} messenger:setup-transports + +### +### PLATFORM +### ¯¯¯¯¯¯¯¯ + +platform: .php-version up ## Setup the platform tools +.PHONY: platform + +docker.pull: ## Pull the docker images + cd ${APP_DIR} && ${COMPOSE} pull + +docker.up: ## Start the docker containers + cd ${APP_DIR} && ${COMPOSE} up -d +.PHONY: docker.up + +docker.stop: ## Stop the docker containers + cd ${APP_DIR} && ${COMPOSE} stop +.PHONY: docker.stop + +docker.down: ## Stop and remove the docker containers + cd ${APP_DIR} && ${COMPOSE} down +.PHONY: docker.down + +docker.logs: ## Logs the docker containers + cd ${APP_DIR} && ${COMPOSE} logs -f +.PHONY: docker.logs + +docker.dc: ARGS=ps +docker.dc: ## Run docker-compose command. Use ARGS="" to pass parameters to docker-compose. + cd ${APP_DIR} && ${COMPOSE} ${ARGS} +.PHONY: docker.dc + +server.start: ## Run the local webserver using Symfony + ${SYMFONY} local:server:start -d + +server.stop: ## Stop the local webserver + ${SYMFONY} local:server:stop + +### +### HELP +### ¯¯¯¯ + +help: SHELL=/bin/bash +help: ## Dislay this help + @IFS=$$'\n'; for line in `grep -h -E '^[a-zA-Z_#-]+:?.*?##.*$$' $(MAKEFILE_LIST)`; do if [ "$${line:0:2}" = "##" ]; then \ + echo $$line | awk 'BEGIN {FS = "## "}; {printf "\033[33m %s\033[0m\n", $$2}'; else \ + echo $$line | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m%s\n", $$1, $$2}'; fi; \ + done; unset IFS; +.PHONY: help diff --git a/README.md b/README.md new file mode 100644 index 0000000..de23b6a --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +

+ + Monsieur Biz logo + +      + + Sylius logo + +
+ Monsieur Biz is a Sylius Extension Artisan partner +

+ +

Scripts Settings for Sylius

+ +[![Scripts Plugin license](https://img.shields.io/github/license/monsieurbiz/SyliusScriptsPlugin?public&nocache)](https://github.com/monsieurbiz/SyliusScriptsPlugin/blob/master/LICENSE) +[![Tests Status](https://github.com/monsieurbiz/SyliusScriptsPlugin/actions/workflows/tests.yaml/badge.svg?branch=master&event=push)](https://github.com/monsieurbiz/SyliusScriptsPlugin/actions?query=workflow%3ATests) +[![Security Status](https://github.com/monsieurbiz/SyliusScriptsPlugin/actions/workflows/security.yaml/badge.svg?branch=master&event=push)](https://github.com/monsieurbiz/SyliusScriptsPlugin/actions?query=workflow%3ASecurity) + +This plugin lets you add JS scripts from the admin panel. You can add scripts to the header or the footer of your website. +For example, add Google Analytics, Facebook Pixel, or any other tracking script. + +# Installation + +```bash +composer require monsieurbiz/sylius-scripts-plugin +``` + +# Configuration + +In progress diff --git a/behat.yml.dist b/behat.yml.dist new file mode 100644 index 0000000..ea37647 --- /dev/null +++ b/behat.yml.dist @@ -0,0 +1,8 @@ +default: + suites: + default: + contexts: + - App\Tests\Behat\DemoContext + + extensions: + FriendsOfBehat\SymfonyExtension: null diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..beb227b --- /dev/null +++ b/composer.json @@ -0,0 +1,81 @@ +{ + "name": "monsieurbiz/sylius-scripts-plugin", + "type": "sylius-plugin", + "keywords": ["sylius", "sylius-plugin", "monsieurbiz"], + "description": "Allows you to add JS scripts from the admin panel.", + "license": "MIT", + "require": { + "php": "^8.1", + "monsieurbiz/sylius-settings-plugin": "^1.0.0" + }, + "require-dev": { + "behat/behat": "^3.6.1", + "behat/mink-selenium2-driver": "^1.4", + "dmore/behat-chrome-extension": "^1.3", + "dmore/chrome-mink-driver": "^2.7", + "friends-of-behat/mink": "^1.8", + "friends-of-behat/mink-browserkit-driver": "^1.4", + "friends-of-behat/mink-debug-extension": "^2.0.0", + "friends-of-behat/mink-extension": "^2.4", + "friends-of-behat/page-object-extension": "^0.3", + "friends-of-behat/suite-settings-extension": "^1.0", + "friends-of-behat/symfony-extension": "^2.1", + "friends-of-behat/variadic-extension": "^1.3", + "phpspec/phpspec": "^7.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.8.1", + "phpstan/phpstan-doctrine": "1.3.40", + "phpstan/phpstan-strict-rules": "^1.3.0", + "phpstan/phpstan-webmozart-assert": "^1.2.0", + "phpunit/phpunit": "^9.5", + "polishsymfonycommunity/symfony-mocker-container": "^1.0", + "sylius-labs/coding-standard": "^4.2", + "symfony/browser-kit": "^5.4 || ^6.0", + "symfony/debug-bundle": "^5.4 || ^6.0", + "symfony/dotenv": "^5.4 || ^6.0", + "symfony/flex": "^2.2.2", + "symfony/intl": "^5.4 || ^6.0", + "symfony/web-profiler-bundle": "^5.4 || ^6.0", + "phpmd/phpmd": "^2.13", + "friendsofphp/php-cs-fixer": "^3.16" + }, + "prefer-stable": true, + "autoload": { + "psr-4": { + "MonsieurBiz\\SyliusScriptsPlugin\\": "src/" + } + }, + "scripts": { + "auto-scripts": { + "cache:clear": "symfony-cmd", + "assets:install %PUBLIC_DIR%": "symfony-cmd" + }, + "phpcs": "php-cs-fixer fix --using-cache=no", + "phpstan": "phpstan analyse -c phpstan.neon src/", + "phpmd": "phpmd --exclude Migrations/* src/ ansi phpmd.xml", + "phpunit": "phpunit", + "phpspec": "phpspec run" + }, + "extra": { + "symfony": { + "docker": false, + "endpoint": [ + "https://api.github.com/repos/monsieurbiz/symfony-recipes/contents/index.json?ref=flex/master", + "flex://defaults" + ] + }, + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true, + "symfony/thanks": true, + "ergebnis/composer-normalize": true, + "symfony/flex": true, + "php-http/discovery": false, + "phpstan/extension-installer": true + } + } +} diff --git a/dist/.gitkeep b/dist/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docker-compose.yaml.dist b/docker-compose.yaml.dist new file mode 100644 index 0000000..955683c --- /dev/null +++ b/docker-compose.yaml.dist @@ -0,0 +1,21 @@ +version: '3.8' +services: + database: + image: mysql:8.0 + command: --default-authentication-plugin=mysql_native_password + ports: + - 3306 + environment: + MYSQL_ALLOW_EMPTY_PASSWORD: 1 + MYSQL_DATABASE: sylius + volumes: + - database:/var/lib/mysql + + mailer: + image: monsieurbiz/mailcatcher + ports: + - 1025 + - 1080 + +volumes: + database: {} diff --git a/php.ini.dist b/php.ini.dist new file mode 100644 index 0000000..b0fe7fe --- /dev/null +++ b/php.ini.dist @@ -0,0 +1 @@ +memory_limit=-1 diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..89195e2 --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,19 @@ + + + + + + + + + + + + bin/ + config/ + public/ + src/ + tests/ + + diff --git a/phpmd.xml b/phpmd.xml new file mode 100644 index 0000000..0000ac5 --- /dev/null +++ b/phpmd.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/phpspec.yml.dist b/phpspec.yml.dist new file mode 100644 index 0000000..6a0a6ff --- /dev/null +++ b/phpspec.yml.dist @@ -0,0 +1,6 @@ +suites: + main: + namespace: MonsieurBiz\SyliusScriptsPlugin + psr4_prefix: MonsieurBiz\SyliusScriptsPlugin + src_path: src + spec_path: tests diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..c43727c --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,11 @@ +parameters: + level: max + paths: + - %rootDir%/src/ + + checkMissingIterableValueType: false + checkGenericClassInNonGenericObjectType: false + + excludePaths: + # Test dependencies + - 'tests/Application/**/*' diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..b469982 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,22 @@ + + + + + + tests/Unit + + + + + + + + + + + + + diff --git a/recipes/1.0-dev/config/packages/monsieurbiz_sylius_scripts_plugin.yaml b/recipes/1.0-dev/config/packages/monsieurbiz_sylius_scripts_plugin.yaml new file mode 100644 index 0000000..ef406ca --- /dev/null +++ b/recipes/1.0-dev/config/packages/monsieurbiz_sylius_scripts_plugin.yaml @@ -0,0 +1,2 @@ +imports: + resource: '@MonsieurBizSyliusScriptsPlugin/Resources/config/config.yaml' diff --git a/recipes/1.0-dev/manifest.json b/recipes/1.0-dev/manifest.json new file mode 100644 index 0000000..897ea3d --- /dev/null +++ b/recipes/1.0-dev/manifest.json @@ -0,0 +1,10 @@ +{ + "bundles": { + "MonsieurBiz\\SyliusScriptsPlugin\\MonsieurBizSyliusScriptsPlugin": [ + "all" + ] + }, + "copy-from-recipe": { + "config/": "%CONFIG_DIR%/" + } +} diff --git a/src/Controller/.gitkeep b/src/Controller/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/DependencyInjection/MonsieurBizSyliusScriptsExtension.php b/src/DependencyInjection/MonsieurBizSyliusScriptsExtension.php new file mode 100644 index 0000000..76c0a1e --- /dev/null +++ b/src/DependencyInjection/MonsieurBizSyliusScriptsExtension.php @@ -0,0 +1,63 @@ + + * For the full copyright and license information, please view the LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace MonsieurBiz\SyliusScriptsPlugin\DependencyInjection; + +use Sylius\Bundle\CoreBundle\DependencyInjection\PrependDoctrineMigrationsTrait; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\Extension; +use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; + +final class MonsieurBizSyliusScriptsExtension extends Extension implements PrependExtensionInterface +{ + use PrependDoctrineMigrationsTrait; + + /** + * @inheritdoc + */ + public function load(array $config, ContainerBuilder $container): void + { + $loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); + $loader->load('services.yaml'); + } + + /** + * @inheritdoc + */ + public function getAlias(): string + { + return 'monsieurbiz_scripts'; + } + + public function prepend(ContainerBuilder $container): void + { + $this->prependDoctrineMigrations($container); + } + + protected function getMigrationsNamespace(): string + { + return 'MonsieurBiz\SyliusScriptsPlugin\Migrations'; + } + + protected function getMigrationsDirectory(): string + { + return '@MonsieurBizSyliusScriptsPlugin/Migrations'; + } + + protected function getNamespacesOfMigrationsExecutedBefore(): array + { + return [ + 'Sylius\Bundle\CoreBundle\Migrations', + ]; + } +} diff --git a/src/Migrations/.gitkeep b/src/Migrations/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/MonsieurBizSyliusScriptsPlugin.php b/src/MonsieurBizSyliusScriptsPlugin.php new file mode 100644 index 0000000..6202405 --- /dev/null +++ b/src/MonsieurBizSyliusScriptsPlugin.php @@ -0,0 +1,44 @@ + + * For the full copyright and license information, please view the LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace MonsieurBiz\SyliusScriptsPlugin; + +use LogicException; +use Sylius\Bundle\CoreBundle\Application\SyliusPluginTrait; +use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +use Symfony\Component\HttpKernel\Bundle\Bundle; + +final class MonsieurBizSyliusScriptsPlugin extends Bundle +{ + use SyliusPluginTrait; + + /** + * Returns the plugin's container extension. + * + * @throws LogicException + * + * @return ExtensionInterface|null The container extension + */ + public function getContainerExtension(): ?ExtensionInterface + { + if (null === $this->containerExtension) { + $this->containerExtension = false; + $extension = $this->createContainerExtension(); + if (null !== $extension) { + $this->containerExtension = $extension; + } + } + + return $this->containerExtension instanceof ExtensionInterface + ? $this->containerExtension + : null; + } +} diff --git a/src/Resources/config/config.yaml b/src/Resources/config/config.yaml new file mode 100644 index 0000000..40fcdd3 --- /dev/null +++ b/src/Resources/config/config.yaml @@ -0,0 +1,2 @@ +# imports: +# - { resource: '...' } diff --git a/src/Resources/config/services.yaml b/src/Resources/config/services.yaml new file mode 100644 index 0000000..e4d3903 --- /dev/null +++ b/src/Resources/config/services.yaml @@ -0,0 +1,13 @@ +services: + _defaults: + autowire: true + autoconfigure: true + public: false + + MonsieurBiz\SyliusScriptsPlugin\: + resource: '../../*' + exclude: '../../{Entity,Migrations}' + + MonsieurBiz\SyliusScriptsPlugin\Controller\: + resource: '../../Controller' + tags: [ 'controller.service_arguments' ] diff --git a/tests/Behat/.gitkeep b/tests/Behat/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/Unit/.gitkeep b/tests/Unit/.gitkeep new file mode 100644 index 0000000..e69de29