diff --git a/.gitea/workflows/release.yaml b/.gitea/workflows/release.yaml
new file mode 100644
index 0000000..6cd97d0
--- /dev/null
+++ b/.gitea/workflows/release.yaml
@@ -0,0 +1,105 @@
+name: Release Workflow
+
+on:
+ push:
+ branches:
+ - main
+ - master
+
+jobs:
+ validate_commit_message:
+ runs-on: ubuntu-latest
+ outputs:
+ version: ${{ steps.validate.outputs.version }}
+ release_notes: ${{ steps.validate.outputs.release_notes }}
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: Validate commit message
+ id: validate
+ run: |
+ COMMIT_MESSAGE="${{ github.event.head_commit.message }}"
+ if [[ "$COMMIT_MESSAGE" =~ ^Release[[:space:]]([0-9]+\.[0-9]+\.[0-9]+)[[:space:]]-[[:space:]](.+)$ ]]; then
+ VERSION=$(echo "$COMMIT_MESSAGE" | grep -oP '(?<=^Release )[0-9]+\.[0-9]+\.[0-9]+')
+ RELEASE_NOTES=$(echo "$COMMIT_MESSAGE" | sed -E 's/^Release [0-9]+\.[0-9]+\.[0-9]+ - //')
+ echo "VERSION=$VERSION" >> $GITHUB_ENV
+ echo "RELEASE_NOTES=$RELEASE_NOTES" >> $GITHUB_ENV
+ echo "::set-output name=version::$VERSION"
+ echo "::set-output name=release_notes::$RELEASE_NOTES"
+ else
+ echo "Invalid commit message format. Skipping release."
+ fi
+ create_release:
+ runs-on: ubuntu-latest
+ needs: validate_commit_message
+ if: needs.validate_commit_message.outputs.version != ''
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: Create a release tag
+ run: |
+ git config --global user.name "Gitea CI"
+ git config --global user.email "ci@gitea.local"
+ git tag -a "${{ needs.validate_commit_message.outputs.version }}" -m "${{ github.event.head_commit.message }}"
+ git push origin "${{ needs.validate_commit_message.outputs.version }}"
+ - name: Create release ZIP file
+ run: |
+ VERSION="${{ needs.validate_commit_message.outputs.version }}"
+ REPO_NAME="${{ github.event.repository.name }}"
+ ZIP_FILE="/tmp/${REPO_NAME}-${VERSION}.zip"
+ zip -r $ZIP_FILE . \
+ -x "*.git*" \
+ -x "*.idea*" \
+ -x ".gitignore" \
+ -x "README.md" \
+ -x "LICENSE"
+ echo "zip_file=$ZIP_FILE" >> $GITHUB_ENV
+ - name: Create release in Gitea
+ env:
+ CICD_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ VERSION="${{ needs.validate_commit_message.outputs.version }}"
+ RELEASE_NOTES="${{ needs.validate_commit_message.outputs.release_notes }}"
+ REPO_NAME="${{ github.event.repository.name }}"
+ OWNER_NAME="${{ github.event.repository.owner.login }}"
+ RELEASE_URL="https://git.dewebsmid.nl/api/v1/repos/$OWNER_NAME/$REPO_NAME/releases"
+ curl -s -X POST $RELEASE_URL \
+ -H "Authorization: token $CICD_TOKEN" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "tag_name": "'"$VERSION"'",
+ "target_commitish": "main",
+ "name": "Release '"$VERSION"'",
+ "body": "'"$RELEASE_NOTES"'",
+ "draft": false,
+ "prerelease": false
+ }' > response.json
+ RELEASE_ID=$(jq -r '.id' response.json)
+ if [ "$RELEASE_ID" == "null" ]; then
+ echo "Failed to create release. Check response.json for details."
+ cat response.json
+ exit 1
+ fi
+ echo "release_id=$RELEASE_ID" >> $GITHUB_ENV
+ - name: Upload ZIP to release
+ env:
+ CICD_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ RELEASE_ID="${{ env.release_id }}"
+ VERSION="${{ needs.validate_commit_message.outputs.version }}"
+ REPO_NAME="${{ github.event.repository.name }}"
+ OWNER_NAME="${{ github.event.repository.owner.login }}"
+ ZIP_FILE="/tmp/${REPO_NAME}-${VERSION}.zip"
+ UPLOAD_URL="https://git.dewebsmid.nl/api/v1/repos/$OWNER_NAME/$REPO_NAME/releases/$RELEASE_ID/assets"
+ curl -s -X POST $UPLOAD_URL \
+ -H "Authorization: token $CICD_TOKEN" \
+ -F "name=${REPO_NAME}-${VERSION}.zip" \
+ -F "attachment=@$ZIP_FILE" > response.json
+ ASSET_ID=$(jq -r '.id' response.json)
+ if [ "$ASSET_ID" == "null" ]; then
+ echo "Failed to upload ZIP file. Check response.json for details."
+ cat response.json
+ exit 1
+ fi
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/deployment.xml b/.idea/deployment.xml
new file mode 100644
index 0000000..6999636
--- /dev/null
+++ b/.idea/deployment.xml
@@ -0,0 +1,588 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..62a60b3
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/php.xml b/.idea/php.xml
new file mode 100644
index 0000000..76c92d6
--- /dev/null
+++ b/.idea/php.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/prestashop-module-template.iml b/.idea/prestashop-module-template.iml
new file mode 100644
index 0000000..c956989
--- /dev/null
+++ b/.idea/prestashop-module-template.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
index d73b72d..3546b4f 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2025 george
+Copyright (c) 2025 MullerXXL
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
diff --git a/README.md b/README.md
index 4038069..74303bb 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1 @@
-# prestashop-module-template
-
+# PrestaShop module template
diff --git a/psmodule/composer.json b/psmodule/composer.json
new file mode 100644
index 0000000..f7b0296
--- /dev/null
+++ b/psmodule/composer.json
@@ -0,0 +1,18 @@
+{
+ "name": "websmid/psmodule",
+ "description": "",
+ "type": "prestashop-module",
+ "license": "mit",
+ "autoload": {
+ "psr-4": {
+ "Websmid\\PsModule": "src/"
+ }
+ },
+ "authors": [
+ {
+ "name": "George van Engers",
+ "email": "george@dewebsmid.nl"
+ }
+ ],
+ "minimum-stability": "dev"
+}
diff --git a/psmodule/config/services.yml b/psmodule/config/services.yml
new file mode 100644
index 0000000..36a1ea5
--- /dev/null
+++ b/psmodule/config/services.yml
@@ -0,0 +1,6 @@
+imports:
+ - { resource: services/*.yml }
+
+services:
+ _defaults:
+ public: true
\ No newline at end of file
diff --git a/psmodule/config/services/event_listener.yml b/psmodule/config/services/event_listener.yml
new file mode 100644
index 0000000..c0d8825
--- /dev/null
+++ b/psmodule/config/services/event_listener.yml
@@ -0,0 +1,3 @@
+services:
+ _defaults:
+ public: true
\ No newline at end of file
diff --git a/psmodule/logo.gif b/psmodule/logo.gif
new file mode 100644
index 0000000..85e2d55
Binary files /dev/null and b/psmodule/logo.gif differ
diff --git a/psmodule/logo.png b/psmodule/logo.png
new file mode 100644
index 0000000..9e0e08c
Binary files /dev/null and b/psmodule/logo.png differ
diff --git a/psmodule/override/index.php b/psmodule/override/index.php
new file mode 100644
index 0000000..44c6141
--- /dev/null
+++ b/psmodule/override/index.php
@@ -0,0 +1,34 @@
+
+* @copyright 2007-2024 PrestaShop SA
+* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
+* International Registered Trademark & Property of PrestaShop SA
+*/
+header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
+header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
+
+header('Cache-Control: no-store, no-cache, must-revalidate');
+header('Cache-Control: post-check=0, pre-check=0', false);
+header('Pragma: no-cache');
+
+header('Location: ../');
+exit;
diff --git a/psmodule/psmodule.php b/psmodule/psmodule.php
new file mode 100644
index 0000000..3246d9f
--- /dev/null
+++ b/psmodule/psmodule.php
@@ -0,0 +1,64 @@
+
+ * @copyright 2007-2025 PrestaShop SA
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
+ * International Registered Trademark & Property of PrestaShop SA
+ */
+
+use Websmid\Muller\WsMullerModule\Module\Helper\Config;
+use Websmid\Muller\WsMullerModule\Module\Helper\ConfigForm;
+use Websmid\Muller\WsMullerModule\Module\Helper\Install;
+
+if (!defined('_PS_VERSION_')) {
+ exit;
+}
+
+require_once __DIR__ . '/vendor/autoload.php';
+
+class psmodule extends Module
+{
+ // use hooks
+ use Config;
+ use Install;
+ use ConfigForm;
+
+ public function __construct()
+ {
+ $this->name = 'psmodule';
+ $this->tab = 'administration';
+ $this->version = '0.0.1';
+ $this->author = 'George van Engers | De Websmid';
+ $this->need_instance = 0;
+ $this->ps_versions_compliancy = [
+ 'min' => '8.2.0',
+ 'max' => _PS_VERSION_,
+ ];
+ $this->bootstrap = true;
+
+ parent::__construct();
+
+ $this->displayName = $this->trans('Ps Module', [], 'Modules.PsModule.Module');
+ $this->description = $this->trans('Ps Module', [], 'Modules.PsModule.Module');
+
+ $this->confirmUninstall = $this->trans('Are you sure you want to uninstall?', [], 'Modules.PsModule.Module');
+ }
+}
\ No newline at end of file
diff --git a/psmodule/src/Module/Helper/Config.php b/psmodule/src/Module/Helper/Config.php
new file mode 100644
index 0000000..50bf0ba
--- /dev/null
+++ b/psmodule/src/Module/Helper/Config.php
@@ -0,0 +1,14 @@
+ 'test',
+ ];
+}
\ No newline at end of file
diff --git a/psmodule/src/Module/Helper/ConfigForm.php b/psmodule/src/Module/Helper/ConfigForm.php
new file mode 100644
index 0000000..ea5f8ab
--- /dev/null
+++ b/psmodule/src/Module/Helper/ConfigForm.php
@@ -0,0 +1,120 @@
+
+ * @since 05-04-2025
+ */
+ public function getContent(): string
+ {
+ if ((Tools::isSubmit($this->name . 'submitBtn'))) {
+ $this->postProcess();
+ }
+ $this->context->smarty->assign('module_dir', $this->_path);
+
+ $output = $this->context->smarty->fetch($this->local_path.'views/templates/admin/index.tpl');;
+
+ return $output.$this->renderForm();
+ }
+
+ /**
+ * @return string
+ * @author George van Engers
+ * @since 05-04-2025
+ */
+ protected function renderForm(): string
+ {
+ $helper = new HelperForm();
+
+ $helper->show_toolbar = false;
+ $helper->table = $this->table;
+ $helper->module = $this;
+ $helper->name_controller = $this->name;
+ $helper->default_form_language = $this->context->language->id;
+ $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG', 0);
+
+ $helper->identifier = $this->identifier;
+ $helper->submit_action = $this->name.'submitBtn';
+ $helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false)
+ .'&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name;
+ $helper->token = Tools::getValue('token');
+
+ $helper->tpl_vars = array(
+ 'fields_value' => $this->getConfigFormValues(), /* Add values for your inputs */
+ 'languages' => $this->context->controller->getLanguages(),
+ 'id_language' => $this->context->language->id,
+ );
+
+ return $helper->generateForm($this->getConfigForm());
+ }
+
+ /**
+ * @return array
+ * @author George van Engers
+ * @since 05-04-2025
+ */
+ protected function getConfigFormValues(): array
+ {
+ $data = [];
+ foreach(self::$config as $key => $value) {
+ $data[$key] = Configuration::get($key);
+ }
+
+ return $data;
+ }
+
+
+ /**
+ * @return void
+ * @author George van Engers
+ * @since 05-04-2025
+ */
+ protected function postProcess(): void
+ {
+ $form_values = $this->getConfigFormValues();
+
+ foreach (array_keys($form_values) as $key) {
+ if (Tools::isSubmit($key)) {
+ Configuration::updateValue($key, Tools::getValue($key));
+ }
+ }
+ }
+
+ /**
+ * @return array[]
+ * @author George van Engers
+ * @since 05-04-2025
+ */
+ protected function getConfigForm(): array
+ {
+ return array(
+ 'api' => array(
+ 'form' => array(
+ 'legend' => array(
+ 'title' => $this->trans('Settings', [], 'Modules.PsModule.Module'),
+ 'icon' => 'icon-cogs',
+ ),
+ 'input' => array(
+ /////
+ /////
+ /////
+ ),
+ 'submit' => array(
+ 'title' => $this->trans('Save', [], 'Modules.PsModule.Module'),
+ ),
+ ),
+ ),
+ );
+ }
+}
\ No newline at end of file
diff --git a/psmodule/src/Module/Helper/Install.php b/psmodule/src/Module/Helper/Install.php
new file mode 100644
index 0000000..5e52414
--- /dev/null
+++ b/psmodule/src/Module/Helper/Install.php
@@ -0,0 +1,55 @@
+
+ * @since 05-04-2025
+ */
+ public function install()
+ {
+ if (!parent::install()) {
+ return false;
+ }
+
+ foreach(self::$hooks as $hook) {
+ if (!$this->registerHook($hook)) {
+ return false;
+ }
+ }
+ foreach(self::$config as $key => $value) {
+ if (!Configuration::updateValue($key, $value)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * @return bool
+ * @author George van Engers
+ * @since 05-04-2025
+ */
+ public function uninstall()
+ {
+ if (!parent::uninstall()) {
+ return false;
+ }
+
+ // hooks are auto-unregistered by PrestaShop
+
+ foreach(self::$config as $key => $value) {
+ if (!Configuration::deleteByName($key)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/psmodule/src/index.php b/psmodule/src/index.php
new file mode 100644
index 0000000..44c6141
--- /dev/null
+++ b/psmodule/src/index.php
@@ -0,0 +1,34 @@
+
+* @copyright 2007-2024 PrestaShop SA
+* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
+* International Registered Trademark & Property of PrestaShop SA
+*/
+header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
+header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
+
+header('Cache-Control: no-store, no-cache, must-revalidate');
+header('Cache-Control: post-check=0, pre-check=0', false);
+header('Pragma: no-cache');
+
+header('Location: ../');
+exit;
diff --git a/psmodule/translations/index.php b/psmodule/translations/index.php
new file mode 100644
index 0000000..44c6141
--- /dev/null
+++ b/psmodule/translations/index.php
@@ -0,0 +1,34 @@
+
+* @copyright 2007-2024 PrestaShop SA
+* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
+* International Registered Trademark & Property of PrestaShop SA
+*/
+header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
+header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
+
+header('Cache-Control: no-store, no-cache, must-revalidate');
+header('Cache-Control: post-check=0, pre-check=0', false);
+header('Pragma: no-cache');
+
+header('Location: ../');
+exit;
diff --git a/psmodule/upgrade/index.php b/psmodule/upgrade/index.php
new file mode 100644
index 0000000..44c6141
--- /dev/null
+++ b/psmodule/upgrade/index.php
@@ -0,0 +1,34 @@
+
+* @copyright 2007-2024 PrestaShop SA
+* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
+* International Registered Trademark & Property of PrestaShop SA
+*/
+header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
+header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
+
+header('Cache-Control: no-store, no-cache, must-revalidate');
+header('Cache-Control: post-check=0, pre-check=0', false);
+header('Pragma: no-cache');
+
+header('Location: ../');
+exit;
diff --git a/psmodule/views/index.php b/psmodule/views/index.php
new file mode 100644
index 0000000..44c6141
--- /dev/null
+++ b/psmodule/views/index.php
@@ -0,0 +1,34 @@
+
+* @copyright 2007-2024 PrestaShop SA
+* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
+* International Registered Trademark & Property of PrestaShop SA
+*/
+header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
+header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
+
+header('Cache-Control: no-store, no-cache, must-revalidate');
+header('Cache-Control: post-check=0, pre-check=0', false);
+header('Pragma: no-cache');
+
+header('Location: ../');
+exit;
diff --git a/psmodule/views/templates/admin/index.tpl b/psmodule/views/templates/admin/index.tpl
new file mode 100644
index 0000000..e69de29