From 312056f84c5aaa6dd94e66cc7b3d95710a754e28 Mon Sep 17 00:00:00 2001 From: Simon Gilli <25326036+gilbertsoft@users.noreply.github.com> Date: Wed, 4 Nov 2020 08:09:48 +0100 Subject: [PATCH 1/8] [TASK] Add Sitepackage Builder classes --- config/packages/nelmio_api_doc.yaml | 2 +- .../bootstrap_package/.editorconfig | 70 ++++ .../bootstrap_package/Build/.htaccess | 2 + .../bootstrap_package/Build/Gruntfile.js.twig | 72 ++++ .../bootstrap_package/Build/package.json.twig | 18 + .../bootstrap_package/Classes/.htaccess | 2 + .../Classes/Controller/.gitkeep | 1 + .../bootstrap_package/Classes/Domain/.gitkeep | 1 + .../Classes/Domain/Model/.gitkeep | 1 + .../Classes/Domain/Repository/.gitkeep | 1 + .../Classes/ViewHelpers/.gitkeep | 1 + .../bootstrap_package/Configuration/.htaccess | 2 + .../Configuration/RTE/Default.yaml.twig | 9 + .../TCA/Overrides/pages.php.twig | 19 + .../TCA/Overrides/sys_template.php.twig | 19 + .../TsConfig/Page/All.tsconfig.twig | 7 + .../WebLayout/BackendLayouts.tsconfig.twig | 4 + .../BackendLayouts/example.tsconfig.twig | 29 ++ .../TsConfig/Page/RTE.tsconfig.twig | 8 + .../TsConfig/Page/TCEFORM.tsconfig.twig | 11 + .../TsConfig/Page/TCEMAIN.tsconfig.twig | 6 + .../TypoScript/constants.typoscript.twig | 60 +++ .../TypoScript/setup.typoscript.twig | 30 ++ .../bootstrap_package/README.md.twig | 4 + .../Resources/Private/.htaccess | 2 + .../Private/Language/locallang.xlf.twig | 11 + .../Private/Language/locallang_be.xlf.twig | 17 + .../Private/Language/locallang_db.xlf.twig | 11 + .../Private/Layouts/ContentElements/.gitkeep | 1 + .../Resources/Private/Layouts/Page/.gitkeep | 0 .../Private/Partials/ContentElements/.gitkeep | 1 + .../Resources/Private/Partials/Page/.gitkeep | 1 + .../Templates/ContentElements/.gitkeep | 1 + .../Private/Templates/Page/Example.html.twig | 22 ++ .../Resources/Public/Css/.gitkeep | 1 + .../Resources/Public/Fonts/.gitkeep | 1 + .../Public/Icons/BackendLayouts/example.svg | 1 + .../Resources/Public/Icons/Extension.svg | 3 + .../Resources/Public/Icons/favicon.ico | Bin 0 -> 1150 bytes .../Resources/Public/Icons/logo-inverted.svg | 1 + .../Resources/Public/Icons/logo.svg | 1 + .../Resources/Public/Images/logo-inverted.svg | 1 + .../Resources/Public/Images/logo.svg | 1 + .../Public/JavaScript/Dist/scripts.js.twig | 6 + .../Public/JavaScript/Src/main.js.twig | 1 + .../Public/Scss/Theme/_variables.scss | 3 + .../Public/Scss/Theme/theme.scss.twig | 9 + .../bootstrap_package/composer.json.twig | 21 + .../ext_conf_template.txt.twig | 3 + .../bootstrap_package/ext_emconf.php.twig | 30 ++ .../bootstrap_package/ext_localconf.php.twig | 12 + .../bootstrap_package/ext_tables.php.twig | 2 + .../bootstrap_package/ext_tables.sql.twig | 3 + .../ext_tables_static+adt.sql.twig | 3 + .../fluid_styled_content/.editorconfig | 70 ++++ .../fluid_styled_content/Build/.htaccess | 2 + .../Build/Gruntfile.js.twig | 124 ++++++ .../Build/package.json.twig | 28 ++ .../fluid_styled_content/Classes/.htaccess | 2 + .../Classes/Controller/.gitkeep | 1 + .../Classes/Domain/.gitkeep | 1 + .../Classes/Domain/Model/.gitkeep | 1 + .../Classes/Domain/Repository/.gitkeep | 1 + .../Classes/ViewHelpers/.gitkeep | 1 + .../Configuration/.htaccess | 2 + .../Configuration/RTE/Default.yaml.twig | 42 ++ .../TCA/Overrides/pages.php.twig | 19 + .../TCA/Overrides/sys_template.php.twig | 19 + .../TsConfig/Page/All.tsconfig.twig | 7 + .../WebLayout/BackendLayouts.tsconfig.twig | 4 + .../BackendLayouts/default.tsconfig.twig | 29 ++ .../TsConfig/Page/RTE.tsconfig.twig | 8 + .../TsConfig/Page/TCEFORM.tsconfig.twig | 11 + .../TsConfig/Page/TCEMAIN.tsconfig.twig | 6 + .../Helper/DynamicContent.typoscript.twig | 64 +++ .../TypoScript/constants.typoscript.twig | 56 +++ .../TypoScript/setup.typoscript.twig | 203 ++++++++++ .../fluid_styled_content/README.md.twig | 4 + .../Resources/Private/.htaccess | 2 + .../Private/Language/locallang.xlf.twig | 11 + .../Private/Language/locallang_be.xlf.twig | 17 + .../Private/Language/locallang_db.xlf.twig | 11 + .../Private/Layouts/ContentElements/.gitkeep | 1 + .../Private/Layouts/Page/Default.html.twig | 21 + .../Private/Partials/ContentElements/.gitkeep | 1 + .../Resources/Private/Partials/Page/.gitkeep | 1 + .../Templates/ContentElements/.gitkeep | 1 + .../Private/Templates/Page/Default.html.twig | 19 + .../Resources/Public/Css/layout.css | 0 .../Resources/Public/Css/layout.min.css | 0 .../Resources/Public/Css/rte.css.twig | 3 + .../Resources/Public/Fonts/.gitkeep | 1 + .../Resources/Public/Icons/Extension.svg | 3 + .../Resources/Public/Icons/favicon.ico | Bin 0 -> 1150 bytes .../Public/Images/BackendLayouts/default.png | Bin 0 -> 182 bytes .../Public/JavaScript/Dist/scripts.js.twig | 6 + .../Public/JavaScript/Src/main.js.twig | 1 + .../Resources/Public/Scss/layout.scss.twig | 5 + .../Resources/Public/Scss/variables.scss.twig | 1 + .../fluid_styled_content/composer.json.twig | 23 ++ .../ext_conf_template.txt.twig | 3 + .../fluid_styled_content/ext_emconf.php.twig | 32 ++ .../ext_localconf.php.twig | 12 + .../fluid_styled_content/ext_tables.php.twig | 2 + .../fluid_styled_content/ext_tables.sql.twig | 3 + .../ext_tables_static+adt.sql.twig | 3 + src/Controller/Api/SitepackageController.php | 118 ++++++ src/Controller/EntryPointController.php | 2 + .../Wizards/SitepackageController.php | 226 +++++++++++ src/Entity/Package/Author.php | 169 ++++++++ src/Entity/Sitepackage.php | 370 ++++++++++++++++++ src/Enum/BasePackageEnum.php | 35 ++ src/Enum/Typo3VersionEnum.php | 39 ++ src/Factory/SitepackageFactory.php | 61 +++ src/Form/Dto/SitepackageDto.php | 162 ++++++++ src/Form/SitepackageType.php | 191 +++++++++ src/Form/Type/BasePackageType.php | 50 +++ src/Form/Type/Typo3VersionType.php | 54 +++ src/Menu/MenuBuilder.php | 14 + src/Service/SitepackageGenerator.php | 110 ++++++ src/Twig/Extension/VersionNumberExtension.php | 62 +++ src/Utility/FileUtility.php | 57 +++ src/Utility/StringUtility.php | 103 +++++ templates/default/root.html.twig | 1 + .../wizards/sitepackage/edit.html.twig | 18 + .../wizards/sitepackage/index.html.twig | 109 ++++++ .../partials/privacy-footer.html.twig | 7 + .../wizards/sitepackage/success.html.twig | 88 +++++ 128 files changed, 3482 insertions(+), 1 deletion(-) create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/.editorconfig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Build/.htaccess create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Build/Gruntfile.js.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Build/package.json.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Classes/.htaccess create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Classes/Controller/.gitkeep create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/.gitkeep create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/Model/.gitkeep create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/Repository/.gitkeep create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Classes/ViewHelpers/.gitkeep create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/.htaccess create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/RTE/Default.yaml.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/TCA/Overrides/pages.php.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/TCA/Overrides/sys_template.php.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/All.tsconfig.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts.tsconfig.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts/example.tsconfig.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/RTE.tsconfig.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/TCEFORM.tsconfig.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/TCEMAIN.tsconfig.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/TypoScript/constants.typoscript.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/TypoScript/setup.typoscript.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/README.md.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/.htaccess create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang.xlf.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang_be.xlf.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang_db.xlf.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Layouts/ContentElements/.gitkeep create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Layouts/Page/.gitkeep create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Partials/ContentElements/.gitkeep create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Partials/Page/.gitkeep create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Templates/ContentElements/.gitkeep create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Templates/Page/Example.html.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Css/.gitkeep create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Fonts/.gitkeep create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/BackendLayouts/example.svg create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/Extension.svg create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/favicon.ico create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/logo-inverted.svg create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/logo.svg create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Images/logo-inverted.svg create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Images/logo.svg create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/JavaScript/Dist/scripts.js.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/JavaScript/Src/main.js.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Scss/Theme/_variables.scss create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Scss/Theme/theme.scss.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/composer.json.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/ext_conf_template.txt.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/ext_emconf.php.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/ext_localconf.php.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/ext_tables.php.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/ext_tables.sql.twig create mode 100644 resources/skeletons/BaseExtension/bootstrap_package/ext_tables_static+adt.sql.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/.editorconfig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Build/.htaccess create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Build/Gruntfile.js.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Build/package.json.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Classes/.htaccess create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Classes/Controller/.gitkeep create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/.gitkeep create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/Model/.gitkeep create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/Repository/.gitkeep create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Classes/ViewHelpers/.gitkeep create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/.htaccess create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/RTE/Default.yaml.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TCA/Overrides/pages.php.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TCA/Overrides/sys_template.php.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/All.tsconfig.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts.tsconfig.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts/default.tsconfig.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/RTE.tsconfig.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/TCEFORM.tsconfig.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/TCEMAIN.tsconfig.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/Helper/DynamicContent.typoscript.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/constants.typoscript.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/setup.typoscript.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/README.md.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/.htaccess create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang.xlf.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang_be.xlf.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang_db.xlf.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Layouts/ContentElements/.gitkeep create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Layouts/Page/Default.html.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Partials/ContentElements/.gitkeep create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Partials/Page/.gitkeep create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Templates/ContentElements/.gitkeep create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Templates/Page/Default.html.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Css/layout.css create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Css/layout.min.css create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Css/rte.css.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Fonts/.gitkeep create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Icons/Extension.svg create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Icons/favicon.ico create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Images/BackendLayouts/default.png create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/JavaScript/Dist/scripts.js.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/JavaScript/Src/main.js.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Scss/layout.scss.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Scss/variables.scss.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/composer.json.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/ext_conf_template.txt.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/ext_emconf.php.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/ext_localconf.php.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/ext_tables.php.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/ext_tables.sql.twig create mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/ext_tables_static+adt.sql.twig create mode 100644 src/Controller/Api/SitepackageController.php create mode 100644 src/Controller/Wizards/SitepackageController.php create mode 100644 src/Entity/Package/Author.php create mode 100644 src/Entity/Sitepackage.php create mode 100644 src/Enum/BasePackageEnum.php create mode 100644 src/Enum/Typo3VersionEnum.php create mode 100644 src/Factory/SitepackageFactory.php create mode 100644 src/Form/Dto/SitepackageDto.php create mode 100644 src/Form/SitepackageType.php create mode 100644 src/Form/Type/BasePackageType.php create mode 100644 src/Form/Type/Typo3VersionType.php create mode 100644 src/Service/SitepackageGenerator.php create mode 100644 src/Twig/Extension/VersionNumberExtension.php create mode 100644 src/Utility/FileUtility.php create mode 100644 src/Utility/StringUtility.php create mode 100644 templates/default/wizards/sitepackage/edit.html.twig create mode 100644 templates/default/wizards/sitepackage/index.html.twig create mode 100644 templates/default/wizards/sitepackage/partials/privacy-footer.html.twig create mode 100644 templates/default/wizards/sitepackage/success.html.twig diff --git a/config/packages/nelmio_api_doc.yaml b/config/packages/nelmio_api_doc.yaml index 0b825b43..7246deb6 100644 --- a/config/packages/nelmio_api_doc.yaml +++ b/config/packages/nelmio_api_doc.yaml @@ -3,7 +3,7 @@ nelmio_api_doc: info: title: get.typo3.org description: REST API for getting information about TYPO3 releases - version: 1.0.0 + version: 1.1.0 components: securitySchemes: Basic: diff --git a/resources/skeletons/BaseExtension/bootstrap_package/.editorconfig b/resources/skeletons/BaseExtension/bootstrap_package/.editorconfig new file mode 100644 index 00000000..ff05afd1 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/.editorconfig @@ -0,0 +1,70 @@ +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +# CSS-Files +[*.css] +indent_style = space +indent_size = 4 + +# HTML-Files +[*.html] +indent_style = space +indent_size = 4 + +# TMPL-Files +[*.tmpl] +indent_style = space +indent_size = 4 + +# JS-Files +[*.js] +indent_style = space +indent_size = 4 + +# PHP-Files +[*.php] +indent_style = space +indent_size = 4 + +# MD-Files +[*.md] +indent_style = space +indent_size = 4 + +# ReST-Files +[*.rst] +indent_style = space +indent_size = 3 + +# TypoScript +[*.typoscript] +indent_style = space +indent_size = 4 + +# YML-Files +[{*.yml,*.yaml}] +indent_style = space +indent_size = 2 + +# package.json +[package.json] +indent_style = space +indent_size = 2 + +# composer.json +[composer.json] +indent_style = space +indent_size = 4 + +# phpstan +[*.neon] +indent_style = tab diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Build/.htaccess b/resources/skeletons/BaseExtension/bootstrap_package/Build/.htaccess new file mode 100644 index 00000000..93169e4e --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Build/.htaccess @@ -0,0 +1,2 @@ +Order deny,allow +Deny from all diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Build/Gruntfile.js.twig b/resources/skeletons/BaseExtension/bootstrap_package/Build/Gruntfile.js.twig new file mode 100644 index 00000000..36dddf66 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Build/Gruntfile.js.twig @@ -0,0 +1,72 @@ +module.exports = function(grunt) { + + /** + * Project configuration. + */ + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + paths: { + root: '../', + resources: '<%= paths.root %>Resources/', + fonts: '<%= paths.resources %>Public/Fonts/', + img: '<%= paths.resources %>Public/Images/', + js: '<%= paths.resources %>Public/JavaScript/' + }, + banner: '/*!\n' + + ' * {{ package.title }} v<%= pkg.version %> (<%= pkg.homepage %>)\n' + + ' * Copyright 2017-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' + + ' * Licensed under the <%= pkg.license %> license\n' + + ' */\n', + uglify: { + all: { + options: { + banner: '<%= banner %>', + mangle: true, + compress: true, + beautify: false + }, + files: { + "<%= paths.js %>/Dist/scripts.js": [ + "<%= paths.js %>Src/main.js" + ] + } + } + }, + imagemin: { + extension: { + files: [{ + expand: true, + cwd: '<%= paths.resources %>', + src: [ + '**/*.{png,jpg,gif,svg}' + ], + dest: '<%= paths.resources %>' + }] + } + }, + watch: { + options: { + livereload: true + }, + javascript: { + files: '<%= paths.js %>Src/**/*.js', + tasks: ['js'] + } + } + }); + + /** + * Register tasks + */ + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-contrib-imagemin'); + + /** + * Grunt update task + */ + grunt.registerTask('js', ['uglify']); + grunt.registerTask('build', ['js', 'imagemin']); + grunt.registerTask('default', ['build']); + +}; diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Build/package.json.twig b/resources/skeletons/BaseExtension/bootstrap_package/Build/package.json.twig new file mode 100644 index 00000000..21fc85af --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Build/package.json.twig @@ -0,0 +1,18 @@ +{ + "name": "{{ package.vendorNameAlternative }}-{{ package.packageNameAlternative }}", + "description": "{{ package.description }}", + "repository": { + "type": "git", + "url": "{{ package.repositoryUrl }}" + }, + "homepage": "{{ package.author.homepage }}", + "author": "{{ package.author.name }}", + "version": "1.0.0", + "license": "GPL-2.0-or-later", + "devDependencies": { + "grunt": "^1.0.3", + "grunt-contrib-uglify": "^4.0.0", + "grunt-contrib-watch": "^1.1.0", + "grunt-contrib-imagemin": "^2.0.1" + } +} diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Classes/.htaccess b/resources/skeletons/BaseExtension/bootstrap_package/Classes/.htaccess new file mode 100644 index 00000000..93169e4e --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Classes/.htaccess @@ -0,0 +1,2 @@ +Order deny,allow +Deny from all diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Classes/Controller/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Classes/Controller/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Classes/Controller/.gitkeep @@ -0,0 +1 @@ + diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/.gitkeep @@ -0,0 +1 @@ + diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/Model/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/Model/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/Model/.gitkeep @@ -0,0 +1 @@ + diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/Repository/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/Repository/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/Repository/.gitkeep @@ -0,0 +1 @@ + diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Classes/ViewHelpers/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Classes/ViewHelpers/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Classes/ViewHelpers/.gitkeep @@ -0,0 +1 @@ + diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/.htaccess b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/.htaccess new file mode 100644 index 00000000..93169e4e --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/.htaccess @@ -0,0 +1,2 @@ +Order deny,allow +Deny from all diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/RTE/Default.yaml.twig b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/RTE/Default.yaml.twig new file mode 100644 index 00000000..282236ed --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/RTE/Default.yaml.twig @@ -0,0 +1,9 @@ +imports: + - { resource: "EXT:rte_ckeditor/Configuration/RTE/Processing.yaml" } + - { resource: "EXT:rte_ckeditor/Configuration/RTE/Editor/Base.yaml" } + - { resource: "EXT:rte_ckeditor/Configuration/RTE/Editor/Plugins.yaml" } + - { resource: "EXT:bootstrap_package/Configuration/RTE/Default.yaml" } + +editor: + config: + contentsCss: "EXT:bootstrap_package/Resources/Public/Css/bootstrap4-rte.min.css" diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TCA/Overrides/pages.php.twig b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TCA/Overrides/pages.php.twig new file mode 100644 index 00000000..672a2d1e --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TCA/Overrides/pages.php.twig @@ -0,0 +1,19 @@ + + + + diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts.tsconfig.twig b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts.tsconfig.twig new file mode 100644 index 00000000..8213cfae --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts.tsconfig.twig @@ -0,0 +1,4 @@ +# +# BACKENDLAYOUTS +# + diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts/example.tsconfig.twig b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts/example.tsconfig.twig new file mode 100644 index 00000000..628a7254 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts/example.tsconfig.twig @@ -0,0 +1,29 @@ +# +# BACKENDLAYOUT: EXAMPLE +# +mod { + web_layout { + BackendLayouts { + example { + title = LLL:EXT:{{ package.extensionKey }}/Resources/Private/Language/locallang_be.xlf:backend_layout.example + config { + backend_layout { + colCount = 1 + rowCount = 1 + rows { + 1 { + columns { + 1 { + name = LLL:EXT:{{ package.extensionKey }}/Resources/Private/Language/locallang_be.xlf:backend_layout.column.normal + colPos = 0 + } + } + } + } + } + } + icon = EXT:{{ package.extensionKey }}/Resources/Public/Icons/BackendLayouts/example.svg + } + } + } +} diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/RTE.tsconfig.twig b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/RTE.tsconfig.twig new file mode 100644 index 00000000..38353247 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/RTE.tsconfig.twig @@ -0,0 +1,8 @@ +############# +#### RTE #### +############# +RTE { + default { + preset = {{ package.extensionKey }} + } +} diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/TCEFORM.tsconfig.twig b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/TCEFORM.tsconfig.twig new file mode 100644 index 00000000..55f97ce7 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/TCEFORM.tsconfig.twig @@ -0,0 +1,11 @@ +# +# TCEFORM +# +TCEFORM { + pages { + + } + tt_content { + + } +} diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/TCEMAIN.tsconfig.twig b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/TCEMAIN.tsconfig.twig new file mode 100644 index 00000000..9d4a5e4e --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/TCEMAIN.tsconfig.twig @@ -0,0 +1,6 @@ +# +# TCEMAIN +# +TCEMAIN { + +} diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TypoScript/constants.typoscript.twig b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TypoScript/constants.typoscript.twig new file mode 100644 index 00000000..32904169 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TypoScript/constants.typoscript.twig @@ -0,0 +1,60 @@ +###################### +#### DEPENDENCIES #### +###################### + + + +############ +### PAGE ### +############ +page { + logo { + file = EXT:{{ package.extensionKey }}/Resources/Public/Images/logo.svg + fileInverted = EXT:{{ package.extensionKey }}/Resources/Public/Images/logo-inverted.svg + height = 52 + width = 192 + alt = {{ package.title }} + linktitle = {{ package.title }} + } + favicon { + file = EXT:{{ package.extensionKey }}/Resources/Public/Icons/favicon.ico + } + fluidtemplate { + layoutRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Layouts/Page/ + partialRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Partials/Page/ + templateRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Templates/Page/ + } +} + + +################## +### EXTENSIONS ### +################## +plugin.bootstrap_package { + view { + layoutRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Layouts/ + partialRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Partials/ + templateRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Templates/ + } +} + + +######################## +### CONTENT ELEMENTS ### +######################## +plugin.bootstrap_package_contentelements { + view { + layoutRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Layouts/ContentElements/ + partialRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Partials/ContentElements/ + templateRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Templates/ContentElements/ + } +} + + +################################ +### BOOTSTRAP SCSS CONSTANTS ### +################################ +plugin.bootstrap_package.settings.scss { + primary = #eb3e4a + secondary = #013859 +} diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TypoScript/setup.typoscript.twig b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TypoScript/setup.typoscript.twig new file mode 100644 index 00000000..00a04208 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TypoScript/setup.typoscript.twig @@ -0,0 +1,30 @@ +###################### +#### DEPENDENCIES #### +###################### + + + +############## +#### PAGE #### +############## +page { + includeCSS { + theme = EXT:{{ package.extensionKey }}/Resources/Public/Scss/Theme/theme.scss + } + + includeJSLibs { + + } + + includeJS { + + } + + includeJSFooterlibs { + + } + + includeJSFooter { + {{ package.extensionKey }}_scripts = EXT:{{ package.extensionKey }}/Resources/Public/JavaScript/Dist/scripts.js + } +} diff --git a/resources/skeletons/BaseExtension/bootstrap_package/README.md.twig b/resources/skeletons/BaseExtension/bootstrap_package/README.md.twig new file mode 100644 index 00000000..8b095c79 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/README.md.twig @@ -0,0 +1,4 @@ +Sitepackage for the project "{{ package.title }}" +============================================================== + +Add some explanation here. diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/.htaccess b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/.htaccess new file mode 100644 index 00000000..93169e4e --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/.htaccess @@ -0,0 +1,2 @@ +Order deny,allow +Deny from all diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang.xlf.twig b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang.xlf.twig new file mode 100644 index 00000000..5aea2770 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang.xlf.twig @@ -0,0 +1,11 @@ + + + +
+ {{ package.author.name }} + {{ package.author.email }} +
+ + +
+
diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang_be.xlf.twig b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang_be.xlf.twig new file mode 100644 index 00000000..8b09912d --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang_be.xlf.twig @@ -0,0 +1,17 @@ + + + +
+ {{ package.author.name }} + {{ package.author.email }} +
+ + + Example + + + Normal + + +
+
diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang_db.xlf.twig b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang_db.xlf.twig new file mode 100644 index 00000000..5aea2770 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang_db.xlf.twig @@ -0,0 +1,11 @@ + + + +
+ {{ package.author.name }} + {{ package.author.email }} +
+ + +
+
diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Layouts/ContentElements/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Layouts/ContentElements/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Layouts/ContentElements/.gitkeep @@ -0,0 +1 @@ + diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Layouts/Page/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Layouts/Page/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Partials/ContentElements/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Partials/ContentElements/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Partials/ContentElements/.gitkeep @@ -0,0 +1 @@ + diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Partials/Page/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Partials/Page/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Partials/Page/.gitkeep @@ -0,0 +1 @@ + diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Templates/ContentElements/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Templates/ContentElements/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Templates/ContentElements/.gitkeep @@ -0,0 +1 @@ + diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Templates/Page/Example.html.twig b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Templates/Page/Example.html.twig new file mode 100644 index 00000000..2b67bb11 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Templates/Page/Example.html.twig @@ -0,0 +1,22 @@ + + + + +
+
+
+
Template file
+
+ typo3conf/ext/{{ package.extensionKey }}/Resources/Private/Templates/Page/Example.html +
+
Backend Configuration
+
+ typo3conf/ext/{{ package.extensionKey }}/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts/example.tsconfig +
+
+
+
+ + +
+ diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Css/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Css/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Css/.gitkeep @@ -0,0 +1 @@ + diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Fonts/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Fonts/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Fonts/.gitkeep @@ -0,0 +1 @@ + diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/BackendLayouts/example.svg b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/BackendLayouts/example.svg new file mode 100644 index 00000000..d05abec2 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/BackendLayouts/example.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/Extension.svg b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/Extension.svg new file mode 100644 index 00000000..d8536373 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/Extension.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/favicon.ico b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..46d4c14df35ee4ccdf7c5a7eba53f00bc4457963 GIT binary patch literal 1150 zcmaKszb^zq6vrP&t{`y*Vj}8oqXL6Y$R~|E{BN6xxSFH~V-8J?S315x+S4 zj-Y)ybmKo(YfpQ6?x1gZYOBicJEMBKKl2?Y;7851p!}yw*Ju2g^_YOA4@`k=u$$QG%PiuMovJt++@ORg$yF+-?obfjA|?e@V(Z#s}~VJtDD0 literal 0 HcmV?d00001 diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/logo-inverted.svg b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/logo-inverted.svg new file mode 100644 index 00000000..f465b080 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/logo-inverted.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/logo.svg b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/logo.svg new file mode 100644 index 00000000..dc1615ff --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Images/logo-inverted.svg b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Images/logo-inverted.svg new file mode 100644 index 00000000..f465b080 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Images/logo-inverted.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Images/logo.svg b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Images/logo.svg new file mode 100644 index 00000000..dc1615ff --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Images/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/JavaScript/Dist/scripts.js.twig b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/JavaScript/Dist/scripts.js.twig new file mode 100644 index 00000000..af832405 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/JavaScript/Dist/scripts.js.twig @@ -0,0 +1,6 @@ +/*! + * {{ package.title }} v1.0.0 ({{ package.author.homepage }}) + * Copyright 2017-{{ 'now'|date('Y') }} {{ package.author.name }} + * Licensed under the GPL-2.0-or-later license + */ +console.log("WE LOVE TYPO3"); diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/JavaScript/Src/main.js.twig b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/JavaScript/Src/main.js.twig new file mode 100644 index 00000000..a5e49024 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/JavaScript/Src/main.js.twig @@ -0,0 +1 @@ +console.log('WE LOVE TYPO3'); diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Scss/Theme/_variables.scss b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Scss/Theme/_variables.scss new file mode 100644 index 00000000..4a4e02e8 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Scss/Theme/_variables.scss @@ -0,0 +1,3 @@ +// +// Variables +// diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Scss/Theme/theme.scss.twig b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Scss/Theme/theme.scss.twig new file mode 100644 index 00000000..2cd35190 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Scss/Theme/theme.scss.twig @@ -0,0 +1,9 @@ +// +// Variables +// +@import "variables"; + +// +// Import needed Bootstrap Package Files +// +{% if package.typo3version < 10004000 %}@import "../../../../../bootstrap_package/Resources/Public/Scss/Theme/theme";{% else %}@import "EXT:bootstrap_package/Resources/Public/Scss/bootstrap5/theme";{% endif %} diff --git a/resources/skeletons/BaseExtension/bootstrap_package/composer.json.twig b/resources/skeletons/BaseExtension/bootstrap_package/composer.json.twig new file mode 100644 index 00000000..4669e4c1 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/composer.json.twig @@ -0,0 +1,21 @@ +{ + "name": "{{ package.vendorNameAlternative }}/{{ package.packageNameAlternative }}", + "type": "typo3-cms-extension", + "description": "{{ package.description}}", + "homepage": "{{ package.author.homepage }}", + "license": ["GPL-2.0-or-later"], + "keywords": ["TYPO3 CMS"], + "require": { + "bk2k/bootstrap-package": "{% if package.typo3version < 9000000 %}^10.0{% elseif package.typo3version < 10000000 %}^10.0 || ^11.0{% else %}^12.0{% endif %}" + }, + "autoload": { + "psr-4": { + "{{ package.vendorName }}\\{{ package.packageName }}\\": "Classes/" + } + }, + "extra": { + "typo3/cms": { + "extension-key": "{{ package.extensionKey }}" + } + } +} diff --git a/resources/skeletons/BaseExtension/bootstrap_package/ext_conf_template.txt.twig b/resources/skeletons/BaseExtension/bootstrap_package/ext_conf_template.txt.twig new file mode 100644 index 00000000..e87dc9ce --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/ext_conf_template.txt.twig @@ -0,0 +1,3 @@ +# +# Extension Configuration template +# diff --git a/resources/skeletons/BaseExtension/bootstrap_package/ext_emconf.php.twig b/resources/skeletons/BaseExtension/bootstrap_package/ext_emconf.php.twig new file mode 100644 index 00000000..14ebcae5 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/ext_emconf.php.twig @@ -0,0 +1,30 @@ + '{{ package.title }}', + 'description' => '{{ package.description }}', + 'category' => 'templates', + 'constraints' => [ + 'depends' => [ + 'bootstrap_package' => '{% if package.typo3version < 9000000 %}10.0.0-10.0.99{% elseif package.typo3version < 10000000 %}10.0.0-11.0.99{% else %}12.0.0-12.9.99{% endif %}', + ], + 'conflicts' => [ + ], + ], + 'autoload' => [ + 'psr-4' => [ + '{{ package.vendorName }}\\{{ package.packageName }}\\' => 'Classes', + ], + ], + 'state' => 'stable', + 'uploadfolder' => 0, + 'createDirs' => '', + 'clearCacheOnLoad' => 1, + 'author' => '{{ package.author.name }}', + 'author_email' => '{{ package.author.email }}', + 'author_company' => '{{ package.author.company }}', + 'version' => '1.0.0', +]; diff --git a/resources/skeletons/BaseExtension/bootstrap_package/ext_localconf.php.twig b/resources/skeletons/BaseExtension/bootstrap_package/ext_localconf.php.twig new file mode 100644 index 00000000..cc9f50b7 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/ext_localconf.php.twig @@ -0,0 +1,12 @@ +'); diff --git a/resources/skeletons/BaseExtension/bootstrap_package/ext_tables.php.twig b/resources/skeletons/BaseExtension/bootstrap_package/ext_tables.php.twig new file mode 100644 index 00000000..8eb918c9 --- /dev/null +++ b/resources/skeletons/BaseExtension/bootstrap_package/ext_tables.php.twig @@ -0,0 +1,2 @@ +Resources/', + sass: '<%= paths.resources %>Public/Scss/', + css: '<%= paths.resources %>Public/Css/', + fonts: '<%= paths.resources %>Public/Fonts/', + img: '<%= paths.resources %>Public/Images/', + js: '<%= paths.resources %>Public/JavaScript/' + }, + banner: '/*!\n' + + ' * {{ package.title }} v<%= pkg.version %> (<%= pkg.homepage %>)\n' + + ' * Copyright 2017-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' + + ' * Licensed under the <%= pkg.license %> license\n' + + ' */\n', + uglify: { + all: { + options: { + banner: '<%= banner %>', + mangle: true, + compress: true, + beautify: false + }, + files: { + "<%= paths.js %>/Dist/scripts.js": [ + "<%= paths.js %>Src/main.js" + ] + } + } + }, + sass: { + options: { + implementation: sass, + outputStyle: 'expanded', + precision: 8, + sourceMap: false + }, + layout: { + files: { + '<%= paths.css %>layout.css': '<%= paths.sass %>layout.scss' + } + } + }, + postcss: { + options: { + map: false, + processors: [ + require('autoprefixer')({ + browsers: [ + 'Last 2 versions', + 'Firefox ESR', + 'IE 9' + ] + }) + ] + }, + layout: { + src: '<%= paths.css %>layout.css' + } + }, + cssmin: { + options: { + keepSpecialComments: '*', + advanced: false + }, + layout: { + src: '<%= paths.css %>layout.css', + dest: '<%= paths.css %>layout.min.css' + } + }, + imagemin: { + extension: { + files: [{ + expand: true, + cwd: '<%= paths.resources %>', + src: [ + '**/*.{png,jpg,gif}' + ], + dest: '<%= paths.resources %>' + }] + } + }, + watch: { + options: { + livereload: true + }, + sass: { + files: '<%= paths.sass %>**/*.scss', + tasks: ['css'] + }, + javascript: { + files: '<%= paths.js %>Src/**/*.js', + tasks: ['js'] + } + } + }); + + /** + * Register tasks + // */ + grunt.loadNpmTasks('grunt-contrib-cssmin'); + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-contrib-imagemin'); + grunt.loadNpmTasks('grunt-postcss'); + grunt.loadNpmTasks('grunt-sass'); + + /** + * Grunt update task + */ + grunt.registerTask('css', ['sass', 'postcss', 'cssmin']); + grunt.registerTask('js', ['uglify']); + grunt.registerTask('build', ['js', 'css', 'imagemin']); + grunt.registerTask('default', ['build']); + +}; diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Build/package.json.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Build/package.json.twig new file mode 100644 index 00000000..a870947b --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Build/package.json.twig @@ -0,0 +1,28 @@ +{ + "name": "{{ package.vendorNameAlternative }}-{{ package.packageNameAlternative }}", + "description": "{{ package.description }}", + "repository": { + "type": "git", + "url": "{{ package.repositoryUrl }}" + }, + "homepage": "{{ package.author.homepage }}", + "author": "{{ package.author.name }}", + "version": "1.0.0", + "license": "GPL-2.0-or-later", + "devDependencies": { + "grunt": "^1.0.4", + "grunt-contrib-cssmin": "^3.0.0", + "grunt-contrib-uglify": "^4.0.1", + "grunt-contrib-watch": "^1.1.0", + "grunt-contrib-imagemin": "^3.1.0", + "grunt-postcss": "^0.9.0", + "grunt-sass": "^3.0.2", + "autoprefixer": "^9.5.0", + "node-sass": "^4.11.0" + }, + "scripts": { + "build": "./node_modules/.bin/grunt", + "css": "./node_modules/.bin/grunt css", + "watch": "./node_modules/.bin/grunt watch" + } +} diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Classes/.htaccess b/resources/skeletons/BaseExtension/fluid_styled_content/Classes/.htaccess new file mode 100644 index 00000000..93169e4e --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Classes/.htaccess @@ -0,0 +1,2 @@ +Order deny,allow +Deny from all diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Controller/.gitkeep b/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Controller/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Controller/.gitkeep @@ -0,0 +1 @@ + diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/.gitkeep b/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/.gitkeep @@ -0,0 +1 @@ + diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/Model/.gitkeep b/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/Model/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/Model/.gitkeep @@ -0,0 +1 @@ + diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/Repository/.gitkeep b/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/Repository/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/Repository/.gitkeep @@ -0,0 +1 @@ + diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Classes/ViewHelpers/.gitkeep b/resources/skeletons/BaseExtension/fluid_styled_content/Classes/ViewHelpers/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Classes/ViewHelpers/.gitkeep @@ -0,0 +1 @@ + diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/.htaccess b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/.htaccess new file mode 100644 index 00000000..93169e4e --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/.htaccess @@ -0,0 +1,2 @@ +Order deny,allow +Deny from all diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/RTE/Default.yaml.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/RTE/Default.yaml.twig new file mode 100644 index 00000000..5d5556da --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/RTE/Default.yaml.twig @@ -0,0 +1,42 @@ +imports: + - { resource: "EXT:rte_ckeditor/Configuration/RTE/Processing.yaml" } + - { resource: "EXT:rte_ckeditor/Configuration/RTE/Editor/Base.yaml" } + - { resource: "EXT:rte_ckeditor/Configuration/RTE/Editor/Plugins.yaml" } + +editor: + config: + contentsCss: "EXT:{{ package.extensionKey }}/Resources/Public/Css/rte.css" + + stylesSet: + - { name: "Lead", element: "p", attributes: { 'class': 'lead' } } + + toolbarGroups: + - { name: styles, groups: [ format, styles ] } + - { name: basicstyles, groups: [ basicstyles ] } + - { name: paragraph, groups: [ list, indent, blocks, align ] } + - "/" + - { name: links, groups: [ links ] } + - { name: clipboard, groups: [ clipboard, cleanup, undo ] } + - { name: editing, groups: [ spellchecker ] } + - { name: insert, groups: [ insert ] } + - { name: tools, groups: [ table, specialchar ] } + - { name: document, groups: [ mode ] } + + format_tags: "p;h1;h2;h3;h4;h5;pre" + + justifyClasses: + - text-left + - text-center + - text-right + - text-justify + + extraPlugins: + - justify + + removePlugins: + - image + + removeButtons: + - Anchor + - Underline + - Strike diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TCA/Overrides/pages.php.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TCA/Overrides/pages.php.twig new file mode 100644 index 00000000..672a2d1e --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TCA/Overrides/pages.php.twig @@ -0,0 +1,19 @@ + + + + diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts.tsconfig.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts.tsconfig.twig new file mode 100644 index 00000000..8213cfae --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts.tsconfig.twig @@ -0,0 +1,4 @@ +# +# BACKENDLAYOUTS +# + diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts/default.tsconfig.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts/default.tsconfig.twig new file mode 100644 index 00000000..a16a9db6 --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts/default.tsconfig.twig @@ -0,0 +1,29 @@ +# +# BACKENDLAYOUT: DEFAULT +# +mod { + web_layout { + BackendLayouts { + default { + title = LLL:EXT:{{ package.extensionKey }}/Resources/Private/Language/locallang_be.xlf:backend_layout.default + config { + backend_layout { + colCount = 1 + rowCount = 1 + rows { + 1 { + columns { + 1 { + name = LLL:EXT:{{ package.extensionKey }}/Resources/Private/Language/locallang_be.xlf:backend_layout.column.normal + colPos = 0 + } + } + } + } + } + } + icon = EXT:{{ package.extensionKey }}/Resources/Public/Images/BackendLayouts/default.png + } + } + } +} diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/RTE.tsconfig.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/RTE.tsconfig.twig new file mode 100644 index 00000000..38353247 --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/RTE.tsconfig.twig @@ -0,0 +1,8 @@ +############# +#### RTE #### +############# +RTE { + default { + preset = {{ package.extensionKey }} + } +} diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/TCEFORM.tsconfig.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/TCEFORM.tsconfig.twig new file mode 100644 index 00000000..55f97ce7 --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/TCEFORM.tsconfig.twig @@ -0,0 +1,11 @@ +# +# TCEFORM +# +TCEFORM { + pages { + + } + tt_content { + + } +} diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/TCEMAIN.tsconfig.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/TCEMAIN.tsconfig.twig new file mode 100644 index 00000000..9d4a5e4e --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/TCEMAIN.tsconfig.twig @@ -0,0 +1,6 @@ +# +# TCEMAIN +# +TCEMAIN { + +} diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/Helper/DynamicContent.typoscript.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/Helper/DynamicContent.typoscript.twig new file mode 100644 index 00000000..993b020b --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/Helper/DynamicContent.typoscript.twig @@ -0,0 +1,64 @@ +################################################ +#### DYNAMIC CONTENT LIB FOR USAGE IN FLUID #### +################################################ +# +# EXAMPLE +# --------------- +# |'}" /> +# +# +# COLUMN NUMBERS +# --------------- +# +# 0 = main +# 1 = left +# 2 = right +# 3 = border +# +################# +lib.dynamicContent = COA +lib.dynamicContent { + 5 = LOAD_REGISTER + 5 { + colPos.cObject = TEXT + colPos.cObject { + field = colPos + ifEmpty.cObject = TEXT + ifEmpty.cObject { + value.current = 1 + ifEmpty = 0 + } + } + pageUid.cObject = TEXT + pageUid.cObject { + field = pageUid + ifEmpty.data = TSFE:id + } + contentFromPid.cObject = TEXT + contentFromPid.cObject { + data = DB:pages:{register:pageUid}:content_from_pid + data.insertData = 1 + } + wrap.cObject = TEXT + wrap.cObject { + field = wrap + } + } + 20 = CONTENT + 20 { + table = tt_content + select { + includeRecordsWithoutDefaultTranslation = 1 + orderBy = sorting + where = {{ '{#colPos}={register:colPos}' }} + where.insertData = 1 + pidInList.data = register:pageUid + pidInList.override.data = register:contentFromPid + } + stdWrap { + dataWrap = {register:wrap} + required = 1 + } + } + 90 = RESTORE_REGISTER +} diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/constants.typoscript.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/constants.typoscript.twig new file mode 100644 index 00000000..5a38ef29 --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/constants.typoscript.twig @@ -0,0 +1,56 @@ +###################### +#### DEPENDENCIES #### +###################### + + + +############################## +#### FLUID STYLED CONTENT #### +############################## +styles { + templates { + layoutRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Layouts/ContentElements/ + partialRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Partials/ContentElements/ + templateRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Templates/ContentElements/ + } +} + + +############ +### PAGE ### +############ +page { + fluidtemplate { + layoutRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Layouts/Page/ + partialRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Partials/Page/ + templateRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Templates/Page/ + } + meta { + description = + author = + keywords = + viewport = width=device-width, initial-scale=1 + robots = index,follow + apple-mobile-web-app-capable = no + compatible = IE=edge + } + tracking { + google { + trackingID = + anonymizeIp = 1 + } + } +} + + +############## +### CONFIG ### +############## +config { + no_cache = 0 + removeDefaultJS = 0 + admPanel = 1 + prefixLocalAnchors = all + headerComment = build by sitepackagebuilder.com + sendCacheHeaders = 1 +} diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/setup.typoscript.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/setup.typoscript.twig new file mode 100644 index 00000000..1ed237f7 --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/setup.typoscript.twig @@ -0,0 +1,203 @@ +###################### +#### DEPENDENCIES #### +###################### + + + +################ +#### HELPER #### +################ + + + +############## +#### PAGE #### +############## +page = PAGE +page { + typeNum = 0 + shortcutIcon = EXT:{{ package.extensionKey }}/Resources/Public/Icons/favicon.ico + + 10 = FLUIDTEMPLATE + 10 { + # Template names will be generated automatically by converting the applied + # backend_layout, there is no explicit mapping necessary anymore. + # + # BackendLayout Key + # subnavigation_right_2_columns -> SubnavigationRight2Columns.html + # + # Backend Record + # uid: 1 -> 1.html + # + # Database Entry + # value: -1 -> None.html + # value: pagets__subnavigation_right_2_columns -> SubnavigationRight2Columns.html + templateName = TEXT + templateName { + cObject = TEXT + cObject { + data = pagelayout + required = 1 + case = uppercamelcase + split { + token = pagets__ + cObjNum = 1 + 1.current = 1 + } + } + ifEmpty = Default + } + templateRootPaths { + 0 = EXT:{{ package.extensionKey }}/Resources/Private/Templates/Page/ + 1 = {$page.fluidtemplate.templateRootPath} + } + partialRootPaths { + 0 = EXT:{{ package.extensionKey }}/Resources/Private/Partials/Page/ + 1 = {$page.fluidtemplate.partialRootPath} + } + layoutRootPaths { + 0 = EXT:{{ package.extensionKey }}/Resources/Private/Layouts/Page/ + 1 = {$page.fluidtemplate.layoutRootPath} + } + dataProcessing { + 10 = TYPO3\CMS\Frontend\DataProcessing\FilesProcessor + 10 { + references.fieldName = media + } + 20 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor + 20 { + levels = 2 + includeSpacer = 1 + as = mainnavigation + } + } + } + + meta { + viewport = {$page.meta.viewport} + robots = {$page.meta.robots} + apple-mobile-web-app-capable = {$page.meta.apple-mobile-web-app-capable} + description = {$page.meta.description} + description { + override.field = description + } + author = {$page.meta.author} + author { + override.field = author + } + keywords = {$page.meta.keywords} + keywords { + override.field = keywords + } + X-UA-Compatible = {$page.meta.compatible} + X-UA-Compatible { + attribute = http-equiv + } + + # OpenGraph Tags + og:title { + attribute = property + field = title + } + og:site_name { + attribute = property + data = TSFE:tmpl|setup|sitetitle + } + og:description = {$page.meta.description} + og:description { + attribute = property + field = description + } + og:image { + attribute = property + stdWrap.cObject = FILES + stdWrap.cObject { + references { + data = levelfield:-1, media, slide + } + maxItems = 1 + renderObj = COA + renderObj { + 10 = IMG_RESOURCE + 10 { + file { + import.data = file:current:uid + treatIdAsReference = 1 + width = 1280c + height = 720c + } + stdWrap { + typolink { + parameter.data = TSFE:lastImgResourceInfo|3 + returnLast = url + forceAbsoluteUrl = 1 + } + } + } + } + } + } + } + + includeCSSLibs { + + } + + includeCSS { + {{ package.extensionKey }}_layout = EXT:{{ package.extensionKey }}/Resources/Public/Css/layout.min.css + } + + includeJSLibs { + + } + + includeJS { + + } + + includeJSFooterlibs { + + } + + includeJSFooter { + {{ package.extensionKey }}_scripts = EXT:{{ package.extensionKey }}/Resources/Public/JavaScript/Dist/scripts.js + } +} + + +################ +#### CONFIG #### +################ +config { + absRefPrefix = auto + no_cache = {$config.no_cache} + uniqueLinkVars = 1 + pageTitleFirst = 1 + linkVars = L + prefixLocalAnchors = {$config.prefixLocalAnchors} + renderCharset = utf-8 + metaCharset = utf-8 + doctype = html5 + removeDefaultJS = {$config.removeDefaultJS} + inlineStyle2TempFile = 1 + admPanel = {$config.admPanel} + debug = 0 + cache_period = 86400 + sendCacheHeaders = {$config.sendCacheHeaders} + intTarget = + extTarget = + disablePrefixComment = 1 + index_enable = 1 + index_externals = 1 + index_metatags = 1 + headerComment = {$config.headerComment} + + // Disable Image Upscaling + noScaleUp = 1 + + // Compression and Concatenation of CSS and JS Files + compressJs = 0 + compressCss = 0 + concatenateJs = 0 + concatenateCss = 0 +} diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/README.md.twig b/resources/skeletons/BaseExtension/fluid_styled_content/README.md.twig new file mode 100644 index 00000000..8b095c79 --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/README.md.twig @@ -0,0 +1,4 @@ +Sitepackage for the project "{{ package.title }}" +============================================================== + +Add some explanation here. diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/.htaccess b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/.htaccess new file mode 100644 index 00000000..93169e4e --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/.htaccess @@ -0,0 +1,2 @@ +Order deny,allow +Deny from all diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang.xlf.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang.xlf.twig new file mode 100644 index 00000000..5aea2770 --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang.xlf.twig @@ -0,0 +1,11 @@ + + + +
+ {{ package.author.name }} + {{ package.author.email }} +
+ + +
+
diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang_be.xlf.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang_be.xlf.twig new file mode 100644 index 00000000..fb3e2d8e --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang_be.xlf.twig @@ -0,0 +1,17 @@ + + + +
+ {{ package.author.name }} + {{ package.author.email }} +
+ + + Default + + + Normal + + +
+
diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang_db.xlf.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang_db.xlf.twig new file mode 100644 index 00000000..5aea2770 --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang_db.xlf.twig @@ -0,0 +1,11 @@ + + + +
+ {{ package.author.name }} + {{ package.author.email }} +
+ + +
+
diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Layouts/ContentElements/.gitkeep b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Layouts/ContentElements/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Layouts/ContentElements/.gitkeep @@ -0,0 +1 @@ + diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Layouts/Page/Default.html.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Layouts/Page/Default.html.twig new file mode 100644 index 00000000..ad57953f --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Layouts/Page/Default.html.twig @@ -0,0 +1,21 @@ + + diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Partials/ContentElements/.gitkeep b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Partials/ContentElements/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Partials/ContentElements/.gitkeep @@ -0,0 +1 @@ + diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Partials/Page/.gitkeep b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Partials/Page/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Partials/Page/.gitkeep @@ -0,0 +1 @@ + diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Templates/ContentElements/.gitkeep b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Templates/ContentElements/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Templates/ContentElements/.gitkeep @@ -0,0 +1 @@ + diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Templates/Page/Default.html.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Templates/Page/Default.html.twig new file mode 100644 index 00000000..312fc91f --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Templates/Page/Default.html.twig @@ -0,0 +1,19 @@ + + + +
+
+
Template file
+
+ typo3conf/ext/{{ package.extensionKey }}/Resources/Private/Templates/Page/Default.html +
+
Backend Configuration
+
+ typo3conf/ext/{{ package.extensionKey }}/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts/default.tsconfig +
+
+
+ + + +
diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Css/layout.css b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Css/layout.css new file mode 100644 index 00000000..e69de29b diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Css/layout.min.css b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Css/layout.min.css new file mode 100644 index 00000000..e69de29b diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Css/rte.css.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Css/rte.css.twig new file mode 100644 index 00000000..1ce5278d --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Css/rte.css.twig @@ -0,0 +1,3 @@ +/** + * Created from sitepackagebuilder.com + */ diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Fonts/.gitkeep b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Fonts/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Fonts/.gitkeep @@ -0,0 +1 @@ + diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Icons/Extension.svg b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Icons/Extension.svg new file mode 100644 index 00000000..d8536373 --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Icons/Extension.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Icons/favicon.ico b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Icons/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..46d4c14df35ee4ccdf7c5a7eba53f00bc4457963 GIT binary patch literal 1150 zcmaKszb^zq6vrP&t{`y*Vj}8oqXL6Y$R~|E{BN6xxSFH~V-8J?S315x+S4 zj-Y)ybmKo(YfpQ6?x1gZYOBicJEMBKKl2?Y;7851p!}yw*Ju2g^_YOA4@`k=u$$QG%PiuMovJt++@ORg$yF+-?obfjA|?e@V(Z#s}~VJtDD0 literal 0 HcmV?d00001 diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Images/BackendLayouts/default.png b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Images/BackendLayouts/default.png new file mode 100644 index 0000000000000000000000000000000000000000..0bed87019c8f61d46b9493157358054e2af23994 GIT binary patch literal 182 zcmeAS@N?(olHy`uVBq!ia0vp^MnLSq!3HEFuBuc6saj7L$B>N1x3?X6TLMH_4jxZ? zT5x1PQ{RuD+D*PICg`zVW=f0BUR&At{>+(;^8W94Jl%8dr;Y8Sc&>{gi!@z=JC+If mD$a5;Y0V%};H~cVZu$S++?AJ4w7LNu!r '{{ package.title }}', + 'description' => '{{ package.description }}', + 'category' => 'templates', + 'constraints' => [ + 'depends' => [ + 'typo3' => '{% if package.typo3version < 9000000 %}8.7.0-8.7.99{% elseif package.typo3version < 10000000 %}9.5.0-9.5.99{% elseif package.typo3version < 11000000 %}10.4.0-10.4.99{% else %}11.5.0-11.5.99{% endif %}', + 'fluid_styled_content' => '{% if package.typo3version < 9000000 %}8.7.0-8.7.99{% elseif package.typo3version < 10000000 %}9.5.0-9.5.99{% elseif package.typo3version < 11000000 %}10.4.0-10.4.99{% else %}11.5.0-11.5.99{% endif %}', + 'rte_ckeditor' => '{% if package.typo3version < 9000000 %}8.7.0-8.7.99{% elseif package.typo3version < 10000000 %}9.5.0-9.5.99{% elseif package.typo3version < 11000000 %}10.4.0-10.4.99{% else %}11.5.0-11.5.99{% endif %}', + ], + 'conflicts' => [ + ], + ], + 'autoload' => [ + 'psr-4' => [ + '{{ package.vendorName }}\\{{ package.packageName }}\\' => 'Classes', + ], + ], + 'state' => 'stable', + 'uploadfolder' => 0, + 'createDirs' => '', + 'clearCacheOnLoad' => 1, + 'author' => '{{ package.author.name }}', + 'author_email' => '{{ package.author.email }}', + 'author_company' => '{{ package.author.company }}', + 'version' => '1.0.0', +]; diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/ext_localconf.php.twig b/resources/skeletons/BaseExtension/fluid_styled_content/ext_localconf.php.twig new file mode 100644 index 00000000..cc9f50b7 --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/ext_localconf.php.twig @@ -0,0 +1,12 @@ +'); diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/ext_tables.php.twig b/resources/skeletons/BaseExtension/fluid_styled_content/ext_tables.php.twig new file mode 100644 index 00000000..8eb918c9 --- /dev/null +++ b/resources/skeletons/BaseExtension/fluid_styled_content/ext_tables.php.twig @@ -0,0 +1,2 @@ +serializer = $serializer; + $this->sitepackageGenerator = $sitepackageGenerator; + } + + /** + * @Route("/", methods={"POST"}) + * @SWG\Parameter( + * name="sitepackage", + * in="body", + * @Model(type=Sitepackage::class) + * ) + * @SWG\Response( + * response=200, + * description="Successfully generated.", + * @SWG\Schema(type="file") + * ) + * @SWG\Response( + * response=400, + * description="Request malformed." + * ) + * @SWG\Tag(name="sitepackage") + */ + public function createSitepackage(Request $request): Response + { + $content = $request->getContent(); + /** @var Sitepackage $sitepackage */ + $sitepackage = $this->serializer->deserialize($content, Sitepackage::class, 'json'); + $this->validateObject($sitepackage); + $this->sitepackageGenerator->create($sitepackage); + $filename = $this->sitepackageGenerator->getFilename(); + BinaryFileResponse::trustXSendfileTypeHeader(); + + return $this + ->file($this->sitepackageGenerator->getZipPath(), StringUtility::toASCII($filename)) + ->deleteFileAfterSend(true); + } + + /** + * @param Sitepackage $object + */ + protected function validateObject(Sitepackage $object): void + { + $validator = Validation::createValidatorBuilder() + ->enableAnnotationMapping() + ->getValidator() + ; + $violations = $validator->validate($object); + + if ($violations->count() > 0) { + $messages = ''; + \iterator_apply($violations, function (\Iterator $iterator) use ($messages) { + $messages .= $iterator->current()->getMessage() . "\n"; + return true; + }); + throw new BadRequestHttpException(trim($messages)); + } + } +} diff --git a/src/Controller/EntryPointController.php b/src/Controller/EntryPointController.php index ccff285d..fec7c32f 100644 --- a/src/Controller/EntryPointController.php +++ b/src/Controller/EntryPointController.php @@ -36,6 +36,8 @@ class EntryPointController extends AbstractController private const ENTRY_POINTS = [ // 'slug' => 'route', 'composer-helper' => 'composer-helper', + 'sitepackage' => 'wizards_sitepackage', + 'sitepackage-builder' => 'wizards_sitepackage', ]; #[Route('/go/{slug}', requirements: ['slug' => '.+'])] diff --git a/src/Controller/Wizards/SitepackageController.php b/src/Controller/Wizards/SitepackageController.php new file mode 100644 index 00000000..11579be3 --- /dev/null +++ b/src/Controller/Wizards/SitepackageController.php @@ -0,0 +1,226 @@ +render( + 'default/wizards/sitepackage/index.html.twig', + [] + ); + } + + /** + * @Route("/new/", name="wizards_sitepackage_new") + */ + public function new(Request $request): Response + { + $session = $request->getSession(); + + $this->setAdvanced($session, false); + $this->setConfiguration($session, new SitepackageDto()); + + return $this->redirectToRoute('wizards_sitepackage_edit'); + } + + /** + * @Route("/edit/", name="wizards_sitepackage_edit") + */ + public function edit(Request $request): Response + { + $session = $request->getSession(); + + try { + $configuration = $this->getConfiguration($session); + } catch (UnexpectedValueException $th) { + return $this->redirectToRoute('wizards_sitepackage_new'); + } + + $form = $this->createSitepackageForm($configuration, $this->getAdvanced($session)); + $form->handleRequest($request); + + if ($form->isSubmitted()) { + if ($form->has('simple') && ($simple = $form->get('simple')) instanceof SubmitButton && $simple->isClicked()) { + $this->setAdvanced($session, false); + $this->setConfiguration($session, $configuration); + + return $this->redirectToRoute('wizards_sitepackage_edit'); + } + if ($form->has('advanced') && ($advanced = $form->get('advanced')) instanceof SubmitButton && $advanced->isClicked()) { + $this->setAdvanced($session, true); + $this->setConfiguration($session, $configuration); + + return $this->redirectToRoute('wizards_sitepackage_edit'); + } + + if ($form->isValid()) { + $this->setConfiguration($session, $configuration); + + return $this->redirectToRoute('wizards_sitepackage_success'); + } + } + + return $this->render( + 'default/wizards/sitepackage/edit.html.twig', + [ + 'form' => $form->createView(), + ] + ); + } + + /** + * @Route("/success/", name="wizards_sitepackage_success") + */ + public function success(Request $request): Response + { + $session = $request->getSession(); + + try { + $configuration = $this->getConfiguration($session); + } catch (UnexpectedValueException $th) { + return $this->redirectToRoute('wizards_sitepackage_new'); + } + + $sitepackage = SitepackageFactory::fromDto($configuration); + $this->setSitepackage($session, $sitepackage); + + return $this->render( + 'default/wizards/sitepackage/success.html.twig', + [ + 'sitepackage' => $sitepackage + ] + ); + } + + /** + * @Route("/download/", name="wizards_sitepackage_download") + */ + public function download(Request $request, SitepackageGenerator $sitepackageGenerator): Response + { + $session = $request->getSession(); + + try { + $sitepackage = $this->getSitepackage($session); + } catch (UnexpectedValueException $th) { + return $this->redirectToRoute('wizards_sitepackage_new'); + } + + $sitepackageGenerator->create($sitepackage); + $filename = $sitepackageGenerator->getFilename(); + + BinaryFileResponse::trustXSendfileTypeHeader(); + + return $this + ->file($sitepackageGenerator->getZipPath(), StringUtility::toASCII($filename)) + ->deleteFileAfterSend(true); + } + + private function createSitepackageForm(SitepackageDto $configuration, bool $advanced = false): FormInterface + { + return $this->createForm( + SitepackageType::class, + $configuration, + [ + 'action' => $this->generateUrl('wizards_sitepackage_edit'), + 'advanced' => $advanced, + ] + ); + } + + private function getAdvanced(SessionInterface $session): bool + { + return $session->get('sitepackage_advanced') === true; + } + + private function setAdvanced(SessionInterface $session, bool $advanced): void + { + $session->set('sitepackage_advanced', $advanced); + } + + private function getConfiguration(SessionInterface $session): SitepackageDto + { + $configuration = $session->get('sitepackage_configuration'); + + if ($configuration === null || !($configuration instanceof SitepackageDto)) { + $this->addFlash( + 'danger', + 'Whoops, we could not find the package configuration. Please submit the configuration again.' + ); + + throw new UnexpectedValueException('Invalid or missing configuration.', 1638038672); + } + + return $configuration; + } + + private function setConfiguration(SessionInterface $session, SitepackageDto $configuration): void + { + $session->set('sitepackage_configuration', $configuration); + } + + private function getSitepackage(SessionInterface $session): Sitepackage + { + $sitepackage = $session->get('sitepackage'); + + if ($sitepackage === null || !($sitepackage instanceof Sitepackage)) { + $this->addFlash( + 'danger', + 'Whoops, we could not find the Sitepackage. Please submit the configuration again.' + ); + + throw new UnexpectedValueException('Invalid or missing Sitepackage.', 1638038673); + } + + return $sitepackage; + } + + private function setSitepackage(SessionInterface $session, Sitepackage $sitepackage): void + { + $session->set('sitepackage', $sitepackage); + } +} diff --git a/src/Entity/Package/Author.php b/src/Entity/Package/Author.php new file mode 100644 index 00000000..b7a67c8d --- /dev/null +++ b/src/Entity/Package/Author.php @@ -0,0 +1,169 @@ +name; + } + + /** + * @param string $name + * @return Author + */ + public function setName(string $name) + { + $this->name = $name; + + return $this; + } + + /** + * @return string + */ + public function getEmail(): string + { + return $this->email; + } + + /** + * @param string $email + * @return Author + */ + public function setEmail(string $email) + { + $this->email = $email; + + return $this; + } + + /** + * @return string + */ + public function getCompany(): string + { + return $this->company; + } + + /** + * @param string $company + * @return Author + */ + public function setCompany(string $company) + { + $this->company = $company; + + return $this; + } + + /** + * @return string + */ + public function getHomepage(): string + { + return $this->homepage; + } + + /** + * @param string $homepage + * @return Author + */ + public function setHomepage(string $homepage) + { + $this->homepage = $homepage; + + return $this; + } + + /** + * @return array + */ + public function jsonSerialize(): array + { + return [ + 'name' => $this->getName(), + 'email' => $this->getEmail(), + 'company' => $this->getCompany(), + 'homepage' => $this->getHomepage(), + ]; + } +} diff --git a/src/Entity/Sitepackage.php b/src/Entity/Sitepackage.php new file mode 100644 index 00000000..58b8340e --- /dev/null +++ b/src/Entity/Sitepackage.php @@ -0,0 +1,370 @@ +company if empty") + * @Serializer\Type("string") + * @var string + */ + private string $vendorName = ''; + + /** + * @Assert\Length( + * allowEmptyString=true, + * min=3 + * ) + * @Assert\Regex( + * pattern="/^[a-z][a-z0-9-]+$/", + * message="Only letters, numbers and hyphens are allowed" + * ) + * @SWG\Property(type="string", example="bk2k", default="generated from vendor name if empty") + * @Serializer\Type("string") + * @var string + */ + private string $composerVendorName = ''; + + /** + * @Assert\NotBlank( + * message="Please enter a title for your Sitepackage" + * ) + * @Assert\Length( + * min=3 + * ) + * @Assert\Regex( + * pattern="/^[A-Za-z0-9\x7f-\xff .:&-]+$/", + * message="Only letters, numbers and spaces are allowed" + * ) + * + * @SWG\Property(type="string", example="My Sitepackage") + * @Serializer\Type("string") + * @var string + */ + private string $title; + + /** + * @Assert\Regex( + * pattern="/^[A-Za-z0-9\x7f-\xff .,:!?&-]+$/", + * message="Only letters, numbers and spaces are allowed" + * ) + * + * @SWG\Property(type="string", example="Project Configuration for Client") + * @Serializer\Type("string") + * @var string + */ + private string $description; + + /** + * @Assert\Length( + * allowEmptyString=true, + * min=3 + * ) + * @Assert\Regex( + * pattern="/^[A-Z][A-Za-z0-9]+$/", + * message="Only letters and numbers are allowed" + * ) + * @SWG\Property(type="string", example="MySitepackage", default="generated from title if empty") + * @Serializer\Type("string") + * @var string + */ + private string $packageName = ''; + + /** + * @Assert\Length( + * allowEmptyString=true, + * min=3 + * ) + * @Assert\Regex( + * pattern="/^[a-z][a-z0-9-]+$/", + * message="Only lower case letters, numbers and hyphens are allowed" + * ) + * @SWG\Property(type="string", example="my-sitepackage", default="generated from package name if empty") + * @Serializer\Type("string") + * @var string + */ + private string $composerProjectName = ''; + + /** + * @Assert\Length( + * allowEmptyString=true, + * min=3 + * ) + * @Assert\Regex( + * pattern="/^[a-z][a-z0-9_]+$/", + * message="Only lower case letters, numbers and undscores are allowed" + * ) + * @SWG\Property(type="string", example="my_sitepackage", default="generated from package name if empty") + * @Serializer\Type("string") + * @var string + */ + private string $extensionKey = ''; + + /** + * @Assert\Url + * @SWG\Property(type="string", example="https://github.com/benjaminkott/packagebuilder") + * + * @Serializer\Type("string") + * @var string + */ + private string $repositoryUrl = ''; + + /** + * @Assert\Valid + * @Serializer\Type(Author::class) + */ + private Author $author; + + public function __construct() + { + $this->author = new Author(); + } + + public function getTypo3Version(): int + { + return $this->typo3Version; + } + + public function setTypo3Version(int $typo3Version): self + { + $this->typo3Version = $typo3Version; + + return $this; + } + + public function getBasePackage(): string + { + return $this->basePackage; + } + + public function setBasePackage(string $basePackage): self + { + $this->basePackage = $basePackage; + + return $this; + } + + public function getVendorName(): string + { + if ($this->vendorName === '') { + return StringUtility::stringToUpperCamelCase($this->getAuthor()->getCompany()); + } + + return $this->vendorName; + } + + public function setVendorName(string $vendorName): self + { + if ($this->getVendorName() !== $vendorName) { + $this->vendorName = StringUtility::stringToUpperCamelCase($vendorName); + } + + return $this; + } + + public function getComposerVendorName(): string + { + if ($this->composerVendorName === '') { + return StringUtility::camelCaseToLowerCaseDashed($this->getVendorName()); + } + + return $this->composerVendorName; + } + + public function setComposerVendorName(string $composerVendorName): self + { + if ($this->getComposerVendorName() !== $composerVendorName) { + $this->composerVendorName = StringUtility::camelCaseToLowerCaseDashed($composerVendorName); + } + + return $this; + } + + public function getTitle(): string + { + return $this->title; + } + + public function setTitle(string $title): self + { + $this->title = $title; + + return $this; + } + + public function getDescription(): string + { + return $this->description; + } + + public function setDescription(string $description): self + { + $this->description = $description; + + return $this; + } + + public function getPackageName(): string + { + if ($this->packageName === '') { + return StringUtility::stringToUpperCamelCase($this->getTitle()); + } + + return $this->packageName; + } + + public function setPackageName(string $packageName): self + { + if ($this->getPackageName() !== $packageName) { + $this->packageName = StringUtility::stringToUpperCamelCase($packageName); + } + + return $this; + } + + public function getComposerProjectName(): string + { + if ($this->composerProjectName === '') { + return StringUtility::camelCaseToLowerCaseDashed($this->getPackageName()); + } + + return $this->composerProjectName; + } + + public function setComposerProjectName(string $composerProjectName): self + { + if ($this->getComposerProjectName() !== $composerProjectName) { + $this->composerProjectName = StringUtility::camelCaseToLowerCaseDashed($composerProjectName); + } + + return $this; + } + + public function getExtensionKey(): string + { + if ($this->extensionKey === '') { + return StringUtility::camelCaseToLowerCaseUnderscored($this->getPackageName()); + } + + return $this->extensionKey; + } + + public function setExtensionKey(string $extensionKey): self + { + if ($this->getExtensionKey() !== $extensionKey) { + $this->extensionKey = StringUtility::camelCaseToLowerCaseUnderscored($extensionKey); + } + + return $this; + } + + public function getRepositoryUrl(): string + { + return $this->repositoryUrl; + } + + public function setRepositoryUrl(string $repositoryUrl): self + { + $this->repositoryUrl = $repositoryUrl; + + return $this; + } + + public function getAuthor(): Author + { + return $this->author; + } + + public function setAuthor(Author $author): self + { + $this->author = $author; + + return $this; + } + + /** + * @return array + */ + public function jsonSerialize(): array + { + return [ + 'typo3Version' => $this->getTypo3Version(), + 'basePackage' => $this->getBasePackage(), + 'vendorName' => $this->getVendorName(), + 'composerVendorName' => $this->getComposerVendorName(), + 'title' => $this->getTitle(), + 'description' => $this->getDescription(), + 'packageName' => $this->getPackageName(), + 'composerProjectName' => $this->getComposerProjectName(), + 'extensionKey' => $this->getExtensionKey(), + 'repositoryUrl' => $this->getRepositoryUrl(), + 'author' => $this->getAuthor(), + ]; + } +} diff --git a/src/Enum/BasePackageEnum.php b/src/Enum/BasePackageEnum.php new file mode 100644 index 00000000..bd8f5adc --- /dev/null +++ b/src/Enum/BasePackageEnum.php @@ -0,0 +1,35 @@ + 'Bootstrap Package', + self::OPTION_FLUID_STYLED_CONTENT => 'Fluid Styled Content', + ]; +} diff --git a/src/Enum/Typo3VersionEnum.php b/src/Enum/Typo3VersionEnum.php new file mode 100644 index 00000000..c70ffd4a --- /dev/null +++ b/src/Enum/Typo3VersionEnum.php @@ -0,0 +1,39 @@ + '11.5 LTS', + self::OPTION_10 => '10.4 LTS', + self::OPTION_9 => '9.5 ELTS', + self::OPTION_8 => '8.7 ELTS', + ]; +} diff --git a/src/Factory/SitepackageFactory.php b/src/Factory/SitepackageFactory.php new file mode 100644 index 00000000..73c16f9a --- /dev/null +++ b/src/Factory/SitepackageFactory.php @@ -0,0 +1,61 @@ +setTypo3Version($dto->typo3Version) + ->setBasePackage($dto->basePackage) + ->setVendorName($dto->vendorName ?? '') + ->setComposerVendorName($dto->composerVendorName ?? '') + ->setTitle($dto->title ?? '') + ->setDescription($dto->description ?? '') + ->setPackageName($dto->packageName ?? '') + ->setComposerProjectName($dto->composerProjectName ?? '') + ->setExtensionKey($dto->extensionKey ?? '') + ->setRepositoryUrl($dto->repositoryUrl ?? '') + ->getAuthor() + ->setName($dto->name ?? '') + ->setEmail($dto->email ?? '') + ->setCompany($dto->company ?? '') + ->setHomepage($dto->homepage ?? '') + ; + + return $sitepackage; + } + + public static function fromEntity(Sitepackage $sitepackage): SitepackageDto + { + $dto = SitepackageDto::fromEntity($sitepackage); + + return $dto; + } +} diff --git a/src/Form/Dto/SitepackageDto.php b/src/Form/Dto/SitepackageDto.php new file mode 100644 index 00000000..81910bae --- /dev/null +++ b/src/Form/Dto/SitepackageDto.php @@ -0,0 +1,162 @@ +typo3Version = $entity->getTypo3Version(); + $dto->basePackage = $entity->getBasePackage(); + $dto->vendorName = $entity->getVendorName(); + $dto->composerVendorName = $entity->getComposerVendorName(); + $dto->title = $entity->getTitle(); + $dto->description = $entity->getDescription(); + $dto->packageName = $entity->getPackageName(); + $dto->composerProjectName = $entity->getComposerProjectName(); + $dto->extensionKey = $entity->getExtensionKey(); + $dto->repositoryUrl = $entity->getRepositoryUrl(); + $dto->name = $entity->getAuthor()->getName(); + $dto->email = $entity->getAuthor()->getEmail(); + $dto->company = $entity->getAuthor()->getCompany(); + $dto->homepage = $entity->getAuthor()->getHomepage(); + + return $dto; + } +} diff --git a/src/Form/SitepackageType.php b/src/Form/SitepackageType.php new file mode 100644 index 00000000..6835043b --- /dev/null +++ b/src/Form/SitepackageType.php @@ -0,0 +1,191 @@ +setAction(is_string($action = $options['action']) ? $action : '') + ->add('typo3Version', Typo3VersionType::class, [ + 'label' => 'TYPO3 Version', + 'label_attr' => ['class' => 'w-auto pe-2'], + 'expanded' => true, + 'row_attr' => ['class' => 'd-inline-flex flex-column w-50'], + ]) + ->add('basePackage', BasePackageType::class, [ + 'label' => 'Base Package', + 'label_attr' => ['class' => 'w-auto me-2'], + 'expanded' => true, + 'row_attr' => ['class' => 'd-inline-flex flex-column w-50'], + ]) + ->add('title', TextType::class, [ + 'attr' => [ + 'autocomplete' => 'off', + 'placeholder' => 'My Sitepackage', + ] + ]) + ->add('description', TextareaType::class, [ + 'required' => false, + 'attr' => [ + 'autocomplete' => 'off', + 'placeholder' => 'Optional description for the use of this sitepackage', + ] + ]) + ->add('repositoryUrl', TextType::class, [ + 'label' => 'Repository URL', + 'required' => false, + 'attr' => [ + 'autocomplete' => 'off', + 'placeholder' => 'https://github.com/username/my_sitepackage', + ] + ]) + ; + + if ($advanced) { + $builder + ->add('composerName', TextType::class, [ + 'label' => 'Composer Name', + 'required' => false, + 'attr' => [ + 'autocomplete' => 'off', + 'placeholder' => 'my-company/my-sitepackage', + ], + ]) + ->add('psr4Namespace', TextType::class, [ + 'label' => 'PSR-4 Namespace', + 'required' => false, + 'attr' => [ + 'autocomplete' => 'off', + 'placeholder' => 'MyCompany\MySitepackage', + ], + ]) + ->add('extensionKey', TextType::class, [ + 'label' => 'Extension Key', + 'required' => false, + 'attr' => [ + 'autocomplete' => 'off', + 'placeholder' => 'my_sitepackage', + ], + ]) + ; + } + + $builder + ->add('name', TextType::class, [ + 'attr' => [ + 'autocomplete' => 'on', + 'placeholder' => 'John Doe', + ], + ]) + ->add('email', EmailType::class, [ + 'attr' => [ + 'autocomplete' => 'on', + 'placeholder' => 'john.doe@example.com', + ], + ]) + ->add('company', TextType::class, [ + 'attr' => [ + 'autocomplete' => 'on', + 'placeholder' => 'My Company', + ], + ]) + ->add('homepage', TextType::class, [ + 'attr' => [ + 'autocomplete' => 'on', + 'placeholder' => 'https://www.example.com', + ], + ]) + ->add( + 'save', + SubmitType::class, + [ + 'label' => 'Create Sitepackage', + //'icon' => 'floppy-disk', + 'attr' => ['class' => 'btn-primary'], + 'row_attr' => ['class' => 'd-inline-flex'], + ] + ) + ; + + if ($advanced) { + $builder->add( + 'simple', + SubmitType::class, + [ + 'label' => 'Simple Configuration', + //'icon' => 'pencil', + 'attr' => ['class' => 'btn-secondary'], + 'row_attr' => ['class' => 'd-inline-flex ms-1'], + 'validate' => false, + ] + ); + } else { + $builder->add( + 'advanced', + SubmitType::class, + [ + 'label' => 'Advanced Configuration', + //'icon' => 'pencil', + 'attr' => ['class' => 'btn-secondary'], + 'row_attr' => ['class' => 'd-inline-flex ms-1'], + 'validate' => false, + ] + ); + } + } + + /** + * {@inheritdoc} + */ + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => SitepackageDto::class, + 'advanced' => false, + ]); + + $resolver->setAllowedTypes('advanced', 'bool'); + } +} diff --git a/src/Form/Type/BasePackageType.php b/src/Form/Type/BasePackageType.php new file mode 100644 index 00000000..88bfbba9 --- /dev/null +++ b/src/Form/Type/BasePackageType.php @@ -0,0 +1,50 @@ +setDefaults([ + 'choices' => $choices, + ]); + } + + public function getParent() + { + return ChoiceType::class; + } +} diff --git a/src/Form/Type/Typo3VersionType.php b/src/Form/Type/Typo3VersionType.php new file mode 100644 index 00000000..1024eb70 --- /dev/null +++ b/src/Form/Type/Typo3VersionType.php @@ -0,0 +1,54 @@ + $name) { + if ($option >= self::LOWEST_SUPPORTED_VERSION) { + $choices['TYPO3 ' . $name] = $option; + } + } + + $resolver->setDefaults([ + 'choices' => $choices, + ]); + } + + public function getParent() + { + return ChoiceType::class; + } +} diff --git a/src/Menu/MenuBuilder.php b/src/Menu/MenuBuilder.php index c57d259a..776fdb70 100644 --- a/src/Menu/MenuBuilder.php +++ b/src/Menu/MenuBuilder.php @@ -48,6 +48,20 @@ public function mainDefault(array $options): ItemInterface 'label' => 'Release Notes', ] ); + $wizards = $menu->addChild( + 'wizards', + [ + 'route' => 'wizards_sitepackage', + 'label' => 'Wizards' + ] + ); + $wizards->addChild( + 'wizards-sitepackage', + [ + 'route' => 'wizards_sitepackage', + 'label' => 'Sitepackage Builder' + ] + ); $composer = $menu->addChild( 'composer', [ diff --git a/src/Service/SitepackageGenerator.php b/src/Service/SitepackageGenerator.php new file mode 100644 index 00000000..ffb1ad84 --- /dev/null +++ b/src/Service/SitepackageGenerator.php @@ -0,0 +1,110 @@ +getExtensionKey(); + $this->filename = $extensionKey . '.zip'; + $sourceDir = __DIR__ . '/../../resources/skeletons/BaseExtension/' . $package->getBasePackage() . '/'; + $this->zipPath = is_string($zipPath = tempnam(sys_get_temp_dir(), $this->filename)) ? $zipPath : $this->filename; + $fileList = FileUtility::listDirectory($sourceDir); + + $zipFile = new \ZipArchive(); + $opened = $zipFile->open($this->zipPath, \ZipArchive::CREATE); + if ($opened === true) { + foreach ($fileList as $file) { + if ($file !== $this->zipPath && file_exists($file)) { + $baseFileName = $this->createRelativeFilePath($file, $sourceDir); + if (is_dir($file)) { + $zipFile->addEmptyDir($baseFileName); + } elseif (!$this->isTwigFile($file)) { + $zipFile->addFile($file, $baseFileName); + } else { + $content = $this->getFileContent($file, $package); + $nameInZip = $this->removeTwigExtension($baseFileName); + $zipFile->addFromString($nameInZip, $content); + } + } + } + $zipFile->close(); + } + } + + public function getZipPath(): string + { + return $this->zipPath; + } + + public function getFilename(): string + { + return $this->filename; + } + + private function getFileContent(string $file, Sitepackage $package): string + { + $content = file_get_contents($file); + $fileUniqueId = uniqid('file'); + $twig = new Environment(new ArrayLoader([$fileUniqueId => $content])); + $rendered = $twig->render( + $fileUniqueId, + [ + 'package' => $package, + 'timestamp' => time() + ] + ); + + return $rendered; + } + + private function isTwigFile(string $file): bool + { + $pathinfo = pathinfo($file); + + return ($pathinfo['extension'] ?? '') === 'twig'; + } + + protected function createRelativeFilePath(string $file, string $sourceDir): string + { + return substr($file, strlen($sourceDir)); + } + + protected function removeTwigExtension(string $baseFileName): string + { + return substr($baseFileName, 0, -5); + } +} diff --git a/src/Twig/Extension/VersionNumberExtension.php b/src/Twig/Extension/VersionNumberExtension.php new file mode 100644 index 00000000..d991a9d9 --- /dev/null +++ b/src/Twig/Extension/VersionNumberExtension.php @@ -0,0 +1,62 @@ + + */ + public static function listDirectory(string $dir, bool $filesOnly = false): array + { + $result = []; + $root = is_array($root = scandir($dir)) ? $root : []; + foreach ($root as $value) { + if ($value === '.' || $value === '..') { + continue; + } + if (is_file("$dir$value")) { + $result[] = "$dir$value"; + + continue; + } + if (is_dir("$dir$value") && !($filesOnly)) { + $result[] = "$dir$value/"; + } + foreach (self::listDirectory("$dir$value/") as $subValue) { + $result[] = $subValue; + } + } + + return $result; + } +} diff --git a/src/Utility/StringUtility.php b/src/Utility/StringUtility.php new file mode 100644 index 00000000..69494a18 --- /dev/null +++ b/src/Utility/StringUtility.php @@ -0,0 +1,103 @@ + {% if communityVersions|length > 0 %}Download TYPO3{% endif %} Try TYPO3 + Create a Sitepackage

{% endframe %} diff --git a/templates/default/wizards/sitepackage/edit.html.twig b/templates/default/wizards/sitepackage/edit.html.twig new file mode 100644 index 00000000..76fb0b12 --- /dev/null +++ b/templates/default/wizards/sitepackage/edit.html.twig @@ -0,0 +1,18 @@ +{% extends 'layout.html.twig' %} +{% block title %}Create your own TYPO3 Sitepackage{% endblock %} +{% block body %} + + {% frame with { color: 'dark', height: 'small', center: true, title: 'Create your own Sitepackage', titleSize: 1, backgroundImage: asset("assets/Images/keyvisual.png") } %} +

+ Awesome you made it here! Just a few more details about your + project and your own Sitepackage is ready for download. +

+ {% endframe %} + + {% frame with { id: 'configuration', indent: true, title: 'Configuration' } %} + {{ form(form, {'attr': {'novalidate': 'novalidate'}}) }} + {% endframe %} + + {% include 'default/wizards/sitepackage/partials/privacy-footer.html.twig' %} + +{% endblock %} diff --git a/templates/default/wizards/sitepackage/index.html.twig b/templates/default/wizards/sitepackage/index.html.twig new file mode 100644 index 00000000..47441996 --- /dev/null +++ b/templates/default/wizards/sitepackage/index.html.twig @@ -0,0 +1,109 @@ +{% extends 'layout.html.twig' %} +{% block title %}Kickstart your TYPO3 template development{% endblock %} +{% block body %} + + {% frame with { color: 'dark', height: 'small', center: true, title: 'Sitepackage Builder', titleSize: 1, backgroundImage: asset("assets/Images/keyvisual.png") } %} +

+ Sitepackage-Builder is your kickstarter for modern TYPO3 Theme development. Learn more about TYPO3 templating + or start your own template right now. +

+

+ + {{ icon('actions-extension-add', 'auto') }} + Create Sitepackage + +

+ {% endframe %} + + {% frame with { id: 'about', color: 'light', title: 'What is a Sitepackage?' } %} +

+ A Sitepackage is a TYPO3 Extension that containers all relevant configuration for a Website. + Having all configuration stored in a package keeps it protected from unauthorized access. + As Extension your Sitepackage will manage your dependencies to other Extensions and/or the TYPO3 Version. + This will ease your deployment and enables you to put the configuration of your Webiste under Version Control. +

+

+ Learn more about the best practices recommended from the TYPO3 Core Team. +

+

+ + {{ icon('actions-notebook', 'auto') }} + Learn about Sitepackages + +

+ {% endframe %} + + {% frame with { id: 'arguments', center: true, indent: true, title: 'Pros and Cons', titleSize: 3 } %} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Site­packageClassic
Config files not accessible by editors YesNo
Config files are protected *YesNo
Autoload PageTSYesNo
Autoload TypoScriptYesNo
Static PageTS TemplateYesNo
Static TypoScript TemplateYesNo
Dependency ManagementYesNo
Distribution through TERYesNo
Clean Version Control possibleYesNo
+
+

+ * Possible but not common practice +

+ {% endframe %} + + {% frame with { color: 'light', center: true, id: 'start', title: 'Start your own Sitepackage' } %} +

+ + {{ icon('actions-extension-add', 'auto') }} + Create Sitepackage + +

+ {% endframe %} + +{% endblock %} diff --git a/templates/default/wizards/sitepackage/partials/privacy-footer.html.twig b/templates/default/wizards/sitepackage/partials/privacy-footer.html.twig new file mode 100644 index 00000000..8ef7e65e --- /dev/null +++ b/templates/default/wizards/sitepackage/partials/privacy-footer.html.twig @@ -0,0 +1,7 @@ +{% frame with { id: 'privacy', color: 'light', center: true, indent: true, title: 'We respect your Privacy!' } %} +

+ We are not storing, sharing or doing any other crazy stuff with the + data you provide to generate your very own sitepackage. Simple as + that, check the sources. +

+{% endframe %} diff --git a/templates/default/wizards/sitepackage/success.html.twig b/templates/default/wizards/sitepackage/success.html.twig new file mode 100644 index 00000000..c0e9f43b --- /dev/null +++ b/templates/default/wizards/sitepackage/success.html.twig @@ -0,0 +1,88 @@ +{% extends 'layout.html.twig' %} +{% block title %}Success{% endblock %} +{% block body %} + + {% frame with { color: 'dark', height: 'small', center: true, title: 'Congratulations!', titleSize: 1, backgroundImage: asset("assets/Images/keyvisual.png") } %} +

+ Your Sitepackage has been successfully created. You can now check the + configuration or download the prepared Sitepackage. +

+

+ + {{ icon('actions-package', 'auto') }} + Download + +

+ {% endframe %} + + {% frame with { id: 'configuration', indent: true, title: 'Your Sitepackage Configuration' } %} +
+
TYPO3 Version
+
{{ sitepackage.typo3Version|version(2) }}
+
Base Package
+
{{ sitepackage.basePackage }}
+
+

Sitepackage Extension

+
+
Titel
+
{{ sitepackage.title }}
+ {% if sitepackage.description %} +
Description
+
{{ sitepackage.description }}
+ {% endif %} +
Extension Key
+
{{ sitepackage.extensionKey }}
+ {% if sitepackage.repositoryUrl %} +
Repository
+
{{ sitepackage.repositoryUrl }}
+ {% endif %} +
+

PHP

+
+ +
Composer Name
+
{{ sitepackage.composerVendorName }}/{{ sitepackage.composerProjectName }}
+
PSR-4 Namespace
+
{{ sitepackage.vendorName }}\{{ sitepackage.packageName }}
+
+

Author

+
+
Name
+
{{ sitepackage.author.name }}
+
E-Mail
+
{{ sitepackage.author.email }}
+
Company
+
{{ sitepackage.author.company }}
+
Homepage
+
{{ sitepackage.author.homepage }}
+
+

+ + {{ icon('actions-arrow-left-alt', 'auto') }} + Restart + + + {{ icon('actions-open', 'auto') }} + Edit Configuration + +

+ {% endframe %} + + {% frame with { color: 'dark', size: 'default', center: true } %} +

+ Your Sitepackage has been successfully created and is ready for download. +

+

+ + {{ icon('actions-package', 'auto') }} + Download + +

+ {% endframe %} + + {% include 'default/wizards/sitepackage/partials/privacy-footer.html.twig' %} + +{% endblock %} From 320283e8e1656450f78dc3f252451925aa3a1fc6 Mon Sep 17 00:00:00 2001 From: Simon Gilli <25326036+gilbertsoft@users.noreply.github.com> Date: Tue, 9 Aug 2022 15:22:02 +0200 Subject: [PATCH 2/8] Separated Composer packages --- .gitignore | 1 + .mage.yml | 4 + cnf/nginx.conf | 3 + composer.json | 4 + composer.lock | 908 ++++++++++++++++-- config/packages/framework.yaml | 3 + config/packages/twig.yaml | 2 + config/services.yaml | 22 +- migrations/Version20220818095608.php | 2 +- migrations/Version20220818183005.php | 53 + public/assets/Css/additions.css | 8 + public/assets/Images/OfficialBadge.svg | 92 ++ .../bootstrap_package/.editorconfig | 70 -- .../bootstrap_package/Build/.htaccess | 2 - .../bootstrap_package/Build/Gruntfile.js.twig | 72 -- .../bootstrap_package/Build/package.json.twig | 18 - .../bootstrap_package/Classes/.htaccess | 2 - .../Classes/Controller/.gitkeep | 1 - .../bootstrap_package/Classes/Domain/.gitkeep | 1 - .../Classes/Domain/Model/.gitkeep | 1 - .../Classes/Domain/Repository/.gitkeep | 1 - .../Classes/ViewHelpers/.gitkeep | 1 - .../bootstrap_package/Configuration/.htaccess | 2 - .../Configuration/RTE/Default.yaml.twig | 9 - .../TCA/Overrides/pages.php.twig | 19 - .../TCA/Overrides/sys_template.php.twig | 19 - .../TsConfig/Page/All.tsconfig.twig | 7 - .../WebLayout/BackendLayouts.tsconfig.twig | 4 - .../BackendLayouts/example.tsconfig.twig | 29 - .../TsConfig/Page/RTE.tsconfig.twig | 8 - .../TsConfig/Page/TCEFORM.tsconfig.twig | 11 - .../TsConfig/Page/TCEMAIN.tsconfig.twig | 6 - .../TypoScript/constants.typoscript.twig | 60 -- .../TypoScript/setup.typoscript.twig | 30 - .../bootstrap_package/README.md.twig | 4 - .../Resources/Private/.htaccess | 2 - .../Private/Language/locallang.xlf.twig | 11 - .../Private/Language/locallang_be.xlf.twig | 17 - .../Private/Language/locallang_db.xlf.twig | 11 - .../Private/Layouts/ContentElements/.gitkeep | 1 - .../Resources/Private/Layouts/Page/.gitkeep | 0 .../Private/Partials/ContentElements/.gitkeep | 1 - .../Resources/Private/Partials/Page/.gitkeep | 1 - .../Templates/ContentElements/.gitkeep | 1 - .../Private/Templates/Page/Example.html.twig | 22 - .../Resources/Public/Css/.gitkeep | 1 - .../Resources/Public/Fonts/.gitkeep | 1 - .../Public/Icons/BackendLayouts/example.svg | 1 - .../Resources/Public/Icons/Extension.svg | 3 - .../Resources/Public/Icons/favicon.ico | Bin 1150 -> 0 bytes .../Resources/Public/Icons/logo-inverted.svg | 1 - .../Resources/Public/Icons/logo.svg | 1 - .../Resources/Public/Images/logo-inverted.svg | 1 - .../Resources/Public/Images/logo.svg | 1 - .../Public/JavaScript/Dist/scripts.js.twig | 6 - .../Public/JavaScript/Src/main.js.twig | 1 - .../Public/Scss/Theme/_variables.scss | 3 - .../Public/Scss/Theme/theme.scss.twig | 9 - .../bootstrap_package/composer.json.twig | 21 - .../ext_conf_template.txt.twig | 3 - .../bootstrap_package/ext_emconf.php.twig | 30 - .../bootstrap_package/ext_localconf.php.twig | 12 - .../bootstrap_package/ext_tables.php.twig | 2 - .../bootstrap_package/ext_tables.sql.twig | 3 - .../ext_tables_static+adt.sql.twig | 3 - .../fluid_styled_content/.editorconfig | 70 -- .../fluid_styled_content/Build/.htaccess | 2 - .../Build/Gruntfile.js.twig | 124 --- .../Build/package.json.twig | 28 - .../fluid_styled_content/Classes/.htaccess | 2 - .../Classes/Controller/.gitkeep | 1 - .../Classes/Domain/.gitkeep | 1 - .../Classes/Domain/Model/.gitkeep | 1 - .../Classes/Domain/Repository/.gitkeep | 1 - .../Classes/ViewHelpers/.gitkeep | 1 - .../Configuration/.htaccess | 2 - .../Configuration/RTE/Default.yaml.twig | 42 - .../TCA/Overrides/pages.php.twig | 19 - .../TCA/Overrides/sys_template.php.twig | 19 - .../TsConfig/Page/All.tsconfig.twig | 7 - .../WebLayout/BackendLayouts.tsconfig.twig | 4 - .../BackendLayouts/default.tsconfig.twig | 29 - .../TsConfig/Page/RTE.tsconfig.twig | 8 - .../TsConfig/Page/TCEFORM.tsconfig.twig | 11 - .../TsConfig/Page/TCEMAIN.tsconfig.twig | 6 - .../Helper/DynamicContent.typoscript.twig | 64 -- .../TypoScript/constants.typoscript.twig | 56 -- .../TypoScript/setup.typoscript.twig | 203 ---- .../fluid_styled_content/README.md.twig | 4 - .../Resources/Private/.htaccess | 2 - .../Private/Language/locallang.xlf.twig | 11 - .../Private/Language/locallang_be.xlf.twig | 17 - .../Private/Language/locallang_db.xlf.twig | 11 - .../Private/Layouts/ContentElements/.gitkeep | 1 - .../Private/Layouts/Page/Default.html.twig | 21 - .../Private/Partials/ContentElements/.gitkeep | 1 - .../Resources/Private/Partials/Page/.gitkeep | 1 - .../Templates/ContentElements/.gitkeep | 1 - .../Private/Templates/Page/Default.html.twig | 19 - .../Resources/Public/Css/layout.css | 0 .../Resources/Public/Css/layout.min.css | 0 .../Resources/Public/Css/rte.css.twig | 3 - .../Resources/Public/Fonts/.gitkeep | 1 - .../Resources/Public/Icons/Extension.svg | 3 - .../Resources/Public/Icons/favicon.ico | Bin 1150 -> 0 bytes .../Public/Images/BackendLayouts/default.png | Bin 182 -> 0 bytes .../Public/JavaScript/Dist/scripts.js.twig | 6 - .../Public/JavaScript/Src/main.js.twig | 1 - .../Resources/Public/Scss/layout.scss.twig | 5 - .../Resources/Public/Scss/variables.scss.twig | 1 - .../fluid_styled_content/composer.json.twig | 23 - .../ext_conf_template.txt.twig | 3 - .../fluid_styled_content/ext_emconf.php.twig | 32 - .../ext_localconf.php.twig | 12 - .../fluid_styled_content/ext_tables.php.twig | 2 - .../fluid_styled_content/ext_tables.sql.twig | 3 - .../ext_tables_static+adt.sql.twig | 3 - .../ExtensionsTerJsonCreateCommand.php | 9 +- .../Admin/BasePackageCrudController.php | 68 ++ src/Controller/Admin/DashboardController.php | 5 +- src/Controller/Api/AbstractController.php | 23 +- .../MajorVersion/RequirementsController.php | 2 +- src/Controller/Api/SitepackageController.php | 103 +- src/Controller/Api/ValidationTrait.php | 54 ++ .../Webhooks/GitHubWebhookController.php | 70 ++ .../Wizards/SitepackageController.php | 249 ++--- src/Entity/BasePackage.php | 114 +++ src/Entity/Package/Author.php | 169 ---- src/Entity/Sitepackage.php | 370 ------- src/Enum/ReleaseTypeEnum.php | 3 - src/Enum/RequirementCategoryEnum.php | 3 - .../GitHubEvent.php} | 32 +- src/EventListener/BasePackageListener.php | 49 + src/Exception/GitHubWebhookException.php | 45 + .../IncompatiblePackageException.php} | 13 +- .../InvalidGitHubRequestPayloadException.php | 48 + ...InvalidGitHubRequestSignatureException.php | 49 + .../MissingGitHubEventTypeException.php | 43 + .../MissingGitHubSignatureException.php | 43 + .../PackageNotInstalledException.php | 30 + .../UnknownGitHubEventTypeException.php | 46 + src/Factory/GitHubEventFactory.php | 60 ++ src/Factory/GitHubEventFactoryInterface.php | 47 + src/Factory/SitepackageFactory.php | 14 +- src/Form/Dto/BasePackageDto.php | 122 +++ src/Form/Dto/SitepackageDto.php | 188 ++-- src/Form/Extension/AbstractIconExtension.php | 57 ++ .../Extension/ButtonTypeIconExtension.php | 34 + src/Form/SitepackageType.php | 72 +- src/Form/Type/BasePackageType.php | 29 +- src/Form/Type/Typo3VersionType.php | 20 +- src/Menu/MenuBuilder.php | 10 +- src/Package/BasePackageManifest.php | 133 +++ src/Package/Package/Author.php | 121 +++ src/Package/Sitepackage.php | 285 ++++++ src/Repository/BasePackageRepository.php | 79 ++ src/Security/GitHubRequestChecker.php | 57 ++ src/Service/BasePackageService.php | 669 +++++++++++++ src/Service/SitepackageGenerator.php | 164 +++- src/Session/WizardSessionTrait.php | 109 +++ src/Twig/Extension/VersionNumberExtension.php | 22 +- src/Utility/FileUtility.php | 57 -- src/Utility/StringUtility.php | 21 +- src/Utility/VersionUtility.php | 13 + .../wizards/sitepackage/success.html.twig | 88 -- templates/form/custom_theme.html.twig | 13 + templates/layout.html.twig | 1 + templates/wizards/layout.html.twig | 10 + .../partials/privacy-footer.html.twig | 2 +- .../sitepackage/configure.html.twig} | 8 +- templates/wizards/sitepackage/error.html.twig | 23 + .../wizards/sitepackage/index.html.twig | 18 +- templates/wizards/sitepackage/new.html.twig | 80 ++ .../wizards/sitepackage/success.html.twig | 84 ++ tmp/.gitkeep | 0 tmp/base-packages/.gitignore | 2 + 176 files changed, 4189 insertions(+), 2700 deletions(-) create mode 100644 migrations/Version20220818183005.php create mode 100644 public/assets/Images/OfficialBadge.svg delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/.editorconfig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Build/.htaccess delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Build/Gruntfile.js.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Build/package.json.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Classes/.htaccess delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Classes/Controller/.gitkeep delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/.gitkeep delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/Model/.gitkeep delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/Repository/.gitkeep delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Classes/ViewHelpers/.gitkeep delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/.htaccess delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/RTE/Default.yaml.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/TCA/Overrides/pages.php.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/TCA/Overrides/sys_template.php.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/All.tsconfig.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts.tsconfig.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts/example.tsconfig.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/RTE.tsconfig.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/TCEFORM.tsconfig.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/TCEMAIN.tsconfig.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/TypoScript/constants.typoscript.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Configuration/TypoScript/setup.typoscript.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/README.md.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/.htaccess delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang.xlf.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang_be.xlf.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang_db.xlf.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Layouts/ContentElements/.gitkeep delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Layouts/Page/.gitkeep delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Partials/ContentElements/.gitkeep delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Partials/Page/.gitkeep delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Templates/ContentElements/.gitkeep delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Templates/Page/Example.html.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Css/.gitkeep delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Fonts/.gitkeep delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/BackendLayouts/example.svg delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/Extension.svg delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/favicon.ico delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/logo-inverted.svg delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/logo.svg delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Images/logo-inverted.svg delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Images/logo.svg delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/JavaScript/Dist/scripts.js.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/JavaScript/Src/main.js.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Scss/Theme/_variables.scss delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Scss/Theme/theme.scss.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/composer.json.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/ext_conf_template.txt.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/ext_emconf.php.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/ext_localconf.php.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/ext_tables.php.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/ext_tables.sql.twig delete mode 100644 resources/skeletons/BaseExtension/bootstrap_package/ext_tables_static+adt.sql.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/.editorconfig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Build/.htaccess delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Build/Gruntfile.js.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Build/package.json.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Classes/.htaccess delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Classes/Controller/.gitkeep delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/.gitkeep delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/Model/.gitkeep delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/Repository/.gitkeep delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Classes/ViewHelpers/.gitkeep delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/.htaccess delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/RTE/Default.yaml.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TCA/Overrides/pages.php.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TCA/Overrides/sys_template.php.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/All.tsconfig.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts.tsconfig.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts/default.tsconfig.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/RTE.tsconfig.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/TCEFORM.tsconfig.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/TCEMAIN.tsconfig.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/Helper/DynamicContent.typoscript.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/constants.typoscript.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/setup.typoscript.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/README.md.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/.htaccess delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang.xlf.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang_be.xlf.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang_db.xlf.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Layouts/ContentElements/.gitkeep delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Layouts/Page/Default.html.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Partials/ContentElements/.gitkeep delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Partials/Page/.gitkeep delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Templates/ContentElements/.gitkeep delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Templates/Page/Default.html.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Css/layout.css delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Css/layout.min.css delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Css/rte.css.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Fonts/.gitkeep delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Icons/Extension.svg delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Icons/favicon.ico delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Images/BackendLayouts/default.png delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/JavaScript/Dist/scripts.js.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/JavaScript/Src/main.js.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Scss/layout.scss.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Scss/variables.scss.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/composer.json.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/ext_conf_template.txt.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/ext_emconf.php.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/ext_localconf.php.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/ext_tables.php.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/ext_tables.sql.twig delete mode 100644 resources/skeletons/BaseExtension/fluid_styled_content/ext_tables_static+adt.sql.twig create mode 100644 src/Controller/Admin/BasePackageCrudController.php create mode 100644 src/Controller/Api/ValidationTrait.php create mode 100644 src/Controller/Webhooks/GitHubWebhookController.php create mode 100644 src/Entity/BasePackage.php delete mode 100644 src/Entity/Package/Author.php delete mode 100644 src/Entity/Sitepackage.php rename src/{Enum/Typo3VersionEnum.php => Event/GitHubEvent.php} (64%) create mode 100644 src/EventListener/BasePackageListener.php create mode 100644 src/Exception/GitHubWebhookException.php rename src/{Enum/BasePackageEnum.php => Exception/IncompatiblePackageException.php} (67%) create mode 100644 src/Exception/InvalidGitHubRequestPayloadException.php create mode 100644 src/Exception/InvalidGitHubRequestSignatureException.php create mode 100644 src/Exception/MissingGitHubEventTypeException.php create mode 100644 src/Exception/MissingGitHubSignatureException.php create mode 100644 src/Exception/PackageNotInstalledException.php create mode 100644 src/Exception/UnknownGitHubEventTypeException.php create mode 100644 src/Factory/GitHubEventFactory.php create mode 100644 src/Factory/GitHubEventFactoryInterface.php create mode 100644 src/Form/Dto/BasePackageDto.php create mode 100644 src/Form/Extension/AbstractIconExtension.php create mode 100644 src/Form/Extension/ButtonTypeIconExtension.php create mode 100644 src/Package/BasePackageManifest.php create mode 100644 src/Package/Package/Author.php create mode 100644 src/Package/Sitepackage.php create mode 100644 src/Repository/BasePackageRepository.php create mode 100644 src/Security/GitHubRequestChecker.php create mode 100644 src/Service/BasePackageService.php create mode 100644 src/Session/WizardSessionTrait.php delete mode 100644 src/Utility/FileUtility.php delete mode 100644 templates/default/wizards/sitepackage/success.html.twig create mode 100644 templates/form/custom_theme.html.twig create mode 100644 templates/wizards/layout.html.twig rename templates/{default/wizards/sitepackage => wizards}/partials/privacy-footer.html.twig (84%) rename templates/{default/wizards/sitepackage/edit.html.twig => wizards/sitepackage/configure.html.twig} (61%) create mode 100644 templates/wizards/sitepackage/error.html.twig rename templates/{default => }/wizards/sitepackage/index.html.twig (89%) create mode 100644 templates/wizards/sitepackage/new.html.twig create mode 100644 templates/wizards/sitepackage/success.html.twig delete mode 100644 tmp/.gitkeep create mode 100644 tmp/base-packages/.gitignore diff --git a/.gitignore b/.gitignore index c6178a65..6884decd 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ /.idea/ /.mage/ /.vscode/ +/public/base-packages/ /public/p/ /public/p2/ /public/satis/ diff --git a/.mage.yml b/.mage.yml index c1609b5d..0e81427a 100644 --- a/.mage.yml +++ b/.mage.yml @@ -11,6 +11,7 @@ magephp: - ./public/packages.json - ./stubs - ./tests + - ./tmp - ./tools - ./var - ./LICENSE @@ -30,8 +31,10 @@ magephp: - exec: { cmd: "echo \"APP_ENV=prod\" >> .env.local", desc: "Create .env.local" } - composer/install: { flags: '--no-dev --no-progress --optimize-autoloader' } on-deploy: + - exec: { cmd: 'mkdir -p tmp/base-packages', desc: 'Create tmp/base-packages folder' } - exec: { cmd: 'mkdir -p var', desc: 'Create var folder' } - exec: { cmd: 'mkdir -p var/satis', desc: 'Create var/satis folder' } + - exec: { cmd: 'test -d ~/site/shared/base-packages || mkdir -p ~/site/shared/base-packages', desc: 'Create shared/base-packages folder' } - exec: { cmd: 'test -d ~/site/shared/public/satis || mkdir -p ~/site/shared/public/satis', desc: 'Create shared/public/satis folder' } - fs/link: { from: "../../../shared/.env.local", to: ".env.local" } - fs/link: { from: "../../../../shared/public/satis", to: "public/satis" } @@ -39,6 +42,7 @@ magephp: - fs/link: { from: "satis/p2", to: "public/p2" } - fs/link: { from: "satis/aliases.json", to: "public/aliases.json" } - fs/link: { from: "satis/packages.json", to: "public/packages.json" } + - fs/link: { from: "../../../../../shared/base-packages", to: "tmp/base-packages/packages" } - exec: { cmd: "sqlite3 ~/site/mage/current/var/gettr.db '.backup var/gettr.db'", desc: "Copy DB" } - exec: { cmd: "php-restart", desc: "Restart PHP and reset OPcache" } - exec: { cmd: "php ./bin/console doctrine:migrations:sync-metadata-storage --no-interaction", desc: "Synchronize DB Migrations" } diff --git a/cnf/nginx.conf b/cnf/nginx.conf index 327f2f4f..eea84713 100644 --- a/cnf/nginx.conf +++ b/cnf/nginx.conf @@ -54,6 +54,9 @@ location ~ (?!^\/\.well-known)\/\. { allow 213.144.157.127; allow 2001:1620:c7f:111::/64; +# Allow GitHub for webhook testing +allow 140.82.115.0/24; + # Block abusing IPs deny 212.95.122.212; diff --git a/composer.json b/composer.json index 1bfdd2ed..26af66ce 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,9 @@ "ext-iconv": "*", "ext-json": "*", "ext-sqlite3": "*", + "ext-zip": "*", "ext-zlib": "*", + "composer/composer": "^2.2", "composer/semver": "^3.3", "doctrine/collections": "^1.6", "doctrine/dbal": "^3.3", @@ -62,6 +64,8 @@ "symfony/dependency-injection": "^6.2", "symfony/dotenv": "^6.2", "symfony/expression-language": "^6.2", + "symfony/filesystem": "^6.2", + "symfony/finder": "^6.2", "symfony/flex": "^2.2", "symfony/form": "^6.2", "symfony/framework-bundle": "^6.2", diff --git a/composer.lock b/composer.lock index 0ee4eacc..f4ba6bc5 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8e1b5f08cabf42768a73e907373eb415", + "content-hash": "5c42f019b3cf9fa9249650716099c142", "packages": [ { "name": "composer/ca-bundle", @@ -82,6 +82,332 @@ ], "time": "2023-01-11T08:27:00+00:00" }, + { + "name": "composer/class-map-generator", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/class-map-generator.git", + "reference": "1e1cb2b791facb2dfe32932a7718cf2571187513" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/class-map-generator/zipball/1e1cb2b791facb2dfe32932a7718cf2571187513", + "reference": "1e1cb2b791facb2dfe32932a7718cf2571187513", + "shasum": "" + }, + "require": { + "composer/pcre": "^2 || ^3", + "php": "^7.2 || ^8.0", + "symfony/finder": "^4.4 || ^5.3 || ^6" + }, + "require-dev": { + "phpstan/phpstan": "^1.6", + "phpstan/phpstan-deprecation-rules": "^1", + "phpstan/phpstan-phpunit": "^1", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/filesystem": "^5.4 || ^6", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\ClassMapGenerator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Utilities to scan PHP code and generate class maps.", + "keywords": [ + "classmap" + ], + "support": { + "issues": "https://github.com/composer/class-map-generator/issues", + "source": "https://github.com/composer/class-map-generator/tree/1.0.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-06-19T11:31:27+00:00" + }, + { + "name": "composer/composer", + "version": "2.5.5", + "source": { + "type": "git", + "url": "https://github.com/composer/composer.git", + "reference": "c7cffaad16a60636a776017eac5bd8cd0095c32f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/composer/zipball/c7cffaad16a60636a776017eac5bd8cd0095c32f", + "reference": "c7cffaad16a60636a776017eac5bd8cd0095c32f", + "shasum": "" + }, + "require": { + "composer/ca-bundle": "^1.0", + "composer/class-map-generator": "^1.0", + "composer/metadata-minifier": "^1.0", + "composer/pcre": "^2.1 || ^3.1", + "composer/semver": "^3.0", + "composer/spdx-licenses": "^1.5.7", + "composer/xdebug-handler": "^2.0.2 || ^3.0.3", + "justinrainbow/json-schema": "^5.2.11", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "react/promise": "^2.8", + "seld/jsonlint": "^1.4", + "seld/phar-utils": "^1.2", + "seld/signal-handler": "^2.0", + "symfony/console": "^5.4.11 || ^6.0.11", + "symfony/filesystem": "^5.4 || ^6.0", + "symfony/finder": "^5.4 || ^6.0", + "symfony/polyfill-php73": "^1.24", + "symfony/polyfill-php80": "^1.24", + "symfony/polyfill-php81": "^1.24", + "symfony/process": "^5.4 || ^6.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.9.3", + "phpstan/phpstan-deprecation-rules": "^1", + "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan-strict-rules": "^1", + "phpstan/phpstan-symfony": "^1.2.10", + "symfony/phpunit-bridge": "^6.0" + }, + "suggest": { + "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", + "ext-zip": "Enabling the zip extension allows you to unzip archives", + "ext-zlib": "Allow gzip compression of HTTP requests" + }, + "bin": [ + "bin/composer" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "phpstan": { + "includes": [ + "phpstan/rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "Composer\\": "src/Composer" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "https://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Composer helps you declare, manage and install dependencies of PHP projects. It ensures you have the right stack everywhere.", + "homepage": "https://getcomposer.org/", + "keywords": [ + "autoload", + "dependency", + "package" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/composer/issues", + "source": "https://github.com/composer/composer/tree/2.5.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2023-03-21T10:50:05+00:00" + }, + { + "name": "composer/metadata-minifier", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/metadata-minifier.git", + "reference": "c549d23829536f0d0e984aaabbf02af91f443207" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/metadata-minifier/zipball/c549d23829536f0d0e984aaabbf02af91f443207", + "reference": "c549d23829536f0d0e984aaabbf02af91f443207", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "composer/composer": "^2", + "phpstan/phpstan": "^0.12.55", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\MetadataMinifier\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Small utility library that handles metadata minification and expansion.", + "keywords": [ + "composer", + "compression" + ], + "support": { + "issues": "https://github.com/composer/metadata-minifier/issues", + "source": "https://github.com/composer/metadata-minifier/tree/1.0.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2021-04-07T13:37:33+00:00" + }, + { + "name": "composer/pcre", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.1.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-11-17T09:50:14+00:00" + }, { "name": "composer/semver", "version": "3.3.2", @@ -163,6 +489,152 @@ ], "time": "2022-04-01T19:23:25+00:00" }, + { + "name": "composer/spdx-licenses", + "version": "1.5.7", + "source": { + "type": "git", + "url": "https://github.com/composer/spdx-licenses.git", + "reference": "c848241796da2abf65837d51dce1fae55a960149" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/c848241796da2abf65837d51dce1fae55a960149", + "reference": "c848241796da2abf65837d51dce1fae55a960149", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.55", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Spdx\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "SPDX licenses list and validation library.", + "keywords": [ + "license", + "spdx", + "validator" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/spdx-licenses/issues", + "source": "https://github.com/composer/spdx-licenses/tree/1.5.7" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-05-23T07:37:50+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "ced299686f41dce890debac69273b47ffe98a40c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", + "reference": "ced299686f41dce890debac69273b47ffe98a40c", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-02-25T21:32:43+00:00" + }, { "name": "doctrine/annotations", "version": "2.0.1", @@ -2393,16 +2865,86 @@ "xml" ], "support": { - "issues": "https://github.com/schmittjoh/JMSSerializerBundle/issues", - "source": "https://github.com/schmittjoh/JMSSerializerBundle/tree/4.2.0" + "issues": "https://github.com/schmittjoh/JMSSerializerBundle/issues", + "source": "https://github.com/schmittjoh/JMSSerializerBundle/tree/4.2.0" + }, + "funding": [ + { + "url": "https://github.com/goetas", + "type": "github" + } + ], + "time": "2022-09-13T19:27:18+00:00" + }, + { + "name": "justinrainbow/json-schema", + "version": "5.2.12", + "source": { + "type": "git", + "url": "https://github.com/justinrainbow/json-schema.git", + "reference": "ad87d5a5ca981228e0e205c2bc7dfb8e24559b60" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/ad87d5a5ca981228e0e205c2bc7dfb8e24559b60", + "reference": "ad87d5a5ca981228e0e205c2bc7dfb8e24559b60", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", + "json-schema/json-schema-test-suite": "1.2.0", + "phpunit/phpunit": "^4.8.35" + }, + "bin": [ + "bin/validate-json" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "JsonSchema\\": "src/JsonSchema/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" + }, + { + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" + } + ], + "description": "A library to validate a json schema.", + "homepage": "https://github.com/justinrainbow/json-schema", + "keywords": [ + "json", + "schema" + ], + "support": { + "issues": "https://github.com/justinrainbow/json-schema/issues", + "source": "https://github.com/justinrainbow/json-schema/tree/5.2.12" }, - "funding": [ - { - "url": "https://github.com/goetas", - "type": "github" - } - ], - "time": "2022-09-13T19:27:18+00:00" + "time": "2022-04-13T08:02:27+00:00" }, { "name": "knplabs/knp-components", @@ -3780,6 +4322,255 @@ }, "time": "2019-03-08T08:55:37+00:00" }, + { + "name": "react/promise", + "version": "v2.9.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "234f8fd1023c9158e2314fa9d7d0e6a83db42910" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/234f8fd1023c9158e2314fa9d7d0e6a83db42910", + "reference": "234f8fd1023c9158e2314fa9d7d0e6a83db42910", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.36" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "React\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "keywords": [ + "promise", + "promises" + ], + "support": { + "issues": "https://github.com/reactphp/promise/issues", + "source": "https://github.com/reactphp/promise/tree/v2.9.0" + }, + "funding": [ + { + "url": "https://github.com/WyriHaximus", + "type": "github" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2022-02-11T10:27:51+00:00" + }, + { + "name": "seld/jsonlint", + "version": "1.9.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/jsonlint.git", + "reference": "4211420d25eba80712bff236a98960ef68b866b7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/4211420d25eba80712bff236a98960ef68b866b7", + "reference": "4211420d25eba80712bff236a98960ef68b866b7", + "shasum": "" + }, + "require": { + "php": "^5.3 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.5", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^8.5.13" + }, + "bin": [ + "bin/jsonlint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Seld\\JsonLint\\": "src/Seld/JsonLint/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "JSON Linter", + "keywords": [ + "json", + "linter", + "parser", + "validator" + ], + "support": { + "issues": "https://github.com/Seldaek/jsonlint/issues", + "source": "https://github.com/Seldaek/jsonlint/tree/1.9.0" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/seld/jsonlint", + "type": "tidelift" + } + ], + "time": "2022-04-01T13:37:23+00:00" + }, + { + "name": "seld/phar-utils", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/phar-utils.git", + "reference": "ea2f4014f163c1be4c601b9b7bd6af81ba8d701c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/ea2f4014f163c1be4c601b9b7bd6af81ba8d701c", + "reference": "ea2f4014f163c1be4c601b9b7bd6af81ba8d701c", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\PharUtils\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "PHAR file format utilities, for when PHP phars you up", + "keywords": [ + "phar" + ], + "support": { + "issues": "https://github.com/Seldaek/phar-utils/issues", + "source": "https://github.com/Seldaek/phar-utils/tree/1.2.1" + }, + "time": "2022-08-31T10:31:18+00:00" + }, + { + "name": "seld/signal-handler", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/signal-handler.git", + "reference": "f69d119511dc0360440cdbdaa71829c149b7be75" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/signal-handler/zipball/f69d119511dc0360440cdbdaa71829c149b7be75", + "reference": "f69d119511dc0360440cdbdaa71829c149b7be75", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "require-dev": { + "phpstan/phpstan": "^1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1", + "phpstan/phpstan-strict-rules": "^1.3", + "phpunit/phpunit": "^7.5.20 || ^8.5.23", + "psr/log": "^1 || ^2 || ^3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\Signal\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Simple unix signal handler that silently fails where signals are not supported for easy cross-platform development", + "keywords": [ + "posix", + "sigint", + "signal", + "sigterm", + "unix" + ], + "support": { + "issues": "https://github.com/Seldaek/signal-handler/issues", + "source": "https://github.com/Seldaek/signal-handler/tree/2.0.1" + }, + "time": "2022-07-20T18:31:45+00:00" + }, { "name": "setasign/fpdi", "version": "v2.3.7", @@ -9675,76 +10466,6 @@ }, "time": "2022-12-13T13:54:32+00:00" }, - { - "name": "justinrainbow/json-schema", - "version": "5.2.12", - "source": { - "type": "git", - "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "ad87d5a5ca981228e0e205c2bc7dfb8e24559b60" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/ad87d5a5ca981228e0e205c2bc7dfb8e24559b60", - "reference": "ad87d5a5ca981228e0e205c2bc7dfb8e24559b60", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", - "json-schema/json-schema-test-suite": "1.2.0", - "phpunit/phpunit": "^4.8.35" - }, - "bin": [ - "bin/validate-json" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "JsonSchema\\": "src/JsonSchema/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bruno Prieto Reis", - "email": "bruno.p.reis@gmail.com" - }, - { - "name": "Justin Rainbow", - "email": "justin.rainbow@gmail.com" - }, - { - "name": "Igor Wiedler", - "email": "igor@wiedler.ch" - }, - { - "name": "Robert Schönthal", - "email": "seroscho@googlemail.com" - } - ], - "description": "A library to validate a json schema.", - "homepage": "https://github.com/justinrainbow/json-schema", - "keywords": [ - "json", - "schema" - ], - "support": { - "issues": "https://github.com/justinrainbow/json-schema/issues", - "source": "https://github.com/justinrainbow/json-schema/tree/5.2.12" - }, - "time": "2022-04-13T08:02:27+00:00" - }, { "name": "localheinz/diff", "version": "1.1.1", @@ -9807,26 +10528,24 @@ }, { "name": "masterminds/html5", - "version": "2.7.6", + "version": "2.8.0", "source": { "type": "git", "url": "https://github.com/Masterminds/html5-php.git", - "reference": "897eb517a343a2281f11bc5556d6548db7d93947" + "reference": "3c5d5a56d56f48a1ca08a0670f0f80c1dad368f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/897eb517a343a2281f11bc5556d6548db7d93947", - "reference": "897eb517a343a2281f11bc5556d6548db7d93947", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/3c5d5a56d56f48a1ca08a0670f0f80c1dad368f3", + "reference": "3c5d5a56d56f48a1ca08a0670f0f80c1dad368f3", "shasum": "" }, "require": { - "ext-ctype": "*", "ext-dom": "*", - "ext-libxml": "*", "php": ">=5.3.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7" + "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8" }, "type": "library", "extra": { @@ -9870,9 +10589,9 @@ ], "support": { "issues": "https://github.com/Masterminds/html5-php/issues", - "source": "https://github.com/Masterminds/html5-php/tree/2.7.6" + "source": "https://github.com/Masterminds/html5-php/tree/2.8.0" }, - "time": "2022-08-18T16:18:26+00:00" + "time": "2023-04-26T07:27:39+00:00" }, { "name": "nikic/php-parser", @@ -10002,12 +10721,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "d2832e4594571d458e36fb4622220915a3c3a8f4" + "reference": "5eb9b0587e4625150e4892e569bb223714c86256" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/d2832e4594571d458e36fb4622220915a3c3a8f4", - "reference": "d2832e4594571d458e36fb4622220915a3c3a8f4", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/5eb9b0587e4625150e4892e569bb223714c86256", + "reference": "5eb9b0587e4625150e4892e569bb223714c86256", "shasum": "" }, "conflict": { @@ -10343,7 +11062,7 @@ "prestashop/blockwishlist": ">=2,<2.1.1", "prestashop/contactform": ">=1.0.1,<4.3", "prestashop/gamification": "<2.3.2", - "prestashop/prestashop": "<8.0.1", + "prestashop/prestashop": "<8.0.4", "prestashop/productcomments": "<5.0.2", "prestashop/ps_emailsubscription": "<2.6.1", "prestashop/ps_facetedsearch": "<3.4.1", @@ -10599,7 +11318,7 @@ "type": "tidelift" } ], - "time": "2023-04-25T13:05:55+00:00" + "time": "2023-04-25T20:04:17+00:00" }, { "name": "symfony/browser-kit", @@ -11161,6 +11880,7 @@ "ext-iconv": "*", "ext-json": "*", "ext-sqlite3": "*", + "ext-zip": "*", "ext-zlib": "*" }, "platform-dev": [], diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml index 7853e9ed..6a7e85e0 100644 --- a/config/packages/framework.yaml +++ b/config/packages/framework.yaml @@ -17,6 +17,9 @@ framework: php_errors: log: true + form: + legacy_error_messages: false + when@test: framework: test: true diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml index 8f4c7e42..5439e3ac 100644 --- a/config/packages/twig.yaml +++ b/config/packages/twig.yaml @@ -5,3 +5,5 @@ twig: packagist: search: https://packagist.org/explore/?type=typo3-cms-extension submit: https://packagist.org/packages/submit + form_themes: + - 'form/custom_theme.html.twig' diff --git a/config/services.yaml b/config/services.yaml index cd4c0610..b158a746 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -5,6 +5,8 @@ # https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration parameters: app.domain: '%env(APP_DOMAIN)%' + app.base_packages_project_dir: 'tmp/base-packages' + app.base_packages_assets_dir: 'base-packages' services: # default configuration for services in *this* file @@ -17,10 +19,14 @@ services: App\: resource: '../src/' exclude: + - '../src/DataFixtures/' - '../src/DependencyInjection/' - '../src/Entity/' - - '../src/Kernel.php' + - '../src/Enum/' + - '../src/Exception/' + - '../src/Package/' - '../src/Tests/' + - '../src/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 @@ -34,6 +40,9 @@ services: arguments: $appDomain: '%env(APP_DOMAIN)%' + App\EventListener\BasePackageListener: + tags: ['doctrine.orm.entity_listener'] + App\EventListener\MajorVersionListener: tags: ['doctrine.orm.entity_listener'] @@ -43,6 +52,17 @@ services: App\EventListener\RequirementListener: tags: ['doctrine.orm.entity_listener'] + App\Security\GitHubRequestChecker: + arguments: + $signingSecret: '%env(APP_WEBHOOK_SECRET_GITHUB)%' + + App\Service\BasePackageService: + arguments: + $projectDir: '%app.base_packages_project_dir%' + $assetsDir: '%app.base_packages_assets_dir%' + App\Service\CacheWarmupService: arguments: $baseUrl: '%env(BASE_URL)%' + + Composer\Console\Application: diff --git a/migrations/Version20220818095608.php b/migrations/Version20220818095608.php index 4f41860e..55f8a83f 100644 --- a/migrations/Version20220818095608.php +++ b/migrations/Version20220818095608.php @@ -33,7 +33,7 @@ final class Version20220818095608 extends AbstractMigration { public function getDescription(): string { - return ''; + return 'Add ID to Requirements'; } public function up(Schema $schema): void diff --git a/migrations/Version20220818183005.php b/migrations/Version20220818183005.php new file mode 100644 index 00000000..ad578d6c --- /dev/null +++ b/migrations/Version20220818183005.php @@ -0,0 +1,53 @@ +addSql('CREATE TABLE base_packages (name VARCHAR(255) NOT NULL, active BOOLEAN NOT NULL, official BOOLEAN NOT NULL, PRIMARY KEY(name))'); + $this->addSql('INSERT INTO base_packages (name, active, official) VALUES (?, ?, ?)', ['1' => 'typo3/bootstrap-package', '2' => 1, '3' => 1], ['1' => 2, '2' => 5, '3' => 5]); + $this->addSql('INSERT INTO base_packages (name, active, official) VALUES (?, ?, ?)', ['1' => 'typo3/fluid-styled-content', '2' => 1, '3' => 1], ['1' => 2, '2' => 5, '3' => 5]); + $this->addSql('INSERT INTO base_packages (name, active, official) VALUES (?, ?, ?)', ['1' => 'typo3/introduction-package', '2' => 1, '3' => 0], ['1' => 2, '2' => 5, '3' => 5]); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('DROP TABLE base_packages'); + } +} diff --git a/public/assets/Css/additions.css b/public/assets/Css/additions.css index 1d507832..7e21c392 100644 --- a/public/assets/Css/additions.css +++ b/public/assets/Css/additions.css @@ -81,3 +81,11 @@ pre { .frame .swagger-ui .auth-wrapper .authorize { margin-right: 0; } + + +/* BasePackage List */ +.basepackage-official-badge { + position: absolute; + right: 0.75em; + transform: translate(0, 25%); +} diff --git a/public/assets/Images/OfficialBadge.svg b/public/assets/Images/OfficialBadge.svg new file mode 100644 index 00000000..829a4ac8 --- /dev/null +++ b/public/assets/Images/OfficialBadge.svg @@ -0,0 +1,92 @@ + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/skeletons/BaseExtension/bootstrap_package/.editorconfig b/resources/skeletons/BaseExtension/bootstrap_package/.editorconfig deleted file mode 100644 index ff05afd1..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/.editorconfig +++ /dev/null @@ -1,70 +0,0 @@ -# EditorConfig is awesome: http://EditorConfig.org - -# top-most EditorConfig file -root = true - -# Unix-style newlines with a newline ending every file -[*] -charset = utf-8 -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true - -# CSS-Files -[*.css] -indent_style = space -indent_size = 4 - -# HTML-Files -[*.html] -indent_style = space -indent_size = 4 - -# TMPL-Files -[*.tmpl] -indent_style = space -indent_size = 4 - -# JS-Files -[*.js] -indent_style = space -indent_size = 4 - -# PHP-Files -[*.php] -indent_style = space -indent_size = 4 - -# MD-Files -[*.md] -indent_style = space -indent_size = 4 - -# ReST-Files -[*.rst] -indent_style = space -indent_size = 3 - -# TypoScript -[*.typoscript] -indent_style = space -indent_size = 4 - -# YML-Files -[{*.yml,*.yaml}] -indent_style = space -indent_size = 2 - -# package.json -[package.json] -indent_style = space -indent_size = 2 - -# composer.json -[composer.json] -indent_style = space -indent_size = 4 - -# phpstan -[*.neon] -indent_style = tab diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Build/.htaccess b/resources/skeletons/BaseExtension/bootstrap_package/Build/.htaccess deleted file mode 100644 index 93169e4e..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Build/.htaccess +++ /dev/null @@ -1,2 +0,0 @@ -Order deny,allow -Deny from all diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Build/Gruntfile.js.twig b/resources/skeletons/BaseExtension/bootstrap_package/Build/Gruntfile.js.twig deleted file mode 100644 index 36dddf66..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Build/Gruntfile.js.twig +++ /dev/null @@ -1,72 +0,0 @@ -module.exports = function(grunt) { - - /** - * Project configuration. - */ - grunt.initConfig({ - pkg: grunt.file.readJSON('package.json'), - paths: { - root: '../', - resources: '<%= paths.root %>Resources/', - fonts: '<%= paths.resources %>Public/Fonts/', - img: '<%= paths.resources %>Public/Images/', - js: '<%= paths.resources %>Public/JavaScript/' - }, - banner: '/*!\n' + - ' * {{ package.title }} v<%= pkg.version %> (<%= pkg.homepage %>)\n' + - ' * Copyright 2017-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' + - ' * Licensed under the <%= pkg.license %> license\n' + - ' */\n', - uglify: { - all: { - options: { - banner: '<%= banner %>', - mangle: true, - compress: true, - beautify: false - }, - files: { - "<%= paths.js %>/Dist/scripts.js": [ - "<%= paths.js %>Src/main.js" - ] - } - } - }, - imagemin: { - extension: { - files: [{ - expand: true, - cwd: '<%= paths.resources %>', - src: [ - '**/*.{png,jpg,gif,svg}' - ], - dest: '<%= paths.resources %>' - }] - } - }, - watch: { - options: { - livereload: true - }, - javascript: { - files: '<%= paths.js %>Src/**/*.js', - tasks: ['js'] - } - } - }); - - /** - * Register tasks - */ - grunt.loadNpmTasks('grunt-contrib-uglify'); - grunt.loadNpmTasks('grunt-contrib-watch'); - grunt.loadNpmTasks('grunt-contrib-imagemin'); - - /** - * Grunt update task - */ - grunt.registerTask('js', ['uglify']); - grunt.registerTask('build', ['js', 'imagemin']); - grunt.registerTask('default', ['build']); - -}; diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Build/package.json.twig b/resources/skeletons/BaseExtension/bootstrap_package/Build/package.json.twig deleted file mode 100644 index 21fc85af..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Build/package.json.twig +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "{{ package.vendorNameAlternative }}-{{ package.packageNameAlternative }}", - "description": "{{ package.description }}", - "repository": { - "type": "git", - "url": "{{ package.repositoryUrl }}" - }, - "homepage": "{{ package.author.homepage }}", - "author": "{{ package.author.name }}", - "version": "1.0.0", - "license": "GPL-2.0-or-later", - "devDependencies": { - "grunt": "^1.0.3", - "grunt-contrib-uglify": "^4.0.0", - "grunt-contrib-watch": "^1.1.0", - "grunt-contrib-imagemin": "^2.0.1" - } -} diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Classes/.htaccess b/resources/skeletons/BaseExtension/bootstrap_package/Classes/.htaccess deleted file mode 100644 index 93169e4e..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Classes/.htaccess +++ /dev/null @@ -1,2 +0,0 @@ -Order deny,allow -Deny from all diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Classes/Controller/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Classes/Controller/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Classes/Controller/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/Model/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/Model/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/Model/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/Repository/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/Repository/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Classes/Domain/Repository/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Classes/ViewHelpers/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Classes/ViewHelpers/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Classes/ViewHelpers/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/.htaccess b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/.htaccess deleted file mode 100644 index 93169e4e..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/.htaccess +++ /dev/null @@ -1,2 +0,0 @@ -Order deny,allow -Deny from all diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/RTE/Default.yaml.twig b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/RTE/Default.yaml.twig deleted file mode 100644 index 282236ed..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/RTE/Default.yaml.twig +++ /dev/null @@ -1,9 +0,0 @@ -imports: - - { resource: "EXT:rte_ckeditor/Configuration/RTE/Processing.yaml" } - - { resource: "EXT:rte_ckeditor/Configuration/RTE/Editor/Base.yaml" } - - { resource: "EXT:rte_ckeditor/Configuration/RTE/Editor/Plugins.yaml" } - - { resource: "EXT:bootstrap_package/Configuration/RTE/Default.yaml" } - -editor: - config: - contentsCss: "EXT:bootstrap_package/Resources/Public/Css/bootstrap4-rte.min.css" diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TCA/Overrides/pages.php.twig b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TCA/Overrides/pages.php.twig deleted file mode 100644 index 672a2d1e..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TCA/Overrides/pages.php.twig +++ /dev/null @@ -1,19 +0,0 @@ - - - - diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts.tsconfig.twig b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts.tsconfig.twig deleted file mode 100644 index 8213cfae..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts.tsconfig.twig +++ /dev/null @@ -1,4 +0,0 @@ -# -# BACKENDLAYOUTS -# - diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts/example.tsconfig.twig b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts/example.tsconfig.twig deleted file mode 100644 index 628a7254..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts/example.tsconfig.twig +++ /dev/null @@ -1,29 +0,0 @@ -# -# BACKENDLAYOUT: EXAMPLE -# -mod { - web_layout { - BackendLayouts { - example { - title = LLL:EXT:{{ package.extensionKey }}/Resources/Private/Language/locallang_be.xlf:backend_layout.example - config { - backend_layout { - colCount = 1 - rowCount = 1 - rows { - 1 { - columns { - 1 { - name = LLL:EXT:{{ package.extensionKey }}/Resources/Private/Language/locallang_be.xlf:backend_layout.column.normal - colPos = 0 - } - } - } - } - } - } - icon = EXT:{{ package.extensionKey }}/Resources/Public/Icons/BackendLayouts/example.svg - } - } - } -} diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/RTE.tsconfig.twig b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/RTE.tsconfig.twig deleted file mode 100644 index 38353247..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/RTE.tsconfig.twig +++ /dev/null @@ -1,8 +0,0 @@ -############# -#### RTE #### -############# -RTE { - default { - preset = {{ package.extensionKey }} - } -} diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/TCEFORM.tsconfig.twig b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/TCEFORM.tsconfig.twig deleted file mode 100644 index 55f97ce7..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/TCEFORM.tsconfig.twig +++ /dev/null @@ -1,11 +0,0 @@ -# -# TCEFORM -# -TCEFORM { - pages { - - } - tt_content { - - } -} diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/TCEMAIN.tsconfig.twig b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/TCEMAIN.tsconfig.twig deleted file mode 100644 index 9d4a5e4e..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TsConfig/Page/TCEMAIN.tsconfig.twig +++ /dev/null @@ -1,6 +0,0 @@ -# -# TCEMAIN -# -TCEMAIN { - -} diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TypoScript/constants.typoscript.twig b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TypoScript/constants.typoscript.twig deleted file mode 100644 index 32904169..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TypoScript/constants.typoscript.twig +++ /dev/null @@ -1,60 +0,0 @@ -###################### -#### DEPENDENCIES #### -###################### - - - -############ -### PAGE ### -############ -page { - logo { - file = EXT:{{ package.extensionKey }}/Resources/Public/Images/logo.svg - fileInverted = EXT:{{ package.extensionKey }}/Resources/Public/Images/logo-inverted.svg - height = 52 - width = 192 - alt = {{ package.title }} - linktitle = {{ package.title }} - } - favicon { - file = EXT:{{ package.extensionKey }}/Resources/Public/Icons/favicon.ico - } - fluidtemplate { - layoutRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Layouts/Page/ - partialRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Partials/Page/ - templateRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Templates/Page/ - } -} - - -################## -### EXTENSIONS ### -################## -plugin.bootstrap_package { - view { - layoutRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Layouts/ - partialRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Partials/ - templateRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Templates/ - } -} - - -######################## -### CONTENT ELEMENTS ### -######################## -plugin.bootstrap_package_contentelements { - view { - layoutRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Layouts/ContentElements/ - partialRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Partials/ContentElements/ - templateRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Templates/ContentElements/ - } -} - - -################################ -### BOOTSTRAP SCSS CONSTANTS ### -################################ -plugin.bootstrap_package.settings.scss { - primary = #eb3e4a - secondary = #013859 -} diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TypoScript/setup.typoscript.twig b/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TypoScript/setup.typoscript.twig deleted file mode 100644 index 00a04208..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Configuration/TypoScript/setup.typoscript.twig +++ /dev/null @@ -1,30 +0,0 @@ -###################### -#### DEPENDENCIES #### -###################### - - - -############## -#### PAGE #### -############## -page { - includeCSS { - theme = EXT:{{ package.extensionKey }}/Resources/Public/Scss/Theme/theme.scss - } - - includeJSLibs { - - } - - includeJS { - - } - - includeJSFooterlibs { - - } - - includeJSFooter { - {{ package.extensionKey }}_scripts = EXT:{{ package.extensionKey }}/Resources/Public/JavaScript/Dist/scripts.js - } -} diff --git a/resources/skeletons/BaseExtension/bootstrap_package/README.md.twig b/resources/skeletons/BaseExtension/bootstrap_package/README.md.twig deleted file mode 100644 index 8b095c79..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/README.md.twig +++ /dev/null @@ -1,4 +0,0 @@ -Sitepackage for the project "{{ package.title }}" -============================================================== - -Add some explanation here. diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/.htaccess b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/.htaccess deleted file mode 100644 index 93169e4e..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/.htaccess +++ /dev/null @@ -1,2 +0,0 @@ -Order deny,allow -Deny from all diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang.xlf.twig b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang.xlf.twig deleted file mode 100644 index 5aea2770..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang.xlf.twig +++ /dev/null @@ -1,11 +0,0 @@ - - - -
- {{ package.author.name }} - {{ package.author.email }} -
- - -
-
diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang_be.xlf.twig b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang_be.xlf.twig deleted file mode 100644 index 8b09912d..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang_be.xlf.twig +++ /dev/null @@ -1,17 +0,0 @@ - - - -
- {{ package.author.name }} - {{ package.author.email }} -
- - - Example - - - Normal - - -
-
diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang_db.xlf.twig b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang_db.xlf.twig deleted file mode 100644 index 5aea2770..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Language/locallang_db.xlf.twig +++ /dev/null @@ -1,11 +0,0 @@ - - - -
- {{ package.author.name }} - {{ package.author.email }} -
- - -
-
diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Layouts/ContentElements/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Layouts/ContentElements/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Layouts/ContentElements/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Layouts/Page/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Layouts/Page/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Partials/ContentElements/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Partials/ContentElements/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Partials/ContentElements/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Partials/Page/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Partials/Page/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Partials/Page/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Templates/ContentElements/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Templates/ContentElements/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Templates/ContentElements/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Templates/Page/Example.html.twig b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Templates/Page/Example.html.twig deleted file mode 100644 index 2b67bb11..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Private/Templates/Page/Example.html.twig +++ /dev/null @@ -1,22 +0,0 @@ - - - - -
-
-
-
Template file
-
- typo3conf/ext/{{ package.extensionKey }}/Resources/Private/Templates/Page/Example.html -
-
Backend Configuration
-
- typo3conf/ext/{{ package.extensionKey }}/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts/example.tsconfig -
-
-
-
- - -
- diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Css/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Css/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Css/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Fonts/.gitkeep b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Fonts/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Fonts/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/BackendLayouts/example.svg b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/BackendLayouts/example.svg deleted file mode 100644 index d05abec2..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/BackendLayouts/example.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/Extension.svg b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/Extension.svg deleted file mode 100644 index d8536373..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/Extension.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/favicon.ico b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/favicon.ico deleted file mode 100644 index 46d4c14df35ee4ccdf7c5a7eba53f00bc4457963..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmaKszb^zq6vrP&t{`y*Vj}8oqXL6Y$R~|E{BN6xxSFH~V-8J?S315x+S4 zj-Y)ybmKo(YfpQ6?x1gZYOBicJEMBKKl2?Y;7851p!}yw*Ju2g^_YOA4@`k=u$$QG%PiuMovJt++@ORg$yF+-?obfjA|?e@V(Z#s}~VJtDD0 diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/logo-inverted.svg b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/logo-inverted.svg deleted file mode 100644 index f465b080..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/logo-inverted.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/logo.svg b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/logo.svg deleted file mode 100644 index dc1615ff..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Icons/logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Images/logo-inverted.svg b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Images/logo-inverted.svg deleted file mode 100644 index f465b080..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Images/logo-inverted.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Images/logo.svg b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Images/logo.svg deleted file mode 100644 index dc1615ff..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Images/logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/JavaScript/Dist/scripts.js.twig b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/JavaScript/Dist/scripts.js.twig deleted file mode 100644 index af832405..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/JavaScript/Dist/scripts.js.twig +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * {{ package.title }} v1.0.0 ({{ package.author.homepage }}) - * Copyright 2017-{{ 'now'|date('Y') }} {{ package.author.name }} - * Licensed under the GPL-2.0-or-later license - */ -console.log("WE LOVE TYPO3"); diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/JavaScript/Src/main.js.twig b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/JavaScript/Src/main.js.twig deleted file mode 100644 index a5e49024..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/JavaScript/Src/main.js.twig +++ /dev/null @@ -1 +0,0 @@ -console.log('WE LOVE TYPO3'); diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Scss/Theme/_variables.scss b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Scss/Theme/_variables.scss deleted file mode 100644 index 4a4e02e8..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Scss/Theme/_variables.scss +++ /dev/null @@ -1,3 +0,0 @@ -// -// Variables -// diff --git a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Scss/Theme/theme.scss.twig b/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Scss/Theme/theme.scss.twig deleted file mode 100644 index 2cd35190..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/Resources/Public/Scss/Theme/theme.scss.twig +++ /dev/null @@ -1,9 +0,0 @@ -// -// Variables -// -@import "variables"; - -// -// Import needed Bootstrap Package Files -// -{% if package.typo3version < 10004000 %}@import "../../../../../bootstrap_package/Resources/Public/Scss/Theme/theme";{% else %}@import "EXT:bootstrap_package/Resources/Public/Scss/bootstrap5/theme";{% endif %} diff --git a/resources/skeletons/BaseExtension/bootstrap_package/composer.json.twig b/resources/skeletons/BaseExtension/bootstrap_package/composer.json.twig deleted file mode 100644 index 4669e4c1..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/composer.json.twig +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "{{ package.vendorNameAlternative }}/{{ package.packageNameAlternative }}", - "type": "typo3-cms-extension", - "description": "{{ package.description}}", - "homepage": "{{ package.author.homepage }}", - "license": ["GPL-2.0-or-later"], - "keywords": ["TYPO3 CMS"], - "require": { - "bk2k/bootstrap-package": "{% if package.typo3version < 9000000 %}^10.0{% elseif package.typo3version < 10000000 %}^10.0 || ^11.0{% else %}^12.0{% endif %}" - }, - "autoload": { - "psr-4": { - "{{ package.vendorName }}\\{{ package.packageName }}\\": "Classes/" - } - }, - "extra": { - "typo3/cms": { - "extension-key": "{{ package.extensionKey }}" - } - } -} diff --git a/resources/skeletons/BaseExtension/bootstrap_package/ext_conf_template.txt.twig b/resources/skeletons/BaseExtension/bootstrap_package/ext_conf_template.txt.twig deleted file mode 100644 index e87dc9ce..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/ext_conf_template.txt.twig +++ /dev/null @@ -1,3 +0,0 @@ -# -# Extension Configuration template -# diff --git a/resources/skeletons/BaseExtension/bootstrap_package/ext_emconf.php.twig b/resources/skeletons/BaseExtension/bootstrap_package/ext_emconf.php.twig deleted file mode 100644 index 14ebcae5..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/ext_emconf.php.twig +++ /dev/null @@ -1,30 +0,0 @@ - '{{ package.title }}', - 'description' => '{{ package.description }}', - 'category' => 'templates', - 'constraints' => [ - 'depends' => [ - 'bootstrap_package' => '{% if package.typo3version < 9000000 %}10.0.0-10.0.99{% elseif package.typo3version < 10000000 %}10.0.0-11.0.99{% else %}12.0.0-12.9.99{% endif %}', - ], - 'conflicts' => [ - ], - ], - 'autoload' => [ - 'psr-4' => [ - '{{ package.vendorName }}\\{{ package.packageName }}\\' => 'Classes', - ], - ], - 'state' => 'stable', - 'uploadfolder' => 0, - 'createDirs' => '', - 'clearCacheOnLoad' => 1, - 'author' => '{{ package.author.name }}', - 'author_email' => '{{ package.author.email }}', - 'author_company' => '{{ package.author.company }}', - 'version' => '1.0.0', -]; diff --git a/resources/skeletons/BaseExtension/bootstrap_package/ext_localconf.php.twig b/resources/skeletons/BaseExtension/bootstrap_package/ext_localconf.php.twig deleted file mode 100644 index cc9f50b7..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/ext_localconf.php.twig +++ /dev/null @@ -1,12 +0,0 @@ -'); diff --git a/resources/skeletons/BaseExtension/bootstrap_package/ext_tables.php.twig b/resources/skeletons/BaseExtension/bootstrap_package/ext_tables.php.twig deleted file mode 100644 index 8eb918c9..00000000 --- a/resources/skeletons/BaseExtension/bootstrap_package/ext_tables.php.twig +++ /dev/null @@ -1,2 +0,0 @@ -Resources/', - sass: '<%= paths.resources %>Public/Scss/', - css: '<%= paths.resources %>Public/Css/', - fonts: '<%= paths.resources %>Public/Fonts/', - img: '<%= paths.resources %>Public/Images/', - js: '<%= paths.resources %>Public/JavaScript/' - }, - banner: '/*!\n' + - ' * {{ package.title }} v<%= pkg.version %> (<%= pkg.homepage %>)\n' + - ' * Copyright 2017-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' + - ' * Licensed under the <%= pkg.license %> license\n' + - ' */\n', - uglify: { - all: { - options: { - banner: '<%= banner %>', - mangle: true, - compress: true, - beautify: false - }, - files: { - "<%= paths.js %>/Dist/scripts.js": [ - "<%= paths.js %>Src/main.js" - ] - } - } - }, - sass: { - options: { - implementation: sass, - outputStyle: 'expanded', - precision: 8, - sourceMap: false - }, - layout: { - files: { - '<%= paths.css %>layout.css': '<%= paths.sass %>layout.scss' - } - } - }, - postcss: { - options: { - map: false, - processors: [ - require('autoprefixer')({ - browsers: [ - 'Last 2 versions', - 'Firefox ESR', - 'IE 9' - ] - }) - ] - }, - layout: { - src: '<%= paths.css %>layout.css' - } - }, - cssmin: { - options: { - keepSpecialComments: '*', - advanced: false - }, - layout: { - src: '<%= paths.css %>layout.css', - dest: '<%= paths.css %>layout.min.css' - } - }, - imagemin: { - extension: { - files: [{ - expand: true, - cwd: '<%= paths.resources %>', - src: [ - '**/*.{png,jpg,gif}' - ], - dest: '<%= paths.resources %>' - }] - } - }, - watch: { - options: { - livereload: true - }, - sass: { - files: '<%= paths.sass %>**/*.scss', - tasks: ['css'] - }, - javascript: { - files: '<%= paths.js %>Src/**/*.js', - tasks: ['js'] - } - } - }); - - /** - * Register tasks - // */ - grunt.loadNpmTasks('grunt-contrib-cssmin'); - grunt.loadNpmTasks('grunt-contrib-uglify'); - grunt.loadNpmTasks('grunt-contrib-watch'); - grunt.loadNpmTasks('grunt-contrib-imagemin'); - grunt.loadNpmTasks('grunt-postcss'); - grunt.loadNpmTasks('grunt-sass'); - - /** - * Grunt update task - */ - grunt.registerTask('css', ['sass', 'postcss', 'cssmin']); - grunt.registerTask('js', ['uglify']); - grunt.registerTask('build', ['js', 'css', 'imagemin']); - grunt.registerTask('default', ['build']); - -}; diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Build/package.json.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Build/package.json.twig deleted file mode 100644 index a870947b..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Build/package.json.twig +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "{{ package.vendorNameAlternative }}-{{ package.packageNameAlternative }}", - "description": "{{ package.description }}", - "repository": { - "type": "git", - "url": "{{ package.repositoryUrl }}" - }, - "homepage": "{{ package.author.homepage }}", - "author": "{{ package.author.name }}", - "version": "1.0.0", - "license": "GPL-2.0-or-later", - "devDependencies": { - "grunt": "^1.0.4", - "grunt-contrib-cssmin": "^3.0.0", - "grunt-contrib-uglify": "^4.0.1", - "grunt-contrib-watch": "^1.1.0", - "grunt-contrib-imagemin": "^3.1.0", - "grunt-postcss": "^0.9.0", - "grunt-sass": "^3.0.2", - "autoprefixer": "^9.5.0", - "node-sass": "^4.11.0" - }, - "scripts": { - "build": "./node_modules/.bin/grunt", - "css": "./node_modules/.bin/grunt css", - "watch": "./node_modules/.bin/grunt watch" - } -} diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Classes/.htaccess b/resources/skeletons/BaseExtension/fluid_styled_content/Classes/.htaccess deleted file mode 100644 index 93169e4e..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Classes/.htaccess +++ /dev/null @@ -1,2 +0,0 @@ -Order deny,allow -Deny from all diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Controller/.gitkeep b/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Controller/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Controller/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/.gitkeep b/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/Model/.gitkeep b/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/Model/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/Model/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/Repository/.gitkeep b/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/Repository/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Classes/Domain/Repository/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Classes/ViewHelpers/.gitkeep b/resources/skeletons/BaseExtension/fluid_styled_content/Classes/ViewHelpers/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Classes/ViewHelpers/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/.htaccess b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/.htaccess deleted file mode 100644 index 93169e4e..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/.htaccess +++ /dev/null @@ -1,2 +0,0 @@ -Order deny,allow -Deny from all diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/RTE/Default.yaml.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/RTE/Default.yaml.twig deleted file mode 100644 index 5d5556da..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/RTE/Default.yaml.twig +++ /dev/null @@ -1,42 +0,0 @@ -imports: - - { resource: "EXT:rte_ckeditor/Configuration/RTE/Processing.yaml" } - - { resource: "EXT:rte_ckeditor/Configuration/RTE/Editor/Base.yaml" } - - { resource: "EXT:rte_ckeditor/Configuration/RTE/Editor/Plugins.yaml" } - -editor: - config: - contentsCss: "EXT:{{ package.extensionKey }}/Resources/Public/Css/rte.css" - - stylesSet: - - { name: "Lead", element: "p", attributes: { 'class': 'lead' } } - - toolbarGroups: - - { name: styles, groups: [ format, styles ] } - - { name: basicstyles, groups: [ basicstyles ] } - - { name: paragraph, groups: [ list, indent, blocks, align ] } - - "/" - - { name: links, groups: [ links ] } - - { name: clipboard, groups: [ clipboard, cleanup, undo ] } - - { name: editing, groups: [ spellchecker ] } - - { name: insert, groups: [ insert ] } - - { name: tools, groups: [ table, specialchar ] } - - { name: document, groups: [ mode ] } - - format_tags: "p;h1;h2;h3;h4;h5;pre" - - justifyClasses: - - text-left - - text-center - - text-right - - text-justify - - extraPlugins: - - justify - - removePlugins: - - image - - removeButtons: - - Anchor - - Underline - - Strike diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TCA/Overrides/pages.php.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TCA/Overrides/pages.php.twig deleted file mode 100644 index 672a2d1e..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TCA/Overrides/pages.php.twig +++ /dev/null @@ -1,19 +0,0 @@ - - - - diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts.tsconfig.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts.tsconfig.twig deleted file mode 100644 index 8213cfae..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts.tsconfig.twig +++ /dev/null @@ -1,4 +0,0 @@ -# -# BACKENDLAYOUTS -# - diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts/default.tsconfig.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts/default.tsconfig.twig deleted file mode 100644 index a16a9db6..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts/default.tsconfig.twig +++ /dev/null @@ -1,29 +0,0 @@ -# -# BACKENDLAYOUT: DEFAULT -# -mod { - web_layout { - BackendLayouts { - default { - title = LLL:EXT:{{ package.extensionKey }}/Resources/Private/Language/locallang_be.xlf:backend_layout.default - config { - backend_layout { - colCount = 1 - rowCount = 1 - rows { - 1 { - columns { - 1 { - name = LLL:EXT:{{ package.extensionKey }}/Resources/Private/Language/locallang_be.xlf:backend_layout.column.normal - colPos = 0 - } - } - } - } - } - } - icon = EXT:{{ package.extensionKey }}/Resources/Public/Images/BackendLayouts/default.png - } - } - } -} diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/RTE.tsconfig.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/RTE.tsconfig.twig deleted file mode 100644 index 38353247..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/RTE.tsconfig.twig +++ /dev/null @@ -1,8 +0,0 @@ -############# -#### RTE #### -############# -RTE { - default { - preset = {{ package.extensionKey }} - } -} diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/TCEFORM.tsconfig.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/TCEFORM.tsconfig.twig deleted file mode 100644 index 55f97ce7..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/TCEFORM.tsconfig.twig +++ /dev/null @@ -1,11 +0,0 @@ -# -# TCEFORM -# -TCEFORM { - pages { - - } - tt_content { - - } -} diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/TCEMAIN.tsconfig.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/TCEMAIN.tsconfig.twig deleted file mode 100644 index 9d4a5e4e..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TsConfig/Page/TCEMAIN.tsconfig.twig +++ /dev/null @@ -1,6 +0,0 @@ -# -# TCEMAIN -# -TCEMAIN { - -} diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/Helper/DynamicContent.typoscript.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/Helper/DynamicContent.typoscript.twig deleted file mode 100644 index 993b020b..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/Helper/DynamicContent.typoscript.twig +++ /dev/null @@ -1,64 +0,0 @@ -################################################ -#### DYNAMIC CONTENT LIB FOR USAGE IN FLUID #### -################################################ -# -# EXAMPLE -# --------------- -# |'}" /> -# -# -# COLUMN NUMBERS -# --------------- -# -# 0 = main -# 1 = left -# 2 = right -# 3 = border -# -################# -lib.dynamicContent = COA -lib.dynamicContent { - 5 = LOAD_REGISTER - 5 { - colPos.cObject = TEXT - colPos.cObject { - field = colPos - ifEmpty.cObject = TEXT - ifEmpty.cObject { - value.current = 1 - ifEmpty = 0 - } - } - pageUid.cObject = TEXT - pageUid.cObject { - field = pageUid - ifEmpty.data = TSFE:id - } - contentFromPid.cObject = TEXT - contentFromPid.cObject { - data = DB:pages:{register:pageUid}:content_from_pid - data.insertData = 1 - } - wrap.cObject = TEXT - wrap.cObject { - field = wrap - } - } - 20 = CONTENT - 20 { - table = tt_content - select { - includeRecordsWithoutDefaultTranslation = 1 - orderBy = sorting - where = {{ '{#colPos}={register:colPos}' }} - where.insertData = 1 - pidInList.data = register:pageUid - pidInList.override.data = register:contentFromPid - } - stdWrap { - dataWrap = {register:wrap} - required = 1 - } - } - 90 = RESTORE_REGISTER -} diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/constants.typoscript.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/constants.typoscript.twig deleted file mode 100644 index 5a38ef29..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/constants.typoscript.twig +++ /dev/null @@ -1,56 +0,0 @@ -###################### -#### DEPENDENCIES #### -###################### - - - -############################## -#### FLUID STYLED CONTENT #### -############################## -styles { - templates { - layoutRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Layouts/ContentElements/ - partialRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Partials/ContentElements/ - templateRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Templates/ContentElements/ - } -} - - -############ -### PAGE ### -############ -page { - fluidtemplate { - layoutRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Layouts/Page/ - partialRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Partials/Page/ - templateRootPath = EXT:{{ package.extensionKey }}/Resources/Private/Templates/Page/ - } - meta { - description = - author = - keywords = - viewport = width=device-width, initial-scale=1 - robots = index,follow - apple-mobile-web-app-capable = no - compatible = IE=edge - } - tracking { - google { - trackingID = - anonymizeIp = 1 - } - } -} - - -############## -### CONFIG ### -############## -config { - no_cache = 0 - removeDefaultJS = 0 - admPanel = 1 - prefixLocalAnchors = all - headerComment = build by sitepackagebuilder.com - sendCacheHeaders = 1 -} diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/setup.typoscript.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/setup.typoscript.twig deleted file mode 100644 index 1ed237f7..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Configuration/TypoScript/setup.typoscript.twig +++ /dev/null @@ -1,203 +0,0 @@ -###################### -#### DEPENDENCIES #### -###################### - - - -################ -#### HELPER #### -################ - - - -############## -#### PAGE #### -############## -page = PAGE -page { - typeNum = 0 - shortcutIcon = EXT:{{ package.extensionKey }}/Resources/Public/Icons/favicon.ico - - 10 = FLUIDTEMPLATE - 10 { - # Template names will be generated automatically by converting the applied - # backend_layout, there is no explicit mapping necessary anymore. - # - # BackendLayout Key - # subnavigation_right_2_columns -> SubnavigationRight2Columns.html - # - # Backend Record - # uid: 1 -> 1.html - # - # Database Entry - # value: -1 -> None.html - # value: pagets__subnavigation_right_2_columns -> SubnavigationRight2Columns.html - templateName = TEXT - templateName { - cObject = TEXT - cObject { - data = pagelayout - required = 1 - case = uppercamelcase - split { - token = pagets__ - cObjNum = 1 - 1.current = 1 - } - } - ifEmpty = Default - } - templateRootPaths { - 0 = EXT:{{ package.extensionKey }}/Resources/Private/Templates/Page/ - 1 = {$page.fluidtemplate.templateRootPath} - } - partialRootPaths { - 0 = EXT:{{ package.extensionKey }}/Resources/Private/Partials/Page/ - 1 = {$page.fluidtemplate.partialRootPath} - } - layoutRootPaths { - 0 = EXT:{{ package.extensionKey }}/Resources/Private/Layouts/Page/ - 1 = {$page.fluidtemplate.layoutRootPath} - } - dataProcessing { - 10 = TYPO3\CMS\Frontend\DataProcessing\FilesProcessor - 10 { - references.fieldName = media - } - 20 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor - 20 { - levels = 2 - includeSpacer = 1 - as = mainnavigation - } - } - } - - meta { - viewport = {$page.meta.viewport} - robots = {$page.meta.robots} - apple-mobile-web-app-capable = {$page.meta.apple-mobile-web-app-capable} - description = {$page.meta.description} - description { - override.field = description - } - author = {$page.meta.author} - author { - override.field = author - } - keywords = {$page.meta.keywords} - keywords { - override.field = keywords - } - X-UA-Compatible = {$page.meta.compatible} - X-UA-Compatible { - attribute = http-equiv - } - - # OpenGraph Tags - og:title { - attribute = property - field = title - } - og:site_name { - attribute = property - data = TSFE:tmpl|setup|sitetitle - } - og:description = {$page.meta.description} - og:description { - attribute = property - field = description - } - og:image { - attribute = property - stdWrap.cObject = FILES - stdWrap.cObject { - references { - data = levelfield:-1, media, slide - } - maxItems = 1 - renderObj = COA - renderObj { - 10 = IMG_RESOURCE - 10 { - file { - import.data = file:current:uid - treatIdAsReference = 1 - width = 1280c - height = 720c - } - stdWrap { - typolink { - parameter.data = TSFE:lastImgResourceInfo|3 - returnLast = url - forceAbsoluteUrl = 1 - } - } - } - } - } - } - } - - includeCSSLibs { - - } - - includeCSS { - {{ package.extensionKey }}_layout = EXT:{{ package.extensionKey }}/Resources/Public/Css/layout.min.css - } - - includeJSLibs { - - } - - includeJS { - - } - - includeJSFooterlibs { - - } - - includeJSFooter { - {{ package.extensionKey }}_scripts = EXT:{{ package.extensionKey }}/Resources/Public/JavaScript/Dist/scripts.js - } -} - - -################ -#### CONFIG #### -################ -config { - absRefPrefix = auto - no_cache = {$config.no_cache} - uniqueLinkVars = 1 - pageTitleFirst = 1 - linkVars = L - prefixLocalAnchors = {$config.prefixLocalAnchors} - renderCharset = utf-8 - metaCharset = utf-8 - doctype = html5 - removeDefaultJS = {$config.removeDefaultJS} - inlineStyle2TempFile = 1 - admPanel = {$config.admPanel} - debug = 0 - cache_period = 86400 - sendCacheHeaders = {$config.sendCacheHeaders} - intTarget = - extTarget = - disablePrefixComment = 1 - index_enable = 1 - index_externals = 1 - index_metatags = 1 - headerComment = {$config.headerComment} - - // Disable Image Upscaling - noScaleUp = 1 - - // Compression and Concatenation of CSS and JS Files - compressJs = 0 - compressCss = 0 - concatenateJs = 0 - concatenateCss = 0 -} diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/README.md.twig b/resources/skeletons/BaseExtension/fluid_styled_content/README.md.twig deleted file mode 100644 index 8b095c79..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/README.md.twig +++ /dev/null @@ -1,4 +0,0 @@ -Sitepackage for the project "{{ package.title }}" -============================================================== - -Add some explanation here. diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/.htaccess b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/.htaccess deleted file mode 100644 index 93169e4e..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/.htaccess +++ /dev/null @@ -1,2 +0,0 @@ -Order deny,allow -Deny from all diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang.xlf.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang.xlf.twig deleted file mode 100644 index 5aea2770..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang.xlf.twig +++ /dev/null @@ -1,11 +0,0 @@ - - - -
- {{ package.author.name }} - {{ package.author.email }} -
- - -
-
diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang_be.xlf.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang_be.xlf.twig deleted file mode 100644 index fb3e2d8e..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang_be.xlf.twig +++ /dev/null @@ -1,17 +0,0 @@ - - - -
- {{ package.author.name }} - {{ package.author.email }} -
- - - Default - - - Normal - - -
-
diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang_db.xlf.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang_db.xlf.twig deleted file mode 100644 index 5aea2770..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Language/locallang_db.xlf.twig +++ /dev/null @@ -1,11 +0,0 @@ - - - -
- {{ package.author.name }} - {{ package.author.email }} -
- - -
-
diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Layouts/ContentElements/.gitkeep b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Layouts/ContentElements/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Layouts/ContentElements/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Layouts/Page/Default.html.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Layouts/Page/Default.html.twig deleted file mode 100644 index ad57953f..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Layouts/Page/Default.html.twig +++ /dev/null @@ -1,21 +0,0 @@ - - diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Partials/ContentElements/.gitkeep b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Partials/ContentElements/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Partials/ContentElements/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Partials/Page/.gitkeep b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Partials/Page/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Partials/Page/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Templates/ContentElements/.gitkeep b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Templates/ContentElements/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Templates/ContentElements/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Templates/Page/Default.html.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Templates/Page/Default.html.twig deleted file mode 100644 index 312fc91f..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Private/Templates/Page/Default.html.twig +++ /dev/null @@ -1,19 +0,0 @@ - - - -
-
-
Template file
-
- typo3conf/ext/{{ package.extensionKey }}/Resources/Private/Templates/Page/Default.html -
-
Backend Configuration
-
- typo3conf/ext/{{ package.extensionKey }}/Configuration/TsConfig/Page/Mod/WebLayout/BackendLayouts/default.tsconfig -
-
-
- - - -
diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Css/layout.css b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Css/layout.css deleted file mode 100644 index e69de29b..00000000 diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Css/layout.min.css b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Css/layout.min.css deleted file mode 100644 index e69de29b..00000000 diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Css/rte.css.twig b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Css/rte.css.twig deleted file mode 100644 index 1ce5278d..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Css/rte.css.twig +++ /dev/null @@ -1,3 +0,0 @@ -/** - * Created from sitepackagebuilder.com - */ diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Fonts/.gitkeep b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Fonts/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Fonts/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Icons/Extension.svg b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Icons/Extension.svg deleted file mode 100644 index d8536373..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Icons/Extension.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Icons/favicon.ico b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Icons/favicon.ico deleted file mode 100644 index 46d4c14df35ee4ccdf7c5a7eba53f00bc4457963..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmaKszb^zq6vrP&t{`y*Vj}8oqXL6Y$R~|E{BN6xxSFH~V-8J?S315x+S4 zj-Y)ybmKo(YfpQ6?x1gZYOBicJEMBKKl2?Y;7851p!}yw*Ju2g^_YOA4@`k=u$$QG%PiuMovJt++@ORg$yF+-?obfjA|?e@V(Z#s}~VJtDD0 diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Images/BackendLayouts/default.png b/resources/skeletons/BaseExtension/fluid_styled_content/Resources/Public/Images/BackendLayouts/default.png deleted file mode 100644 index 0bed87019c8f61d46b9493157358054e2af23994..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 182 zcmeAS@N?(olHy`uVBq!ia0vp^MnLSq!3HEFuBuc6saj7L$B>N1x3?X6TLMH_4jxZ? zT5x1PQ{RuD+D*PICg`zVW=f0BUR&At{>+(;^8W94Jl%8dr;Y8Sc&>{gi!@z=JC+If mD$a5;Y0V%};H~cVZu$S++?AJ4w7LNu!r '{{ package.title }}', - 'description' => '{{ package.description }}', - 'category' => 'templates', - 'constraints' => [ - 'depends' => [ - 'typo3' => '{% if package.typo3version < 9000000 %}8.7.0-8.7.99{% elseif package.typo3version < 10000000 %}9.5.0-9.5.99{% elseif package.typo3version < 11000000 %}10.4.0-10.4.99{% else %}11.5.0-11.5.99{% endif %}', - 'fluid_styled_content' => '{% if package.typo3version < 9000000 %}8.7.0-8.7.99{% elseif package.typo3version < 10000000 %}9.5.0-9.5.99{% elseif package.typo3version < 11000000 %}10.4.0-10.4.99{% else %}11.5.0-11.5.99{% endif %}', - 'rte_ckeditor' => '{% if package.typo3version < 9000000 %}8.7.0-8.7.99{% elseif package.typo3version < 10000000 %}9.5.0-9.5.99{% elseif package.typo3version < 11000000 %}10.4.0-10.4.99{% else %}11.5.0-11.5.99{% endif %}', - ], - 'conflicts' => [ - ], - ], - 'autoload' => [ - 'psr-4' => [ - '{{ package.vendorName }}\\{{ package.packageName }}\\' => 'Classes', - ], - ], - 'state' => 'stable', - 'uploadfolder' => 0, - 'createDirs' => '', - 'clearCacheOnLoad' => 1, - 'author' => '{{ package.author.name }}', - 'author_email' => '{{ package.author.email }}', - 'author_company' => '{{ package.author.company }}', - 'version' => '1.0.0', -]; diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/ext_localconf.php.twig b/resources/skeletons/BaseExtension/fluid_styled_content/ext_localconf.php.twig deleted file mode 100644 index cc9f50b7..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/ext_localconf.php.twig +++ /dev/null @@ -1,12 +0,0 @@ -'); diff --git a/resources/skeletons/BaseExtension/fluid_styled_content/ext_tables.php.twig b/resources/skeletons/BaseExtension/fluid_styled_content/ext_tables.php.twig deleted file mode 100644 index 8eb918c9..00000000 --- a/resources/skeletons/BaseExtension/fluid_styled_content/ext_tables.php.twig +++ /dev/null @@ -1,2 +0,0 @@ -composerinfo !== null) { - $composerInfo = json_decode((string)$version->composerinfo, true, 512); - if (is_array($composerInfo) && is_array($composerInfo['autoload'] ?? null)) { - $autoload = $composerInfo['autoload']; + try { + $composerInfo = json_decode((string)$version->composerinfo, true, 512, JSON_THROW_ON_ERROR); + if (is_array($composerInfo) && is_array($composerInfo['autoload'] ?? null)) { + $autoload = $composerInfo['autoload']; + } + } catch (\Throwable) { } } diff --git a/src/Controller/Admin/BasePackageCrudController.php b/src/Controller/Admin/BasePackageCrudController.php new file mode 100644 index 00000000..9d9934e5 --- /dev/null +++ b/src/Controller/Admin/BasePackageCrudController.php @@ -0,0 +1,68 @@ +add(Crud::PAGE_INDEX, Action::DETAIL) + ->add(Crud::PAGE_EDIT, Action::DETAIL) + ->remove(Crud::PAGE_INDEX, Action::DELETE) + ; + } + + public function configureFilters(Filters $filters): Filters + { + return $filters + ->add('name') + ->add('active') + ->add('official') + ; + } + + public function configureFields(string $pageName): iterable + { + return [ + TextField::new('name', 'Composer Package Name'), + BooleanField::new('active', 'Active'), + BooleanField::new('official', 'Official'), + ]; + } +} diff --git a/src/Controller/Admin/DashboardController.php b/src/Controller/Admin/DashboardController.php index 96d0b9de..b111edff 100644 --- a/src/Controller/Admin/DashboardController.php +++ b/src/Controller/Admin/DashboardController.php @@ -23,6 +23,7 @@ namespace App\Controller\Admin; +use App\Entity\BasePackage; use App\Entity\MajorVersion; use App\Entity\Release; use App\Entity\Requirement; @@ -49,14 +50,12 @@ public function configureDashboard(): Dashboard ->setTitle('Administration'); } - /** - * @return Iterator<\EasyCorp\Bundle\EasyAdminBundle\Config\Menu\CrudMenuItem|\EasyCorp\Bundle\EasyAdminBundle\Config\Menu\DashboardMenuItem> - */ public function configureMenuItems(): iterable { yield MenuItem::linkToDashboard('Dashboard', 'fa fa-home'); yield MenuItem::linkToCrud('Major Versions', 'fas fa-list', MajorVersion::class); yield MenuItem::linkToCrud('Requirements', 'fas fa-list', Requirement::class); yield MenuItem::linkToCrud('Releases', 'fas fa-list', Release::class); + yield MenuItem::linkToCrud('Base Packages', 'fas fa-list', BasePackage::class); } } diff --git a/src/Controller/Api/AbstractController.php b/src/Controller/Api/AbstractController.php index 8e567041..a34f5dfb 100644 --- a/src/Controller/Api/AbstractController.php +++ b/src/Controller/Api/AbstractController.php @@ -36,7 +36,6 @@ use JMS\Serializer\SerializerInterface; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; -use Symfony\Component\Validator\ConstraintViolationInterface; use Symfony\Contracts\Cache\TagAwareCacheInterface; use DateTime; use DateTimeImmutable; @@ -47,6 +46,8 @@ abstract class AbstractController extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractController { + use ValidationTrait; + public function __construct( private \Symfony\Contracts\Cache\TagAwareCacheInterface $cache, private \App\Service\CacheService $cacheService, @@ -106,26 +107,6 @@ protected function findMajorVersion(string $version): MajorVersion return $majorVersion; } - protected function validateObject(object $object): void - { - $violations = $this->validator->validate($object); - - if ($violations->count() > 0) { - $messages = ''; - - iterator_apply( - $violations, - static function (ConstraintViolationInterface $violation) use (&$messages): bool { - $messages .= \sprintf("%s: %s\n", $violation->getPropertyPath(), $violation->getMessage()); - return true; - }, - iterator_to_array($violations) - ); - - throw new BadRequestHttpException(trim($messages)); - } - } - /** * @param array $data */ diff --git a/src/Controller/Api/MajorVersion/RequirementsController.php b/src/Controller/Api/MajorVersion/RequirementsController.php index fd4441b3..68feca2b 100644 --- a/src/Controller/Api/MajorVersion/RequirementsController.php +++ b/src/Controller/Api/MajorVersion/RequirementsController.php @@ -233,7 +233,7 @@ public function updateRequirement(string $version, Request $request): JsonRespon ] ); if (!$entity instanceof Requirement) { - throw new NotFoundHttpException('Requirement does not exists'); + throw new NotFoundHttpException('Requirement does not exists.'); } $requirement->setVersion($entity->getVersion()); diff --git a/src/Controller/Api/SitepackageController.php b/src/Controller/Api/SitepackageController.php index a51bcc9c..ed29aac1 100644 --- a/src/Controller/Api/SitepackageController.php +++ b/src/Controller/Api/SitepackageController.php @@ -23,96 +23,87 @@ namespace App\Controller\Api; -use App\Entity\Sitepackage; -use App\Service\SitepackageGenerator; +use App\Package\Sitepackage; use App\Utility\StringUtility; -use JMS\Serializer\SerializerInterface; use Nelmio\ApiDocBundle\Annotation\Model; -use Swagger\Annotations as SWG; +use OpenApi\Annotations as OA; +//use OpenApi\Attributes as OA; +use OpenApi\Attributes\MediaType; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\BinaryFileResponse; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Routing\Annotation\Route; -use Symfony\Component\Validator\Validation; +use function is_string; -/** - * @Route("/api/v1/sitepackage", defaults={"_format": "json"}) - * @Route("/v1/api/sitepackage", defaults={"_format": "json"}) - */ +#[Route(path: '/api/v1/sitepackage', defaults: ['_format' => 'json'])] class SitepackageController extends AbstractController { - /** - * @var \JMS\Serializer\SerializerInterface - */ - protected $serializer; - - /** - * @var SitepackageGenerator - */ - protected $sitepackageGenerator; + use ValidationTrait; public function __construct( - SerializerInterface $serializer, - SitepackageGenerator $sitepackageGenerator + private \App\Service\SitepackageGenerator $sitepackageGenerator, + private \JMS\Serializer\SerializerInterface $serializer, + private \Symfony\Component\Validator\Validator\ValidatorInterface $validator, ) { - $this->serializer = $serializer; - $this->sitepackageGenerator = $sitepackageGenerator; } /** - * @Route("/", methods={"POST"}) - * @SWG\Parameter( - * name="sitepackage", - * in="body", - * @Model(type=Sitepackage::class) + * @OA\RequestBody( + * @Model(type=Sitepackage::class), + * request="sitepackage", + * required=true * ) - * @SWG\Response( + * @OA\Response( * response=200, * description="Successfully generated.", - * @SWG\Schema(type="file") + * @OA\Schema(type="file") * ) - * @SWG\Response( + * @OA\Response( * response=400, * description="Request malformed." * ) - * @SWG\Tag(name="sitepackage") + * @OA\Tag(name="sitepackage") */ - public function createSitepackage(Request $request): Response + /* + #[OA\RequestBody( + //new Model(type: Sitepackage::class) + //ref: new OA\Schema(type: Sitepackage::class), + request: 'sitepackage', + required: true, + //new Model(type: Sitepackage::class) + content: new Model(type: Sitepackage::class) + //content: new OA\Schema(ref: new Model(type: Sitepackage::class)) + )] + #[OA\RequestBody(new Model(type: Sitepackage::class))] + #[OA\Response( + response: 200, + description: 'Successfully generated.', + //content: new OA\Schema(type: 'file') + content: new OA\MediaType(mediaType: 'application/zip') + )] + #[OA\Response( + response: 400, + description: 'Request malformed.' + )] + #[OA\Tag(name: 'sitepackage')] + */ + #[Route(path: '/create', methods: ['POST'])] + public function createSitepackage(Request $request): BinaryFileResponse { - $content = $request->getContent(); + if (!is_string($content = $request->getContent())) { + throw new BadRequestHttpException('Missing or invalid request body.'); + } + /** @var Sitepackage $sitepackage */ $sitepackage = $this->serializer->deserialize($content, Sitepackage::class, 'json'); $this->validateObject($sitepackage); $this->sitepackageGenerator->create($sitepackage); $filename = $this->sitepackageGenerator->getFilename(); BinaryFileResponse::trustXSendfileTypeHeader(); - return $this ->file($this->sitepackageGenerator->getZipPath(), StringUtility::toASCII($filename)) ->deleteFileAfterSend(true); } - - /** - * @param Sitepackage $object - */ - protected function validateObject(Sitepackage $object): void - { - $validator = Validation::createValidatorBuilder() - ->enableAnnotationMapping() - ->getValidator() - ; - $violations = $validator->validate($object); - - if ($violations->count() > 0) { - $messages = ''; - \iterator_apply($violations, function (\Iterator $iterator) use ($messages) { - $messages .= $iterator->current()->getMessage() . "\n"; - return true; - }); - throw new BadRequestHttpException(trim($messages)); - } - } } diff --git a/src/Controller/Api/ValidationTrait.php b/src/Controller/Api/ValidationTrait.php new file mode 100644 index 00000000..19755071 --- /dev/null +++ b/src/Controller/Api/ValidationTrait.php @@ -0,0 +1,54 @@ +validator->validate($object); + + if ($violations->count() > 0) { + $messages = ''; + + iterator_apply( + $violations, + static function (ConstraintViolationInterface $violation) use (&$messages): bool { + $messages .= sprintf("%s: %s\n", $violation->getPropertyPath(), $violation->getMessage()); + return true; + }, + iterator_to_array($violations) + ); + + throw new BadRequestHttpException(trim($messages)); + } + } +} diff --git a/src/Controller/Webhooks/GitHubWebhookController.php b/src/Controller/Webhooks/GitHubWebhookController.php new file mode 100644 index 00000000..6a45f3cd --- /dev/null +++ b/src/Controller/Webhooks/GitHubWebhookController.php @@ -0,0 +1,70 @@ + 'json'])] +class GitHubWebhookController extends AbstractController +{ + public function __construct( + private readonly GitHubEventFactory $gitHubEventFactory, + private readonly GitHubRequestChecker $gitHubRequestChecker, + private \App\Service\BasePackageService $basePackageService + ) { + } + + #[Route(path: '', name: 'github_endpoint', methods: ['POST'])] + public function endPoint(Request $request): Response + { + try { + $this->gitHubRequestChecker->checkRequestSanity($request); + } catch (Throwable $throwable) { + // GitHub requires a successful (2xx) status in every case see + // https://pubsubhubbub.github.io/PubSubHubbub/pubsubhubbub-core-0.4.html#authednotify + return new Response($throwable->getMessage(), Response::HTTP_ACCEPTED); + } + + $gitHubEvent = $this->gitHubEventFactory->buildFromRequest($request); + + switch ($gitHubEvent->getType()) { + case 'ping': + return new Response('Ping received.', Response::HTTP_OK); + + case 'push': + $this->basePackageService->updatePackageRepository(); + return new Response('Package repository updated.', Response::HTTP_OK); + + default: + throw new UnknownGitHubEventTypeException($request, $gitHubEvent->getType(), 1_661_157_800); + } + } +} diff --git a/src/Controller/Wizards/SitepackageController.php b/src/Controller/Wizards/SitepackageController.php index 11579be3..05f070d8 100644 --- a/src/Controller/Wizards/SitepackageController.php +++ b/src/Controller/Wizards/SitepackageController.php @@ -23,204 +23,213 @@ namespace App\Controller\Wizards; -use App\Entity\Sitepackage; use App\Factory\SitepackageFactory; use App\Form\Dto\SitepackageDto; use App\Form\SitepackageType; -use App\Service\SitepackageGenerator; +use App\Session\WizardSessionTrait; use App\Utility\StringUtility; +use App\Utility\VersionUtility; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; -use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\SubmitButton; use Symfony\Component\HttpFoundation\BinaryFileResponse; +use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\Routing\Annotation\Route; +use Throwable; +use Twig\Error\RuntimeError; use UnexpectedValueException; -/** - * @Route("/wizards/sitepackage") -*/ +use function sprintf; + +#[Route(path: '/wizards/sitepackage')] final class SitepackageController extends AbstractController { - /** - * @Route("/", name="wizards_sitepackage") - */ + use WizardSessionTrait; + + public function __construct( + private \App\Service\BasePackageService $basePackageService, + private \App\Service\SitepackageGenerator $sitepackageGenerator, + ) { + } + + #[Route(path: '', name: 'wizards_sitepackage')] public function index(): Response { return $this->render( - 'default/wizards/sitepackage/index.html.twig', - [] + 'wizards/sitepackage/index.html.twig' ); } - /** - * @Route("/new/", name="wizards_sitepackage_new") - */ - public function new(Request $request): Response + #[Route(path: '/new', name: 'wizards_sitepackage_new')] + #[Route(path: '/new/{vendor}/{project}', name: 'wizards_sitepackage_new_filtered')] + public function new(string $vendor = '', string $project = ''): Response { - $session = $request->getSession(); - - $this->setAdvanced($session, false); - $this->setConfiguration($session, new SitepackageDto()); + $this->setSitepackageConfig(new SitepackageDto(), false); + + $filtered = false; + $basePackages = $this->basePackageService->getBasePackages(); + + if ($vendor !== '' && $project !== '') { + $basePackageName = sprintf('%s/%s', $vendor, $project); + + try { + $basePackage = $this->basePackageService->checkAndInstallMissingBasePackage($basePackageName); + $basePackages = [$basePackage]; + $filtered = true; + } catch (Throwable $throwable) { + $this->addFlash( + 'fatal', + $throwable->getMessage() + ); + return $this->redirectToRoute('wizards_sitepackage_new'); + } + } - return $this->redirectToRoute('wizards_sitepackage_edit'); + return $this->render( + 'wizards/sitepackage/new.html.twig', + [ + 'basePackages' => $basePackages, + 'filtered' => $filtered, + ] + ); } - /** - * @Route("/edit/", name="wizards_sitepackage_edit") - */ - public function edit(Request $request): Response + #[Route(path: '/validate/{vendor}/{project}', name: 'wizards_sitepackage_validate')] + public function validate(string $vendor, string $project): RedirectResponse { - $session = $request->getSession(); + try { + $configuration = $this->getSitepackageConfig(); + } catch (UnexpectedValueException) { + return $this->redirectToRoute('wizards_sitepackage_new'); + } + + $configuration->basePackage = sprintf('%s/%s', $vendor, $project); try { - $configuration = $this->getConfiguration($session); - } catch (UnexpectedValueException $th) { + $basePackage = $this->basePackageService->checkAndInstallMissingBasePackage($configuration->basePackage); + $configuration->typo3Version = VersionUtility::versionToInt($basePackage->typo3Versions[0]); + } catch (Throwable $throwable) { + $this->addFlash( + 'fatal', + $throwable->getMessage() + ); return $this->redirectToRoute('wizards_sitepackage_new'); } - $form = $this->createSitepackageForm($configuration, $this->getAdvanced($session)); + $this->setSitepackageConfig($configuration, $this->isAdvancedSitepackageConfig()); + + return $this->redirectToRoute('wizards_sitepackage_configure'); + } + + #[Route(path: '/configure', name: 'wizards_sitepackage_configure')] + public function configure(Request $request): Response + { + try { + $configuration = $this->getSitepackageConfig(); + } catch (UnexpectedValueException) { + return $this->redirectToRoute('wizards_sitepackage_new'); + } + + $form = $this->createForm( + SitepackageType::class, + $configuration, + [ + 'action' => $this->generateUrl('wizards_sitepackage_configure'), + 'advanced' => $this->isAdvancedSitepackageConfig(), + ] + ); $form->handleRequest($request); if ($form->isSubmitted()) { - if ($form->has('simple') && ($simple = $form->get('simple')) instanceof SubmitButton && $simple->isClicked()) { - $this->setAdvanced($session, false); - $this->setConfiguration($session, $configuration); + if ( + $form->has('simple') && + ($simple = $form->get('simple')) instanceof SubmitButton && $simple->isClicked() + ) { + $this->setSitepackageConfig($configuration, false); - return $this->redirectToRoute('wizards_sitepackage_edit'); + return $this->redirectToRoute('wizards_sitepackage_configure'); } - if ($form->has('advanced') && ($advanced = $form->get('advanced')) instanceof SubmitButton && $advanced->isClicked()) { - $this->setAdvanced($session, true); - $this->setConfiguration($session, $configuration); - return $this->redirectToRoute('wizards_sitepackage_edit'); + if ( + $form->has('advanced') && + ($advanced = $form->get('advanced')) instanceof SubmitButton && $advanced->isClicked() + ) { + $this->setSitepackageConfig($configuration, true); + + return $this->redirectToRoute('wizards_sitepackage_configure'); } if ($form->isValid()) { - $this->setConfiguration($session, $configuration); + $this->setSitepackageConfig($configuration, $this->isAdvancedSitepackageConfig()); return $this->redirectToRoute('wizards_sitepackage_success'); } } return $this->render( - 'default/wizards/sitepackage/edit.html.twig', + 'wizards/sitepackage/configure.html.twig', [ 'form' => $form->createView(), ] ); } - /** - * @Route("/success/", name="wizards_sitepackage_success") - */ - public function success(Request $request): Response + #[Route(path: '/success', name: 'wizards_sitepackage_success')] + public function success(): Response { - $session = $request->getSession(); - try { - $configuration = $this->getConfiguration($session); - } catch (UnexpectedValueException $th) { + $sitepackage = SitepackageFactory::fromDto($this->getSitepackageConfig()); + } catch (UnexpectedValueException) { return $this->redirectToRoute('wizards_sitepackage_new'); } - $sitepackage = SitepackageFactory::fromDto($configuration); - $this->setSitepackage($session, $sitepackage); + $this->setSitepackage($sitepackage); return $this->render( - 'default/wizards/sitepackage/success.html.twig', + 'wizards/sitepackage/success.html.twig', [ - 'sitepackage' => $sitepackage + 'base_package' => $this->basePackageService->getInstalledBasePackage($sitepackage->getBasePackage()), + 'sitepackage' => $sitepackage, ] ); } - /** - * @Route("/download/", name="wizards_sitepackage_download") - */ - public function download(Request $request, SitepackageGenerator $sitepackageGenerator): Response + #[Route(path: '/download', name: 'wizards_sitepackage_download')] + public function download(): Response { - $session = $request->getSession(); - try { - $sitepackage = $this->getSitepackage($session); - } catch (UnexpectedValueException $th) { + $sitepackage = $this->getSitepackage(); + } catch (UnexpectedValueException) { return $this->redirectToRoute('wizards_sitepackage_new'); } - $sitepackageGenerator->create($sitepackage); - $filename = $sitepackageGenerator->getFilename(); + try { + $this->sitepackageGenerator->create($sitepackage); + } catch (RuntimeError $runtimeError) { + $this->setSitepackageError($runtimeError->getMessage()); + + return $this->redirectToRoute('wizards_sitepackage_error'); + } BinaryFileResponse::trustXSendfileTypeHeader(); return $this - ->file($sitepackageGenerator->getZipPath(), StringUtility::toASCII($filename)) + ->file( + $this->sitepackageGenerator->getZipPath(), + StringUtility::toASCII($this->sitepackageGenerator->getFilename()) + ) ->deleteFileAfterSend(true); } - private function createSitepackageForm(SitepackageDto $configuration, bool $advanced = false): FormInterface + #[Route(path: '/error', name: 'wizards_sitepackage_error')] + public function error(): Response { - return $this->createForm( - SitepackageType::class, - $configuration, + return $this->render( + 'wizards/sitepackage/error.html.twig', [ - 'action' => $this->generateUrl('wizards_sitepackage_edit'), - 'advanced' => $advanced, + 'error' => $this->getSitepackageError(), ] ); } - - private function getAdvanced(SessionInterface $session): bool - { - return $session->get('sitepackage_advanced') === true; - } - - private function setAdvanced(SessionInterface $session, bool $advanced): void - { - $session->set('sitepackage_advanced', $advanced); - } - - private function getConfiguration(SessionInterface $session): SitepackageDto - { - $configuration = $session->get('sitepackage_configuration'); - - if ($configuration === null || !($configuration instanceof SitepackageDto)) { - $this->addFlash( - 'danger', - 'Whoops, we could not find the package configuration. Please submit the configuration again.' - ); - - throw new UnexpectedValueException('Invalid or missing configuration.', 1638038672); - } - - return $configuration; - } - - private function setConfiguration(SessionInterface $session, SitepackageDto $configuration): void - { - $session->set('sitepackage_configuration', $configuration); - } - - private function getSitepackage(SessionInterface $session): Sitepackage - { - $sitepackage = $session->get('sitepackage'); - - if ($sitepackage === null || !($sitepackage instanceof Sitepackage)) { - $this->addFlash( - 'danger', - 'Whoops, we could not find the Sitepackage. Please submit the configuration again.' - ); - - throw new UnexpectedValueException('Invalid or missing Sitepackage.', 1638038673); - } - - return $sitepackage; - } - - private function setSitepackage(SessionInterface $session, Sitepackage $sitepackage): void - { - $session->set('sitepackage', $sitepackage); - } } diff --git a/src/Entity/BasePackage.php b/src/Entity/BasePackage.php new file mode 100644 index 00000000..19ed7626 --- /dev/null +++ b/src/Entity/BasePackage.php @@ -0,0 +1,114 @@ +name; + } + + public function setName(string $name): self + { + $this->name = $name; + + return $this; + } + + public function isActive(): bool + { + return $this->active; + } + + public function setActive(bool $active): self + { + $this->active = $active; + + return $this; + } + + public function isOfficial(): bool + { + return $this->official; + } + + public function setOfficial(bool $official): self + { + $this->official = $official; + + return $this; + } + + /** + * @return array{name: string, active: bool, official: bool} + */ + public function jsonSerialize(): array + { + return [ + 'name' => $this->getName(), + 'active' => $this->isActive(), + 'official' => $this->isOfficial(), + ]; + } + + public function __toString(): string + { + return $this->getName(); + } +} diff --git a/src/Entity/Package/Author.php b/src/Entity/Package/Author.php deleted file mode 100644 index b7a67c8d..00000000 --- a/src/Entity/Package/Author.php +++ /dev/null @@ -1,169 +0,0 @@ -name; - } - - /** - * @param string $name - * @return Author - */ - public function setName(string $name) - { - $this->name = $name; - - return $this; - } - - /** - * @return string - */ - public function getEmail(): string - { - return $this->email; - } - - /** - * @param string $email - * @return Author - */ - public function setEmail(string $email) - { - $this->email = $email; - - return $this; - } - - /** - * @return string - */ - public function getCompany(): string - { - return $this->company; - } - - /** - * @param string $company - * @return Author - */ - public function setCompany(string $company) - { - $this->company = $company; - - return $this; - } - - /** - * @return string - */ - public function getHomepage(): string - { - return $this->homepage; - } - - /** - * @param string $homepage - * @return Author - */ - public function setHomepage(string $homepage) - { - $this->homepage = $homepage; - - return $this; - } - - /** - * @return array - */ - public function jsonSerialize(): array - { - return [ - 'name' => $this->getName(), - 'email' => $this->getEmail(), - 'company' => $this->getCompany(), - 'homepage' => $this->getHomepage(), - ]; - } -} diff --git a/src/Entity/Sitepackage.php b/src/Entity/Sitepackage.php deleted file mode 100644 index 58b8340e..00000000 --- a/src/Entity/Sitepackage.php +++ /dev/null @@ -1,370 +0,0 @@ -company if empty") - * @Serializer\Type("string") - * @var string - */ - private string $vendorName = ''; - - /** - * @Assert\Length( - * allowEmptyString=true, - * min=3 - * ) - * @Assert\Regex( - * pattern="/^[a-z][a-z0-9-]+$/", - * message="Only letters, numbers and hyphens are allowed" - * ) - * @SWG\Property(type="string", example="bk2k", default="generated from vendor name if empty") - * @Serializer\Type("string") - * @var string - */ - private string $composerVendorName = ''; - - /** - * @Assert\NotBlank( - * message="Please enter a title for your Sitepackage" - * ) - * @Assert\Length( - * min=3 - * ) - * @Assert\Regex( - * pattern="/^[A-Za-z0-9\x7f-\xff .:&-]+$/", - * message="Only letters, numbers and spaces are allowed" - * ) - * - * @SWG\Property(type="string", example="My Sitepackage") - * @Serializer\Type("string") - * @var string - */ - private string $title; - - /** - * @Assert\Regex( - * pattern="/^[A-Za-z0-9\x7f-\xff .,:!?&-]+$/", - * message="Only letters, numbers and spaces are allowed" - * ) - * - * @SWG\Property(type="string", example="Project Configuration for Client") - * @Serializer\Type("string") - * @var string - */ - private string $description; - - /** - * @Assert\Length( - * allowEmptyString=true, - * min=3 - * ) - * @Assert\Regex( - * pattern="/^[A-Z][A-Za-z0-9]+$/", - * message="Only letters and numbers are allowed" - * ) - * @SWG\Property(type="string", example="MySitepackage", default="generated from title if empty") - * @Serializer\Type("string") - * @var string - */ - private string $packageName = ''; - - /** - * @Assert\Length( - * allowEmptyString=true, - * min=3 - * ) - * @Assert\Regex( - * pattern="/^[a-z][a-z0-9-]+$/", - * message="Only lower case letters, numbers and hyphens are allowed" - * ) - * @SWG\Property(type="string", example="my-sitepackage", default="generated from package name if empty") - * @Serializer\Type("string") - * @var string - */ - private string $composerProjectName = ''; - - /** - * @Assert\Length( - * allowEmptyString=true, - * min=3 - * ) - * @Assert\Regex( - * pattern="/^[a-z][a-z0-9_]+$/", - * message="Only lower case letters, numbers and undscores are allowed" - * ) - * @SWG\Property(type="string", example="my_sitepackage", default="generated from package name if empty") - * @Serializer\Type("string") - * @var string - */ - private string $extensionKey = ''; - - /** - * @Assert\Url - * @SWG\Property(type="string", example="https://github.com/benjaminkott/packagebuilder") - * - * @Serializer\Type("string") - * @var string - */ - private string $repositoryUrl = ''; - - /** - * @Assert\Valid - * @Serializer\Type(Author::class) - */ - private Author $author; - - public function __construct() - { - $this->author = new Author(); - } - - public function getTypo3Version(): int - { - return $this->typo3Version; - } - - public function setTypo3Version(int $typo3Version): self - { - $this->typo3Version = $typo3Version; - - return $this; - } - - public function getBasePackage(): string - { - return $this->basePackage; - } - - public function setBasePackage(string $basePackage): self - { - $this->basePackage = $basePackage; - - return $this; - } - - public function getVendorName(): string - { - if ($this->vendorName === '') { - return StringUtility::stringToUpperCamelCase($this->getAuthor()->getCompany()); - } - - return $this->vendorName; - } - - public function setVendorName(string $vendorName): self - { - if ($this->getVendorName() !== $vendorName) { - $this->vendorName = StringUtility::stringToUpperCamelCase($vendorName); - } - - return $this; - } - - public function getComposerVendorName(): string - { - if ($this->composerVendorName === '') { - return StringUtility::camelCaseToLowerCaseDashed($this->getVendorName()); - } - - return $this->composerVendorName; - } - - public function setComposerVendorName(string $composerVendorName): self - { - if ($this->getComposerVendorName() !== $composerVendorName) { - $this->composerVendorName = StringUtility::camelCaseToLowerCaseDashed($composerVendorName); - } - - return $this; - } - - public function getTitle(): string - { - return $this->title; - } - - public function setTitle(string $title): self - { - $this->title = $title; - - return $this; - } - - public function getDescription(): string - { - return $this->description; - } - - public function setDescription(string $description): self - { - $this->description = $description; - - return $this; - } - - public function getPackageName(): string - { - if ($this->packageName === '') { - return StringUtility::stringToUpperCamelCase($this->getTitle()); - } - - return $this->packageName; - } - - public function setPackageName(string $packageName): self - { - if ($this->getPackageName() !== $packageName) { - $this->packageName = StringUtility::stringToUpperCamelCase($packageName); - } - - return $this; - } - - public function getComposerProjectName(): string - { - if ($this->composerProjectName === '') { - return StringUtility::camelCaseToLowerCaseDashed($this->getPackageName()); - } - - return $this->composerProjectName; - } - - public function setComposerProjectName(string $composerProjectName): self - { - if ($this->getComposerProjectName() !== $composerProjectName) { - $this->composerProjectName = StringUtility::camelCaseToLowerCaseDashed($composerProjectName); - } - - return $this; - } - - public function getExtensionKey(): string - { - if ($this->extensionKey === '') { - return StringUtility::camelCaseToLowerCaseUnderscored($this->getPackageName()); - } - - return $this->extensionKey; - } - - public function setExtensionKey(string $extensionKey): self - { - if ($this->getExtensionKey() !== $extensionKey) { - $this->extensionKey = StringUtility::camelCaseToLowerCaseUnderscored($extensionKey); - } - - return $this; - } - - public function getRepositoryUrl(): string - { - return $this->repositoryUrl; - } - - public function setRepositoryUrl(string $repositoryUrl): self - { - $this->repositoryUrl = $repositoryUrl; - - return $this; - } - - public function getAuthor(): Author - { - return $this->author; - } - - public function setAuthor(Author $author): self - { - $this->author = $author; - - return $this; - } - - /** - * @return array - */ - public function jsonSerialize(): array - { - return [ - 'typo3Version' => $this->getTypo3Version(), - 'basePackage' => $this->getBasePackage(), - 'vendorName' => $this->getVendorName(), - 'composerVendorName' => $this->getComposerVendorName(), - 'title' => $this->getTitle(), - 'description' => $this->getDescription(), - 'packageName' => $this->getPackageName(), - 'composerProjectName' => $this->getComposerProjectName(), - 'extensionKey' => $this->getExtensionKey(), - 'repositoryUrl' => $this->getRepositoryUrl(), - 'author' => $this->getAuthor(), - ]; - } -} diff --git a/src/Enum/ReleaseTypeEnum.php b/src/Enum/ReleaseTypeEnum.php index cd2d3815..b3ba2ce8 100644 --- a/src/Enum/ReleaseTypeEnum.php +++ b/src/Enum/ReleaseTypeEnum.php @@ -40,9 +40,6 @@ final class ReleaseTypeEnum extends AbstractEnum */ public const OPTION_SECURITY = 'security'; - /** - * @inheritDoc - */ protected static array $optionNames = [ self::OPTION_REGULAR => 'Regular', self::OPTION_DEVELOPMENT => 'Development', diff --git a/src/Enum/RequirementCategoryEnum.php b/src/Enum/RequirementCategoryEnum.php index bc1c9a99..a2e20cfc 100644 --- a/src/Enum/RequirementCategoryEnum.php +++ b/src/Enum/RequirementCategoryEnum.php @@ -50,9 +50,6 @@ final class RequirementCategoryEnum extends AbstractEnum */ public const OPTION_COMPOSER = 'composer'; - /** - * @inheritDoc - */ protected static array $optionNames = [ self::OPTION_PHP => 'PHP', self::OPTION_DATABASE => 'Database', diff --git a/src/Enum/Typo3VersionEnum.php b/src/Event/GitHubEvent.php similarity index 64% rename from src/Enum/Typo3VersionEnum.php rename to src/Event/GitHubEvent.php index c70ffd4a..1f449024 100644 --- a/src/Enum/Typo3VersionEnum.php +++ b/src/Event/GitHubEvent.php @@ -21,19 +21,27 @@ * The TYPO3 project - inspiring people to share! */ -namespace App\Enum; +namespace App\Event; -final class Typo3VersionEnum extends AbstractEnum +class GitHubEvent { - public const OPTION_8 = 8007000; - public const OPTION_9 = 9005000; - public const OPTION_10 = 10004000; - public const OPTION_11 = 11005000; + /** + * @param mixed[] $payload + */ + public function __construct(private readonly string $type, private readonly array $payload) + { + } - protected static array $optionNames = [ - self::OPTION_11 => '11.5 LTS', - self::OPTION_10 => '10.4 LTS', - self::OPTION_9 => '9.5 ELTS', - self::OPTION_8 => '8.7 ELTS', - ]; + public function getType(): string + { + return $this->type; + } + + /** + * @return mixed[] + */ + public function getPayload(): array + { + return $this->payload; + } } diff --git a/src/EventListener/BasePackageListener.php b/src/EventListener/BasePackageListener.php new file mode 100644 index 00000000..8f5ea560 --- /dev/null +++ b/src/EventListener/BasePackageListener.php @@ -0,0 +1,49 @@ +basePackageService->resetCache(); + } + + public function postRemove(): void + { + $this->basePackageService->resetCache(); + } + + public function postPersist(): void + { + $this->basePackageService->resetCache(); + } +} diff --git a/src/Exception/GitHubWebhookException.php b/src/Exception/GitHubWebhookException.php new file mode 100644 index 00000000..4acde40e --- /dev/null +++ b/src/Exception/GitHubWebhookException.php @@ -0,0 +1,45 @@ +request; + } +} diff --git a/src/Enum/BasePackageEnum.php b/src/Exception/IncompatiblePackageException.php similarity index 67% rename from src/Enum/BasePackageEnum.php rename to src/Exception/IncompatiblePackageException.php index bd8f5adc..279d9610 100644 --- a/src/Enum/BasePackageEnum.php +++ b/src/Exception/IncompatiblePackageException.php @@ -21,15 +21,10 @@ * The TYPO3 project - inspiring people to share! */ -namespace App\Enum; +namespace App\Exception; -final class BasePackageEnum extends AbstractEnum -{ - public const OPTION_BOOTSTRAP_PACKAGE = 'bootstrap_package'; - public const OPTION_FLUID_STYLED_CONTENT = 'fluid_styled_content'; +use RuntimeException; - protected static array $optionNames = [ - self::OPTION_BOOTSTRAP_PACKAGE => 'Bootstrap Package', - self::OPTION_FLUID_STYLED_CONTENT => 'Fluid Styled Content', - ]; +class IncompatiblePackageException extends RuntimeException +{ } diff --git a/src/Exception/InvalidGitHubRequestPayloadException.php b/src/Exception/InvalidGitHubRequestPayloadException.php new file mode 100644 index 00000000..319ea92e --- /dev/null +++ b/src/Exception/InvalidGitHubRequestPayloadException.php @@ -0,0 +1,48 @@ +getRequest()->getContent(); + } +} diff --git a/src/Exception/InvalidGitHubRequestSignatureException.php b/src/Exception/InvalidGitHubRequestSignatureException.php new file mode 100644 index 00000000..ba725179 --- /dev/null +++ b/src/Exception/InvalidGitHubRequestSignatureException.php @@ -0,0 +1,49 @@ +signature; + } +} diff --git a/src/Exception/MissingGitHubEventTypeException.php b/src/Exception/MissingGitHubEventTypeException.php new file mode 100644 index 00000000..91a999ad --- /dev/null +++ b/src/Exception/MissingGitHubEventTypeException.php @@ -0,0 +1,43 @@ +eventType), + $code, + $previous + ); + } +} diff --git a/src/Factory/GitHubEventFactory.php b/src/Factory/GitHubEventFactory.php new file mode 100644 index 00000000..cb1fc5d2 --- /dev/null +++ b/src/Factory/GitHubEventFactory.php @@ -0,0 +1,60 @@ +headers->get('X-GitHub-Event')) === null) { + throw new MissingGitHubEventTypeException($request); + } + + $content = $request->getContent(); + + try { + /** @var array $payload */ + $payload = json_decode($content, true, 512, JSON_THROW_ON_ERROR); + } catch (Throwable $throwable) { + throw new InvalidGitHubRequestPayloadException($request, 1_661_155_479, $throwable); + } + + return $this->build($eventType, $payload); + } +} diff --git a/src/Factory/GitHubEventFactoryInterface.php b/src/Factory/GitHubEventFactoryInterface.php new file mode 100644 index 00000000..2e9c8b42 --- /dev/null +++ b/src/Factory/GitHubEventFactoryInterface.php @@ -0,0 +1,47 @@ + $payload + */ + public function build(string $type, array $payload): GitHubEvent; + + /** + * Build a GitHub web hook event object based on the incoming request. + * + * @throws InvalidGitHubRequestPayloadException If the request payload is not a valid JSON content + * @throws MissingGitHubEventTypeException If the GitHub event type could not be found in the request headers + */ + public function buildFromRequest(Request $request): GitHubEvent; +} diff --git a/src/Factory/SitepackageFactory.php b/src/Factory/SitepackageFactory.php index 73c16f9a..f6d7b1c3 100644 --- a/src/Factory/SitepackageFactory.php +++ b/src/Factory/SitepackageFactory.php @@ -23,8 +23,8 @@ namespace App\Factory; -use App\Entity\Sitepackage; use App\Form\Dto\SitepackageDto; +use App\Package\Sitepackage; class SitepackageFactory { @@ -32,16 +32,14 @@ public static function fromDto(SitepackageDto $dto, Sitepackage $entity = null): { $sitepackage = $entity ?? new Sitepackage(); $sitepackage - ->setTypo3Version($dto->typo3Version) ->setBasePackage($dto->basePackage) - ->setVendorName($dto->vendorName ?? '') - ->setComposerVendorName($dto->composerVendorName ?? '') + ->setTypo3Version($dto->typo3Version) ->setTitle($dto->title ?? '') ->setDescription($dto->description ?? '') - ->setPackageName($dto->packageName ?? '') - ->setComposerProjectName($dto->composerProjectName ?? '') ->setExtensionKey($dto->extensionKey ?? '') ->setRepositoryUrl($dto->repositoryUrl ?? '') + ->setComposerName($dto->composerName ?? '') + ->setPsr4Namespace($dto->psr4Namespace ?? '') ->getAuthor() ->setName($dto->name ?? '') ->setEmail($dto->email ?? '') @@ -54,8 +52,6 @@ public static function fromDto(SitepackageDto $dto, Sitepackage $entity = null): public static function fromEntity(Sitepackage $sitepackage): SitepackageDto { - $dto = SitepackageDto::fromEntity($sitepackage); - - return $dto; + return SitepackageDto::fromEntity($sitepackage); } } diff --git a/src/Form/Dto/BasePackageDto.php b/src/Form/Dto/BasePackageDto.php new file mode 100644 index 00000000..e63d3110 --- /dev/null +++ b/src/Form/Dto/BasePackageDto.php @@ -0,0 +1,122 @@ + + */ + public array $typo3Versions = []; + + #[Assert\NotBlank(message: 'Please enter a preview image for the base package.')] + #[Assert\Length(min: 5)] + public string $previewImage = 'images/preview.png'; + + public static function fromPackage(string $installPath, PackageInterface $package, ?BasePackageEntity $entity = null): self + { + $dto = new self($installPath); + $dto->loadManifest($package); + + $dto->active = ($entity !== null) ? $entity->isActive() : true; + $dto->official = $entity !== null && $entity->isOfficial(); + $dto->thirdParty = ($entity === null); + + return $dto; + } + + public function __construct( + private readonly string $installPath, + ) { + } + + public function getInstallPath(): string + { + return $this->installPath; + } + + public function getAssetsDir(): string + { + return str_replace('/', '-', strtolower($this->packageName)); + } + + public function getVendorName(): string + { + return explode('/', strtolower($this->packageName))[0]; + } + + public function getProjectName(): string + { + return explode('/', strtolower($this->packageName))[1]; + } + + private function loadManifest(PackageInterface $package): void + { + $manifest = new BasePackageManifest($package); + + $this->packageName = $package->getName(); + $this->packageVersion = $package->getVersion(); + $this->title = $manifest->getTitle(); + $this->description = $manifest->getDescription(); + $this->typo3Versions = $manifest->getCoreVersions(); + $this->previewImage = $manifest->getPreviewImage(); + } +} diff --git a/src/Form/Dto/SitepackageDto.php b/src/Form/Dto/SitepackageDto.php index 81910bae..1c6c4d65 100644 --- a/src/Form/Dto/SitepackageDto.php +++ b/src/Form/Dto/SitepackageDto.php @@ -23,135 +23,85 @@ namespace App\Form\Dto; -use App\Entity\Sitepackage; -use App\Enum\BasePackageEnum; -use App\Enum\Typo3VersionEnum; +use App\Package\Sitepackage; use Symfony\Component\Validator\Constraints as Assert; class SitepackageDto { - /** - * @Assert\NotBlank - * @Assert\Choice(callback={"App\Enum\Typo3VersionEnum", "getAvailableOptions"}) - */ - public int $typo3Version = Typo3VersionEnum::OPTION_11; - - /** - * @Assert\NotBlank - * @Assert\Choice(callback={"App\Enum\BasePackageEnum", "getAvailableOptions"}) - */ - public string $basePackage = BasePackageEnum::OPTION_BOOTSTRAP_PACKAGE; - - /** - * @Assert\Length( - * allowEmptyString=true, - * min=3 - * ) - * @Assert\Regex( - * pattern="/^[a-z0-9]([_.-]?[a-z0-9]+)*\/[a-z0-9](([_.]?|-{0,2})[a-z0-9]+)*$/", - * message="Only lower case letters, numbers, underscores, dots and hyphens are allowed" - * ) - */ - public ?string $composerName; - - /** - * @Assert\Length( - * allowEmptyString=true, - * min=3 - * ) - * @Assert\Regex( - * pattern="/^[A-Z][A-Za-z0-9]+\[A-Z][A-Za-z0-9]+$/", - * message="Only letters and numbers are allowed" - * ) - */ - public ?string $psr4Namespace; - - /** - * @Assert\NotBlank( - * message="Please enter a title for your Sitepackage" - * ) - * @Assert\Length( - * min=3 - * ) - * @Assert\Regex( - * pattern="/^[A-Za-z0-9\x7f-\xff .:&-]+$/", - * message="Only letters, numbers and spaces are allowed" - * ) - */ - public ?string $title; - - /** - * @Assert\Regex( - * pattern="/^[A-Za-z0-9\x7f-\xff .,:!?&-]+$/", - * message="Only letters, numbers and spaces are allowed" - * ) - */ - public ?string $description; - - /** - * @Assert\Url - */ - public ?string $repositoryUrl; - - /** - * @Assert\Length( - * allowEmptyString=true, - * min=3 - * ) - * @Assert\Regex( - * pattern="/^[a-z][a-z0-9_]+$/", - * message="Only lower case letters, numbers and undscores are allowed" - * ) - */ - public ?string $extensionKey; - - /** - * @Assert\NotBlank(message="Please enter the authors' name.") - * @Assert\Length( - * min=3 - * ) - */ - public ?string $name; - - /** - * @Assert\NotBlank(message="Please enter the authors' email address.") - * @Assert\Email( - * message="The email '{{ value }}' is not a valid email.", - * ) - */ - public ?string $email; - - /** - * @Assert\NotBlank(message="Please enter the authors' company.") - * @Assert\Length( - * min=3 - * ) - * @Assert\Regex( - * pattern="/^[A-Za-z0-9\x7f-\xff .:&-]+$/", - * message="Only letters, numbers and spaces are allowed" - * ) - */ - public ?string $company; - - /** - * @Assert\NotBlank(message="Please enter the authors' homepage URL.") - * @Assert\Url - */ - public ?string $homepage; - - public static function fromEntity(Sitepackage $entity): self - { + #[Assert\NotBlank] + public string $basePackage = ''; + + #[Assert\NotBlank] + public int $typo3Version = 0; + + #[Assert\NotBlank(message: 'Please enter a title for your Sitepackage.')] + #[Assert\Length(min: 3)] + #[Assert\Regex( + pattern: '/^[A-Za-z0-9\x7f-\xff .:&-]+$/', + message: 'Only letters, numbers and spaces are allowed.' + )] + public ?string $title = null; + + #[Assert\Regex( + pattern: '/^[A-Za-z0-9\x7f-\xff .,:!?&-]+$/', + message: 'Only letters, numbers and spaces are allowed.' + )] + public ?string $description = null; + + #[Assert\Url] + public ?string $repositoryUrl = null; + + #[Assert\Length(min: 3)] + #[Assert\Regex( + pattern: '/^[a-z][a-z0-9_]+$/', + message: 'Only lower case letters, numbers and underscores are allowed.' + )] + public ?string $extensionKey = null; + + #[Assert\Regex( + pattern: '/^[a-z0-9]([_.-]?[a-z0-9]+)*\/[a-z0-9](([_.]?|-{0,2})[a-z0-9]+)*$/', + message: 'The name must be lowercased and consist of words separated by `-`, `.` or `_`.' + )] + public ?string $composerName = null; + + #[Assert\Regex( + pattern: '/^[A-Z][A-Za-z0-9]+\\\[A-Z][A-Za-z0-9]+$/', + message: 'Only letters and numbers are allowed.' + )] + public ?string $psr4Namespace = null; + + #[Assert\NotBlank(message: "Please enter the authors' name.")] + #[Assert\Length(min: 3)] + public ?string $name = null; + + #[Assert\NotBlank(message: "Please enter the authors' email address.")] + #[Assert\Email(message: "The email '{{ value }}' is not a valid email.")] + public ?string $email = null; + + #[Assert\NotBlank(message: "Please enter the authors' company.")] + #[Assert\Length(min: 3)] + #[Assert\Regex( + pattern: '/^[A-Za-z0-9\x7f-\xff .:&-]+$/', + message: 'Only letters, numbers and spaces are allowed.' + )] + public ?string $company = null; + + #[Assert\NotBlank(message: "Please enter the authors' homepage URL.")] + #[Assert\Url] + public ?string $homepage = null; + + public static function fromEntity( + Sitepackage $entity + ): self { $dto = new self(); - $dto->typo3Version = $entity->getTypo3Version(); $dto->basePackage = $entity->getBasePackage(); - $dto->vendorName = $entity->getVendorName(); - $dto->composerVendorName = $entity->getComposerVendorName(); + $dto->typo3Version = $entity->getTypo3Version(); $dto->title = $entity->getTitle(); $dto->description = $entity->getDescription(); - $dto->packageName = $entity->getPackageName(); - $dto->composerProjectName = $entity->getComposerProjectName(); $dto->extensionKey = $entity->getExtensionKey(); $dto->repositoryUrl = $entity->getRepositoryUrl(); + $dto->composerName = $entity->getComposerName(); + $dto->psr4Namespace = $entity->getPsr4Namespace(); $dto->name = $entity->getAuthor()->getName(); $dto->email = $entity->getAuthor()->getEmail(); $dto->company = $entity->getAuthor()->getCompany(); diff --git a/src/Form/Extension/AbstractIconExtension.php b/src/Form/Extension/AbstractIconExtension.php new file mode 100644 index 00000000..c9eb7ece --- /dev/null +++ b/src/Form/Extension/AbstractIconExtension.php @@ -0,0 +1,57 @@ + $options + */ + public function buildView(FormView $view, FormInterface $form, array $options): void + { + if (is_string($icon = $options['icon'])) { + $view->vars['label'] = $this->iconExtension->getIcon($icon) . $view->vars['label']; + $view->vars['label_html'] = true; + } + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults(['icon' => null]); + $resolver->setAllowedTypes('icon', ['null', 'string']); + } +} diff --git a/src/Form/Extension/ButtonTypeIconExtension.php b/src/Form/Extension/ButtonTypeIconExtension.php new file mode 100644 index 00000000..38cb921d --- /dev/null +++ b/src/Form/Extension/ButtonTypeIconExtension.php @@ -0,0 +1,34 @@ +basePackageService->getInstalledBasePackage($configuration->basePackage); + + if (!$basePackage->official) { + $notification = 'This is a third party base package, not provided by TYPO3. Please contact the author in case of problems, we do not provide support.'; + $notificationType = 'info'; + } else { + $notification = null; + $notificationType = ''; + } + $builder - //->setAction(is_string($action = $options['action']) ? $action : '') - ->add('typo3Version', Typo3VersionType::class, [ - 'label' => 'TYPO3 Version', - 'label_attr' => ['class' => 'w-auto pe-2'], - 'expanded' => true, - 'row_attr' => ['class' => 'd-inline-flex flex-column w-50'], - ]) ->add('basePackage', BasePackageType::class, [ 'label' => 'Base Package', - 'label_attr' => ['class' => 'w-auto me-2'], + 'notification' => $notification, + 'notification_type' => $notificationType, + ]) + ->add('typo3Version', Typo3VersionType::class, [ + 'label' => 'TYPO3 Version', + 'choice_filter' => static function (int $version) use ($basePackage): bool { + foreach ($basePackage->typo3Versions as $typo3Version) { + if ($version < VersionUtility::versionToInt($typo3Version)) { + continue; + } + + if ($version % 1_000_000 !== VersionUtility::versionToInt($typo3Version) % 1_000_000) { + continue; + } + + return true; + } + + return false; + }, 'expanded' => true, - 'row_attr' => ['class' => 'd-inline-flex flex-column w-50'], ]) ->add('title', TextType::class, [ 'attr' => [ 'autocomplete' => 'off', 'placeholder' => 'My Sitepackage', - ] + ], ]) ->add('description', TextareaType::class, [ 'required' => false, 'attr' => [ 'autocomplete' => 'off', 'placeholder' => 'Optional description for the use of this sitepackage', - ] + ], ]) ->add('repositoryUrl', TextType::class, [ 'label' => 'Repository URL', @@ -79,7 +106,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'attr' => [ 'autocomplete' => 'off', 'placeholder' => 'https://github.com/username/my_sitepackage', - ] + ], ]) ; @@ -142,7 +169,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void SubmitType::class, [ 'label' => 'Create Sitepackage', - //'icon' => 'floppy-disk', + 'icon' => 'actions-save', 'attr' => ['class' => 'btn-primary'], 'row_attr' => ['class' => 'd-inline-flex'], ] @@ -155,7 +182,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void SubmitType::class, [ 'label' => 'Simple Configuration', - //'icon' => 'pencil', + 'icon' => 'actions-toggle-off', 'attr' => ['class' => 'btn-secondary'], 'row_attr' => ['class' => 'd-inline-flex ms-1'], 'validate' => false, @@ -167,7 +194,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void SubmitType::class, [ 'label' => 'Advanced Configuration', - //'icon' => 'pencil', + 'icon' => 'actions-toggle-on', 'attr' => ['class' => 'btn-secondary'], 'row_attr' => ['class' => 'd-inline-flex ms-1'], 'validate' => false, @@ -176,9 +203,6 @@ public function buildForm(FormBuilderInterface $builder, array $options): void } } - /** - * {@inheritdoc} - */ public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ diff --git a/src/Form/Type/BasePackageType.php b/src/Form/Type/BasePackageType.php index 88bfbba9..975062d2 100644 --- a/src/Form/Type/BasePackageType.php +++ b/src/Form/Type/BasePackageType.php @@ -23,27 +23,48 @@ namespace App\Form\Type; -use App\Enum\BasePackageEnum; +use App\Service\BasePackageService; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; +use Symfony\Component\Form\FormInterface; +use Symfony\Component\Form\FormView; use Symfony\Component\OptionsResolver\OptionsResolver; +use function sprintf; + class BasePackageType extends AbstractType { + public function __construct( + private readonly BasePackageService $basePackageService, + ) { + } + public function configureOptions(OptionsResolver $resolver): void { $choices = []; - foreach (BasePackageEnum::getAvailableOptions() as $option) { - $choices[BasePackageEnum::getName($option)] = $option; + foreach ($this->basePackageService->getInstalledBasePackages() as $basePackage) { + $choices[sprintf('%s (%s)', $basePackage->title, $basePackage->packageName)] = $basePackage->packageName; } $resolver->setDefaults([ 'choices' => $choices, + 'disabled' => true, + 'notification' => null, + 'notification_type' => 'danger', ]); + + $resolver->setAllowedTypes('notification', ['null', 'string']); + $resolver->setAllowedTypes('notification_type', 'string'); + } + + public function buildView(FormView $view, FormInterface $form, array $options): void + { + $view->vars['notification'] = $options['notification']; + $view->vars['notification_type'] = $options['notification_type']; } - public function getParent() + public function getParent(): string { return ChoiceType::class; } diff --git a/src/Form/Type/Typo3VersionType.php b/src/Form/Type/Typo3VersionType.php index 1024eb70..7ef48e59 100644 --- a/src/Form/Type/Typo3VersionType.php +++ b/src/Form/Type/Typo3VersionType.php @@ -23,23 +23,31 @@ namespace App\Form\Type; -use App\Enum\Typo3VersionEnum; +use App\Repository\MajorVersionRepository; +use App\Utility\VersionUtility; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\OptionsResolver\OptionsResolver; class Typo3VersionType extends AbstractType { - private const LOWEST_SUPPORTED_VERSION = Typo3VersionEnum::OPTION_8; + public function __construct( + private readonly MajorVersionRepository $majorVersions, + ) { + } public function configureOptions(OptionsResolver $resolver): void { $choices = []; - foreach (Typo3VersionEnum::getAvailableOptions(true) as $option => $name) { - if ($option >= self::LOWEST_SUPPORTED_VERSION) { - $choices['TYPO3 ' . $name] = $option; + foreach ($this->majorVersions->findAllComposerSupported() as $majorVersion) { + if ($majorVersion->getLatestRelease() === null) { + continue; } + + $choices[$majorVersion->getTitle()] = VersionUtility::versionToInt( + VersionUtility::normalize($majorVersion->getLatestRelease()->getVersion(), 2) + ); } $resolver->setDefaults([ @@ -47,7 +55,7 @@ public function configureOptions(OptionsResolver $resolver): void ]); } - public function getParent() + public function getParent(): string { return ChoiceType::class; } diff --git a/src/Menu/MenuBuilder.php b/src/Menu/MenuBuilder.php index 776fdb70..7ea1ea7e 100644 --- a/src/Menu/MenuBuilder.php +++ b/src/Menu/MenuBuilder.php @@ -28,9 +28,6 @@ class MenuBuilder extends TemplateMenuBuider { - /** - * @inheritDoc - */ public function mainDefault(array $options): ItemInterface { $menu = parent::mainDefault($options); @@ -52,14 +49,14 @@ public function mainDefault(array $options): ItemInterface 'wizards', [ 'route' => 'wizards_sitepackage', - 'label' => 'Wizards' + 'label' => 'Wizards', ] ); $wizards->addChild( 'wizards-sitepackage', [ 'route' => 'wizards_sitepackage', - 'label' => 'Sitepackage Builder' + 'label' => 'Sitepackage Builder', ] ); $composer = $menu->addChild( @@ -93,9 +90,6 @@ public function mainDefault(array $options): ItemInterface return $menu; } - /** - * @inheritDoc - */ public function mainProfile(array $options): ItemInterface { $menu = parent::mainProfile($options); diff --git a/src/Package/BasePackageManifest.php b/src/Package/BasePackageManifest.php new file mode 100644 index 00000000..4faae494 --- /dev/null +++ b/src/Package/BasePackageManifest.php @@ -0,0 +1,133 @@ +package->getName(); + } + + public function getVersion(): string + { + return $this->package->getVersion(); + } + + public function getTitle(): string + { + return $this->getStringValue('title'); + } + + public function getDescription(): string + { + return $this->getStringValue('description'); + } + + /** + * @return array + */ + public function getCoreVersions(): array + { + $array = $this->getArrayValue('core-versions'); + rsort($array, SORT_NUMERIC); + return $array; + } + + public function getPreviewImage(): string + { + $array = $this->getArrayValue('images', []); + return $array['preview'] ?? 'images/preview.png'; + } + + /** + * @return array + */ + private function getExtraConfig(): array + { + if (!is_array($extraConfig = ($this->package->getExtra()[self::EXTRA_KEY] ?? []))) { + throw new RuntimeException( + 'Extra config is not defined or is not an array.', + 1_658_926_616 + ); + } + + return $extraConfig; + } + + private function getStringValue(string $key, ?string $default = null): string + { + if (!is_string($value = ($this->getExtraConfig()[$key] ?? null))) { + if ($default === null) { + throw new RuntimeException( + sprintf('Mandatory property "%s" is not defined or is not a string.', $key), + 1_658_926_617 + ); + } + + $value = $default; + } + + return $value; + } + + /** + * @param string[]|null $default + * + * @return string[] + */ + private function getArrayValue(string $key, ?array $default = null): array + { + if (!is_array($value = ($this->getExtraConfig()[$key] ?? null))) { + if ($default === null) { + throw new RuntimeException( + sprintf('Mandatory property "%s" is not defined or is not an array.', $key), + 1_658_926_618 + ); + } + + $value = $default; + } + + return $value; + } +} diff --git a/src/Package/Package/Author.php b/src/Package/Package/Author.php new file mode 100644 index 00000000..71fdaa5c --- /dev/null +++ b/src/Package/Package/Author.php @@ -0,0 +1,121 @@ +name; + } + + public function setName(string $name): static + { + $this->name = $name; + + return $this; + } + + public function getEmail(): string + { + return $this->email; + } + + public function setEmail(string $email): static + { + $this->email = $email; + + return $this; + } + + public function getCompany(): string + { + return $this->company; + } + + public function setCompany(string $company): static + { + $this->company = $company; + + return $this; + } + + public function getHomepage(): string + { + return $this->homepage; + } + + public function setHomepage(string $homepage): static + { + $this->homepage = $homepage; + + return $this; + } + + /** + * @return array{name: string, email: string, company: string, homepage: string} + */ + public function jsonSerialize(): array + { + return [ + 'name' => $this->getName(), + 'email' => $this->getEmail(), + 'company' => $this->getCompany(), + 'homepage' => $this->getHomepage(), + ]; + } +} diff --git a/src/Package/Sitepackage.php b/src/Package/Sitepackage.php new file mode 100644 index 00000000..80c0966a --- /dev/null +++ b/src/Package/Sitepackage.php @@ -0,0 +1,285 @@ +company and title if empty") + */ + #[Assert\Regex( + pattern: '/^[a-z0-9]([_.-]?[a-z0-9]+)*\/[a-z0-9](([_.]?|-{0,2})[a-z0-9]+)*$/', + message: 'The name must be lowercased and consist of words separated by `-`, `.` or `_`.' + )] + #[Serializer\Type('string')] + private string $composerName = ''; + + /** + * @SWG\Property(type="string", example="MyCompany\MySitepackage", default="generated from author->company and title if empty") + */ + #[Assert\Regex( + pattern: '/^[A-Z][A-Za-z0-9]+\\\[A-Z][A-Za-z0-9]+$/', + message: 'Only letters and numbers are allowed.' + )] + #[Serializer\Type('string')] + private string $psr4Namespace = ''; + + #[Assert\Valid] + #[Serializer\Type(Author::class)] + private Author $author; + + public function __construct() + { + $this->author = new Author(); + } + + public function getBasePackage(): string + { + return $this->basePackage; + } + + public function setBasePackage(string $basePackage): self + { + $this->basePackage = $basePackage; + + return $this; + } + + public function getTypo3Version(): int + { + return $this->typo3Version; + } + + public function setTypo3Version(int $typo3Version): self + { + $this->typo3Version = $typo3Version; + + return $this; + } + + public function getTitle(): string + { + return $this->title; + } + + public function setTitle(string $title): self + { + $this->title = $title; + + return $this; + } + + public function getDescription(): string + { + return $this->description; + } + + public function setDescription(string $description): self + { + $this->description = $description; + + return $this; + } + + public function getExtensionKey(): string + { + if ($this->extensionKey === '') { + return StringUtility::camelCaseToLowerCaseUnderscored($this->getTitle()); + } + + return $this->extensionKey; + } + + public function setExtensionKey(string $extensionKey): self + { + if ($this->getExtensionKey() !== $extensionKey) { + $this->extensionKey = StringUtility::camelCaseToLowerCaseUnderscored($extensionKey); + } + + return $this; + } + + public function getRepositoryUrl(): string + { + return $this->repositoryUrl; + } + + public function setRepositoryUrl(string $repositoryUrl): self + { + $this->repositoryUrl = $repositoryUrl; + + return $this; + } + + public function getComposerName(): string + { + if ($this->composerName === '') { + return StringUtility::camelCaseToLowerCaseDashed($this->getAuthor()->getCompany()) . '/' . + StringUtility::camelCaseToLowerCaseDashed($this->getTitle()); + } + + return $this->composerName; + } + + public function setComposerName(string $composerName): self + { + if ($this->getComposerName() !== $composerName) { + $this->composerName = $composerName; + } + + return $this; + } + + public function getComposerVendorName(): string + { + return explode('/', $this->getComposerName())[0]; + } + + public function getComposerProjectName(): string + { + return explode('/', $this->getComposerName())[1]; + } + + public function getPsr4Namespace(): string + { + if ($this->psr4Namespace === '') { + return StringUtility::stringToUpperCamelCase($this->getAuthor()->getCompany()) . '\\' . + StringUtility::stringToUpperCamelCase($this->getTitle()); + } + + return $this->psr4Namespace; + } + + public function setPsr4Namespace(string $psr4Namespace): self + { + if ($this->getPsr4Namespace() !== $psr4Namespace) { + $this->psr4Namespace = $psr4Namespace; + } + + return $this; + } + + public function getAuthor(): Author + { + return $this->author; + } + + public function setAuthor(Author $author): self + { + $this->author = $author; + + return $this; + } + + /** + * @return array{ + * basePackage: string, + * typo3Version: int, + * title: string, + * description: string, + * extensionKey: string, + * repositoryUrl: string, + * composerName: string, + * psr4Namespace: string, + * author: Author + * } + */ + public function jsonSerialize(): array + { + return [ + 'basePackage' => $this->getBasePackage(), + 'typo3Version' => $this->getTypo3Version(), + 'title' => $this->getTitle(), + 'description' => $this->getDescription(), + 'extensionKey' => $this->getExtensionKey(), + 'repositoryUrl' => $this->getRepositoryUrl(), + 'composerName' => $this->getComposerName(), + 'psr4Namespace' => $this->getPsr4Namespace(), + 'author' => $this->getAuthor(), + ]; + } +} diff --git a/src/Repository/BasePackageRepository.php b/src/Repository/BasePackageRepository.php new file mode 100644 index 00000000..9ab5bda1 --- /dev/null +++ b/src/Repository/BasePackageRepository.php @@ -0,0 +1,79 @@ + + */ +final class BasePackageRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, BasePackage::class); + } + + public function add(BasePackage $entity, bool $flush = false): void + { + $this->getEntityManager()->persist($entity); + + if ($flush) { + $this->getEntityManager()->flush(); + } + } + + public function remove(BasePackage $entity, bool $flush = false): void + { + $this->getEntityManager()->remove($entity); + + if ($flush) { + $this->getEntityManager()->flush(); + } + } + + /** + * @return BasePackage[] + */ + public function findAllActive(): array + { + return $this->findBy( + ['active' => true], + ['name' => 'ASC'] + ); + } + + /** + * @return BasePackage[] + */ + public function findAllActiveGroupedByOfficial(): array + { + return $this->findBy( + ['active' => true], + ['official' => 'DESC', 'name' => 'ASC'] + ); + } +} diff --git a/src/Security/GitHubRequestChecker.php b/src/Security/GitHubRequestChecker.php new file mode 100644 index 00000000..e23e7841 --- /dev/null +++ b/src/Security/GitHubRequestChecker.php @@ -0,0 +1,57 @@ +headers->get('X-Hub-Signature-256')) === null) { + throw new MissingGitHubSignatureException($request, 1_661_156_488); + } + + $algo = explode('=', $signature)[0]; + $digest = hash_hmac('sha256', $request->getContent(), $this->signingSecret); + + if (!hash_equals(sprintf('%s=%s', $algo, $digest), $signature)) { + throw new InvalidGitHubRequestSignatureException($request, $signature, 1_661_156_489); + } + } +} diff --git a/src/Service/BasePackageService.php b/src/Service/BasePackageService.php new file mode 100644 index 00000000..2ce30e19 --- /dev/null +++ b/src/Service/BasePackageService.php @@ -0,0 +1,669 @@ +composerApplication->setAutoExit(false); + } + + private function getProjectDir(): string + { + return rtrim($this->kernel->getProjectDir() . '/' . $this->projectDir, '/'); + } + + private function getRepositoryDir(): string + { + return rtrim($this->getProjectDir() . '/packages', '/'); + } + + private function changeToProjectDir(): void + { + $oldWorkingDir = (string)getcwd(); + //$oldWorkingDir = Platform::getCwd(true); + + if ($oldWorkingDir !== $this->getProjectDir()) { + chdir($this->getProjectDir()); + $this->oldWorkingDir = $oldWorkingDir; + } + } + + private function restoreToWorkingDir(): void + { + if ($this->oldWorkingDir !== '') { + chdir($this->oldWorkingDir); + $this->oldWorkingDir = ''; + } + } + + private function getPublicDir(): string + { + $defaultPublicDir = 'public'; + + $composerFilePath = $this->kernel->getProjectDir() . '/composer.json'; + + if (!file_exists($composerFilePath)) { + return $defaultPublicDir; + } + + if (!is_string($contents = file_get_contents($composerFilePath))) { + return $defaultPublicDir; + } + + if (!is_array($composerConfig = json_decode($contents, true, 512, JSON_THROW_ON_ERROR))) { + return $defaultPublicDir; + } + + return $composerConfig['extra']['public-dir'] ?? $defaultPublicDir; + } + + private function getPublicAssetsDir(): string + { + $publicDir = $this->kernel->getProjectDir() . '/' . $this->getPublicDir(); + + if (!is_dir($publicDir)) { + throw new RuntimeException(sprintf('The target directory "%s" does not exist.', $publicDir)); + } + + return rtrim($publicDir . '/' . $this->assetsDir, '/'); + } + + /** + * Creates symbolic link. + * + * @throws RuntimeException if link cannot be created + */ + private function symlink(string $originDir, string $targetDir, bool $relative = false): void + { + if ($relative) { + $this->filesystem->mkdir(dirname($targetDir)); + + if (!is_string($absoluteTargetDir = realpath(dirname($targetDir)))) { + throw new RuntimeException( + sprintf('Could not determine absolute path for "%s".', $targetDir), + 1_658_923_646 + ); + } + + $originDir = $this->filesystem->makePathRelative($originDir, $absoluteTargetDir); + } + + $this->filesystem->symlink($originDir, $targetDir); + + if (!file_exists($targetDir)) { + throw new RuntimeException( + sprintf('Symbolic link "%s" was created but appears to be broken.', $targetDir), + 1_658_923_653 + ); + } + } + + private function installAssets(): void + { + $publicAssetsDir = $this->getPublicAssetsDir() . '/'; + $validAssetDirs = []; + + foreach ($this->getInstalledBasePackages() as $basePackage) { + if (!is_dir($originDir = $basePackage->getInstallPath() . '/public')) { + continue; + } + + $assetDir = $basePackage->getAssetsDir(); + $targetDir = $publicAssetsDir . $assetDir; + $validAssetDirs[] = $assetDir; + + $this->filesystem->remove($targetDir); + $this->symlink($originDir, $targetDir, true); + } + + // remove the assets of the bundles that no longer exist + if (is_dir($publicAssetsDir)) { + $dirsToRemove = Finder::create()->depth(0)->directories()->exclude($validAssetDirs)->in($publicAssetsDir); + $this->filesystem->remove($dirsToRemove); + } + } + + private function getComposer(): Composer + { + $composer = $this->composerApplication->getComposer(); + + if (!$composer instanceof \Composer\Composer) { + throw new RuntimeException( + \sprintf('Composer project is not setup in "%s".', $this->getProjectDir()), + 1_658_915_927 + ); + } + + return $composer; + } + + private function cloneRepository(): void + { + $process = new Process( + ['git', 'clone', 'https://github.com/GsTYPO3/base-packages.git', 'packages'], + $this->getProjectDir() + ); + if ($process->run() !== 0) { + throw new RuntimeException(\sprintf( + "Error while cloning repository.\n\nOutput:\n%s\n\nError Output:\n%s\n\Command:\n%s\n\nProject Dir:\n%s", + $process->getOutput(), + $process->getErrorOutput(), + $process->getCommandLine(), + $this->getProjectDir() + ), 1_660_919_239); + } + } + + private function updateRepository(): void + { + $process = new Process( + ['git', 'pull'], + $this->getRepositoryDir() + ); + if ($process->run() !== 0) { + throw new RuntimeException(\sprintf( + "Error while cloning repository:\n%s\n\n%s", + $process->getOutput(), + $process->getErrorOutput() + ), 1_660_919_240); + } + } + + /** + * @return array + */ + private function getComposerProjectFiles(): array + { + return [ + $this->getProjectDir() . '/vendor', + $this->getProjectDir() . '/composer.json', + $this->getProjectDir() . '/composer.lock', + ]; + } + + private function initializeProject(bool $force = false): void + { + // Clone or update the base-packages repository + if (!$this->filesystem->exists($this->getRepositoryDir() . '/.git')) { + $this->cloneRepository(); + } else { + $this->updateRepository(); + } + + // Remove previous installation + if ($force) { + $this->filesystem->remove($this->getComposerProjectFiles()); + } + + // Early return if project already exists + if ($this->filesystem->exists($this->getComposerProjectFiles())) { + return; + } + + // Create project + $output = new BufferedOutput(); + $input = new ArrayInput([ + 'command' => 'init', + '--name' => 't3o/base-packages', + '--description' => 'Known base packages shown at the get.typo3.org wizards.', + '--type' => 'project', + '--stability' => 'dev', + '--repository' => ['{"type": "path", "url": "packages/*/*"}', '{"packagist.org": false}'], + '--ansi' => true, + '--no-interaction' => true, + '--working-dir' => $this->getProjectDir(), + ]); + + if (($exitCode = $this->composerApplication->run($input, $output)) !== 0) { + throw new RuntimeException(\sprintf('Composer failed:\n%s', $output->fetch()), $exitCode); + } + + $this->cache->invalidateTags(['installed-base-packages']); + } + + private function installBasePackages(): void + { + $this->initializeProject(); + + // Prepare packages to require + $requirements = []; + foreach ($this->basePackageRepository->findAllActive() as $basePackage) { + $requirements[] = \sprintf('%s:%s', $basePackage->getName(), '@dev'); + } + + // Require packages + $output = new BufferedOutput(); + $input = new ArrayInput([ + 'command' => 'require', + '--no-progress' => true, + //'--no-update' => true, + //'--no-install' => true, + '--update-with-all-dependencies' => true, + '--ansi' => true, + '--no-interaction' => true, + '--working-dir' => $this->getProjectDir(), + 'packages' => $requirements, + ]); + + if (($exitCode = $this->composerApplication->run($input, $output)) !== 0) { + throw new RuntimeException(\sprintf('Composer failed:\n%s', $output->fetch()), $exitCode); + } + + $this->cache->invalidateTags(['installed-base-packages']); + + $this->installAssets(); + } + + private function installBasePackage(string $packageName): void + { + $this->initializeProject(); + + // Require package + $output = new BufferedOutput(); + $input = new ArrayInput([ + 'command' => 'require', + '--no-progress' => true, + //'--no-update' => true, + //'--no-install' => true, + '--update-with-all-dependencies' => true, + '--ansi' => true, + '--no-interaction' => true, + '--working-dir' => $this->getProjectDir(), + 'packages' => [$packageName . ':*'], + ]); + + if (($exitCode = $this->composerApplication->run($input, $output)) !== 0) { + throw new RuntimeException(\sprintf('Composer failed:\n%s', $output->fetch()), $exitCode); + } + + $this->cache->invalidateTags(['installed-base-packages']); + + $this->installAssets(); + } + + public function updateBasePackages(): void + { + // Install or update packages + $output = new BufferedOutput(); + $input = new ArrayInput([ + 'command' => 'update', + '--no-progress' => true, + '--with-all-dependencies' => true, + '--ignore-platform-reqs' => true, + '--prefer-stable' => true, + '--ansi' => true, + '--no-interaction' => true, + '--working-dir' => $this->getProjectDir(), + ]); + + if (($exitCode = $this->composerApplication->run($input, $output)) !== 0) { + throw new RuntimeException(\sprintf('Composer failed:\n%s', $output->fetch()), $exitCode); + } + + $this->cache->invalidateTags(['installed-base-packages']); + + $this->installAssets(); + } + + private function removeBasePackage(string $packageName): void + { + $this->initializeProject(); + + // Require package + $output = new BufferedOutput(); + $input = new ArrayInput([ + 'command' => 'remove', + '--no-progress' => true, + //'--no-update' => true, + //'--no-install' => true, + '--update-with-all-dependencies' => true, + '--unused' => true, + '--ansi' => true, + '--no-interaction' => true, + '--working-dir' => $this->getProjectDir(), + 'packages' => [$packageName], + ]); + + if (($exitCode = $this->composerApplication->run($input, $output)) !== 0) { + throw new RuntimeException(\sprintf('Composer failed:\n%s', $output->fetch()), $exitCode); + } + + $this->cache->invalidateTags(['installed-base-packages']); + + $this->installAssets(); + } + + /** + * @return array + */ + public function getInstalledBasePackages(): array + { + return $this->cache->get('installed-base-packages-grouped-by-official', function (ItemInterface $item): array { + $item->tag(['installed-base-packages', 'base-packages']); + $installedBasePackages = []; + + $this->changeToProjectDir(); + + try { + try { + $composer = $this->getComposer(); + } catch (Throwable) { + return $installedBasePackages; + } + + foreach ($composer->getRepositoryManager()->getLocalRepository()->getPackages() as $package) { + if ($package->getType() === self::PACKAGE_TYPE) { + $basePackageDto = BasePackageDto::fromPackage( + $composer->getInstallationManager()->getInstallPath($package), + $package, + $this->basePackageRepository->findOneBy([ + 'name' => $package->getName(), + 'active' => true, + ]) + ); + $installedBasePackages[] = $basePackageDto; + } + } + + usort($installedBasePackages, static function (BasePackageDto $a, BasePackageDto $b): int { + if ($a->official !== $b->official) { + if ($a->official) { + return -1; + } + + return 1; + } + + return $a->title <=> $b->title; + }); + + return $installedBasePackages; + } finally { + $this->restoreToWorkingDir(); + } + }); + } + + public function getInstalledBasePackage(string $packageName): BasePackageDto + { + foreach ($this->getInstalledBasePackages() as $basePackage) { + if ($basePackage->packageName === $packageName) { + return $basePackage; + } + } + + throw new PackageNotInstalledException(\sprintf('Base package "%s" not found.', $packageName), 1_658_839_466); + } + + /** + * @return array + */ + public function getBasePackages(): array + { + return $this->cache->get('active-base-packages-grouped-by-official', function (ItemInterface $item): array { + $item->tag(['active-base-packages', 'base-packages']); + + $basePackages = []; + + $this->changeToProjectDir(); + + try { + $this->installBasePackages(); + + try { + $composer = $this->getComposer(); + } catch (Throwable) { + return $basePackages; + } + + foreach ($this->basePackageRepository->findAllActiveGroupedByOfficial() as $basePackage) { + $package = $composer->getRepositoryManager()->getLocalRepository()->findPackage( + $basePackage->getName(), + new MatchAllConstraint() + ); + + if (!$package instanceof PackageInterface) { + throw new RuntimeException( + \sprintf('Package "%s" not found.', $basePackage->getName()), + 1_658_944_953 + ); + } + + $basePackageDto = BasePackageDto::fromPackage( + $composer->getInstallationManager()->getInstallPath($package), + $package, + $basePackage + ); + + $basePackages[] = $basePackageDto; + } + + return $basePackages; + } finally { + $this->restoreToWorkingDir(); + } + }); + } + + public function checkAndInstallMissingBasePackage(string $packageName): BasePackageDto + { + $this->changeToProjectDir(); + + try { + try { + $basePackage = $this->getInstalledBasePackage($packageName); + } catch (PackageNotInstalledException) { + try { + $basePackage = $this->validate($packageName); + } catch (Throwable $throwable) { + $this->removeBasePackage($packageName); + + throw $throwable; + } + } + + return $basePackage; + } finally { + $this->restoreToWorkingDir(); + } + } + + public function validate(string $packageName): BasePackageDto + { + $this->changeToProjectDir(); + + try { + try { + $basePackage = $this->getInstalledBasePackage($packageName); + } catch (PackageNotInstalledException) { + $package = $this->getComposer()->getRepositoryManager()->findPackage( + $packageName, + new MatchAllConstraint() + ); + + if (!$package instanceof PackageInterface) { + throw new RuntimeException( + \sprintf('Package "%s" not found.', $packageName), + 1_658_944_953 + ); + } + + if ($package->getType() !== self::PACKAGE_TYPE) { + throw new IncompatiblePackageException( + \sprintf('Package "%s" is not of type "%s".', $packageName, self::PACKAGE_TYPE), + 1_658_786_562 + ); + } + + $this->installBasePackage($packageName); + + $basePackage = $this->getInstalledBasePackage($packageName); + } + } finally { + $this->restoreToWorkingDir(); + } + + try { + if (strlen($basePackage->title) < 5) { + throw new IncompatiblePackageException( + \sprintf('Title "%s" must have 5 characters or more.', $basePackage->title), + 1_658_945_128 + ); + } + + if (strlen($basePackage->description) < 10) { + throw new IncompatiblePackageException( + \sprintf('Description "%s" must have 10 characters or more.', $basePackage->description), + 1_658_945_398 + ); + } + + if ($basePackage->typo3Versions === []) { + throw new IncompatiblePackageException( + 'A base package must define one or more supported TYPO3 core versions.', + 1_658_945_403 + ); + } + + if (!\file_exists($basePackage->getInstallPath() . '/public/' . $basePackage->previewImage)) { + throw new IncompatiblePackageException( + 'A base package must have a preview image.', + 1_658_946_257 + ); + } + + $forbiddenFiles = Finder::create() + ->ignoreDotFiles(false) + ->files() + ->notName(self::ALLOWED_FILE_TYPES) + ->in($basePackage->getInstallPath()/* . '/templates/skeletons'*/) + ; + if ($forbiddenFiles->hasResults()) { + throw new IncompatiblePackageException( + \sprintf( + 'Package contains not allowed files: %s', + str_replace( + $basePackage->getInstallPath() . '/', + '', + implode( + ', ', + iterator_to_array($forbiddenFiles->getIterator()) + ) + ) + ), + 1_658_952_036 + ); + } + + return $basePackage; + } catch (Throwable $throwable) { + throw new IncompatiblePackageException( + \sprintf('Package "%s" is not a valid base package. %s', $packageName, $throwable->getMessage()), + 1_658_949_297 + ); + } + } + + public function resetCache(): void + { + $this->cache->invalidateTags(['base-packages']); + } + + public function updatePackageRepository(): void + { + $this->updateRepository(); + $this->updateBasePackages(); + $this->cache->invalidateTags(['base-packages']); + } +} diff --git a/src/Service/SitepackageGenerator.php b/src/Service/SitepackageGenerator.php index ffb1ad84..95455b6a 100644 --- a/src/Service/SitepackageGenerator.php +++ b/src/Service/SitepackageGenerator.php @@ -23,44 +23,61 @@ namespace App\Service; -use App\Entity\Sitepackage; -use App\Utility\FileUtility; +use App\Form\Dto\BasePackageDto; +use App\Package\Sitepackage; +use App\Utility\VersionUtility; +use RuntimeException; +use Symfony\Component\Finder\Finder; use Twig\Environment; use Twig\Loader\ArrayLoader; +use ZipArchive; -/** - * SitepackageGenerator - */ -class SitepackageGenerator +use function sprintf; +use function dirname; +use function rtrim; + +final class SitepackageGenerator { - protected string $zipPath; - protected string $filename; + /** + * @var array + */ + private array $basePackages = []; + + private string $zipPath; + + private string $filename; + + public function __construct( + private readonly BasePackageService $basePackageService, + ) { + } public function create(Sitepackage $package): void { - $extensionKey = $package->getExtensionKey(); - $this->filename = $extensionKey . '.zip'; - $sourceDir = __DIR__ . '/../../resources/skeletons/BaseExtension/' . $package->getBasePackage() . '/'; - $this->zipPath = is_string($zipPath = tempnam(sys_get_temp_dir(), $this->filename)) ? $zipPath : $this->filename; - $fileList = FileUtility::listDirectory($sourceDir); - - $zipFile = new \ZipArchive(); - $opened = $zipFile->open($this->zipPath, \ZipArchive::CREATE); + $this->filename = $package->getExtensionKey() . '.zip'; + $this->zipPath = ($zipPath = tempnam(sys_get_temp_dir(), $this->filename)) !== false + ? $zipPath : $this->filename + ; + + $zipFile = new ZipArchive(); + $opened = $zipFile->open($this->zipPath, ZipArchive::CREATE); if ($opened === true) { - foreach ($fileList as $file) { - if ($file !== $this->zipPath && file_exists($file)) { - $baseFileName = $this->createRelativeFilePath($file, $sourceDir); - if (is_dir($file)) { - $zipFile->addEmptyDir($baseFileName); - } elseif (!$this->isTwigFile($file)) { - $zipFile->addFile($file, $baseFileName); - } else { - $content = $this->getFileContent($file, $package); - $nameInZip = $this->removeTwigExtension($baseFileName); - $zipFile->addFromString($nameInZip, $content); - } - } - } + $sourceDir = $this->getSourceDir($package); + $files = Finder::create() + ->ignoreDotFiles(false) + ->ignoreVCS(false) + ->in($sourceDir) + ; + $this->addFiles($zipFile, $files, $package, $sourceDir); + + $sourceDir = dirname($sourceDir) . '/shared'; + $files = Finder::create() + ->ignoreDotFiles(false) + ->ignoreVCS(false) + ->in($sourceDir) + ; + $this->addFiles($zipFile, $files, $package, $sourceDir); + $zipFile->close(); } } @@ -75,36 +92,95 @@ public function getFilename(): string return $this->filename; } - private function getFileContent(string $file, Sitepackage $package): string + private function getBasePackage(Sitepackage $package): BasePackageDto + { + if (!($this->basePackages[$package->getBasePackage()] ?? null) instanceof BasePackageDto) { + $this->basePackages[$package->getBasePackage()] = + $this->basePackageService->getInstalledBasePackage($package->getBasePackage()); + } + + return $this->basePackages[$package->getBasePackage()]; + } + + private function getSourceDir(Sitepackage $package): string + { + $basePackage = $this->getBasePackage($package); + $version = $package->getTypo3Version(); + $versionDir = ''; + + foreach ($basePackage->typo3Versions as $v) { + if ($version < VersionUtility::versionToInt($v)) { + continue; + } + + $versionDir = $v; + break; + } + + if ($versionDir === '') { + throw new RuntimeException( + sprintf('Template for version "%s" not found.', $version), + 1_658_939_427 + ); + } + + return $basePackage->getInstallPath() . '/templates/skeletons/' . $versionDir; + } + + private function getFileContent(string $file, string $baseDir, Sitepackage $package): string { $content = file_get_contents($file); - $fileUniqueId = uniqid('file'); - $twig = new Environment(new ArrayLoader([$fileUniqueId => $content])); - $rendered = $twig->render( + $fileUniqueId = uniqid($this->createRelativeFilePath( + $file, + $baseDir + )); + $twig = new Environment(new ArrayLoader([$fileUniqueId => $content]), [ + 'strict_variables' => true, + ]); + + return $twig->render( $fileUniqueId, [ 'package' => $package, - 'timestamp' => time() + 'timestamp' => time(), ] ); - - return $rendered; } - private function isTwigFile(string $file): bool + private function createRelativeFilePath(string $file, string $sourceDir): string { - $pathinfo = pathinfo($file); - - return ($pathinfo['extension'] ?? '') === 'twig'; + return substr($file, strlen(rtrim($sourceDir, '/')) + 1); } - protected function createRelativeFilePath(string $file, string $sourceDir): string + private function isTwigFile(string $extension): bool { - return substr($file, strlen($sourceDir)); + return $extension === 'twig'; } - protected function removeTwigExtension(string $baseFileName): string + private function removeTwigExtension(string $baseFileName): string { return substr($baseFileName, 0, -5); } + + private function addFiles( + ZipArchive $zipFile, + Finder $files, + Sitepackage $package, + string $sourceDir + ): void { + $baseDir = dirname($sourceDir, 5); + + foreach ($files as $file) { + $baseFileName = $this->createRelativeFilePath($file->getPathname(), $sourceDir); + if ($file->isDir()) { + $zipFile->addEmptyDir($baseFileName); + } elseif (!$this->isTwigFile($file->getExtension())) { + $zipFile->addFile($file->getPathname(), $baseFileName); + } else { + $content = $this->getFileContent($file->getPathname(), $baseDir, $package); + $nameInZip = $this->removeTwigExtension($baseFileName); + $zipFile->addFromString($nameInZip, $content); + } + } + } } diff --git a/src/Session/WizardSessionTrait.php b/src/Session/WizardSessionTrait.php new file mode 100644 index 00000000..200ed016 --- /dev/null +++ b/src/Session/WizardSessionTrait.php @@ -0,0 +1,109 @@ +container->get('request_stack')) instanceof RequestStack) { + throw new RuntimeException('Invalid request stack.', 1_659_141_555); + } + + return $requestStack->getSession(); + } + + /** + * @throws UnexpectedValueException + */ + private function getSitepackageConfig(): SitepackageDto + { + $configuration = $this->getSession()->get('sitepackage_config'); + + if (!($configuration instanceof SitepackageDto)) { + $this->addFlash( + 'error', + 'Whoops, we could not find the package configuration. Please submit the configuration again.' + ); + + throw new UnexpectedValueException('Invalid or missing configuration.', 1_638_038_672); + } + + return $configuration; + } + + private function isAdvancedSitepackageConfig(): bool + { + return $this->getSession()->get('sitepackage_config_advanced') === true; + } + + private function setSitepackageConfig(SitepackageDto $configuration, bool $advanced): void + { + $this->getSession()->set('sitepackage_config', $configuration); + $this->getSession()->set('sitepackage_config_advanced', $advanced); + } + + /** + * @throws UnexpectedValueException + */ + private function getSitepackage(): Sitepackage + { + $sitepackage = $this->getSession()->get('sitepackage'); + + if (!($sitepackage instanceof Sitepackage)) { + $this->addFlash( + 'error', + 'Whoops, we could not find the Sitepackage. Please submit the configuration again.' + ); + + throw new UnexpectedValueException('Invalid or missing Sitepackage.', 1_638_038_673); + } + + return $sitepackage; + } + + private function setSitepackage(Sitepackage $sitepackage): void + { + $this->getSession()->set('sitepackage', $sitepackage); + } + + private function getSitepackageError(): string + { + return is_string($error = $this->getSession()->get('sitepackage_error')) ? $error : ''; + } + + private function setSitepackageError(string $error): void + { + $this->getSession()->set('sitepackage_error', $error); + } +} diff --git a/src/Twig/Extension/VersionNumberExtension.php b/src/Twig/Extension/VersionNumberExtension.php index d991a9d9..80c2721a 100644 --- a/src/Twig/Extension/VersionNumberExtension.php +++ b/src/Twig/Extension/VersionNumberExtension.php @@ -26,18 +26,15 @@ use Twig\Extension\AbstractExtension; use Twig\TwigFilter; -/** - * VersionNumberExtension. - **/ class VersionNumberExtension extends AbstractExtension { /** * @return TwigFilter[] */ - public function getFilters() + public function getFilters(): array { return [ - new TwigFilter('version', [$this, 'versionFilter']), + new TwigFilter('version', $this->versionFilter(...)), ]; } @@ -47,16 +44,13 @@ public function versionFilter(int $version, int $positions = 3): string $parts = [ substr($versionString, 0, 3), substr($versionString, 3, 3), - substr($versionString, 6, 3) + substr($versionString, 6, 3), ]; - switch ($positions) { - case 1: - return (string)(int)$parts[0]; - case 2: - return (int)$parts[0] . '.' . (int)$parts[1]; - default: - return (int)$parts[0] . '.' . (int)$parts[1] . '.' . (int)$parts[2]; - } + return match ($positions) { + 1 => (string)(int)$parts[0], + 2 => (int)$parts[0] . '.' . (int)$parts[1], + default => (int)$parts[0] . '.' . (int)$parts[1] . '.' . (int)$parts[2], + }; } } diff --git a/src/Utility/FileUtility.php b/src/Utility/FileUtility.php deleted file mode 100644 index 7be60ba2..00000000 --- a/src/Utility/FileUtility.php +++ /dev/null @@ -1,57 +0,0 @@ - - */ - public static function listDirectory(string $dir, bool $filesOnly = false): array - { - $result = []; - $root = is_array($root = scandir($dir)) ? $root : []; - foreach ($root as $value) { - if ($value === '.' || $value === '..') { - continue; - } - if (is_file("$dir$value")) { - $result[] = "$dir$value"; - - continue; - } - if (is_dir("$dir$value") && !($filesOnly)) { - $result[] = "$dir$value/"; - } - foreach (self::listDirectory("$dir$value/") as $subValue) { - $result[] = $subValue; - } - } - - return $result; - } -} diff --git a/src/Utility/StringUtility.php b/src/Utility/StringUtility.php index 69494a18..e4ce65b8 100644 --- a/src/Utility/StringUtility.php +++ b/src/Utility/StringUtility.php @@ -23,9 +23,6 @@ namespace App\Utility; -/** - * StringUtility - */ class StringUtility { public static function clean(string $string): string @@ -36,9 +33,8 @@ public static function clean(string $string): string $string = str_replace('&', '', $string); $string = self::convertUmlauts($string); $string = self::toASCII($string); - $string = trim($string); - return $string; + return trim($string); } public static function convertUmlauts(string $string): string @@ -61,26 +57,25 @@ public static function toASCII(string $string): string public static function stringToUpperCamelCase(string $string): string { $string = self::clean($string); - $string = is_string($result = preg_replace('/[^a-z0-9]+/i', ' ', $string)) ? $result : $string; - $string = is_string($result = preg_replace('/[A-Z]+/', ' $0', $string)) ? $result : $string; + $string = is_string($result = preg_replace('#[^a-z0-9]+#i', ' ', $string)) ? $result : $string; + $string = is_string($result = preg_replace('#[A-Z]+#', ' $0', $string)) ? $result : $string; $string = trim($string); $string = strtolower($string); $string = ucwords($string); - $string = str_replace(' ', '', $string); - return $string; + return str_replace(' ', '', $string); } public static function camelCaseToLowerCaseUnderscored(string $string): string { preg_match_all( - '!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', + '#([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)#', self::clean($string), $matches ); $ret = $matches[0]; foreach ($ret as &$match) { - $match = $match == strtoupper($match) ? strtolower($match) : lcfirst($match); + $match = $match == strtoupper((string)$match) ? strtolower((string)$match) : lcfirst((string)$match); } return implode('_', $ret); @@ -89,13 +84,13 @@ public static function camelCaseToLowerCaseUnderscored(string $string): string public static function camelCaseToLowerCaseDashed(string $string): string { preg_match_all( - '!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', + '#([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)#', self::clean($string), $matches ); $ret = $matches[0]; foreach ($ret as &$match) { - $match = $match == strtoupper($match) ? strtolower($match) : lcfirst($match); + $match = $match == strtoupper((string)$match) ? strtolower((string)$match) : lcfirst((string)$match); } return implode('-', $ret); diff --git a/src/Utility/VersionUtility.php b/src/Utility/VersionUtility.php index 8cee378a..f75d6a14 100644 --- a/src/Utility/VersionUtility.php +++ b/src/Utility/VersionUtility.php @@ -89,4 +89,17 @@ public static function normalize($version, int $digits = 3): ?string return $version; } + + public static function versionToInt(?string $version): int + { + if (($version = self::normalize($version, 3)) === null) { + return 0; + } + + $versionParts = explode('.', $version); + + return ((int)$versionParts[0] % 1000) * 1_000_000 + + ((int)$versionParts[1] % 1000) * 1000 + + ((int)$versionParts[2] % 1000); + } } diff --git a/templates/default/wizards/sitepackage/success.html.twig b/templates/default/wizards/sitepackage/success.html.twig deleted file mode 100644 index c0e9f43b..00000000 --- a/templates/default/wizards/sitepackage/success.html.twig +++ /dev/null @@ -1,88 +0,0 @@ -{% extends 'layout.html.twig' %} -{% block title %}Success{% endblock %} -{% block body %} - - {% frame with { color: 'dark', height: 'small', center: true, title: 'Congratulations!', titleSize: 1, backgroundImage: asset("assets/Images/keyvisual.png") } %} -

- Your Sitepackage has been successfully created. You can now check the - configuration or download the prepared Sitepackage. -

-

- - {{ icon('actions-package', 'auto') }} - Download - -

- {% endframe %} - - {% frame with { id: 'configuration', indent: true, title: 'Your Sitepackage Configuration' } %} -
-
TYPO3 Version
-
{{ sitepackage.typo3Version|version(2) }}
-
Base Package
-
{{ sitepackage.basePackage }}
-
-

Sitepackage Extension

-
-
Titel
-
{{ sitepackage.title }}
- {% if sitepackage.description %} -
Description
-
{{ sitepackage.description }}
- {% endif %} -
Extension Key
-
{{ sitepackage.extensionKey }}
- {% if sitepackage.repositoryUrl %} -
Repository
-
{{ sitepackage.repositoryUrl }}
- {% endif %} -
-

PHP

-
- -
Composer Name
-
{{ sitepackage.composerVendorName }}/{{ sitepackage.composerProjectName }}
-
PSR-4 Namespace
-
{{ sitepackage.vendorName }}\{{ sitepackage.packageName }}
-
-

Author

-
-
Name
-
{{ sitepackage.author.name }}
-
E-Mail
-
{{ sitepackage.author.email }}
-
Company
-
{{ sitepackage.author.company }}
-
Homepage
-
{{ sitepackage.author.homepage }}
-
-

- - {{ icon('actions-arrow-left-alt', 'auto') }} - Restart - - - {{ icon('actions-open', 'auto') }} - Edit Configuration - -

- {% endframe %} - - {% frame with { color: 'dark', size: 'default', center: true } %} -

- Your Sitepackage has been successfully created and is ready for download. -

-

- - {{ icon('actions-package', 'auto') }} - Download - -

- {% endframe %} - - {% include 'default/wizards/sitepackage/partials/privacy-footer.html.twig' %} - -{% endblock %} diff --git a/templates/form/custom_theme.html.twig b/templates/form/custom_theme.html.twig new file mode 100644 index 00000000..e2a7b269 --- /dev/null +++ b/templates/form/custom_theme.html.twig @@ -0,0 +1,13 @@ +{% extends "custom_theme.html.twig" %} + +{%- block base_package_widget -%} + + {% if notification is not empty %} + + {% endif %} + + {{- block('choice_widget') -}} + +{%- endblock base_package_widget -%} diff --git a/templates/layout.html.twig b/templates/layout.html.twig index 2c71dc0f..33bb50c6 100644 --- a/templates/layout.html.twig +++ b/templates/layout.html.twig @@ -14,6 +14,7 @@ gtag(\'config\', \'G-JTSKLNF4S0\'); ') }} {% endblock %} +{% block headline %}Try the new Sitepackage Builder now and create a Sitepackage in 2 easy steps.{% endblock %} {% block footer %} {% frame with { color: 'primary' } %}
diff --git a/templates/wizards/layout.html.twig b/templates/wizards/layout.html.twig new file mode 100644 index 00000000..e38a310f --- /dev/null +++ b/templates/wizards/layout.html.twig @@ -0,0 +1,10 @@ +{% extends 'layout.html.twig' %} + +{% block headline %}{% endblock %} + +{% block footer %} + + {% include 'wizards/partials/privacy-footer.html.twig' %} + {{ parent() }} + +{% endblock %} diff --git a/templates/default/wizards/sitepackage/partials/privacy-footer.html.twig b/templates/wizards/partials/privacy-footer.html.twig similarity index 84% rename from templates/default/wizards/sitepackage/partials/privacy-footer.html.twig rename to templates/wizards/partials/privacy-footer.html.twig index 8ef7e65e..aaaf371a 100644 --- a/templates/default/wizards/sitepackage/partials/privacy-footer.html.twig +++ b/templates/wizards/partials/privacy-footer.html.twig @@ -1,7 +1,7 @@ {% frame with { id: 'privacy', color: 'light', center: true, indent: true, title: 'We respect your Privacy!' } %}

We are not storing, sharing or doing any other crazy stuff with the - data you provide to generate your very own sitepackage. Simple as + data you provide to generate your very own Sitepackage. Simple as that, check the sources.

{% endframe %} diff --git a/templates/default/wizards/sitepackage/edit.html.twig b/templates/wizards/sitepackage/configure.html.twig similarity index 61% rename from templates/default/wizards/sitepackage/edit.html.twig rename to templates/wizards/sitepackage/configure.html.twig index 76fb0b12..7b0e5e79 100644 --- a/templates/default/wizards/sitepackage/edit.html.twig +++ b/templates/wizards/sitepackage/configure.html.twig @@ -1,8 +1,10 @@ -{% extends 'layout.html.twig' %} +{% extends 'wizards/layout.html.twig' %} + {% block title %}Create your own TYPO3 Sitepackage{% endblock %} + {% block body %} - {% frame with { color: 'dark', height: 'small', center: true, title: 'Create your own Sitepackage', titleSize: 1, backgroundImage: asset("assets/Images/keyvisual.png") } %} + {% frame with { color: 'dark', center: true, title: 'Create your own Sitepackage', titleSize: 1, backgroundImage: asset("assets/Images/keyvisual.png") } %}

Awesome you made it here! Just a few more details about your project and your own Sitepackage is ready for download. @@ -13,6 +15,4 @@ {{ form(form, {'attr': {'novalidate': 'novalidate'}}) }} {% endframe %} - {% include 'default/wizards/sitepackage/partials/privacy-footer.html.twig' %} - {% endblock %} diff --git a/templates/wizards/sitepackage/error.html.twig b/templates/wizards/sitepackage/error.html.twig new file mode 100644 index 00000000..1b8c72e1 --- /dev/null +++ b/templates/wizards/sitepackage/error.html.twig @@ -0,0 +1,23 @@ +{% extends 'wizards/layout.html.twig' %} + +{% block title %}Error{% endblock %} + +{% block body %} + + {% frame with { color: 'dark', center: true, title: 'Error', titleSize: 1, backgroundImage: asset("assets/Images/keyvisual.png") } %} +

+ Your sitepackage was not created, please check the error below. +

+ {% endframe %} + + {% frame with { id: 'error', indent: true, title: 'Error information' } %} +

{{ error }}

+

+ + {{ icon('actions-arrow-left-alt', 'auto') }} + Back + +

+ {% endframe %} + +{% endblock %} diff --git a/templates/default/wizards/sitepackage/index.html.twig b/templates/wizards/sitepackage/index.html.twig similarity index 89% rename from templates/default/wizards/sitepackage/index.html.twig rename to templates/wizards/sitepackage/index.html.twig index 47441996..df12d969 100644 --- a/templates/default/wizards/sitepackage/index.html.twig +++ b/templates/wizards/sitepackage/index.html.twig @@ -1,15 +1,17 @@ -{% extends 'layout.html.twig' %} +{% extends 'wizards/layout.html.twig' %} + {% block title %}Kickstart your TYPO3 template development{% endblock %} + {% block body %} - {% frame with { color: 'dark', height: 'small', center: true, title: 'Sitepackage Builder', titleSize: 1, backgroundImage: asset("assets/Images/keyvisual.png") } %} + {% frame with { color: 'dark', center: true, title: 'Sitepackage Builder', titleSize: 1, backgroundImage: asset("assets/Images/keyvisual.png") } %}

Sitepackage-Builder is your kickstarter for modern TYPO3 Theme development. Learn more about TYPO3 templating or start your own template right now.

- {{ icon('actions-extension-add', 'auto') }} + {{ icon('actions-rocket', 'auto') }} Create Sitepackage

@@ -26,7 +28,7 @@ Learn more about the best practices recommended from the TYPO3 Core Team.

- + {{ icon('actions-notebook', 'auto') }} Learn about Sitepackages @@ -35,7 +37,7 @@ {% frame with { id: 'arguments', center: true, indent: true, title: 'Pros and Cons', titleSize: 3 } %}

- +
@@ -45,7 +47,7 @@ - + @@ -97,10 +99,10 @@

{% endframe %} - {% frame with { color: 'light', center: true, id: 'start', title: 'Start your own Sitepackage' } %} + {% frame with { center: true, id: 'start', title: 'Start your own Sitepackage' } %}

- {{ icon('actions-extension-add', 'auto') }} + {{ icon('actions-rocket', 'auto') }} Create Sitepackage

diff --git a/templates/wizards/sitepackage/new.html.twig b/templates/wizards/sitepackage/new.html.twig new file mode 100644 index 00000000..5d3080b2 --- /dev/null +++ b/templates/wizards/sitepackage/new.html.twig @@ -0,0 +1,80 @@ +{% extends 'wizards/layout.html.twig' %} + +{% block title %}Create your own TYPO3 Sitepackage{% endblock %} + +{% block body %} + + {% frame with { color: 'dark', center: true, title: 'Create your own Sitepackage', titleSize: 1, backgroundImage: asset("assets/Images/keyvisual.png") } %} +

+ Awesome you made it here! Just a few more details about your + project and your own Sitepackage is ready for download. +

+ {% endframe %} + + {% if basePackages|length > 0 %} + {% if not filtered %} + {% frame with { id: 'base-packages', center: true, title: 'Choose a Base Package to continue with' } %}{% endframe %} + {% endif %} + + {% frame %} +
+ {% for basePackage in basePackages %} +
+
+
+

{{ basePackage.title }}

+
+ + {% if basePackage.official %} + {{ basePackage.title }} + {% endif %} +
+

{{ basePackage.description }}

+
+ +
+
+ {% endfor %} +
+ {% endframe %} + + {% if filtered %} + {% frame with { center: true } %} +

+ + {{ icon('actions-rocket', 'auto') }} + Show all Base Packages + +

+ {% endframe %} + {% endif %} + {% else %} +
+

No BasePackages found.

+
+ {% endif %} + +{% endblock %} diff --git a/templates/wizards/sitepackage/success.html.twig b/templates/wizards/sitepackage/success.html.twig new file mode 100644 index 00000000..86ef0b03 --- /dev/null +++ b/templates/wizards/sitepackage/success.html.twig @@ -0,0 +1,84 @@ +{% extends 'wizards/layout.html.twig' %} + +{% block title %}Success{% endblock %} + +{% block body %} + + {% frame with { color: 'dark', center: true, title: 'Congratulations!', titleSize: 1, backgroundImage: asset("assets/Images/keyvisual.png") } %} +

+ Your Sitepackage has been successfully prepared. You can now check the + configuration or download the prepared Sitepackage. +

+ {% endframe %} + + {% frame with { id: 'configuration', indent: true, title: 'Your Sitepackage Configuration' } %} +
+
Base Package
+
{{ base_package.title }} ({{ base_package.packageName }})
+
Source
+
{% if base_package.official %}TYPO3 official base package{% elseif base_package.thirdParty %}Unknown third party{% else %}Verified third party{% endif %}
+
TYPO3 Version
+
{{ sitepackage.typo3Version|version(2) }}
+
+

Sitepackage Extension

+
+
Titel
+
{{ sitepackage.title }}
+ {% if sitepackage.description %} +
Description
+
{{ sitepackage.description }}
+ {% endif %} +
Extension Key
+
{{ sitepackage.extensionKey }}
+ {% if sitepackage.repositoryUrl %} +
Repository
+
{{ sitepackage.repositoryUrl }}
+ {% endif %} +
+

PHP

+
+
Composer Name
+
{{ sitepackage.composerName }}
+
PSR-4 Namespace
+
{{ sitepackage.psr4Namespace }}
+
+

Author

+
+
Name
+
{{ sitepackage.author.name }}
+
E-Mail
+
{{ sitepackage.author.email }}
+
Company
+
{{ sitepackage.author.company }}
+
Homepage
+
{{ sitepackage.author.homepage }}
+
+

+ + {{ icon('actions-undo', 'auto') }} + Restart + + + {{ icon('actions-open', 'auto') }} + Edit Configuration + + + {{ icon('actions-download', 'auto') }} + Download + +

+ {% endframe %} + + {% frame with { color: 'dark', size: 'default', center: true } %} +

+ Your Sitepackage has been successfully created and is ready for download. +

+

+ + {{ icon('actions-download', 'auto') }} + Download + +

+ {% endframe %} + +{% endblock %} diff --git a/tmp/.gitkeep b/tmp/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/tmp/base-packages/.gitignore b/tmp/base-packages/.gitignore new file mode 100644 index 00000000..a68d087b --- /dev/null +++ b/tmp/base-packages/.gitignore @@ -0,0 +1,2 @@ +/* +!/.gitignore From f8243c920ae6ec0ce36bfc0f106a483736f52796 Mon Sep 17 00:00:00 2001 From: Simon Gilli <25326036+gilbertsoft@users.noreply.github.com> Date: Wed, 26 Apr 2023 10:33:21 +0200 Subject: [PATCH 3/8] Add missing package and bump versions --- composer.json | 135 +++++++++++++++++++++++++------------------------- composer.lock | 2 +- 2 files changed, 69 insertions(+), 68 deletions(-) diff --git a/composer.json b/composer.json index 26af66ce..bc0d9179 100644 --- a/composer.json +++ b/composer.json @@ -37,79 +37,80 @@ "ext-sqlite3": "*", "ext-zip": "*", "ext-zlib": "*", - "composer/composer": "^2.2", - "composer/semver": "^3.3", - "doctrine/collections": "^1.6", - "doctrine/dbal": "^3.3", - "doctrine/doctrine-bundle": "^2.7", - "doctrine/doctrine-migrations-bundle": "^3.2", - "doctrine/inflector": "^2.0", - "doctrine/orm": "^2.12", - "doctrine/persistence": "^2.5", - "easycorp/easyadmin-bundle": "^4.3", - "erusev/parsedown": "^1.7", - "guzzlehttp/guzzle": "^7.4", - "guzzlehttp/promises": "^1.5", - "jms/serializer": "^3.17", - "jms/serializer-bundle": "^4.0.2", + "composer/composer": "^2.5.5", + "composer/semver": "^3.3.2", + "doctrine/collections": "^1.8", + "doctrine/dbal": "^3.6.2", + "doctrine/doctrine-bundle": "^2.9.1", + "doctrine/doctrine-migrations-bundle": "^3.2.2", + "doctrine/inflector": "^2.0.6", + "doctrine/orm": "^2.14.3", + "doctrine/persistence": "^2.5.7", + "easycorp/easyadmin-bundle": "^4.6.1", + "erusev/parsedown": "^1.7.4", + "guzzlehttp/guzzle": "^7.5.1", + "guzzlehttp/promises": "^1.5.2", + "jms/serializer": "^3.23", + "jms/serializer-bundle": "^4.2.0", "knplabs/knp-menu": "^3.3", - "nelmio/api-doc-bundle": "^4.9", - "nelmio/cors-bundle": "^2.2", - "nelmio/security-bundle": "^2.5", + "nelmio/api-doc-bundle": "^4.11.1", + "nelmio/cors-bundle": "^2.3.1", + "nelmio/security-bundle": "^2.12", "psr/log": "^2.0", - "symfony/asset": "^6.2", - "symfony/cache": "^6.2", - "symfony/cache-contracts": "^2.5", - "symfony/console": "^6.2", - "symfony/dependency-injection": "^6.2", - "symfony/dotenv": "^6.2", - "symfony/expression-language": "^6.2", - "symfony/filesystem": "^6.2", - "symfony/finder": "^6.2", - "symfony/flex": "^2.2", - "symfony/form": "^6.2", - "symfony/framework-bundle": "^6.2", - "symfony/http-client": "^6.2", - "symfony/http-foundation": "^6.2", - "symfony/http-kernel": "^6.2", - "symfony/intl": "^6.2", - "symfony/mailer": "^6.2", - "symfony/mime": "^6.2", - "symfony/monolog-bundle": "^3.1", - "symfony/notifier": "^6.2", - "symfony/process": "^6.2", - "symfony/property-access": "^6.2", - "symfony/property-info": "^6.2", - "symfony/proxy-manager-bridge": "^6.2", - "symfony/routing": "^6.2", - "symfony/runtime": "^6.2", - "symfony/security-bundle": "^6.2", - "symfony/security-http": "^6.2", - "symfony/serializer": "^6.2", - "symfony/translation": "^6.2", - "symfony/twig-bundle": "^6.2", - "symfony/validator": "^6.2", - "symfony/web-link": "^6.2", - "symfony/yaml": "^6.2", - "t3g/symfony-template-bundle": "^3.4", + "symfony/asset": "^6.2.7", + "symfony/cache": "^6.2.8", + "symfony/cache-contracts": "^2.5.2", + "symfony/console": "^6.2.8", + "symfony/dependency-injection": "^6.2.8", + "symfony/dotenv": "^6.2.8", + "symfony/expression-language": "^6.2.7", + "symfony/filesystem": "^6.2.7", + "symfony/finder": "^6.2.7", + "symfony/flex": "^2.2.5", + "symfony/form": "^6.2.8", + "symfony/framework-bundle": "^6.2.9", + "symfony/http-client": "^6.2.9", + "symfony/http-foundation": "^6.2.8", + "symfony/http-kernel": "^6.2.9", + "symfony/intl": "^6.2.9", + "symfony/mailer": "^6.2.8", + "symfony/mime": "^6.2.7", + "symfony/monolog-bundle": "^3.8", + "symfony/notifier": "^6.2.8", + "symfony/options-resolver": "^6.2.7", + "symfony/process": "^6.2.8", + "symfony/property-access": "^6.2.8", + "symfony/property-info": "^6.2.8", + "symfony/proxy-manager-bridge": "^6.2.7", + "symfony/routing": "^6.2.8", + "symfony/runtime": "^6.2.8", + "symfony/security-bundle": "^6.2.8", + "symfony/security-http": "^6.2.8", + "symfony/serializer": "^6.2.8", + "symfony/translation": "^6.2.8", + "symfony/twig-bundle": "^6.2.7", + "symfony/validator": "^6.2.8", + "symfony/web-link": "^6.2.7", + "symfony/yaml": "^6.2.7", + "t3g/symfony-template-bundle": "^3.5", "t3g/symfony-usercentrics-bundle": "^1.0.2 || dev-master", - "twig/extra-bundle": "^2.12 || ^3.0", - "twig/twig": "^2.12 || ^3.0" + "twig/extra-bundle": "^2.12 || ^3.5.1", + "twig/twig": "^2.12 || ^3.5.1" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.8", - "doctrine/doctrine-fixtures-bundle": "^3.4", - "ergebnis/composer-normalize": "^2.28", - "fakerphp/faker": "^1.20", + "bamarni/composer-bin-plugin": "^1.8.2", + "doctrine/doctrine-fixtures-bundle": "^3.4.3", + "ergebnis/composer-normalize": "^2.30.2", + "fakerphp/faker": "^1.21", "roave/security-advisories": "dev-latest", - "symfony/browser-kit": "^6.2", - "symfony/css-selector": "^6.2", - "symfony/debug-bundle": "^6.2", - "symfony/maker-bundle": "^1.45", - "symfony/panther": "^2.0", - "symfony/stopwatch": "^6.2", - "symfony/var-dumper": "^6.2", - "symfony/web-profiler-bundle": "^6.2" + "symfony/browser-kit": "^6.2.7", + "symfony/css-selector": "^6.2.7", + "symfony/debug-bundle": "^6.2.7", + "symfony/maker-bundle": "^1.48", + "symfony/panther": "^2.0.1", + "symfony/stopwatch": "^6.2.7", + "symfony/var-dumper": "^6.2.8", + "symfony/web-profiler-bundle": "^6.2.7" }, "replace": { "paragonie/random_compat": "2.*", diff --git a/composer.lock b/composer.lock index f4ba6bc5..36702824 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5c42f019b3cf9fa9249650716099c142", + "content-hash": "c6c0594bd0d3e02a10c50ca5f4bfc3b4", "packages": [ { "name": "composer/ca-bundle", From f12648c2306b372379ff4d9877ff2d6f881940bd Mon Sep 17 00:00:00 2001 From: Simon Gilli <25326036+gilbertsoft@users.noreply.github.com> Date: Wed, 26 Apr 2023 10:38:49 +0200 Subject: [PATCH 4/8] Apply cs rules --- src/Controller/Admin/DashboardController.php | 1 - src/Controller/Api/AbstractController.php | 2 -- src/Controller/Api/SitepackageController.php | 5 +++++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Controller/Admin/DashboardController.php b/src/Controller/Admin/DashboardController.php index b111edff..c82c6bf0 100644 --- a/src/Controller/Admin/DashboardController.php +++ b/src/Controller/Admin/DashboardController.php @@ -33,7 +33,6 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Http\Attribute\IsGranted; -use Iterator; #[IsGranted('ROLE_ADMIN')] class DashboardController extends AbstractDashboardController diff --git a/src/Controller/Api/AbstractController.php b/src/Controller/Api/AbstractController.php index a34f5dfb..83d47961 100644 --- a/src/Controller/Api/AbstractController.php +++ b/src/Controller/Api/AbstractController.php @@ -40,8 +40,6 @@ use DateTime; use DateTimeImmutable; -use function iterator_apply; -use function iterator_to_array; use function is_string; abstract class AbstractController extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractController diff --git a/src/Controller/Api/SitepackageController.php b/src/Controller/Api/SitepackageController.php index ed29aac1..4055e2b7 100644 --- a/src/Controller/Api/SitepackageController.php +++ b/src/Controller/Api/SitepackageController.php @@ -51,19 +51,24 @@ public function __construct( /** * @OA\RequestBody( + * * @Model(type=Sitepackage::class), * request="sitepackage", * required=true * ) + * * @OA\Response( * response=200, * description="Successfully generated.", + * * @OA\Schema(type="file") * ) + * * @OA\Response( * response=400, * description="Request malformed." * ) + * * @OA\Tag(name="sitepackage") */ /* From e829bcd0963580a9b3b3463c3c547f45718f7dee Mon Sep 17 00:00:00 2001 From: Simon Gilli <25326036+gilbertsoft@users.noreply.github.com> Date: Wed, 26 Apr 2023 11:08:13 +0200 Subject: [PATCH 5/8] Fix tests --- .../Controller/Web/DefaultControllerTest.php | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/Functional/Controller/Web/DefaultControllerTest.php b/tests/Functional/Controller/Web/DefaultControllerTest.php index c75f4e1b..5c6d5679 100644 --- a/tests/Functional/Controller/Web/DefaultControllerTest.php +++ b/tests/Functional/Controller/Web/DefaultControllerTest.php @@ -46,7 +46,7 @@ public function webDefault(): void { $this->client->request('GET', '/'); self::assertResponseIsSuccessful(); - self::assertSelectorTextContains('h1', 'Build Blazingly'); + self::assertSelectorTextContains('div.frame-container:nth-child(2) > div:nth-child(1) > h1:nth-child(1)', 'Build Blazingly'); self::assertSelectorTextContains('#download-community-1 .btn', 'Get version 10'); self::assertSelectorTextContains('#download-community-2 .btn', 'Get version 9'); self::assertSelectorTextContains('#download-elts-1 .btn-primary', 'Buy ELTS'); @@ -70,7 +70,7 @@ public function webVersionSprint(): void { $this->client->request('GET', '/version/10'); self::assertResponseIsSuccessful(); - self::assertSelectorTextContains('h1', 'TYPO3 10'); + self::assertSelectorTextContains('div.frame-container:nth-child(2) > div:nth-child(1) > h1:nth-child(1)', 'TYPO3 10'); } /** @@ -80,7 +80,7 @@ public function webVersionSpecific(): void { $this->client->request('GET', '/version/10.0.0'); self::assertResponseIsSuccessful(); - self::assertSelectorTextContains('h1', '(10.0.0)'); + self::assertSelectorTextContains('div.frame-container:nth-child(2) > div:nth-child(1) > h1:nth-child(1)', '(10.0.0)'); self::assertSelectorNotExists('#notice-elts'); self::assertSelectorExists('#accordion-download'); } @@ -92,7 +92,7 @@ public function webVersionElts(): void { $this->client->request('GET', '/version/6.2'); self::assertResponseIsSuccessful(); - self::assertSelectorTextContains('h1', '(6.2.23 ELTS)'); + self::assertSelectorTextContains('div.frame-container:nth-child(2) > div:nth-child(1) > h1:nth-child(1)', '(6.2.23 ELTS)'); self::assertSelectorExists('#notice-elts'); self::assertSelectorNotExists('#accordion-download'); } @@ -104,7 +104,7 @@ public function webVersionBeforeElts(): void { $this->client->request('GET', '/version/6.2.0'); self::assertResponseIsSuccessful(); - self::assertSelectorTextContains('h1', '(6.2.0)'); + self::assertSelectorTextContains('div.frame-container:nth-child(2) > div:nth-child(1) > h1:nth-child(1)', '(6.2.0)'); self::assertSelectorExists('#notice-elts'); self::assertSelectorExists('#accordion-download'); } @@ -116,7 +116,7 @@ public function webVersionOutdated(): void { $this->client->request('GET', '/version/4.5.0'); self::assertResponseIsSuccessful(); - self::assertSelectorTextContains('h1', '(4.5.0)'); + self::assertSelectorTextContains('div.frame-container:nth-child(2) > div:nth-child(1) > h1:nth-child(1)', '(4.5.0)'); self::assertSelectorExists('#notice-outdated'); self::assertSelectorExists('#accordion-download'); } @@ -128,7 +128,7 @@ public function webVersionOutdatedElts(): void { $this->client->request('GET', '/version/4.5'); self::assertResponseIsSuccessful(); - self::assertSelectorTextContains('h1', '(4.5.23 ELTS)'); + self::assertSelectorTextContains('div.frame-container:nth-child(2) > div:nth-child(1) > h1:nth-child(1)', '(4.5.23 ELTS)'); self::assertSelectorExists('#notice-outdated'); self::assertSelectorNotExists('#accordion-download'); } @@ -150,7 +150,7 @@ public function weReleaseNotesSprint(): void { $this->client->request('GET', '/release-notes/10'); self::assertResponseIsSuccessful(); - self::assertSelectorTextContains('h1', '10.0.5'); + self::assertSelectorTextContains('div.frame-container:nth-child(2) > div:nth-child(1) > h1:nth-child(1)', '10.0.5'); } /** @@ -160,7 +160,7 @@ public function webReleaseNotesSpecific(): void { $this->client->request('GET', '/release-notes/10.0.0'); self::assertResponseIsSuccessful(); - self::assertSelectorTextContains('h1', '10.0.0'); + self::assertSelectorTextContains('div.frame-container:nth-child(2) > div:nth-child(1) > h1:nth-child(1)', '10.0.0'); self::assertSelectorNotExists('#notice-elts'); } @@ -171,7 +171,7 @@ public function webReleaseNotesElts(): void { $this->client->request('GET', '/release-notes/6.2'); self::assertResponseIsSuccessful(); - self::assertSelectorTextContains('h1', '6.2.23 ELTS'); + self::assertSelectorTextContains('div.frame-container:nth-child(2) > div:nth-child(1) > h1:nth-child(1)', '6.2.23 ELTS'); self::assertSelectorExists('#notice-elts'); } @@ -182,7 +182,7 @@ public function webReleaseNotesBeforeElts(): void { $this->client->request('GET', '/release-notes/6.2.0'); self::assertResponseIsSuccessful(); - self::assertSelectorTextContains('h1', '6.2.0'); + self::assertSelectorTextContains('div.frame-container:nth-child(2) > div:nth-child(1) > h1:nth-child(1)', '6.2.0'); self::assertSelectorExists('#notice-elts'); } @@ -193,7 +193,7 @@ public function webReleaseNotesOutdated(): void { $this->client->request('GET', '/release-notes/4.5.0'); self::assertResponseIsSuccessful(); - self::assertSelectorTextContains('h1', '4.5.0'); + self::assertSelectorTextContains('div.frame-container:nth-child(2) > div:nth-child(1) > h1:nth-child(1)', '4.5.0'); self::assertSelectorExists('#notice-outdated'); } @@ -204,7 +204,7 @@ public function webReleaseNotesOutdatedElts(): void { $this->client->request('GET', '/release-notes/4.5'); self::assertResponseIsSuccessful(); - self::assertSelectorTextContains('h1', '4.5.23 ELTS'); + self::assertSelectorTextContains('div.frame-container:nth-child(2) > div:nth-child(1) > h1:nth-child(1)', '4.5.23 ELTS'); self::assertSelectorExists('#notice-outdated'); } } From c83f729286951e75d70748f9830f360cdc75b813 Mon Sep 17 00:00:00 2001 From: Simon Gilli <25326036+gilbertsoft@users.noreply.github.com> Date: Wed, 26 Apr 2023 11:22:17 +0200 Subject: [PATCH 6/8] Replace deprecated utf8_decode --- composer.json | 1 + composer.lock | 3 ++- src/Utility/StringUtility.php | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index bc0d9179..fb26dbb3 100644 --- a/composer.json +++ b/composer.json @@ -34,6 +34,7 @@ "ext-ctype": "*", "ext-iconv": "*", "ext-json": "*", + "ext-mbstring": "*", "ext-sqlite3": "*", "ext-zip": "*", "ext-zlib": "*", diff --git a/composer.lock b/composer.lock index 36702824..b4639770 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c6c0594bd0d3e02a10c50ca5f4bfc3b4", + "content-hash": "1ddf83ba22b6b292386b8ac262f094da", "packages": [ { "name": "composer/ca-bundle", @@ -11879,6 +11879,7 @@ "ext-ctype": "*", "ext-iconv": "*", "ext-json": "*", + "ext-mbstring": "*", "ext-sqlite3": "*", "ext-zip": "*", "ext-zlib": "*" diff --git a/src/Utility/StringUtility.php b/src/Utility/StringUtility.php index e4ce65b8..90be037c 100644 --- a/src/Utility/StringUtility.php +++ b/src/Utility/StringUtility.php @@ -48,8 +48,8 @@ public static function convertUmlauts(string $string): string public static function toASCII(string $string): string { return strtr( - utf8_decode($string), - utf8_decode('ŠŒŽšœžŸ¥µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ'), + mb_convert_encoding($string, 'ISO-8859-1', 'UTF-8'), + mb_convert_encoding('ŠŒŽšœžŸ¥µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ', 'ISO-8859-1', 'UTF-8'), 'SOZsozYYuAAAAAAACEEEEIIIIDNOOOOOOUUUUYsaaaaaaaceeeeiiiionoooooouuuuyy' ); } From aada7cd369f87ce0d41675aa99d12ee0a1f7a57f Mon Sep 17 00:00:00 2001 From: Simon Gilli <25326036+gilbertsoft@users.noreply.github.com> Date: Wed, 26 Apr 2023 12:14:56 +0200 Subject: [PATCH 7/8] Rename wizards to tools --- src/Controller/EntryPointController.php | 4 +- .../SitepackageController.php | 58 +++++++++---------- src/Entity/BasePackage.php | 2 +- src/Menu/MenuBuilder.php | 14 ++--- src/Service/BasePackageService.php | 2 +- ...dSessionTrait.php => ToolSessionTrait.php} | 2 +- templates/default/root.html.twig | 2 +- templates/layout.html.twig | 2 +- templates/{wizards => tools}/layout.html.twig | 2 +- .../partials/privacy-footer.html.twig | 0 .../sitepackage/configure.html.twig | 2 +- .../sitepackage/error.html.twig | 4 +- .../sitepackage/index.html.twig | 6 +- .../sitepackage/new.html.twig | 6 +- .../sitepackage/success.html.twig | 10 ++-- 15 files changed, 58 insertions(+), 58 deletions(-) rename src/Controller/{Wizards => Tools}/SitepackageController.php (76%) rename src/Session/{WizardSessionTrait.php => ToolSessionTrait.php} (99%) rename templates/{wizards => tools}/layout.html.twig (66%) rename templates/{wizards => tools}/partials/privacy-footer.html.twig (100%) rename templates/{wizards => tools}/sitepackage/configure.html.twig (93%) rename templates/{wizards => tools}/sitepackage/error.html.twig (82%) rename templates/{wizards => tools}/sitepackage/index.html.twig (95%) rename templates/{wizards => tools}/sitepackage/new.html.twig (91%) rename templates/{wizards => tools}/sitepackage/success.html.twig (89%) diff --git a/src/Controller/EntryPointController.php b/src/Controller/EntryPointController.php index fec7c32f..d18a173f 100644 --- a/src/Controller/EntryPointController.php +++ b/src/Controller/EntryPointController.php @@ -36,8 +36,8 @@ class EntryPointController extends AbstractController private const ENTRY_POINTS = [ // 'slug' => 'route', 'composer-helper' => 'composer-helper', - 'sitepackage' => 'wizards_sitepackage', - 'sitepackage-builder' => 'wizards_sitepackage', + 'sitepackage' => 'tools_sitepackage', + 'sitepackage-builder' => 'tools_sitepackage', ]; #[Route('/go/{slug}', requirements: ['slug' => '.+'])] diff --git a/src/Controller/Wizards/SitepackageController.php b/src/Controller/Tools/SitepackageController.php similarity index 76% rename from src/Controller/Wizards/SitepackageController.php rename to src/Controller/Tools/SitepackageController.php index 05f070d8..5f5ca8c2 100644 --- a/src/Controller/Wizards/SitepackageController.php +++ b/src/Controller/Tools/SitepackageController.php @@ -21,12 +21,12 @@ * The TYPO3 project - inspiring people to share! */ -namespace App\Controller\Wizards; +namespace App\Controller\Tools; use App\Factory\SitepackageFactory; use App\Form\Dto\SitepackageDto; use App\Form\SitepackageType; -use App\Session\WizardSessionTrait; +use App\Session\ToolSessionTrait; use App\Utility\StringUtility; use App\Utility\VersionUtility; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -42,10 +42,10 @@ use function sprintf; -#[Route(path: '/wizards/sitepackage')] +#[Route(path: '/tools/sitepackage')] final class SitepackageController extends AbstractController { - use WizardSessionTrait; + use ToolSessionTrait; public function __construct( private \App\Service\BasePackageService $basePackageService, @@ -53,16 +53,16 @@ public function __construct( ) { } - #[Route(path: '', name: 'wizards_sitepackage')] + #[Route(path: '', name: 'tools_sitepackage')] public function index(): Response { return $this->render( - 'wizards/sitepackage/index.html.twig' + 'tools/sitepackage/index.html.twig' ); } - #[Route(path: '/new', name: 'wizards_sitepackage_new')] - #[Route(path: '/new/{vendor}/{project}', name: 'wizards_sitepackage_new_filtered')] + #[Route(path: '/new', name: 'tools_sitepackage_new')] + #[Route(path: '/new/{vendor}/{project}', name: 'tools_sitepackage_new_filtered')] public function new(string $vendor = '', string $project = ''): Response { $this->setSitepackageConfig(new SitepackageDto(), false); @@ -82,12 +82,12 @@ public function new(string $vendor = '', string $project = ''): Response 'fatal', $throwable->getMessage() ); - return $this->redirectToRoute('wizards_sitepackage_new'); + return $this->redirectToRoute('tools_sitepackage_new'); } } return $this->render( - 'wizards/sitepackage/new.html.twig', + 'tools/sitepackage/new.html.twig', [ 'basePackages' => $basePackages, 'filtered' => $filtered, @@ -95,13 +95,13 @@ public function new(string $vendor = '', string $project = ''): Response ); } - #[Route(path: '/validate/{vendor}/{project}', name: 'wizards_sitepackage_validate')] + #[Route(path: '/validate/{vendor}/{project}', name: 'tools_sitepackage_validate')] public function validate(string $vendor, string $project): RedirectResponse { try { $configuration = $this->getSitepackageConfig(); } catch (UnexpectedValueException) { - return $this->redirectToRoute('wizards_sitepackage_new'); + return $this->redirectToRoute('tools_sitepackage_new'); } $configuration->basePackage = sprintf('%s/%s', $vendor, $project); @@ -114,28 +114,28 @@ public function validate(string $vendor, string $project): RedirectResponse 'fatal', $throwable->getMessage() ); - return $this->redirectToRoute('wizards_sitepackage_new'); + return $this->redirectToRoute('tools_sitepackage_new'); } $this->setSitepackageConfig($configuration, $this->isAdvancedSitepackageConfig()); - return $this->redirectToRoute('wizards_sitepackage_configure'); + return $this->redirectToRoute('tools_sitepackage_configure'); } - #[Route(path: '/configure', name: 'wizards_sitepackage_configure')] + #[Route(path: '/configure', name: 'tools_sitepackage_configure')] public function configure(Request $request): Response { try { $configuration = $this->getSitepackageConfig(); } catch (UnexpectedValueException) { - return $this->redirectToRoute('wizards_sitepackage_new'); + return $this->redirectToRoute('tools_sitepackage_new'); } $form = $this->createForm( SitepackageType::class, $configuration, [ - 'action' => $this->generateUrl('wizards_sitepackage_configure'), + 'action' => $this->generateUrl('tools_sitepackage_configure'), 'advanced' => $this->isAdvancedSitepackageConfig(), ] ); @@ -148,7 +148,7 @@ public function configure(Request $request): Response ) { $this->setSitepackageConfig($configuration, false); - return $this->redirectToRoute('wizards_sitepackage_configure'); + return $this->redirectToRoute('tools_sitepackage_configure'); } if ( @@ -157,37 +157,37 @@ public function configure(Request $request): Response ) { $this->setSitepackageConfig($configuration, true); - return $this->redirectToRoute('wizards_sitepackage_configure'); + return $this->redirectToRoute('tools_sitepackage_configure'); } if ($form->isValid()) { $this->setSitepackageConfig($configuration, $this->isAdvancedSitepackageConfig()); - return $this->redirectToRoute('wizards_sitepackage_success'); + return $this->redirectToRoute('tools_sitepackage_success'); } } return $this->render( - 'wizards/sitepackage/configure.html.twig', + 'tools/sitepackage/configure.html.twig', [ 'form' => $form->createView(), ] ); } - #[Route(path: '/success', name: 'wizards_sitepackage_success')] + #[Route(path: '/success', name: 'tools_sitepackage_success')] public function success(): Response { try { $sitepackage = SitepackageFactory::fromDto($this->getSitepackageConfig()); } catch (UnexpectedValueException) { - return $this->redirectToRoute('wizards_sitepackage_new'); + return $this->redirectToRoute('tools_sitepackage_new'); } $this->setSitepackage($sitepackage); return $this->render( - 'wizards/sitepackage/success.html.twig', + 'tools/sitepackage/success.html.twig', [ 'base_package' => $this->basePackageService->getInstalledBasePackage($sitepackage->getBasePackage()), 'sitepackage' => $sitepackage, @@ -195,13 +195,13 @@ public function success(): Response ); } - #[Route(path: '/download', name: 'wizards_sitepackage_download')] + #[Route(path: '/download', name: 'tools_sitepackage_download')] public function download(): Response { try { $sitepackage = $this->getSitepackage(); } catch (UnexpectedValueException) { - return $this->redirectToRoute('wizards_sitepackage_new'); + return $this->redirectToRoute('tools_sitepackage_new'); } try { @@ -209,7 +209,7 @@ public function download(): Response } catch (RuntimeError $runtimeError) { $this->setSitepackageError($runtimeError->getMessage()); - return $this->redirectToRoute('wizards_sitepackage_error'); + return $this->redirectToRoute('tools_sitepackage_error'); } BinaryFileResponse::trustXSendfileTypeHeader(); @@ -222,11 +222,11 @@ public function download(): Response ->deleteFileAfterSend(true); } - #[Route(path: '/error', name: 'wizards_sitepackage_error')] + #[Route(path: '/error', name: 'tools_sitepackage_error')] public function error(): Response { return $this->render( - 'wizards/sitepackage/error.html.twig', + 'tools/sitepackage/error.html.twig', [ 'error' => $this->getSitepackageError(), ] diff --git a/src/Entity/BasePackage.php b/src/Entity/BasePackage.php index 19ed7626..9e02d348 100644 --- a/src/Entity/BasePackage.php +++ b/src/Entity/BasePackage.php @@ -33,7 +33,7 @@ #[OA\Schema( title: 'Base package', - description: 'Base package available in the wizards' + description: 'Base package available in the Tools' )] #[ORM\Entity(repositoryClass: BasePackageRepository::class)] #[ORM\EntityListeners([BasePackageListener::class])] diff --git a/src/Menu/MenuBuilder.php b/src/Menu/MenuBuilder.php index 7ea1ea7e..868294b5 100644 --- a/src/Menu/MenuBuilder.php +++ b/src/Menu/MenuBuilder.php @@ -45,17 +45,17 @@ public function mainDefault(array $options): ItemInterface 'label' => 'Release Notes', ] ); - $wizards = $menu->addChild( - 'wizards', + $tools = $menu->addChild( + 'tools', [ - 'route' => 'wizards_sitepackage', - 'label' => 'Wizards', + 'route' => 'tools_sitepackage', + 'label' => 'Tools', ] ); - $wizards->addChild( - 'wizards-sitepackage', + $tools->addChild( + 'tools-sitepackage', [ - 'route' => 'wizards_sitepackage', + 'route' => 'tools_sitepackage', 'label' => 'Sitepackage Builder', ] ); diff --git a/src/Service/BasePackageService.php b/src/Service/BasePackageService.php index 2ce30e19..d0c841df 100644 --- a/src/Service/BasePackageService.php +++ b/src/Service/BasePackageService.php @@ -296,7 +296,7 @@ private function initializeProject(bool $force = false): void $input = new ArrayInput([ 'command' => 'init', '--name' => 't3o/base-packages', - '--description' => 'Known base packages shown at the get.typo3.org wizards.', + '--description' => 'Known base packages shown at the get.typo3.org Tools.', '--type' => 'project', '--stability' => 'dev', '--repository' => ['{"type": "path", "url": "packages/*/*"}', '{"packagist.org": false}'], diff --git a/src/Session/WizardSessionTrait.php b/src/Session/ToolSessionTrait.php similarity index 99% rename from src/Session/WizardSessionTrait.php rename to src/Session/ToolSessionTrait.php index 200ed016..b97a36af 100644 --- a/src/Session/WizardSessionTrait.php +++ b/src/Session/ToolSessionTrait.php @@ -32,7 +32,7 @@ use function is_string; -trait WizardSessionTrait +trait ToolSessionTrait { private function getSession(): SessionInterface { diff --git a/templates/default/root.html.twig b/templates/default/root.html.twig index 8fbf7222..ca0d4e30 100644 --- a/templates/default/root.html.twig +++ b/templates/default/root.html.twig @@ -7,7 +7,7 @@

{% if communityVersions|length > 0 %}Download TYPO3{% endif %} Try TYPO3 - Create a Sitepackage + Create a Sitepackage

{% endframe %} diff --git a/templates/layout.html.twig b/templates/layout.html.twig index 33bb50c6..e1aeb490 100644 --- a/templates/layout.html.twig +++ b/templates/layout.html.twig @@ -14,7 +14,7 @@ gtag(\'config\', \'G-JTSKLNF4S0\'); ') }} {% endblock %} -{% block headline %}Try the new Sitepackage Builder now and create a Sitepackage in 2 easy steps.{% endblock %} +{% block headline %}Try the new Sitepackage Builder now and create a Sitepackage in 2 easy steps.{% endblock %} {% block footer %} {% frame with { color: 'primary' } %}
diff --git a/templates/wizards/layout.html.twig b/templates/tools/layout.html.twig similarity index 66% rename from templates/wizards/layout.html.twig rename to templates/tools/layout.html.twig index e38a310f..b1e59e9d 100644 --- a/templates/wizards/layout.html.twig +++ b/templates/tools/layout.html.twig @@ -4,7 +4,7 @@ {% block footer %} - {% include 'wizards/partials/privacy-footer.html.twig' %} + {% include 'tools/partials/privacy-footer.html.twig' %} {{ parent() }} {% endblock %} diff --git a/templates/wizards/partials/privacy-footer.html.twig b/templates/tools/partials/privacy-footer.html.twig similarity index 100% rename from templates/wizards/partials/privacy-footer.html.twig rename to templates/tools/partials/privacy-footer.html.twig diff --git a/templates/wizards/sitepackage/configure.html.twig b/templates/tools/sitepackage/configure.html.twig similarity index 93% rename from templates/wizards/sitepackage/configure.html.twig rename to templates/tools/sitepackage/configure.html.twig index 7b0e5e79..dc5a8284 100644 --- a/templates/wizards/sitepackage/configure.html.twig +++ b/templates/tools/sitepackage/configure.html.twig @@ -1,4 +1,4 @@ -{% extends 'wizards/layout.html.twig' %} +{% extends 'tools/layout.html.twig' %} {% block title %}Create your own TYPO3 Sitepackage{% endblock %} diff --git a/templates/wizards/sitepackage/error.html.twig b/templates/tools/sitepackage/error.html.twig similarity index 82% rename from templates/wizards/sitepackage/error.html.twig rename to templates/tools/sitepackage/error.html.twig index 1b8c72e1..bb863ae9 100644 --- a/templates/wizards/sitepackage/error.html.twig +++ b/templates/tools/sitepackage/error.html.twig @@ -1,4 +1,4 @@ -{% extends 'wizards/layout.html.twig' %} +{% extends 'tools/layout.html.twig' %} {% block title %}Error{% endblock %} @@ -13,7 +13,7 @@ {% frame with { id: 'error', indent: true, title: 'Error information' } %}

{{ error }}

- + {{ icon('actions-arrow-left-alt', 'auto') }} Back diff --git a/templates/wizards/sitepackage/index.html.twig b/templates/tools/sitepackage/index.html.twig similarity index 95% rename from templates/wizards/sitepackage/index.html.twig rename to templates/tools/sitepackage/index.html.twig index df12d969..17bc5ebc 100644 --- a/templates/wizards/sitepackage/index.html.twig +++ b/templates/tools/sitepackage/index.html.twig @@ -1,4 +1,4 @@ -{% extends 'wizards/layout.html.twig' %} +{% extends 'tools/layout.html.twig' %} {% block title %}Kickstart your TYPO3 template development{% endblock %} @@ -10,7 +10,7 @@ or start your own template right now.

- + {{ icon('actions-rocket', 'auto') }} Create Sitepackage @@ -101,7 +101,7 @@ {% frame with { center: true, id: 'start', title: 'Start your own Sitepackage' } %}

- + {{ icon('actions-rocket', 'auto') }} Create Sitepackage diff --git a/templates/wizards/sitepackage/new.html.twig b/templates/tools/sitepackage/new.html.twig similarity index 91% rename from templates/wizards/sitepackage/new.html.twig rename to templates/tools/sitepackage/new.html.twig index 5d3080b2..aa5ce8f7 100644 --- a/templates/wizards/sitepackage/new.html.twig +++ b/templates/tools/sitepackage/new.html.twig @@ -1,4 +1,4 @@ -{% extends 'wizards/layout.html.twig' %} +{% extends 'tools/layout.html.twig' %} {% block title %}Create your own TYPO3 Sitepackage{% endblock %} @@ -50,7 +50,7 @@ {% if basePackage.official %} {% set btnClass = 'primary' %} {% endif %} - + {{ icon('actions-rocket', 'auto') }} Create Sitepackage @@ -64,7 +64,7 @@ {% if filtered %} {% frame with { center: true } %}

- + {{ icon('actions-rocket', 'auto') }} Show all Base Packages diff --git a/templates/wizards/sitepackage/success.html.twig b/templates/tools/sitepackage/success.html.twig similarity index 89% rename from templates/wizards/sitepackage/success.html.twig rename to templates/tools/sitepackage/success.html.twig index 86ef0b03..be0d5ee6 100644 --- a/templates/wizards/sitepackage/success.html.twig +++ b/templates/tools/sitepackage/success.html.twig @@ -1,4 +1,4 @@ -{% extends 'wizards/layout.html.twig' %} +{% extends 'tools/layout.html.twig' %} {% block title %}Success{% endblock %} @@ -54,15 +54,15 @@

{{ sitepackage.author.homepage }}

- + {{ icon('actions-undo', 'auto') }} Restart - + {{ icon('actions-open', 'auto') }} Edit Configuration - + {{ icon('actions-download', 'auto') }} Download @@ -74,7 +74,7 @@ Your Sitepackage has been successfully created and is ready for download.

- + {{ icon('actions-download', 'auto') }} Download From c7da56eb95cd051d2912d4c7e8169be51ab04d97 Mon Sep 17 00:00:00 2001 From: Simon Gilli <25326036+gilbertsoft@users.noreply.github.com> Date: Mon, 15 May 2023 22:13:17 +0200 Subject: [PATCH 8/8] New base-package structure and detail page --- .../Tools/SitepackageController.php | 38 ++++- src/Form/Dto/BasePackageDto.php | 122 ---------------- src/Form/SitepackageType.php | 4 +- src/Form/Type/BasePackageType.php | 2 +- src/Package/BasePackage.php | 138 ++++++++++++++++++ src/Package/BasePackageManifest.php | 133 ----------------- src/Package/BasePackageTemplate.php | 95 ++++++++++++ src/Package/Manifest/BasePackageManifest.php | 84 +++++++++++ .../Manifest/BasePackageManifestTrait.php | 49 +++++++ .../Manifest/BasePackageTemplateManifest.php | 77 ++++++++++ src/Service/BasePackageService.php | 88 +++++++---- src/Service/LegacyDataService.php | 1 + src/Service/SitepackageGenerator.php | 28 ++-- src/Twig/Filter/BasePackageFilter.php | 47 ++++++ .../tools/partials/privacy-footer.html.twig | 6 + templates/tools/sitepackage/detail.html.twig | 90 ++++++++++++ templates/tools/sitepackage/index.html.twig | 75 +--------- templates/tools/sitepackage/new.html.twig | 14 +- templates/tools/sitepackage/success.html.twig | 2 +- 19 files changed, 712 insertions(+), 381 deletions(-) delete mode 100644 src/Form/Dto/BasePackageDto.php create mode 100644 src/Package/BasePackage.php delete mode 100644 src/Package/BasePackageManifest.php create mode 100644 src/Package/BasePackageTemplate.php create mode 100644 src/Package/Manifest/BasePackageManifest.php create mode 100644 src/Package/Manifest/BasePackageManifestTrait.php create mode 100644 src/Package/Manifest/BasePackageTemplateManifest.php create mode 100644 src/Twig/Filter/BasePackageFilter.php create mode 100644 templates/tools/sitepackage/detail.html.twig diff --git a/src/Controller/Tools/SitepackageController.php b/src/Controller/Tools/SitepackageController.php index 5f5ca8c2..32312bcf 100644 --- a/src/Controller/Tools/SitepackageController.php +++ b/src/Controller/Tools/SitepackageController.php @@ -62,7 +62,7 @@ public function index(): Response } #[Route(path: '/new', name: 'tools_sitepackage_new')] - #[Route(path: '/new/{vendor}/{project}', name: 'tools_sitepackage_new_filtered')] + #[Route(path: '/new/{vendor}/{project}', name: 'tools_sitepackage_new')] public function new(string $vendor = '', string $project = ''): Response { $this->setSitepackageConfig(new SitepackageDto(), false); @@ -95,6 +95,40 @@ public function new(string $vendor = '', string $project = ''): Response ); } + #[Route(path: '/detail/{vendor}/{project}', name: 'tools_sitepackage_detail')] + #[Route(path: '/detail/{vendor}/{project}/{typo3Version}', name: 'tools_sitepackage_detail')] + public function detail(string $vendor, string $project, string $typo3Version = ''): Response + { + $this->setSitepackageConfig(new SitepackageDto(), false); + + $basePackageName = sprintf('%s/%s', $vendor, $project); + + try { + $basePackage = $this->basePackageService->checkAndInstallMissingBasePackage($basePackageName); + + if ($typo3Version === '') { + $typo3Version = $basePackage->getTypo3Versions()[0]; + } + + $basePackageTemplate = $basePackage->getTemplates()[$typo3Version]; + } catch (Throwable $throwable) { + $this->addFlash( + 'fatal', + $throwable->getMessage() + ); + return $this->redirectToRoute('tools_sitepackage_new'); + } + + return $this->render( + 'tools/sitepackage/detail.html.twig', + [ + 'basePackage' => $basePackage, + 'basePackageTemplate' => $basePackageTemplate, + 'typo3Version' => $typo3Version, + ] + ); + } + #[Route(path: '/validate/{vendor}/{project}', name: 'tools_sitepackage_validate')] public function validate(string $vendor, string $project): RedirectResponse { @@ -108,7 +142,7 @@ public function validate(string $vendor, string $project): RedirectResponse try { $basePackage = $this->basePackageService->checkAndInstallMissingBasePackage($configuration->basePackage); - $configuration->typo3Version = VersionUtility::versionToInt($basePackage->typo3Versions[0]); + $configuration->typo3Version = VersionUtility::versionToInt($basePackage->getTypo3Versions()[0]); } catch (Throwable $throwable) { $this->addFlash( 'fatal', diff --git a/src/Form/Dto/BasePackageDto.php b/src/Form/Dto/BasePackageDto.php deleted file mode 100644 index e63d3110..00000000 --- a/src/Form/Dto/BasePackageDto.php +++ /dev/null @@ -1,122 +0,0 @@ - - */ - public array $typo3Versions = []; - - #[Assert\NotBlank(message: 'Please enter a preview image for the base package.')] - #[Assert\Length(min: 5)] - public string $previewImage = 'images/preview.png'; - - public static function fromPackage(string $installPath, PackageInterface $package, ?BasePackageEntity $entity = null): self - { - $dto = new self($installPath); - $dto->loadManifest($package); - - $dto->active = ($entity !== null) ? $entity->isActive() : true; - $dto->official = $entity !== null && $entity->isOfficial(); - $dto->thirdParty = ($entity === null); - - return $dto; - } - - public function __construct( - private readonly string $installPath, - ) { - } - - public function getInstallPath(): string - { - return $this->installPath; - } - - public function getAssetsDir(): string - { - return str_replace('/', '-', strtolower($this->packageName)); - } - - public function getVendorName(): string - { - return explode('/', strtolower($this->packageName))[0]; - } - - public function getProjectName(): string - { - return explode('/', strtolower($this->packageName))[1]; - } - - private function loadManifest(PackageInterface $package): void - { - $manifest = new BasePackageManifest($package); - - $this->packageName = $package->getName(); - $this->packageVersion = $package->getVersion(); - $this->title = $manifest->getTitle(); - $this->description = $manifest->getDescription(); - $this->typo3Versions = $manifest->getCoreVersions(); - $this->previewImage = $manifest->getPreviewImage(); - } -} diff --git a/src/Form/SitepackageType.php b/src/Form/SitepackageType.php index b9dc1fe5..c3d62630 100644 --- a/src/Form/SitepackageType.php +++ b/src/Form/SitepackageType.php @@ -71,12 +71,12 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ->add('typo3Version', Typo3VersionType::class, [ 'label' => 'TYPO3 Version', 'choice_filter' => static function (int $version) use ($basePackage): bool { - foreach ($basePackage->typo3Versions as $typo3Version) { + foreach ($basePackage->getTypo3Versions() as $typo3Version) { if ($version < VersionUtility::versionToInt($typo3Version)) { continue; } - if ($version % 1_000_000 !== VersionUtility::versionToInt($typo3Version) % 1_000_000) { + if ($version / 1_000_000 !== VersionUtility::versionToInt($typo3Version) / 1_000_000) { continue; } diff --git a/src/Form/Type/BasePackageType.php b/src/Form/Type/BasePackageType.php index 975062d2..0fa741b6 100644 --- a/src/Form/Type/BasePackageType.php +++ b/src/Form/Type/BasePackageType.php @@ -44,7 +44,7 @@ public function configureOptions(OptionsResolver $resolver): void $choices = []; foreach ($this->basePackageService->getInstalledBasePackages() as $basePackage) { - $choices[sprintf('%s (%s)', $basePackage->title, $basePackage->packageName)] = $basePackage->packageName; + $choices[sprintf('%s (%s)', $basePackage->getTitle(), $basePackage->getComposerPackageName())] = $basePackage->getComposerPackageName(); } $resolver->setDefaults([ diff --git a/src/Package/BasePackage.php b/src/Package/BasePackage.php new file mode 100644 index 00000000..6129f992 --- /dev/null +++ b/src/Package/BasePackage.php @@ -0,0 +1,138 @@ +getName(), + ($entity !== null) ? $entity->isActive() : true, + $entity !== null && $entity->isOfficial(), + ($entity === null) + ); + + return $basePackage; + } + + public function __construct( + private readonly string $composerPackageInstallPath, + private readonly string $composerPackageName, + public readonly bool $active, + public readonly bool $official, + public readonly bool $thirdParty, + ) { + $this->manifest = new BasePackageManifest($this->composerPackageInstallPath); + } + + public function getAssetsDir(): string + { + return str_replace('/', '-', strtolower($this->composerPackageName)); + } + + public function getAssetPreviewImage(): string + { + return \sprintf('%s/images/%s', $this->getAssetsDir(), $this->manifest->getPreviewImage()); + } + + public function getInstallPath(): string + { + return $this->composerPackageInstallPath; + } + + public function getPublicInstallPath(): string + { + return \sprintf('%s/public', $this->composerPackageInstallPath); + } + + public function getComposerPackageName(): string + { + return $this->composerPackageName; + } + + public function getComposerVendorName(): string + { + return explode('/', strtolower($this->composerPackageName))[0]; + } + + public function getComposerProjectName(): string + { + return explode('/', strtolower($this->composerPackageName))[1]; + } + + public function getTitle(): string + { + return $this->manifest->getTitle(); + } + + public function getDescription(): string + { + return $this->manifest->getDescription(); + } + + /** + * @return string[] + */ + public function getTypo3Versions(): array + { + return $this->manifest->getTypo3Versions(); + } + + public function getPreviewImage(): string + { + return $this->manifest->getPreviewImage(); + } + + /** + * @return BasePackageTemplate[] + */ + public function getTemplates(): array + { + if ($this->templates === []) { + foreach ($this->getTypo3Versions() as $typo3Version) { + $this->templates[$typo3Version] = new BasePackageTemplate($this->composerPackageInstallPath, $this, $typo3Version); + } + } + + return $this->templates; + } +} diff --git a/src/Package/BasePackageManifest.php b/src/Package/BasePackageManifest.php deleted file mode 100644 index 4faae494..00000000 --- a/src/Package/BasePackageManifest.php +++ /dev/null @@ -1,133 +0,0 @@ -package->getName(); - } - - public function getVersion(): string - { - return $this->package->getVersion(); - } - - public function getTitle(): string - { - return $this->getStringValue('title'); - } - - public function getDescription(): string - { - return $this->getStringValue('description'); - } - - /** - * @return array - */ - public function getCoreVersions(): array - { - $array = $this->getArrayValue('core-versions'); - rsort($array, SORT_NUMERIC); - return $array; - } - - public function getPreviewImage(): string - { - $array = $this->getArrayValue('images', []); - return $array['preview'] ?? 'images/preview.png'; - } - - /** - * @return array - */ - private function getExtraConfig(): array - { - if (!is_array($extraConfig = ($this->package->getExtra()[self::EXTRA_KEY] ?? []))) { - throw new RuntimeException( - 'Extra config is not defined or is not an array.', - 1_658_926_616 - ); - } - - return $extraConfig; - } - - private function getStringValue(string $key, ?string $default = null): string - { - if (!is_string($value = ($this->getExtraConfig()[$key] ?? null))) { - if ($default === null) { - throw new RuntimeException( - sprintf('Mandatory property "%s" is not defined or is not a string.', $key), - 1_658_926_617 - ); - } - - $value = $default; - } - - return $value; - } - - /** - * @param string[]|null $default - * - * @return string[] - */ - private function getArrayValue(string $key, ?array $default = null): array - { - if (!is_array($value = ($this->getExtraConfig()[$key] ?? null))) { - if ($default === null) { - throw new RuntimeException( - sprintf('Mandatory property "%s" is not defined or is not an array.', $key), - 1_658_926_618 - ); - } - - $value = $default; - } - - return $value; - } -} diff --git a/src/Package/BasePackageTemplate.php b/src/Package/BasePackageTemplate.php new file mode 100644 index 00000000..152f624f --- /dev/null +++ b/src/Package/BasePackageTemplate.php @@ -0,0 +1,95 @@ +manifest = new BasePackageTemplateManifest( + $this->composerPackageInstallPath, + $coreVersion + ); + } + + public function getAssetsDir(): string + { + return sprintf('%s/%s', $this->basePackage->getAssetsDir(), $this->coreVersion); + } + + /** + * @return array + */ + public function getAssetsGallery(): array + { + $gallery = []; + $assetsDir = $this->getAssetsDir(); + + foreach ($this->manifest->getGallery() as $imageFilename => $imageDescription) { + $gallery[sprintf('%s/images/%s', $assetsDir, $imageFilename)] = $imageDescription; + } + + return $gallery; + } + + public function getPublicInstallPath(): string + { + return \sprintf('%s/templates/%s/public', $this->composerPackageInstallPath, $this->coreVersion); + } + + public function getSkeletonInstallPath(): string + { + return \sprintf('%s/templates/%s/skeleton', $this->composerPackageInstallPath, $this->coreVersion); + } + + public function getDescription(): string + { + return $this->manifest->getDescription(); + } + + /** + * @return array + */ + public function getDependencies(): array + { + return $this->manifest->getDependencies(); + } + + /** + * @return array + */ + public function getGallery(): array + { + return $this->manifest->getGallery(); + } +} diff --git a/src/Package/Manifest/BasePackageManifest.php b/src/Package/Manifest/BasePackageManifest.php new file mode 100644 index 00000000..5259e922 --- /dev/null +++ b/src/Package/Manifest/BasePackageManifest.php @@ -0,0 +1,84 @@ +, + * images: array{ + * preview: string|null + * }|array{} + * } + */ + private array $manifest; + + public function __construct( + private readonly string $composerPackageInstallPath, + ) { + $this->load($this->getFilename(), self::SCHEMA_PATH); + } + + public function getTitle(): string + { + return $this->manifest['title']; + } + + public function getDescription(): string + { + return $this->manifest['description']; + } + + /** + * @return string[] + */ + public function getTypo3Versions(): array + { + $array = $this->manifest['typo3-versions']; + rsort($array, SORT_NUMERIC); + return $array; + } + + public function getPreviewImage(): string + { + return $this->manifest['images']['preview'] ?? 'preview.png'; + } + + private function getFilename(): string + { + return sprintf('%s/manifest.json', rtrim(trim($this->composerPackageInstallPath), '/\\')); + } +} diff --git a/src/Package/Manifest/BasePackageManifestTrait.php b/src/Package/Manifest/BasePackageManifestTrait.php new file mode 100644 index 00000000..6900de5f --- /dev/null +++ b/src/Package/Manifest/BasePackageManifestTrait.php @@ -0,0 +1,49 @@ +validateSchema(JsonFile::STRICT_SCHEMA, $manifestSchemaFilename); + + if (!is_array($manifest = $jsonFile->read())) { + throw new RuntimeException( + sprintf('Manifest "%s" could not be decoded.', $manifestFilename), + 1_658_926_618 + ); + } + + /** @phpstan-ignore-next-line because validation above makes this assignment safe */ + $this->manifest = $manifest; + } +} diff --git a/src/Package/Manifest/BasePackageTemplateManifest.php b/src/Package/Manifest/BasePackageTemplateManifest.php new file mode 100644 index 00000000..092e5e2d --- /dev/null +++ b/src/Package/Manifest/BasePackageTemplateManifest.php @@ -0,0 +1,77 @@ +, + * images: array{ + * gallery: array + * } + * } + */ + private array $manifest; + + public function __construct( + private readonly string $composerPackageInstallPath, + private readonly string $coreVersion, + ) { + $this->load($this->getFilename(), self::SCHEMA_PATH); + } + + public function getDescription(): string + { + return $this->manifest['description']; + } + + /** + * @return array + */ + public function getDependencies(): array + { + return $this->manifest['dependencies']; + } + + /** + * @return array + */ + public function getGallery(): array + { + return $this->manifest['images']['gallery']; + } + + public function getFilename(): string + { + return sprintf('%s/templates/%s/manifest.json', $this->composerPackageInstallPath, $this->coreVersion); + } +} diff --git a/src/Service/BasePackageService.php b/src/Service/BasePackageService.php index d0c841df..05e4460a 100644 --- a/src/Service/BasePackageService.php +++ b/src/Service/BasePackageService.php @@ -25,7 +25,7 @@ use App\Exception\IncompatiblePackageException; use App\Exception\PackageNotInstalledException; -use App\Form\Dto\BasePackageDto; +use App\Package\BasePackage; use App\Repository\BasePackageRepository; use Composer\Composer; use Composer\Console\Application as ComposerApplication; @@ -113,8 +113,11 @@ private function changeToProjectDir(): void $oldWorkingDir = (string)getcwd(); //$oldWorkingDir = Platform::getCwd(true); - if ($oldWorkingDir !== $this->getProjectDir()) { - chdir($this->getProjectDir()); + if ($oldWorkingDir !== ($projectDir = $this->getProjectDir())) { + if (!$this->filesystem->exists($projectDir)) { + $this->filesystem->mkdir($projectDir); + } + chdir($projectDir); $this->oldWorkingDir = $oldWorkingDir; } } @@ -195,16 +198,31 @@ private function installAssets(): void $validAssetDirs = []; foreach ($this->getInstalledBasePackages() as $basePackage) { - if (!is_dir($originDir = $basePackage->getInstallPath() . '/public')) { - continue; - } - $assetDir = $basePackage->getAssetsDir(); $targetDir = $publicAssetsDir . $assetDir; - $validAssetDirs[] = $assetDir; $this->filesystem->remove($targetDir); + + if (!is_dir($originDir = $basePackage->getPublicInstallPath())) { + continue; + } + $this->symlink($originDir, $targetDir, true); + $validAssetDirs[] = $assetDir; + + foreach ($basePackage->getTemplates() as $template) { + $assetDir = $template->getAssetsDir(); + $targetDir = $publicAssetsDir . $assetDir; + + $this->filesystem->remove($targetDir); + + if (!is_dir($originDir = $template->getPublicInstallPath())) { + continue; + } + + $this->symlink($originDir, $targetDir, true); + $validAssetDirs[] = $assetDir; + } } // remove the assets of the bundles that no longer exist @@ -360,7 +378,7 @@ private function installBasePackage(string $packageName): void '--ansi' => true, '--no-interaction' => true, '--working-dir' => $this->getProjectDir(), - 'packages' => [$packageName . ':*'], + 'packages' => [$packageName . ':@dev'], ]); if (($exitCode = $this->composerApplication->run($input, $output)) !== 0) { @@ -425,10 +443,11 @@ private function removeBasePackage(string $packageName): void } /** - * @return array + * @return array */ public function getInstalledBasePackages(): array { + /** @var array */ return $this->cache->get('installed-base-packages-grouped-by-official', function (ItemInterface $item): array { $item->tag(['installed-base-packages', 'base-packages']); $installedBasePackages = []; @@ -444,7 +463,7 @@ public function getInstalledBasePackages(): array foreach ($composer->getRepositoryManager()->getLocalRepository()->getPackages() as $package) { if ($package->getType() === self::PACKAGE_TYPE) { - $basePackageDto = BasePackageDto::fromPackage( + $basePackageDto = BasePackage::fromPackage( $composer->getInstallationManager()->getInstallPath($package), $package, $this->basePackageRepository->findOneBy([ @@ -456,7 +475,7 @@ public function getInstalledBasePackages(): array } } - usort($installedBasePackages, static function (BasePackageDto $a, BasePackageDto $b): int { + usort($installedBasePackages, static function (BasePackage $a, BasePackage $b): int { if ($a->official !== $b->official) { if ($a->official) { return -1; @@ -465,7 +484,7 @@ public function getInstalledBasePackages(): array return 1; } - return $a->title <=> $b->title; + return $a->getTitle() <=> $b->getTitle(); }); return $installedBasePackages; @@ -475,10 +494,10 @@ public function getInstalledBasePackages(): array }); } - public function getInstalledBasePackage(string $packageName): BasePackageDto + public function getInstalledBasePackage(string $packageName): BasePackage { foreach ($this->getInstalledBasePackages() as $basePackage) { - if ($basePackage->packageName === $packageName) { + if ($basePackage->getComposerPackageName() === $packageName) { return $basePackage; } } @@ -487,10 +506,11 @@ public function getInstalledBasePackage(string $packageName): BasePackageDto } /** - * @return array + * @return array */ public function getBasePackages(): array { + /** @var array */ return $this->cache->get('active-base-packages-grouped-by-official', function (ItemInterface $item): array { $item->tag(['active-base-packages', 'base-packages']); @@ -520,7 +540,7 @@ public function getBasePackages(): array ); } - $basePackageDto = BasePackageDto::fromPackage( + $basePackageDto = BasePackage::fromPackage( $composer->getInstallationManager()->getInstallPath($package), $package, $basePackage @@ -536,7 +556,7 @@ public function getBasePackages(): array }); } - public function checkAndInstallMissingBasePackage(string $packageName): BasePackageDto + public function checkAndInstallMissingBasePackage(string $packageName): BasePackage { $this->changeToProjectDir(); @@ -559,7 +579,7 @@ public function checkAndInstallMissingBasePackage(string $packageName): BasePack } } - public function validate(string $packageName): BasePackageDto + public function validate(string $packageName): BasePackage { $this->changeToProjectDir(); @@ -594,7 +614,10 @@ public function validate(string $packageName): BasePackageDto $this->restoreToWorkingDir(); } + //return $basePackage; + try { + /* if (strlen($basePackage->title) < 5) { throw new IncompatiblePackageException( \sprintf('Title "%s" must have 5 characters or more.', $basePackage->title), @@ -608,20 +631,35 @@ public function validate(string $packageName): BasePackageDto 1_658_945_398 ); } + */ - if ($basePackage->typo3Versions === []) { + if ($basePackage->getTypo3Versions() === []) { throw new IncompatiblePackageException( 'A base package must define one or more supported TYPO3 core versions.', 1_658_945_403 ); } - if (!\file_exists($basePackage->getInstallPath() . '/public/' . $basePackage->previewImage)) { - throw new IncompatiblePackageException( - 'A base package must have a preview image.', - 1_658_946_257 - ); + /* + foreach ($basePackage->getTypo3Versions() as $typo3Version) { + if (!\file_exists($basePackage->getInstallPath() . '/templates/' . $typo3Version . '/public/' . $basePackage->previewImage)) { + throw new IncompatiblePackageException( + 'A base package must have a preview image.', + 1_658_946_257 + ); + } + } + + /* + foreach ($basePackage->typo3Versions as $typo3Version) { + if (!\file_exists($basePackage->getInstallPath() . '/templates/' . $typo3Version . '/docs/detail.md')) { + throw new IncompatiblePackageException( + 'A base package must have a detail.md.', + 1_658_946_258 + ); + } } + */ $forbiddenFiles = Finder::create() ->ignoreDotFiles(false) diff --git a/src/Service/LegacyDataService.php b/src/Service/LegacyDataService.php index 022721fd..786972f7 100644 --- a/src/Service/LegacyDataService.php +++ b/src/Service/LegacyDataService.php @@ -37,6 +37,7 @@ public function __construct( public function getReleaseJson(): string { + /** @var string */ return $this->cache->get('releases.json', function (ItemInterface $item): string { $item->tag(['major-versions', 'major-version', 'releases', 'release']); $content = json_encode($this->majorVersionRepository->findAllPreparedForJson(), JSON_THROW_ON_ERROR); diff --git a/src/Service/SitepackageGenerator.php b/src/Service/SitepackageGenerator.php index 95455b6a..81dc6f85 100644 --- a/src/Service/SitepackageGenerator.php +++ b/src/Service/SitepackageGenerator.php @@ -23,7 +23,7 @@ namespace App\Service; -use App\Form\Dto\BasePackageDto; +use App\Package\BasePackage; use App\Package\Sitepackage; use App\Utility\VersionUtility; use RuntimeException; @@ -39,7 +39,7 @@ final class SitepackageGenerator { /** - * @var array + * @var array */ private array $basePackages = []; @@ -70,14 +70,6 @@ public function create(Sitepackage $package): void ; $this->addFiles($zipFile, $files, $package, $sourceDir); - $sourceDir = dirname($sourceDir) . '/shared'; - $files = Finder::create() - ->ignoreDotFiles(false) - ->ignoreVCS(false) - ->in($sourceDir) - ; - $this->addFiles($zipFile, $files, $package, $sourceDir); - $zipFile->close(); } } @@ -92,9 +84,9 @@ public function getFilename(): string return $this->filename; } - private function getBasePackage(Sitepackage $package): BasePackageDto + private function getBasePackage(Sitepackage $package): BasePackage { - if (!($this->basePackages[$package->getBasePackage()] ?? null) instanceof BasePackageDto) { + if (!($this->basePackages[$package->getBasePackage()] ?? null) instanceof BasePackage) { $this->basePackages[$package->getBasePackage()] = $this->basePackageService->getInstalledBasePackage($package->getBasePackage()); } @@ -105,26 +97,26 @@ private function getBasePackage(Sitepackage $package): BasePackageDto private function getSourceDir(Sitepackage $package): string { $basePackage = $this->getBasePackage($package); + $basePackageTemplate = null; $version = $package->getTypo3Version(); - $versionDir = ''; - foreach ($basePackage->typo3Versions as $v) { - if ($version < VersionUtility::versionToInt($v)) { + foreach ($basePackage->getTypo3Versions() as $typo3Version) { + if ($version < VersionUtility::versionToInt($typo3Version)) { continue; } - $versionDir = $v; + $basePackageTemplate = $basePackage->getTemplates()[$typo3Version]; break; } - if ($versionDir === '') { + if ($basePackageTemplate === null) { throw new RuntimeException( sprintf('Template for version "%s" not found.', $version), 1_658_939_427 ); } - return $basePackage->getInstallPath() . '/templates/skeletons/' . $versionDir; + return $basePackageTemplate->getSkeletonInstallPath(); } private function getFileContent(string $file, string $baseDir, Sitepackage $package): string diff --git a/src/Twig/Filter/BasePackageFilter.php b/src/Twig/Filter/BasePackageFilter.php new file mode 100644 index 00000000..c56be474 --- /dev/null +++ b/src/Twig/Filter/BasePackageFilter.php @@ -0,0 +1,47 @@ + $this->parse($markdown, $publicPath)), + ]; + } + + public function parse(string $markdown, string $publicPath): string + { + return str_replace('../public', $publicPath, $markdown); + } +} diff --git a/templates/tools/partials/privacy-footer.html.twig b/templates/tools/partials/privacy-footer.html.twig index aaaf371a..a47f9274 100644 --- a/templates/tools/partials/privacy-footer.html.twig +++ b/templates/tools/partials/privacy-footer.html.twig @@ -1,3 +1,9 @@ +{% frame with { id: 'api', color: 'dark', center: true, indent: true, title: 'Do you already know the Sitepackage Builder API?' } %} +

+ Instead of using the website, you can also create your Sitepackage using + the API. +

+{% endframe %} {% frame with { id: 'privacy', color: 'light', center: true, indent: true, title: 'We respect your Privacy!' } %}

We are not storing, sharing or doing any other crazy stuff with the diff --git a/templates/tools/sitepackage/detail.html.twig b/templates/tools/sitepackage/detail.html.twig new file mode 100644 index 00000000..580a5a1b --- /dev/null +++ b/templates/tools/sitepackage/detail.html.twig @@ -0,0 +1,90 @@ +{% extends 'tools/layout.html.twig' %} + +{% block title %}Create your own TYPO3 Sitepackage{% endblock %} + +{% block body %} + + {% frame with { color: 'dark', center: true, title: 'Create your own Sitepackage', titleSize: 1, backgroundImage: asset("assets/Images/keyvisual.png") } %} +

+ Awesome you made it here! Just a few more details about your + project and your own Sitepackage is ready for download. +

+ {% endframe %} + + {% frame %} +
+

+ {{ basePackage.title }} Base Package for TYPO3 {{ typo3Version }} + {% if basePackage.official %} + {{ basePackage.title }} + {% endif %} +

+
+
+
+
+
+ {{ basePackageTemplate.description|markdown_to_html }} +
+
+ {% for imageFile, imageDescription in basePackageTemplate.assetsGallery %} +
+ {{ imageDescription }} +
{{ imageDescription }}
+
+ {% endfor %} +
+ +
+
+
+
+
Config files not accessible by editors Config files not accessible by editors Yes No
+ + + + + + + + + + + + + + + + + + + + + + +
Last Update15 September 2020
ExtensionsBootstrap Package
Extension XY
FrameworkBootstrap
Columns3
LayoutResponsive
+
+
+ + + + {% endframe %} + +{% endblock %} diff --git a/templates/tools/sitepackage/index.html.twig b/templates/tools/sitepackage/index.html.twig index 17bc5ebc..ab5b8bdd 100644 --- a/templates/tools/sitepackage/index.html.twig +++ b/templates/tools/sitepackage/index.html.twig @@ -17,7 +17,7 @@

{% endframe %} - {% frame with { id: 'about', color: 'light', title: 'What is a Sitepackage?' } %} + {% frame with { id: 'about', title: 'What is a Sitepackage?' } %}

A Sitepackage is a TYPO3 Extension that containers all relevant configuration for a Website. Having all configuration stored in a package keeps it protected from unauthorized access. @@ -35,77 +35,4 @@

{% endframe %} - {% frame with { id: 'arguments', center: true, indent: true, title: 'Pros and Cons', titleSize: 3 } %} -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Site­packageClassic
Config files not accessible by editorsYesNo
Config files are protected *YesNo
Autoload PageTSYesNo
Autoload TypoScriptYesNo
Static PageTS TemplateYesNo
Static TypoScript TemplateYesNo
Dependency ManagementYesNo
Distribution through TERYesNo
Clean Version Control possibleYesNo
-
-

- * Possible but not common practice -

- {% endframe %} - - {% frame with { center: true, id: 'start', title: 'Start your own Sitepackage' } %} -

- - {{ icon('actions-rocket', 'auto') }} - Create Sitepackage - -

- {% endframe %} - {% endblock %} diff --git a/templates/tools/sitepackage/new.html.twig b/templates/tools/sitepackage/new.html.twig index aa5ce8f7..7a87e261 100644 --- a/templates/tools/sitepackage/new.html.twig +++ b/templates/tools/sitepackage/new.html.twig @@ -26,7 +26,7 @@ {% if basePackage.official %} Supported TYPO3 versions {% set btnClass = 'light' %} {% if basePackage.official %} {% set btnClass = 'primary' %} {% endif %} - + {{ icon('actions-rocket', 'auto') }} Create Sitepackage + + {{ icon('actions-info', 'auto') }} + Show details + diff --git a/templates/tools/sitepackage/success.html.twig b/templates/tools/sitepackage/success.html.twig index be0d5ee6..50afe07e 100644 --- a/templates/tools/sitepackage/success.html.twig +++ b/templates/tools/sitepackage/success.html.twig @@ -14,7 +14,7 @@ {% frame with { id: 'configuration', indent: true, title: 'Your Sitepackage Configuration' } %}
Base Package
-
{{ base_package.title }} ({{ base_package.packageName }})
+
{{ base_package.title }} ({{ base_package.composerPackageName }})
Source
{% if base_package.official %}TYPO3 official base package{% elseif base_package.thirdParty %}Unknown third party{% else %}Verified third party{% endif %}
TYPO3 Version