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 } %}
+
+
+
+
+
+ Sitepackage
+ Classic
+
+
+
+
+ Config files not accessible by editors
+ Yes
+ No
+
+
+ Config files are protected *
+ Yes
+ No
+
+
+ Autoload PageTS
+ Yes
+ No
+
+
+ Autoload TypoScript
+ Yes
+ No
+
+
+ Static PageTS Template
+ Yes
+ No
+
+
+ Static TypoScript Template
+ Yes
+ No
+
+
+ Dependency Management
+ Yes
+ No
+
+
+ Distribution through TER
+ Yes
+ No
+
+
+ Clean Version Control possible
+ Yes
+ No
+
+
+
+
+
+ * 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 %}
+
+ {{ notification }}
+
+ {% 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 @@
- Config files not accessible by editors
+ Config files not accessible by editors
Yes
No
@@ -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 %}
+
+
+
+
+ {% if basePackage.official %}
+
+ {% 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 %}
+
+
+
+
+
+ {{ basePackageTemplate.description|markdown_to_html }}
+
+
+ {% for imageFile, imageDescription in basePackageTemplate.assetsGallery %}
+
+
+ {{ imageDescription }}
+
+ {% endfor %}
+
+
+
+
+
+
+
+
+
+ Last Update
+ 15 September 2020
+
+
+ Extensions
+ Bootstrap Package Extension XY
+
+
+ Framework
+ Bootstrap
+
+
+ Columns
+ 3
+
+
+ Layout
+ Responsive
+
+
+
+
+
+
+
+
+ {% 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 } %}
-
-
-
-
-
- Sitepackage
- Classic
-
-
-
-
- Config files not accessible by editors
- Yes
- No
-
-
- Config files are protected *
- Yes
- No
-
-
- Autoload PageTS
- Yes
- No
-
-
- Autoload TypoScript
- Yes
- No
-
-
- Static PageTS Template
- Yes
- No
-
-
- Static TypoScript Template
- Yes
- No
-
-
- Dependency Management
- Yes
- No
-
-
- Distribution through TER
- Yes
- No
-
-
- Clean Version Control possible
- Yes
- No
-
-
-
-
-
- * 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
{% for typo3Version in basePackage.typo3Versions %}
- {{ typo3Version }}
+
+
+ {{ typo3Version }}
+
+
{% endfor %}
{% 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