From 7590e7f1789ff7a8be48d85a25ce87cdd8b1809c Mon Sep 17 00:00:00 2001
From: Sebastian Zoglowek <55794780+zoglo@users.noreply.github.com>
Date: Wed, 31 May 2023 13:06:12 +0200
Subject: [PATCH 01/19] [Update] Drop Contao 4.9 support
---
composer.json | 6 +--
src/Resources/contao/config/config.php | 52 +++++++++++++-------------
src/Resources/public/style.css | 3 --
3 files changed, 28 insertions(+), 33 deletions(-)
delete mode 100644 src/Resources/public/style.css
diff --git a/composer.json b/composer.json
index 1944f7d..77ba86c 100644
--- a/composer.json
+++ b/composer.json
@@ -13,8 +13,8 @@
}
],
"require": {
- "php": "^7.4 || ^8.0",
- "contao/core-bundle":"^4.9"
+ "php": "^8.0",
+ "contao/core-bundle":"^4.13"
},
"require-dev": {
"contao/manager-plugin": "^2.0"
@@ -39,7 +39,7 @@
},
"extra": {
"branch-alias": {
- "dev-master": "1.2.x-dev"
+ "dev-master": "1.3.x-dev"
},
"contao-manager-plugin": "Oveleon\\ContaoRecommendationBundle\\ContaoManager\\Plugin"
}
diff --git a/src/Resources/contao/config/config.php b/src/Resources/contao/config/config.php
index 5aa2f67..d55f768 100644
--- a/src/Resources/contao/config/config.php
+++ b/src/Resources/contao/config/config.php
@@ -2,33 +2,37 @@
declare(strict_types=1);
+use Contao\ArrayUtil;
+
+
+
// Back end modules
-array_insert($GLOBALS['BE_MOD']['content'], 5, array
-(
- 'recommendation' => array
- (
- 'tables' => array('tl_recommendation_archive', 'tl_recommendation')
- )
-));
-array_insert($GLOBALS['BE_MOD']['system'], 3, array
-(
- 'recommendation_settings' => array
- (
- 'tables' => array('tl_recommendation_settings'),
- 'hideInNavigation' => true
- )
-));
+ArrayUtil::arrayInsert($GLOBALS['BE_MOD']['content'], 5, [
+ 'recommendation' => [
+ 'tables' => [
+ 'tl_recommendation_archive',
+ 'tl_recommendation'
+ ]
+ ]
+]);
+
+ArrayUtil::arrayInsert($GLOBALS['BE_MOD']['system'], 3, [
+ 'recommendation_settings' => [
+ 'tables' => [
+ 'tl_recommendation_settings'
+ ],
+ 'hideInNavigation' => true
+ ]
+]);
// Front end modules
-array_insert($GLOBALS['FE_MOD'], 2, array
-(
- 'recommendation' => array
- (
+ArrayUtil::arrayInsert($GLOBALS['FE_MOD'], 2, [
+ 'recommendation' => [
'recommendationlist' => 'Oveleon\ContaoRecommendationBundle\ModuleRecommendationList',
'recommendationreader' => 'Oveleon\ContaoRecommendationBundle\ModuleRecommendationReader',
'recommendationform' => 'Oveleon\ContaoRecommendationBundle\ModuleRecommendationForm',
- )
-));
+ ]
+]);
// Models
$GLOBALS['TL_MODELS']['tl_recommendation'] = 'Oveleon\ContaoRecommendationBundle\RecommendationModel';
@@ -43,9 +47,3 @@
// Register hooks
$GLOBALS['TL_HOOKS']['getSearchablePages'][] = array('Oveleon\ContaoRecommendationBundle\Recommendation', 'getSearchablePages');
-
-// Style sheet
-if (TL_MODE == 'BE')
-{
- $GLOBALS['TL_CSS'][] = 'bundles/contaorecommendation/style.css|static';
-}
diff --git a/src/Resources/public/style.css b/src/Resources/public/style.css
deleted file mode 100644
index ec6318c..0000000
--- a/src/Resources/public/style.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.navigation.recommendation_settings {
- display: none !important;
-}
From e8fb8c56a49bff0d88f5b9311fdcdd87449383c4 Mon Sep 17 00:00:00 2001
From: Sebastian Zoglowek <55794780+zoglo@users.noreply.github.com>
Date: Wed, 31 May 2023 14:02:40 +0200
Subject: [PATCH 02/19] [Update] Change bundle structure
---
composer.json | 87 ++---
.../classes/Recommendation.php | 0
.../contao => contao}/config/config.php | 6 +-
.../contao => contao}/dca/tl_module.php | 179 ++++-----
.../dca/tl_recommendation.php | 342 +++++++-----------
.../dca/tl_recommendation_archive.php | 204 +++++------
contao/dca/tl_recommendation_settings.php | 33 ++
contao/dca/tl_user.php | 35 ++
.../contao => contao}/dca/tl_user_group.php | 26 +-
.../languages/de/default.xlf | 2 +-
.../languages/de/modules.xlf | 2 +-
.../languages/de/tl_module.xlf | 2 +-
.../languages/de/tl_recommendation.xlf | 2 +-
.../de/tl_recommendation_archive.xlf | 2 +-
.../languages/de/tl_recommendation_list.xlf | 2 +-
.../de/tl_recommendation_notification.xlf | 2 +-
.../de/tl_recommendation_settings.xlf | 2 +-
.../languages/de/tl_user.xlf | 2 +-
contao/languages/de/tl_user_group.xlf | 26 ++
.../languages/en/default.xlf | 2 +-
.../languages/en/modules.xlf | 2 +-
.../languages/en/tl_module.xlf | 2 +-
.../languages/en/tl_recommendation.xlf | 2 +-
.../en/tl_recommendation_archive.xlf | 2 +-
.../languages/en/tl_recommendation_list.xlf | 2 +-
.../en/tl_recommendation_notification.xlf | 2 +-
.../en/tl_recommendation_settings.xlf | 2 +-
.../languages/en/tl_user.xlf | 2 +-
contao/languages/en/tl_user_group.xlf | 21 ++
.../models/RecommendationArchiveModel.php | 0
.../models/RecommendationModel.php | 8 +-
.../modules/ModuleRecommendation.php | 12 +-
.../modules/ModuleRecommendationForm.php | 84 ++---
.../modules/ModuleRecommendationList.php | 4 +-
.../modules/ModuleRecommendationReader.php | 0
.../modules/mod_recommendationform.html5 | 0
.../modules/mod_recommendationlist.html5 | 0
.../modules/mod_recommendationreader.html5 | 0
.../recommendation_default.html5 | 0
.../recommendation/recommendation_full.html5 | 0
.../recommendation_latest.html5 | 0
src/ContaoManager/Plugin.php | 4 +-
src/ContaoRecommendationBundle.php | 4 +
.../contao/dca/tl_recommendation_settings.php | 41 ---
src/Resources/contao/dca/tl_user.php | 37 --
.../contao/languages/de/tl_user_group.xlf | 10 -
.../contao/languages/en/tl_user_group.xlf | 9 -
47 files changed, 539 insertions(+), 669 deletions(-)
rename {src/Resources/contao => contao}/classes/Recommendation.php (100%)
rename {src/Resources/contao => contao}/config/config.php (82%)
rename {src/Resources/contao => contao}/dca/tl_module.php (67%)
rename {src/Resources/contao => contao}/dca/tl_recommendation.php (75%)
rename {src/Resources/contao => contao}/dca/tl_recommendation_archive.php (73%)
create mode 100644 contao/dca/tl_recommendation_settings.php
create mode 100644 contao/dca/tl_user.php
rename {src/Resources/contao => contao}/dca/tl_user_group.php (50%)
rename {src/Resources/contao => contao}/languages/de/default.xlf (70%)
rename {src/Resources/contao => contao}/languages/de/modules.xlf (94%)
rename {src/Resources/contao => contao}/languages/de/tl_module.xlf (98%)
rename {src/Resources/contao => contao}/languages/de/tl_recommendation.xlf (99%)
rename {src/Resources/contao => contao}/languages/de/tl_recommendation_archive.xlf (97%)
rename {src/Resources/contao => contao}/languages/de/tl_recommendation_list.xlf (94%)
rename {src/Resources/contao => contao}/languages/de/tl_recommendation_notification.xlf (95%)
rename {src/Resources/contao => contao}/languages/de/tl_recommendation_settings.xlf (89%)
rename {src/Resources/contao => contao}/languages/de/tl_user.xlf (89%)
create mode 100644 contao/languages/de/tl_user_group.xlf
rename {src/Resources/contao => contao}/languages/en/default.xlf (68%)
rename {src/Resources/contao => contao}/languages/en/modules.xlf (93%)
rename {src/Resources/contao => contao}/languages/en/tl_module.xlf (98%)
rename {src/Resources/contao => contao}/languages/en/tl_recommendation.xlf (98%)
rename {src/Resources/contao => contao}/languages/en/tl_recommendation_archive.xlf (96%)
rename {src/Resources/contao => contao}/languages/en/tl_recommendation_list.xlf (93%)
rename {src/Resources/contao => contao}/languages/en/tl_recommendation_notification.xlf (93%)
rename {src/Resources/contao => contao}/languages/en/tl_recommendation_settings.xlf (88%)
rename {src/Resources/contao => contao}/languages/en/tl_user.xlf (88%)
create mode 100644 contao/languages/en/tl_user_group.xlf
rename {src/Resources/contao => contao}/models/RecommendationArchiveModel.php (100%)
rename {src/Resources/contao => contao}/models/RecommendationModel.php (97%)
rename {src/Resources/contao => contao}/modules/ModuleRecommendation.php (97%)
rename {src/Resources/contao => contao}/modules/ModuleRecommendationForm.php (89%)
rename {src/Resources/contao => contao}/modules/ModuleRecommendationList.php (98%)
rename {src/Resources/contao => contao}/modules/ModuleRecommendationReader.php (100%)
rename {src/Resources/contao => contao}/templates/modules/mod_recommendationform.html5 (100%)
rename {src/Resources/contao => contao}/templates/modules/mod_recommendationlist.html5 (100%)
rename {src/Resources/contao => contao}/templates/modules/mod_recommendationreader.html5 (100%)
rename {src/Resources/contao => contao}/templates/recommendation/recommendation_default.html5 (100%)
rename {src/Resources/contao => contao}/templates/recommendation/recommendation_full.html5 (100%)
rename {src/Resources/contao => contao}/templates/recommendation/recommendation_latest.html5 (100%)
delete mode 100644 src/Resources/contao/dca/tl_recommendation_settings.php
delete mode 100644 src/Resources/contao/dca/tl_user.php
delete mode 100644 src/Resources/contao/languages/de/tl_user_group.xlf
delete mode 100644 src/Resources/contao/languages/en/tl_user_group.xlf
diff --git a/composer.json b/composer.json
index 77ba86c..e390bef 100644
--- a/composer.json
+++ b/composer.json
@@ -1,46 +1,49 @@
{
- "name": "oveleon/contao-recommendation-bundle",
- "type": "contao-bundle",
- "description": "Recommendation integration for Contao 4 Open Source CMS",
- "keywords": ["contao","recommendation-bundle"],
- "homepage": "https://www.oveleon.de/",
- "license": "MIT",
- "authors": [
- {
- "name": "Oveleon",
- "homepage": "https://oveleon.de/",
- "role": "Developer"
- }
- ],
- "require": {
- "php": "^8.0",
- "contao/core-bundle":"^4.13"
- },
- "require-dev": {
- "contao/manager-plugin": "^2.0"
- },
- "conflict": {
- "contao/core": "*",
- "contao/manager-plugin": "<2.0 || >=3.0"
+ "name": "oveleon/contao-recommendation-bundle",
+ "type": "contao-bundle",
+ "description": "Recommendation integration for Contao 4 Open Source CMS",
+ "keywords": [
+ "contao",
+ "recommendation-bundle"
+ ],
+ "homepage": "https://www.oveleon.de/",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Oveleon",
+ "homepage": "https://oveleon.de/",
+ "role": "Developer"
+ }
+ ],
+ "require": {
+ "php": "^8.1",
+ "contao/core-bundle": "^4.13"
+ },
+ "require-dev": {
+ "contao/manager-plugin": "^2.0"
+ },
+ "conflict": {
+ "contao/core": "*",
+ "contao/manager-plugin": "<2.0 || >=3.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Oveleon\\ContaoRecommendationBundle\\": "src/"
},
- "autoload": {
- "psr-4": {
- "Oveleon\\ContaoRecommendationBundle\\": "src/"
- },
- "classmap": [
- "src/Resources/contao/"
- ],
- "exclude-from-classmap": [
- "src/Resources/contao/config/",
- "src/Resources/contao/dca/",
- "src/Resources/contao/languages/",
- "src/Resources/contao/templates/"
- ]
+ "classmap": [
+ "contao/"
+ ],
+ "exclude-from-classmap": [
+ "contao/config/",
+ "contao/dca/",
+ "contao/languages/",
+ "contao/templates/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.3.x-dev"
},
- "extra": {
- "branch-alias": {
- "dev-master": "1.3.x-dev"
- },
- "contao-manager-plugin": "Oveleon\\ContaoRecommendationBundle\\ContaoManager\\Plugin"
- }
+ "contao-manager-plugin": "Oveleon\\ContaoRecommendationBundle\\ContaoManager\\Plugin"
+ }
}
diff --git a/src/Resources/contao/classes/Recommendation.php b/contao/classes/Recommendation.php
similarity index 100%
rename from src/Resources/contao/classes/Recommendation.php
rename to contao/classes/Recommendation.php
diff --git a/src/Resources/contao/config/config.php b/contao/config/config.php
similarity index 82%
rename from src/Resources/contao/config/config.php
rename to contao/config/config.php
index d55f768..a69b991 100644
--- a/src/Resources/contao/config/config.php
+++ b/contao/config/config.php
@@ -4,8 +4,6 @@
use Contao\ArrayUtil;
-
-
// Back end modules
ArrayUtil::arrayInsert($GLOBALS['BE_MOD']['content'], 5, [
'recommendation' => [
@@ -43,7 +41,7 @@
$GLOBALS['TL_PERMISSIONS'][] = 'recommendationp';
// Cron jobs
-$GLOBALS['TL_CRON']['daily']['purgeRecommendations'] = array('Oveleon\ContaoRecommendationBundle\Recommendation', 'purgeRecommendations');
+$GLOBALS['TL_CRON']['daily']['purgeRecommendations'] = ['Oveleon\ContaoRecommendationBundle\Recommendation', 'purgeRecommendations'];
// Register hooks
-$GLOBALS['TL_HOOKS']['getSearchablePages'][] = array('Oveleon\ContaoRecommendationBundle\Recommendation', 'getSearchablePages');
+$GLOBALS['TL_HOOKS']['getSearchablePages'][] = ['Oveleon\ContaoRecommendationBundle\Recommendation', 'getSearchablePages'];
diff --git a/src/Resources/contao/dca/tl_module.php b/contao/dca/tl_module.php
similarity index 67%
rename from src/Resources/contao/dca/tl_module.php
rename to contao/dca/tl_module.php
index a4571ee..ef4df7f 100644
--- a/src/Resources/contao/dca/tl_module.php
+++ b/contao/dca/tl_module.php
@@ -6,9 +6,11 @@
* (c) https://www.oveleon.de/
*/
-Contao\System::loadLanguageFile('tl_recommendation');
-Contao\System::loadLanguageFile('tl_recommendation_notification');
-Contao\System::loadLanguageFile('tl_recommendation_list');
+use Contao\System;
+
+System::loadLanguageFile('tl_recommendation');
+System::loadLanguageFile('tl_recommendation_notification');
+System::loadLanguageFile('tl_recommendation_list');
// Add a palette selector
$GLOBALS['TL_DCA']['tl_module']['palettes']['__selector__'][] = 'recommendation_activate';
@@ -21,185 +23,156 @@
$GLOBALS['TL_DCA']['tl_module']['subpalettes']['recommendation_activate'] = 'recommendation_activateJumpTo,recommendation_activateText';
// Add fields to tl_module
-$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_archives'] = array
-(
- 'label' => &$GLOBALS['TL_LANG']['tl_module']['recommendation_archives'],
+$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_archives'] = [
'exclude' => true,
'inputType' => 'checkbox',
- 'options_callback' => array('tl_module_recommendation', 'getRecommendationArchives'),
- 'eval' => array('multiple'=>true, 'mandatory'=>true),
+ 'options_callback' => ['tl_module_recommendation', 'getRecommendationArchives'],
+ 'eval' => ['multiple'=>true, 'mandatory'=>true],
'sql' => "blob NULL"
-);
+];
-$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_archive'] = array
-(
- 'label' => &$GLOBALS['TL_LANG']['tl_module']['recommendation_archive'],
+$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_archive'] = [
'exclude' => true,
'inputType' => 'select',
- 'options_callback' => array('tl_module_recommendation', 'getRecommendationArchives'),
- 'eval' => array('mandatory'=>true, 'includeBlankOption'=>true, 'tl_class'=>'w50 clr'),
+ 'options_callback' => ['tl_module_recommendation', 'getRecommendationArchives'],
+ 'eval' => ['mandatory'=>true, 'includeBlankOption'=>true, 'tl_class'=>'w50 clr'],
'sql' => "int(10) unsigned NOT NULL default 0"
-);
+];
-$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_featured'] = array
-(
- 'label' => &$GLOBALS['TL_LANG']['tl_module']['recommendation_featured'],
+$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_featured'] = [
'default' => 'all_items',
'exclude' => true,
'inputType' => 'select',
- 'options' => array('all_items', 'featured', 'unfeatured', 'featured_first'),
+ 'options' => ['all_items', 'featured', 'unfeatured', 'featured_first'],
'reference' => &$GLOBALS['TL_LANG']['tl_recommendation_list'],
- 'eval' => array('tl_class'=>'w50'),
+ 'eval' => ['tl_class'=>'w50'],
'sql' => "varchar(16) NOT NULL default ''"
-);
+];
-$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_readerModule'] = array
-(
+$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_readerModule'] = [
'exclude' => true,
'inputType' => 'select',
- 'options_callback' => array('tl_module_recommendation', 'getReaderModules'),
+ 'options_callback' => ['tl_module_recommendation', 'getReaderModules'],
'reference' => &$GLOBALS['TL_LANG']['tl_module'],
- 'eval' => array('includeBlankOption'=>true, 'tl_class'=>'w50'),
+ 'eval' => ['includeBlankOption'=>true, 'tl_class'=>'w50'],
'sql' => "int(10) unsigned NOT NULL default 0"
-);
+];
-$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_metaFields'] = array
-(
- 'label' => &$GLOBALS['TL_LANG']['tl_module']['recommendation_metaFields'],
- 'default' => array('date', 'author'),
+$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_metaFields'] = [
+ 'default' => ['date', 'author'],
'exclude' => true,
'inputType' => 'checkbox',
- 'options' => array('image', 'date', 'author', 'rating', 'location', 'customField'),
+ 'options' => ['image', 'date', 'author', 'rating', 'location', 'customField'],
'reference' => &$GLOBALS['TL_LANG']['tl_recommendation'],
- 'eval' => array('multiple'=>true),
+ 'eval' => ['multiple'=>true],
'sql' => "varchar(255) NOT NULL default ''"
-);
+];
-$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_order'] = array
-(
+$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_order'] = [
'exclude' => true,
'inputType' => 'select',
- 'options' => array('order_date_asc', 'order_date_desc', 'order_random', 'order_rating_desc'),
+ 'options' => ['order_date_asc', 'order_date_desc', 'order_random', 'order_rating_desc'],
'reference' => &$GLOBALS['TL_LANG']['tl_recommendation_list'],
- 'eval' => array('tl_class'=>'w50'),
+ 'eval' => ['tl_class'=>'w50'],
'sql' => "varchar(32) NOT NULL default 'order_date_desc'"
-);
+];
-$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_minRating'] = array
-(
+$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_minRating'] = [
'exclude' => true,
'inputType' => 'select',
- 'options' => array(1=> 'minOne', 2=>'minTwo', 3=>'minThree', 4=>'minFour', 5=>'minFive'),
+ 'options' => [1=> 'minOne', 2=>'minTwo', 3=>'minThree', 4=>'minFour', 5=>'minFive'],
'reference' => &$GLOBALS['TL_LANG']['tl_recommendation_list'],
- 'eval' => array('tl_class'=>'w50'),
+ 'eval' => ['tl_class'=>'w50'],
'sql' => "char(1) NOT NULL default '1'"
-);
+];
-$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_optionalFormFields'] = array
-(
- 'label' => &$GLOBALS['TL_LANG']['tl_module']['recommendation_optionalFormFields'],
+$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_optionalFormFields'] = [
'exclude' => true,
'inputType' => 'checkbox',
- 'options' => array('title', 'location', 'email', 'customField'),
+ 'options' => ['title', 'location', 'email', 'customField'],
'reference' => &$GLOBALS['TL_LANG']['tl_recommendation'],
- 'eval' => array('multiple'=>true, 'tl_class'=>'w50 clr'),
+ 'eval' => ['multiple'=>true, 'tl_class'=>'w50 clr'],
'sql' => "varchar(255) NOT NULL default ''"
-);
+];
-$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_customFieldLabel'] = array
-(
- 'label' => &$GLOBALS['TL_LANG']['tl_module']['recommendation_customFieldLabel'],
+$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_customFieldLabel'] = [
'exclude' => true,
'inputType' => 'text',
- 'eval' => array('maxlength'=>64, 'tl_class'=>'w50 clr'),
+ 'eval' => ['maxlength'=>64, 'tl_class'=>'w50 clr'],
'sql' => "varchar(64) NOT NULL default ''"
-);
+];
-$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_notify'] = array
-(
- 'label' => &$GLOBALS['TL_LANG']['tl_module']['recommendation_notify'],
+$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_notify'] = [
'default' => true,
'exclude' => true,
'inputType' => 'checkbox',
- 'eval' => array('tl_class'=>'w50 clr'),
+ 'eval' => ['tl_class'=>'w50 clr'],
'sql' => "char(1) NOT NULL default '1'"
-);
+];
-$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_moderate'] = array
-(
- 'label' => &$GLOBALS['TL_LANG']['tl_module']['recommendation_moderate'],
+$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_moderate'] = [
'default' => true,
'exclude' => true,
'inputType' => 'checkbox',
- 'eval' => array('tl_class'=>'w50'),
+ 'eval' => ['tl_class'=>'w50'],
'sql' => "char(1) NOT NULL default '1'"
-);
+];
-$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_disableCaptcha'] = array
-(
- 'label' => &$GLOBALS['TL_LANG']['tl_module']['recommendation_disableCaptcha'],
+$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_disableCaptcha'] = [
'exclude' => true,
'inputType' => 'checkbox',
- 'eval' => array('tl_class'=>'w50'),
+ 'eval' => ['tl_class'=>'w50'],
'sql' => "char(1) NOT NULL default ''"
-);
+];
-$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_disableCaptcha'] = array
-(
- 'label' => &$GLOBALS['TL_LANG']['tl_module']['recommendation_disableCaptcha'],
+$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_disableCaptcha'] = [
'exclude' => true,
'inputType' => 'checkbox',
- 'eval' => array('tl_class'=>'w50'),
+ 'eval' => ['tl_class'=>'w50'],
'sql' => "char(1) NOT NULL default ''"
-);
+];
-$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_privacyText'] = array
-(
+$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_privacyText'] = [
'exclude' => true,
'inputType' => 'textarea',
- 'eval' => array('style'=>'height:100px', 'allowHtml'=>true),
+ 'eval' => ['style'=>'height:100px', 'allowHtml'=>true],
'sql' => "text NULL"
-);
+];
-$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_activate'] = array
-(
+$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_activate'] = [
'exclude' => true,
'inputType' => 'checkbox',
- 'eval' => array('submitOnChange'=>true),
+ 'eval' => ['submitOnChange'=>true],
'sql' => "char(1) NOT NULL default ''"
-);
+];
-$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_activateJumpTo'] = array
-(
+$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_activateJumpTo'] = [
'exclude' => true,
'inputType' => 'pageTree',
'foreignKey' => 'tl_page.title',
- 'eval' => array('fieldType'=>'radio'),
+ 'eval' => ['fieldType'=>'radio'],
'sql' => "int(10) unsigned NOT NULL default 0",
- 'relation' => array('type'=>'hasOne', 'load'=>'lazy')
-);
+ 'relation' => ['type'=>'hasOne', 'load'=>'lazy']
+];
-$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_activateText'] = array
-(
+$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_activateText'] = [
'exclude' => true,
'inputType' => 'textarea',
- 'eval' => array('style'=>'height:120px', 'decodeEntities'=>true, 'alwaysSave'=>true),
- 'load_callback' => array
- (
- array('tl_module_recommendation', 'getRecommendationActivationDefault')
- ),
+ 'eval' => ['style'=>'height:120px', 'decodeEntities'=>true, 'alwaysSave'=>true],
+ 'load_callback' =>
+ [
+ ['tl_module_recommendation', 'getRecommendationActivationDefault']
+ ],
'sql' => "text NULL"
-);
+];
-$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_template'] = array
-(
- 'label' => &$GLOBALS['TL_LANG']['tl_module']['recommendation_template'],
+$GLOBALS['TL_DCA']['tl_module']['fields']['recommendation_template'] = [
'exclude' => true,
'inputType' => 'select',
'options_callback' => static fn () => Controller::getTemplateGroup('recommendation_'),
- 'eval' => array('includeBlankOption' => true, 'chosen' => true, 'tl_class'=>'w50'),
+ 'eval' => ['includeBlankOption' => true, 'chosen' => true, 'tl_class'=>'w50'],
'sql' => "varchar(64) NOT NULL default ''"
-);
+];
/**
@@ -228,10 +201,10 @@ public function getRecommendationArchives()
{
if (!$this->User->isAdmin && !is_array($this->User->recommendations))
{
- return array();
+ return [];
}
- $arrArchives = array();
+ $arrArchives = [];
$objArchives = $this->Database->execute("SELECT id, title FROM tl_recommendation_archive ORDER BY title");
while ($objArchives->next())
@@ -252,7 +225,7 @@ public function getRecommendationArchives()
*/
public function getReaderModules()
{
- $arrModules = array();
+ $arrModules = [];
$objModules = $this->Database->execute("SELECT m.id, m.name, t.name AS theme FROM tl_module m LEFT JOIN tl_theme t ON m.pid=t.id WHERE m.type='recommendationreader' ORDER BY t.name, m.name");
while ($objModules->next())
diff --git a/src/Resources/contao/dca/tl_recommendation.php b/contao/dca/tl_recommendation.php
similarity index 75%
rename from src/Resources/contao/dca/tl_recommendation.php
rename to contao/dca/tl_recommendation.php
index 03290bb..4a47eda 100644
--- a/src/Resources/contao/dca/tl_recommendation.php
+++ b/contao/dca/tl_recommendation.php
@@ -8,327 +8,254 @@
use Oveleon\ContaoRecommendationBundle\RecommendationArchiveModel;
-$GLOBALS['TL_DCA']['tl_recommendation'] = array
-(
+$GLOBALS['TL_DCA']['tl_recommendation'] = [
// Config
- 'config' => array
- (
+ 'config' => [
'dataContainer' => 'Table',
'ptable' => 'tl_recommendation_archive',
'switchToEdit' => true,
'enableVersioning' => true,
- 'onload_callback' => array
- (
- array('tl_recommendation', 'checkPermission'),
- array('tl_recommendation', 'generateSitemap')
- ),
- 'oncut_callback' => array
- (
- array('tl_recommendation', 'scheduleUpdate')
- ),
- 'ondelete_callback' => array
- (
- array('tl_recommendation', 'scheduleUpdate')
- ),
- 'onsubmit_callback' => array
- (
- array('tl_recommendation', 'adjustTime'),
- array('tl_recommendation', 'scheduleUpdate')
- ),
- 'oninvalidate_cache_tags_callback' => array
- (
- array('tl_recommendation', 'addSitemapCacheInvalidationTag'),
- ),
- 'sql' => array
- (
- 'keys' => array
- (
+ 'onload_callback' => [
+ ['tl_recommendation', 'checkPermission'],
+ ['tl_recommendation', 'generateSitemap']
+ ],
+ 'oncut_callback' => [
+ ['tl_recommendation', 'scheduleUpdate']
+ ],
+ 'ondelete_callback' => [
+ ['tl_recommendation', 'scheduleUpdate']
+ ],
+ 'onsubmit_callback' => [
+ ['tl_recommendation', 'adjustTime'],
+ ['tl_recommendation', 'scheduleUpdate']
+ ],
+ 'oninvalidate_cache_tags_callback' => [
+ ['tl_recommendation', 'addSitemapCacheInvalidationTag'],
+ ],
+ 'sql' => [
+ 'keys' => [
'id' => 'primary',
'alias' => 'index',
'pid,start,stop,published' => 'index'
- )
- )
- ),
+ ]
+ ]
+ ],
// List
- 'list' => array
- (
- 'sorting' => array
- (
+ 'list' => [
+ 'sorting' => [
'mode' => 4,
- 'fields' => array('date DESC'),
- 'headerFields' => array('title', 'jumpTo', 'tstamp', 'protected'),
+ 'fields' => ['date DESC'],
+ 'headerFields' => ['title', 'jumpTo', 'tstamp', 'protected'],
'panelLayout' => 'filter;sort,search,limit',
- 'child_record_callback' => array('tl_recommendation', 'listRecommendations'),
+ 'child_record_callback' => ['tl_recommendation', 'listRecommendations'],
'child_record_class' => 'no_padding'
- ),
- 'global_operations' => array
- (
- 'all' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['MSC']['all'],
+ ],
+ 'global_operations' => [
+ 'all' => [
'href' => 'act=select',
'class' => 'header_edit_all',
'attributes' => 'onclick="Backend.getScrollOffset()" accesskey="e"'
- )
- ),
- 'operations' => array
- (
- 'edit' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['edit'],
+ ]
+ ],
+ 'operations' => [
+ 'edit' => [
'href' => 'act=edit',
'icon' => 'edit.svg'
- ),
- 'copy' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['copy'],
+ ],
+ 'copy' => [
'href' => 'act=paste&mode=copy',
'icon' => 'copy.svg'
- ),
- 'cut' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['cut'],
+ ],
+ 'cut' => [
'href' => 'act=paste&mode=cut',
'icon' => 'cut.svg'
- ),
- 'delete' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['delete'],
+ ],
+ 'delete' => [
'href' => 'act=delete',
'icon' => 'delete.svg',
'attributes' => 'onclick="if(!confirm(\'' . ($GLOBALS['TL_LANG']['MSC']['deleteConfirm'] ?? null) . '\'))return false;Backend.getScrollOffset()"'
- ),
- 'toggle' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['toggle'],
+ ],
+ 'toggle' => [
'icon' => 'visible.svg',
'attributes' => 'onclick="Backend.getScrollOffset();return AjaxRequest.toggleVisibility(this,%s)"',
- 'button_callback' => array('tl_recommendation', 'toggleIcon')
- ),
- 'feature' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['feature'],
+ 'button_callback' => ['tl_recommendation', 'toggleIcon']
+ ],
+ 'feature' => [
'icon' => 'featured.svg',
'attributes' => 'onclick="Backend.getScrollOffset();return AjaxRequest.toggleFeatured(this,%s)"',
- 'button_callback' => array('tl_recommendation', 'iconFeatured')
- ),
- 'show' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['show'],
+ 'button_callback' => ['tl_recommendation', 'iconFeatured']
+ ],
+ 'show' => [
'href' => 'act=show',
'icon' => 'show.svg'
- )
- )
- ),
+ ]
+ ]
+ ],
// Palettes
- 'palettes' => array
- (
+ 'palettes' => [
'default' => '{title_legend},author,title,alias,email,location;{date_legend},date,time;{recommendation_legend},text,imageUrl,rating,customField;{teaser_legend:hide},teaser;{expert_legend:hide},cssClass,featured;{publish_legend},published,start,stop'
- ),
+ ],
// Fields
- 'fields' => array
- (
- 'id' => array
- (
+ 'fields' => [
+ 'id' => [
'sql' => "int(10) unsigned NOT NULL auto_increment"
- ),
- 'pid' => array
- (
+ ],
+ 'pid' => [
'foreignKey' => 'tl_recommendation_archive.title',
'sql' => "int(10) unsigned NOT NULL default '0'",
- 'relation' => array('type'=>'belongsTo', 'load'=>'lazy')
- ),
- 'tstamp' => array
- (
+ 'relation' => ['type'=>'belongsTo', 'load'=>'lazy']
+ ],
+ 'tstamp' => [
'sql' => "int(10) unsigned NOT NULL default '0'"
- ),
- 'title' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['title'],
+ ],
+ 'title' => [
'exclude' => true,
'search' => true,
'sorting' => true,
'flag' => 1,
'inputType' => 'text',
- 'eval' => array('maxlength'=>255, 'tl_class'=>'w50 clr'),
+ 'eval' => ['maxlength'=>255, 'tl_class'=>'w50 clr'],
'sql' => "varchar(255) NOT NULL default ''"
- ),
- 'alias' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['alias'],
+ ],
+ 'alias' => [
'exclude' => true,
'search' => true,
'inputType' => 'text',
- 'eval' => array('rgxp'=>'alias', 'doNotCopy'=>true, 'unique'=>true, 'maxlength'=>128, 'tl_class'=>'w50'),
- 'save_callback' => array
- (
- array('tl_recommendation', 'generateAlias')
- ),
+ 'eval' => ['rgxp'=>'alias', 'doNotCopy'=>true, 'unique'=>true, 'maxlength'=>128, 'tl_class'=>'w50'],
+ 'save_callback' => [
+ ['tl_recommendation', 'generateAlias']
+ ],
'sql' => "varchar(255) BINARY NOT NULL default ''"
- ),
- 'author' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['author'],
+ ],
+ 'author' => [
'exclude' => true,
'search' => true,
'sorting' => true,
'flag' => 1,
'inputType' => 'text',
- 'eval' => array('doNotCopy'=>true, 'mandatory'=>true, 'maxlength'=>128, 'tl_class'=>'w50'),
+ 'eval' => ['doNotCopy'=>true, 'mandatory'=>true, 'maxlength'=>128, 'tl_class'=>'w50'],
'sql' => "varchar(128) NOT NULL default ''"
- ),
- 'email' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['email'],
+ ],
+ 'email' => [
'exclude' => true,
'search' => true,
'inputType' => 'text',
- 'eval' => array('doNotCopy'=>true, 'maxlength'=>255, 'rgxp'=>'email', 'decodeEntities'=>true, 'tl_class'=>'w50'),
+ 'eval' => ['doNotCopy'=>true, 'maxlength'=>255, 'rgxp'=>'email', 'decodeEntities'=>true, 'tl_class'=>'w50'],
'sql' => "varchar(255) NOT NULL default ''"
- ),
- 'location' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['location'],
+ ],
+ 'location' => [
'exclude' => true,
'search' => true,
'sorting' => true,
'flag' => 1,
'inputType' => 'text',
- 'eval' => array('doNotCopy'=>true, 'maxlength'=>128, 'tl_class'=>'w50'),
+ 'eval' => ['doNotCopy'=>true, 'maxlength'=>128, 'tl_class'=>'w50'],
'sql' => "varchar(128) NOT NULL default ''"
- ),
- 'date' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['date'],
+ ],
+ 'date' => [
'default' => time(),
'exclude' => true,
'filter' => true,
'sorting' => true,
'flag' => 8,
'inputType' => 'text',
- 'eval' => array('rgxp'=>'date', 'mandatory'=>true, 'doNotCopy'=>true, 'datepicker'=>true, 'tl_class'=>'w50 wizard'),
- 'load_callback' => array
- (
- array('tl_recommendation', 'loadDate')
- ),
- 'sql' => "int(10) unsigned NOT NULL default '0'"
- ),
- 'time' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['time'],
+ 'eval' => ['rgxp'=>'date', 'mandatory'=>true, 'doNotCopy'=>true, 'datepicker'=>true, 'tl_class'=>'w50 wizard'],
+ 'load_callback' => [
+ ['tl_recommendation', 'loadDate']
+ ],
+ 'sql' => "int(10) unsigned NOT NULL default 0"
+ ],
+ 'time' => [
'default' => time(),
'exclude' => true,
'inputType' => 'text',
- 'eval' => array('rgxp'=>'time', 'mandatory'=>true, 'doNotCopy'=>true, 'tl_class'=>'w50'),
- 'load_callback' => array
- (
- array('tl_recommendation', 'loadTime')
- ),
- 'sql' => "int(10) unsigned NOT NULL default '0'"
- ),
- 'teaser' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['teaser'],
+ 'eval' => ['rgxp'=>'time', 'mandatory'=>true, 'doNotCopy'=>true, 'tl_class'=>'w50'],
+ 'load_callback' => [
+ ['tl_recommendation', 'loadTime']
+ ],
+ 'sql' => "int(10) unsigned NOT NULL default 0"
+ ],
+ 'teaser' => [
'exclude' => true,
'search' => true,
'inputType' => 'textarea',
- 'eval' => array('rte'=>'tinyMCE', 'tl_class'=>'clr'),
+ 'eval' => ['rte'=>'tinyMCE', 'tl_class'=>'clr'],
'sql' => "mediumtext NULL"
- ),
- 'text' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['text'],
+ ],
+ 'text' => [
'exclude' => true,
'search' => true,
'inputType' => 'textarea',
- 'eval' => array('mandatory'=>true, 'rte'=>'tinyMCE', 'tl_class'=>'clr'),
+ 'eval' => ['mandatory'=>true, 'rte'=>'tinyMCE', 'tl_class'=>'clr'],
'sql' => "mediumtext NULL"
- ),
- 'imageUrl' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['imageUrl'],
+ ],
+ 'imageUrl' => [
'exclude' => true,
'search' => true,
'inputType' => 'text',
- 'eval' => array('rgxp'=>'url', 'decodeEntities'=>true, 'maxlength'=>255, 'dcaPicker'=>true, 'tl_class'=>'w50 wizard'),
+ 'eval' => ['rgxp'=>'url', 'decodeEntities'=>true, 'maxlength'=>255, 'dcaPicker'=>true, 'tl_class'=>'w50 wizard'],
'sql' => "varchar(255) NOT NULL default ''"
- ),
- 'rating' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['rating'],
+ ],
+ 'rating' => [
'default' => 5,
'exclude' => true,
'search' => true,
'filter' => true,
'sorting' => true,
'inputType' => 'select',
- 'options' => array(1,2,3,4,5),
- 'eval' => array('mandatory'=>true, 'tl_class'=>'w50'),
+ 'options' => [1,2,3,4,5],
+ 'eval' => ['mandatory'=>true, 'tl_class'=>'w50'],
'sql' => "char(1) NOT NULL default ''"
- ),
- 'customField' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['customField'],
+ ],
+ 'customField' => [
'exclude' => true,
'inputType' => 'text',
- 'eval' => array('doNotCopy'=>true, 'maxlength'=>255, 'tl_class'=>'w100 clr'),
+ 'eval' => ['doNotCopy'=>true, 'maxlength'=>255, 'tl_class'=>'w100 clr'],
'sql' => "varchar(255) NOT NULL default ''"
- ),
- 'cssClass' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['cssClass'],
+ ],
+ 'cssClass' => [
'exclude' => true,
'inputType' => 'text',
- 'eval' => array('tl_class'=>'w50'),
+ 'eval' => ['tl_class'=>'w50'],
'sql' => "varchar(255) NOT NULL default ''"
- ),
- 'featured' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['featured'],
+ ],
+ 'featured' => [
'exclude' => true,
'filter' => true,
'inputType' => 'checkbox',
- 'eval' => array('tl_class'=>'w50 m12'),
+ 'eval' => ['tl_class'=>'w50 m12'],
'sql' => "char(1) NOT NULL default ''"
- ),
- 'verified' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['verified'],
+ ],
+ 'verified' => [
'filter' => true,
- 'eval' => array('isBoolean'=>true),
+ 'eval' => ['isBoolean'=>true],
'sql' => "char(1) NOT NULL default '1'"
- ),
- 'published' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['published'],
+ ],
+ 'published' => [
'exclude' => true,
'filter' => true,
'flag' => 1,
'inputType' => 'checkbox',
- 'eval' => array('doNotCopy'=>true),
+ 'eval' => ['doNotCopy'=>true],
'sql' => "char(1) NOT NULL default ''"
- ),
- 'start' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['start'],
+ ],
+ 'start' => [
'exclude' => true,
'inputType' => 'text',
- 'eval' => array('rgxp'=>'datim', 'datepicker'=>true, 'tl_class'=>'w50 wizard'),
+ 'eval' => ['rgxp'=>'datim', 'datepicker'=>true, 'tl_class'=>'w50 wizard'],
'sql' => "varchar(10) NOT NULL default ''"
- ),
- 'stop' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation']['stop'],
+ ],
+ 'stop' => [
'exclude' => true,
'inputType' => 'text',
- 'eval' => array('rgxp'=>'datim', 'datepicker'=>true, 'tl_class'=>'w50 wizard'),
+ 'eval' => ['rgxp'=>'datim', 'datepicker'=>true, 'tl_class'=>'w50 wizard'],
'sql' => "varchar(10) NOT NULL default ''"
- )
- )
-);
+ ]
+ ]
+];
/**
* Provide miscellaneous methods that are used by the data configuration array.
@@ -337,7 +264,6 @@
*/
class tl_recommendation extends Contao\Backend
{
-
/**
* Import the back end user object
*/
@@ -362,7 +288,7 @@ public function checkPermission()
// Set the root IDs
if (empty($this->User->recommendations) || !is_array($this->User->recommendations))
{
- $root = array(0);
+ $root = [0];
}
else
{
@@ -562,7 +488,7 @@ public function adjustTime(Contao\DataContainer $dc)
return;
}
- $arrSet['date'] = strtotime(date('Y-m-d', $dc->activeRecord->date) . ' ' . date('H:i:s', $dc->activeRecord->time));
+ $arrSet['date'] = strtotime(date('Y-m-d', $dc->activeRecord->date) . ' tl_recommendation.php' . date('H:i:s', $dc->activeRecord->time));
$arrSet['time'] = $arrSet['date'];
$this->Database->prepare("UPDATE tl_recommendation %s WHERE id=?")->set($arrSet)->execute($dc->id);
@@ -868,6 +794,6 @@ public function addSitemapCacheInvalidationTag($dc, array $tags)
return $tags;
}
- return array_merge($tags, array('contao.sitemap.' . $pageModel->rootId));
+ return array_merge($tags, ['contao.sitemap.' . $pageModel->rootId]);
}
}
diff --git a/src/Resources/contao/dca/tl_recommendation_archive.php b/contao/dca/tl_recommendation_archive.php
similarity index 73%
rename from src/Resources/contao/dca/tl_recommendation_archive.php
rename to contao/dca/tl_recommendation_archive.php
index 75de17e..066517e 100644
--- a/src/Resources/contao/dca/tl_recommendation_archive.php
+++ b/contao/dca/tl_recommendation_archive.php
@@ -6,176 +6,136 @@
* (c) https://www.oveleon.de/
*/
-$GLOBALS['TL_DCA']['tl_recommendation_archive'] = array
-(
+$GLOBALS['TL_DCA']['tl_recommendation_archive'] = [
// Config
- 'config' => array
- (
+ 'config' => [
'dataContainer' => 'Table',
- 'ctable' => array('tl_recommendation'),
+ 'ctable' => ['tl_recommendation'],
'switchToEdit' => true,
'enableVersioning' => true,
- 'onload_callback' => array
- (
- array('tl_recommendation_archive', 'checkPermission')
- ),
- 'oncreate_callback' => array
- (
- array('tl_recommendation_archive', 'adjustPermissions')
- ),
- 'oncopy_callback' => array
- (
- array('tl_recommendation_archive', 'adjustPermissions')
- ),
- 'oninvalidate_cache_tags_callback' => array
- (
- array('tl_recommendation_archive', 'addSitemapCacheInvalidationTag'),
- ),
- 'sql' => array
- (
- 'keys' => array
- (
+ 'onload_callback' => [
+ ['tl_recommendation_archive', 'checkPermission']
+ ],
+ 'oncreate_callback' => [
+ ['tl_recommendation_archive', 'adjustPermissions']
+ ],
+ 'oncopy_callback' => [
+ ['tl_recommendation_archive', 'adjustPermissions']
+ ],
+ 'oninvalidate_cache_tags_callback' => [
+ ['tl_recommendation_archive', 'addSitemapCacheInvalidationTag'],
+ ],
+ 'sql' => [
+ 'keys' => [
'id' => 'primary'
- )
- )
- ),
+ ]
+ ]
+ ],
// List
- 'list' => array
- (
- 'sorting' => array
- (
+ 'list' => [
+ 'sorting' => [
'mode' => 1,
- 'fields' => array('title'),
+ 'fields' => ['title'],
'flag' => 1,
'panelLayout' => 'filter;search,limit'
- ),
- 'label' => array
- (
- 'fields' => array('title'),
+ ],
+ 'label' => [
+ 'fields' => ['title'],
'format' => '%s'
- ),
- 'global_operations' => array
- (
- 'settings' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation_archive']['settings'],
+ ],
+ 'global_operations' => [
+ 'settings' => [
'href' => 'do=recommendation_settings',
'class' => '',
'icon' => 'edit.svg',
'attributes' => 'onclick="Backend.getScrollOffset()" accesskey="e"'
- ),
- 'all' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['MSC']['all'],
+ ],
+ 'all' => [
'href' => 'act=select',
'class' => 'header_edit_all',
'attributes' => 'onclick="Backend.getScrollOffset()" accesskey="e"'
- )
- ),
- 'operations' => array
- (
- 'edit' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation_archive']['edit'],
+ ]
+ ],
+ 'operations' => [
+ 'edit' => [
'href' => 'table=tl_recommendation',
'icon' => 'edit.svg'
- ),
- 'editheader' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation_archive']['editheader'],
+ ],
+ 'editheader' => [
'href' => 'act=edit',
'icon' => 'header.svg',
- 'button_callback' => array('tl_recommendation_archive', 'editHeader')
- ),
- 'copy' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation_archive']['copy'],
+ 'button_callback' => ['tl_recommendation_archive', 'editHeader']
+ ],
+ 'copy' => [
'href' => 'act=copy',
'icon' => 'copy.svg',
- 'button_callback' => array('tl_recommendation_archive', 'copyArchive')
- ),
- 'delete' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation_archive']['delete'],
+ 'button_callback' => ['tl_recommendation_archive', 'copyArchive']
+ ],
+ 'delete' => [
'href' => 'act=delete',
'icon' => 'delete.svg',
'attributes' => 'onclick="if(!confirm(\'' . ($GLOBALS['TL_LANG']['MSC']['deleteConfirm'] ?? null) . '\'))return false;Backend.getScrollOffset()"',
- 'button_callback' => array('tl_recommendation_archive', 'deleteArchive')
- ),
- 'show' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation_archive']['show'],
+ 'button_callback' => ['tl_recommendation_archive', 'deleteArchive']
+ ],
+ 'show' => [
'href' => 'act=show',
'icon' => 'show.svg'
- )
- )
- ),
+ ]
+ ]
+ ],
// Palettes
- 'palettes' => array
- (
- '__selector__' => array('protected'),
+ 'palettes' => [
+ '__selector__' => ['protected'],
'default' => '{title_legend},title,jumpTo;{protected_legend:hide},protected'
- ),
+ ],
// Subpalettes
- 'subpalettes' => array
- (
+ 'subpalettes' => [
'protected' => 'groups'
- ),
+ ],
// Fields
- 'fields' => array
- (
- 'id' => array
- (
+ 'fields' => [
+ 'id' => [
'sql' => "int(10) unsigned NOT NULL auto_increment"
- ),
- 'tstamp' => array
- (
+ ],
+ 'tstamp' => [
'sql' => "int(10) unsigned NOT NULL default '0'"
- ),
- 'title' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation_archive']['title'],
+ ],
+ 'title' => [
'exclude' => true,
'search' => true,
'inputType' => 'text',
- 'eval' => array('mandatory'=>true, 'maxlength'=>255, 'tl_class'=>'w50'),
+ 'eval' => ['mandatory'=>true, 'maxlength'=>255, 'tl_class'=>'w50'],
'sql' => "varchar(255) NOT NULL default ''"
- ),
- 'jumpTo' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation_archive']['jumpTo'],
+ ],
+ 'jumpTo' => [
'exclude' => true,
'inputType' => 'pageTree',
'foreignKey' => 'tl_page.title',
- 'eval' => array('fieldType'=>'radio', 'tl_class'=>'clr'),
+ 'eval' => ['fieldType'=>'radio', 'tl_class'=>'clr'],
'sql' => "int(10) unsigned NOT NULL default '0'",
- 'relation' => array('type'=>'hasOne', 'load'=>'eager')
- ),
- 'protected' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation_archive']['protected'],
+ 'relation' => ['type'=>'hasOne', 'load'=>'eager']
+ ],
+ 'protected' => [
'exclude' => true,
'filter' => true,
'inputType' => 'checkbox',
- 'eval' => array('submitOnChange'=>true),
+ 'eval' => ['submitOnChange'=>true],
'sql' => "char(1) NOT NULL default ''"
- ),
- 'groups' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation_archive']['groups'],
+ ],
+ 'groups' => [
'exclude' => true,
'inputType' => 'checkbox',
'foreignKey' => 'tl_member_group.name',
- 'eval' => array('mandatory'=>true, 'multiple'=>true),
+ 'eval' => ['mandatory'=>true, 'multiple'=>true],
'sql' => "blob NULL",
- 'relation' => array('type'=>'hasMany', 'load'=>'lazy')
- )
- )
-);
+ 'relation' => ['type'=>'hasMany', 'load'=>'lazy']
+ ]
+ ]
+];
/**
* Provide miscellaneous methods that are used by the data configuration array.
@@ -209,7 +169,7 @@ public function checkPermission()
// Set root IDs
if (empty($this->User->recommendations) || !is_array($this->User->recommendations))
{
- $root = array(0);
+ $root = [0];
}
else
{
@@ -267,7 +227,7 @@ public function checkPermission()
if (Contao\Input::get('act') == 'deleteAll' && !$this->User->hasAccess('delete', 'recommendationp'))
{
- $session['CURRENT']['IDS'] = array();
+ $session['CURRENT']['IDS'] = [];
}
else
{
@@ -306,7 +266,7 @@ public function adjustPermissions($insertId)
// Set root IDs
if (empty($this->User->recommendations) || !is_array($this->User->recommendations))
{
- $root = array(0);
+ $root = [0];
}
else
{
@@ -385,7 +345,7 @@ public function adjustPermissions($insertId)
*/
public function editHeader($row, $href, $label, $title, $icon, $attributes)
{
- return $this->User->canEditFieldsOf('tl_recommendation_archive') ? ''.Contao\Image::getHtml($icon, $label).' ' : Contao\Image::getHtml(preg_replace('/\.svg$/i', '_.svg', $icon)).' ';
+ return $this->User->canEditFieldsOf('tl_recommendation_archive') ? ''.Contao\Image::getHtml($icon, $label).' ' : Contao\Image::getHtml(preg_replace('/\.svg$/i', '_.svg', $icon)) . ' tl_recommendation_archive.php';
}
/**
@@ -402,7 +362,7 @@ public function editHeader($row, $href, $label, $title, $icon, $attributes)
*/
public function copyArchive($row, $href, $label, $title, $icon, $attributes)
{
- return $this->User->hasAccess('create', 'recommendationp') ? ''.Contao\Image::getHtml($icon, $label).' ' : Contao\Image::getHtml(preg_replace('/\.svg$/i', '_.svg', $icon)).' ';
+ return $this->User->hasAccess('create', 'recommendationp') ? ''.Contao\Image::getHtml($icon, $label).' ' : Contao\Image::getHtml(preg_replace('/\.svg$/i', '_.svg', $icon)) . ' tl_recommendation_archive.php';
}
/**
@@ -419,7 +379,7 @@ public function copyArchive($row, $href, $label, $title, $icon, $attributes)
*/
public function deleteArchive($row, $href, $label, $title, $icon, $attributes)
{
- return $this->User->hasAccess('delete', 'recommendationp') ? ''.Contao\Image::getHtml($icon, $label).' ' : Contao\Image::getHtml(preg_replace('/\.svg$/i', '_.svg', $icon)).' ';
+ return $this->User->hasAccess('delete', 'recommendationp') ? ''.Contao\Image::getHtml($icon, $label).' ' : Contao\Image::getHtml(preg_replace('/\.svg$/i', '_.svg', $icon)) . ' tl_recommendation_archive.php';
}
/**
@@ -436,6 +396,6 @@ public function addSitemapCacheInvalidationTag($dc, array $tags)
return $tags;
}
- return array_merge($tags, array('contao.sitemap.' . $pageModel->rootId));
+ return array_merge($tags, ['contao.sitemap.' . $pageModel->rootId]);
}
}
diff --git a/contao/dca/tl_recommendation_settings.php b/contao/dca/tl_recommendation_settings.php
new file mode 100644
index 0000000..9be3b28
--- /dev/null
+++ b/contao/dca/tl_recommendation_settings.php
@@ -0,0 +1,33 @@
+ [
+ 'dataContainer' => 'File',
+ 'closed' => true
+ ],
+
+ // Palettes
+ 'palettes' => [
+ 'default' => '{recommendation_legend},recommendationDefaultImage,recommendationActiveColor;'
+ ],
+
+ // Fields
+ 'fields' => [
+ 'recommendationDefaultImage' => [
+ 'inputType' => 'fileTree',
+ 'eval' => ['fieldType'=>'radio', 'filesOnly'=>true, 'isGallery'=>true, 'extensions'=>Contao\Config::get('validImageTypes'), 'tl_class'=>'clr']
+ ],
+ 'recommendationActiveColor' => [
+ 'inputType' => 'text',
+ 'eval' => ['maxlength'=>6, 'multiple'=>true, 'size'=>1, 'colorpicker'=>true, 'isHexColor'=>true, 'decodeEntities'=>true, 'tl_class'=>'w50 wizard'],
+ ]
+ ]
+];
diff --git a/contao/dca/tl_user.php b/contao/dca/tl_user.php
new file mode 100644
index 0000000..a1cde50
--- /dev/null
+++ b/contao/dca/tl_user.php
@@ -0,0 +1,35 @@
+addLegend('recommendation_legend', 'amg_legend', PaletteManipulator::POSITION_BEFORE)
+ ->addField(['recommendations', 'recommendationp'], 'recommendation_legend', PaletteManipulator::POSITION_APPEND)
+ ->applyToPalette('extend', 'tl_user')
+ ->applyToPalette('custom', 'tl_user')
+;
+
+// Add fields to tl_user_group
+$GLOBALS['TL_DCA']['tl_user']['fields']['recommendations'] = [
+ 'exclude' => true,
+ 'inputType' => 'checkbox',
+ 'foreignKey' => 'tl_recommendation_archive.title',
+ 'eval' => ['multiple'=>true],
+ 'sql' => "blob NULL"
+];
+
+$GLOBALS['TL_DCA']['tl_user']['fields']['recommendationp'] = [
+ 'exclude' => true,
+ 'inputType' => 'checkbox',
+ 'options' => ['create', 'delete'],
+ 'reference' => &$GLOBALS['TL_LANG']['MSC'],
+ 'eval' => ['multiple'=>true],
+ 'sql' => "blob NULL"
+];
diff --git a/src/Resources/contao/dca/tl_user_group.php b/contao/dca/tl_user_group.php
similarity index 50%
rename from src/Resources/contao/dca/tl_user_group.php
rename to contao/dca/tl_user_group.php
index 52071ad..0af419e 100644
--- a/src/Resources/contao/dca/tl_user_group.php
+++ b/contao/dca/tl_user_group.php
@@ -6,31 +6,29 @@
* (c) https://www.oveleon.de/
*/
+use Contao\CoreBundle\DataContainer\PaletteManipulator;
+
// Extend the default palette
-Contao\CoreBundle\DataContainer\PaletteManipulator::create()
- ->addLegend('recommendation_legend', 'amg_legend', Contao\CoreBundle\DataContainer\PaletteManipulator::POSITION_BEFORE)
- ->addField(array('recommendations', 'recommendationp'), 'recommendation_legend', Contao\CoreBundle\DataContainer\PaletteManipulator::POSITION_APPEND)
+PaletteManipulator::create()
+ ->addLegend('recommendation_legend', 'amg_legend', PaletteManipulator::POSITION_BEFORE)
+ ->addField(['recommendations', 'recommendationp'], 'recommendation_legend', PaletteManipulator::POSITION_APPEND)
->applyToPalette('default', 'tl_user_group')
;
// Add fields to tl_user_group
-$GLOBALS['TL_DCA']['tl_user_group']['fields']['recommendations'] = array
-(
- 'label' => &$GLOBALS['TL_LANG']['tl_user']['recommendations'],
+$GLOBALS['TL_DCA']['tl_user_group']['fields']['recommendations'] = [
'exclude' => true,
'inputType' => 'checkbox',
'foreignKey' => 'tl_recommendation_archive.title',
- 'eval' => array('multiple'=>true),
+ 'eval' => ['multiple'=>true],
'sql' => "blob NULL"
-);
+];
-$GLOBALS['TL_DCA']['tl_user_group']['fields']['recommendationp'] = array
-(
- 'label' => &$GLOBALS['TL_LANG']['tl_user']['recommendationp'],
+$GLOBALS['TL_DCA']['tl_user_group']['fields']['recommendationp'] = [
'exclude' => true,
'inputType' => 'checkbox',
- 'options' => array('create', 'delete'),
+ 'options' => ['create', 'delete'],
'reference' => &$GLOBALS['TL_LANG']['MSC'],
- 'eval' => array('multiple'=>true),
+ 'eval' => ['multiple'=>true],
'sql' => "blob NULL"
-);
+];
diff --git a/src/Resources/contao/languages/de/default.xlf b/contao/languages/de/default.xlf
similarity index 70%
rename from src/Resources/contao/languages/de/default.xlf
rename to contao/languages/de/default.xlf
index 1d7701f..97241b7 100644
--- a/src/Resources/contao/languages/de/default.xlf
+++ b/contao/languages/de/default.xlf
@@ -1,5 +1,5 @@
-
+
diff --git a/src/Resources/contao/languages/de/modules.xlf b/contao/languages/de/modules.xlf
similarity index 94%
rename from src/Resources/contao/languages/de/modules.xlf
rename to contao/languages/de/modules.xlf
index a187565..9b6d02e 100644
--- a/src/Resources/contao/languages/de/modules.xlf
+++ b/contao/languages/de/modules.xlf
@@ -1,5 +1,5 @@
-
+
diff --git a/src/Resources/contao/languages/de/tl_module.xlf b/contao/languages/de/tl_module.xlf
similarity index 98%
rename from src/Resources/contao/languages/de/tl_module.xlf
rename to contao/languages/de/tl_module.xlf
index 123da80..8fed375 100644
--- a/src/Resources/contao/languages/de/tl_module.xlf
+++ b/contao/languages/de/tl_module.xlf
@@ -1,5 +1,5 @@
-
+
diff --git a/src/Resources/contao/languages/de/tl_recommendation.xlf b/contao/languages/de/tl_recommendation.xlf
similarity index 99%
rename from src/Resources/contao/languages/de/tl_recommendation.xlf
rename to contao/languages/de/tl_recommendation.xlf
index db80856..f5b4311 100644
--- a/src/Resources/contao/languages/de/tl_recommendation.xlf
+++ b/contao/languages/de/tl_recommendation.xlf
@@ -1,5 +1,5 @@
-
+
diff --git a/src/Resources/contao/languages/de/tl_recommendation_archive.xlf b/contao/languages/de/tl_recommendation_archive.xlf
similarity index 97%
rename from src/Resources/contao/languages/de/tl_recommendation_archive.xlf
rename to contao/languages/de/tl_recommendation_archive.xlf
index 6647544..fee7720 100644
--- a/src/Resources/contao/languages/de/tl_recommendation_archive.xlf
+++ b/contao/languages/de/tl_recommendation_archive.xlf
@@ -1,5 +1,5 @@
-
+
diff --git a/src/Resources/contao/languages/de/tl_recommendation_list.xlf b/contao/languages/de/tl_recommendation_list.xlf
similarity index 94%
rename from src/Resources/contao/languages/de/tl_recommendation_list.xlf
rename to contao/languages/de/tl_recommendation_list.xlf
index 8cb36e9..4dcc15c 100644
--- a/src/Resources/contao/languages/de/tl_recommendation_list.xlf
+++ b/contao/languages/de/tl_recommendation_list.xlf
@@ -1,5 +1,5 @@
-
+
diff --git a/src/Resources/contao/languages/de/tl_recommendation_notification.xlf b/contao/languages/de/tl_recommendation_notification.xlf
similarity index 95%
rename from src/Resources/contao/languages/de/tl_recommendation_notification.xlf
rename to contao/languages/de/tl_recommendation_notification.xlf
index a1ba652..faafae8 100644
--- a/src/Resources/contao/languages/de/tl_recommendation_notification.xlf
+++ b/contao/languages/de/tl_recommendation_notification.xlf
@@ -1,5 +1,5 @@
-
+
diff --git a/src/Resources/contao/languages/de/tl_recommendation_settings.xlf b/contao/languages/de/tl_recommendation_settings.xlf
similarity index 89%
rename from src/Resources/contao/languages/de/tl_recommendation_settings.xlf
rename to contao/languages/de/tl_recommendation_settings.xlf
index 37347ab..cd147f0 100644
--- a/src/Resources/contao/languages/de/tl_recommendation_settings.xlf
+++ b/contao/languages/de/tl_recommendation_settings.xlf
@@ -1,5 +1,5 @@
-
+
diff --git a/src/Resources/contao/languages/de/tl_user.xlf b/contao/languages/de/tl_user.xlf
similarity index 89%
rename from src/Resources/contao/languages/de/tl_user.xlf
rename to contao/languages/de/tl_user.xlf
index e0bbd9b..305763a 100644
--- a/src/Resources/contao/languages/de/tl_user.xlf
+++ b/contao/languages/de/tl_user.xlf
@@ -1,5 +1,5 @@
-
+
diff --git a/contao/languages/de/tl_user_group.xlf b/contao/languages/de/tl_user_group.xlf
new file mode 100644
index 0000000..faf9fe6
--- /dev/null
+++ b/contao/languages/de/tl_user_group.xlf
@@ -0,0 +1,26 @@
+
+
+
+
+
+ Bewertungsrechte
+
+
+
+ Erlaubte Archive
+
+
+
+ Hier können Sie den Zugriff auf ein oder mehrere Bewertungs-Archive erlauben.
+
+
+
+ Archivrechte
+
+
+
+ Hier können Sie die Archivrechte festlegen.
+
+
+
+
diff --git a/src/Resources/contao/languages/en/default.xlf b/contao/languages/en/default.xlf
similarity index 68%
rename from src/Resources/contao/languages/en/default.xlf
rename to contao/languages/en/default.xlf
index 48abcdb..7244fee 100644
--- a/src/Resources/contao/languages/en/default.xlf
+++ b/contao/languages/en/default.xlf
@@ -1,5 +1,5 @@
-
+
diff --git a/src/Resources/contao/languages/en/modules.xlf b/contao/languages/en/modules.xlf
similarity index 93%
rename from src/Resources/contao/languages/en/modules.xlf
rename to contao/languages/en/modules.xlf
index 6002ff0..cb85905 100644
--- a/src/Resources/contao/languages/en/modules.xlf
+++ b/contao/languages/en/modules.xlf
@@ -1,5 +1,5 @@
-
+
diff --git a/src/Resources/contao/languages/en/tl_module.xlf b/contao/languages/en/tl_module.xlf
similarity index 98%
rename from src/Resources/contao/languages/en/tl_module.xlf
rename to contao/languages/en/tl_module.xlf
index a7e0744..45df350 100644
--- a/src/Resources/contao/languages/en/tl_module.xlf
+++ b/contao/languages/en/tl_module.xlf
@@ -1,5 +1,5 @@
-
+
diff --git a/src/Resources/contao/languages/en/tl_recommendation.xlf b/contao/languages/en/tl_recommendation.xlf
similarity index 98%
rename from src/Resources/contao/languages/en/tl_recommendation.xlf
rename to contao/languages/en/tl_recommendation.xlf
index 665104b..1073f30 100644
--- a/src/Resources/contao/languages/en/tl_recommendation.xlf
+++ b/contao/languages/en/tl_recommendation.xlf
@@ -1,5 +1,5 @@
-
+
diff --git a/src/Resources/contao/languages/en/tl_recommendation_archive.xlf b/contao/languages/en/tl_recommendation_archive.xlf
similarity index 96%
rename from src/Resources/contao/languages/en/tl_recommendation_archive.xlf
rename to contao/languages/en/tl_recommendation_archive.xlf
index 65cea85..d44fc23 100644
--- a/src/Resources/contao/languages/en/tl_recommendation_archive.xlf
+++ b/contao/languages/en/tl_recommendation_archive.xlf
@@ -1,5 +1,5 @@
-
+
diff --git a/src/Resources/contao/languages/en/tl_recommendation_list.xlf b/contao/languages/en/tl_recommendation_list.xlf
similarity index 93%
rename from src/Resources/contao/languages/en/tl_recommendation_list.xlf
rename to contao/languages/en/tl_recommendation_list.xlf
index c602cf1..7014289 100644
--- a/src/Resources/contao/languages/en/tl_recommendation_list.xlf
+++ b/contao/languages/en/tl_recommendation_list.xlf
@@ -1,5 +1,5 @@
-
+
diff --git a/src/Resources/contao/languages/en/tl_recommendation_notification.xlf b/contao/languages/en/tl_recommendation_notification.xlf
similarity index 93%
rename from src/Resources/contao/languages/en/tl_recommendation_notification.xlf
rename to contao/languages/en/tl_recommendation_notification.xlf
index 32535f5..dda2248 100644
--- a/src/Resources/contao/languages/en/tl_recommendation_notification.xlf
+++ b/contao/languages/en/tl_recommendation_notification.xlf
@@ -1,5 +1,5 @@
-
+
diff --git a/src/Resources/contao/languages/en/tl_recommendation_settings.xlf b/contao/languages/en/tl_recommendation_settings.xlf
similarity index 88%
rename from src/Resources/contao/languages/en/tl_recommendation_settings.xlf
rename to contao/languages/en/tl_recommendation_settings.xlf
index e4e3396..15c2e9a 100644
--- a/src/Resources/contao/languages/en/tl_recommendation_settings.xlf
+++ b/contao/languages/en/tl_recommendation_settings.xlf
@@ -1,5 +1,5 @@
-
+
diff --git a/src/Resources/contao/languages/en/tl_user.xlf b/contao/languages/en/tl_user.xlf
similarity index 88%
rename from src/Resources/contao/languages/en/tl_user.xlf
rename to contao/languages/en/tl_user.xlf
index 26da2b3..59e1c15 100644
--- a/src/Resources/contao/languages/en/tl_user.xlf
+++ b/contao/languages/en/tl_user.xlf
@@ -1,5 +1,5 @@
-
+
diff --git a/contao/languages/en/tl_user_group.xlf b/contao/languages/en/tl_user_group.xlf
new file mode 100644
index 0000000..aa0555d
--- /dev/null
+++ b/contao/languages/en/tl_user_group.xlf
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Resources/contao/models/RecommendationArchiveModel.php b/contao/models/RecommendationArchiveModel.php
similarity index 100%
rename from src/Resources/contao/models/RecommendationArchiveModel.php
rename to contao/models/RecommendationArchiveModel.php
diff --git a/src/Resources/contao/models/RecommendationModel.php b/contao/models/RecommendationModel.php
similarity index 97%
rename from src/Resources/contao/models/RecommendationModel.php
rename to contao/models/RecommendationModel.php
index 45f6ee0..9bcd114 100644
--- a/src/Resources/contao/models/RecommendationModel.php
+++ b/contao/models/RecommendationModel.php
@@ -133,7 +133,7 @@ public static function findPublishedByParentAndIdOrAlias($varId, $arrPids, array
}
$t = static::$strTable;
- $arrColumns = !is_numeric($varId) ? array("$t.alias=?") : array("$t.id=?");
+ $arrColumns = !is_numeric($varId) ? ["$t.alias=?"] : ["$t.id=?"];
$arrColumns[] = "$t.pid IN(" . implode(',', array_map('\intval', $arrPids)) . ") AND $t.verified='1'";
if (!static::isPreviewMode($arrOptions))
@@ -156,7 +156,7 @@ public static function findPublishedByParentAndIdOrAlias($varId, $arrPids, array
public static function findPublishedByPid($intPid, array $arrOptions=array())
{
$t = static::$strTable;
- $arrColumns = array("$t.pid=? AND $t.verified='1'");
+ $arrColumns = ["$t.pid=? AND $t.verified='1'"];
if (!static::isPreviewMode($arrOptions))
{
@@ -191,7 +191,7 @@ public static function findPublishedByPids($arrPids, $blnFeatured=null, $intLimi
}
$t = static::$strTable;
- $arrColumns = array("$t.pid IN(" . implode(',', array_map('\intval', $arrPids)) . ") AND $t.verified='1'");
+ $arrColumns = ["$t.pid IN(" . implode(',', array_map('\intval', $arrPids)) . ") AND $t.verified='1'"];
if ($blnFeatured === true)
{
@@ -241,7 +241,7 @@ public static function countPublishedByPids($arrPids, $blnFeatured=null, $minRat
}
$t = static::$strTable;
- $arrColumns = array("$t.pid IN(" . implode(',', array_map('\intval', $arrPids)) . ") AND $t.verified='1'");
+ $arrColumns = ["$t.pid IN(" . implode(',', array_map('\intval', $arrPids)) . ") AND $t.verified='1'"];
if ($blnFeatured === true)
{
diff --git a/src/Resources/contao/modules/ModuleRecommendation.php b/contao/modules/ModuleRecommendation.php
similarity index 97%
rename from src/Resources/contao/modules/ModuleRecommendation.php
rename to contao/modules/ModuleRecommendation.php
index d55781a..40cee75 100644
--- a/src/Resources/contao/modules/ModuleRecommendation.php
+++ b/contao/modules/ModuleRecommendation.php
@@ -48,7 +48,7 @@ protected function sortOutProtected($arrArchives)
$this->import(FrontendUser::class, 'User');
$objArchive = RecommendationArchiveModel::findMultipleByIds($arrArchives);
- $arrArchives = array();
+ $arrArchives = [];
if ($objArchive !== null)
{
@@ -181,7 +181,7 @@ protected function parseRecommendation($objRecommendation, $objRecommendationArc
if (System::getContainer()->has('fos_http_cache.http.symfony_response_tagger'))
{
$responseTagger = System::getContainer()->get('fos_http_cache.http.symfony_response_tagger');
- $responseTagger->addTags(array('contao.db.tl_recommendation.' . $objRecommendation->id));
+ $responseTagger->addTags(['contao.db.tl_recommendation.' . $objRecommendation->id]);
}
return $objTemplate->parse();
@@ -200,11 +200,11 @@ protected function parseRecommendations($objRecommendations)
if ($limit < 1)
{
- return array();
+ return [];
}
$count = 0;
- $arrRecommendations = array();
+ $arrRecommendations = [];
while ($objRecommendations->next())
{
@@ -233,13 +233,13 @@ protected function getMetaFields($objRecommendation)
if (!\is_array($meta))
{
- return array();
+ return [];
}
/** @var PageModel $objPage */
global $objPage;
- $return = array();
+ $return = [];
foreach ($meta as $field)
{
diff --git a/src/Resources/contao/modules/ModuleRecommendationForm.php b/contao/modules/ModuleRecommendationForm.php
similarity index 89%
rename from src/Resources/contao/modules/ModuleRecommendationForm.php
rename to contao/modules/ModuleRecommendationForm.php
index 4957d83..0308fab 100644
--- a/src/Resources/contao/modules/ModuleRecommendationForm.php
+++ b/contao/modules/ModuleRecommendationForm.php
@@ -98,70 +98,61 @@ protected function compile()
}
// Form fields
- $arrFields = array
- (
- 'author' => array
- (
+ $arrFields = [
+ 'author' => [
'name' => 'author',
'label' => $GLOBALS['TL_LANG']['tl_recommendation']['author'],
'inputType' => 'text',
- 'eval' => array('mandatory'=>true, 'maxlength'=>128)
- ),
- 'rating' => array
- (
+ 'eval' => ['mandatory'=>true, 'maxlength'=>128]
+ ],
+ 'rating' => [
'name' => 'rating',
'label' => $GLOBALS['TL_LANG']['tl_recommendation']['rating'],
'inputType' => 'select',
- 'options' => array(5,4,3,2,1),
- 'eval' => array('mandatory'=>true)
- ),
- 'title' => array
- (
+ 'options' => [5,4,3,2,1],
+ 'eval' => ['mandatory'=>true]
+ ],
+ 'title' => [
'name' => 'title',
'label' => $GLOBALS['TL_LANG']['tl_recommendation']['title'],
'inputType' => 'text',
- 'eval' => array('optional'=>true, 'maxlength'=>255),
- ),
- 'customField' => array
- (
+ 'eval' => ['optional'=>true, 'maxlength'=>255],
+ ],
+ 'customField' => [
'name' => 'customField',
'label' => $this->recommendation_customFieldLabel ?: $GLOBALS['TL_LANG']['tl_recommendation']['customFieldLabel'],
'inputType' => 'text',
- 'eval' => array('optional'=>true, 'maxlength'=>255),
- ),
- 'location' => array
- (
+ 'eval' => ['optional'=>true, 'maxlength'=>255],
+ ],
+ 'location' => [
'name' => 'location',
'label' => $GLOBALS['TL_LANG']['tl_recommendation']['location'],
'inputType' => 'text',
- 'eval' => array('optional'=>true, 'maxlength'=>128),
- ),
- 'text' => array
- (
+ 'eval' => ['optional'=>true, 'maxlength'=>128],
+ ],
+ 'text' => [
'name' => 'text',
'label' => $GLOBALS['TL_LANG']['tl_recommendation']['text'],
'inputType' => 'textarea',
- 'eval' => array('mandatory'=>true, 'rows'=>4, 'cols'=>40)
- ),
- 'email' => array
- (
+ 'eval' => ['mandatory'=>true, 'rows'=>4, 'cols'=>40]
+ ],
+ 'email' => [
'name' => 'email',
'label' => $GLOBALS['TL_LANG']['tl_recommendation']['email'],
'inputType' => 'text',
- 'eval' => array('optional'=>true, 'maxlength'=>255, 'rgxp'=>'email', 'decodeEntities'=>true),
- ),
- );
+ 'eval' => ['optional'=>true, 'maxlength'=>255, 'rgxp'=>'email', 'decodeEntities'=>true],
+ ],
+ ];
// Captcha
if (!$this->recommendation_disableCaptcha == true)
{
- $arrFields['captcha'] = array
- (
+ $arrFields['captcha'] = [
'name' => 'captcha',
'label' => $GLOBALS['TL_LANG']['MSC']['securityQuestion'],
'inputType' => 'captcha',
- 'eval' => array('mandatory'=>true)
- );
+ 'eval' => ['mandatory'=>true]
+ ];
}
// Set e-mail as mandatory and non-optional if comments should be validated via activation mail
@@ -174,17 +165,16 @@ protected function compile()
// Set an opt-in checkbox when privacy text is given
if ($this->recommendation_privacyText)
{
- $arrFields['privacy'] = array
- (
+ $arrFields['privacy'] = [
'name' => 'privacy',
'inputType' => 'checkbox',
- 'options' => array(1=>$this->recommendation_privacyText),
- 'eval' => array('mandatory'=>true)
- );
+ 'options' => [1=>$this->recommendation_privacyText],
+ 'eval' => ['mandatory'=>true]
+ ];
}
$doNotSubmit = false;
- $arrWidgets = array();
+ $arrWidgets = [];
$strFormId = 'recommendation_' . $this->id;
// Optional recommendation form fields
@@ -255,7 +245,7 @@ protected function compile()
// Do not parse any tags in the recommendation
$strText = StringUtil::specialchars(trim($arrWidgets['text']->value));
- $strText = str_replace(array('&', '<', '>'), array('[&]', '[lt]', '[gt]'), $strText);
+ $strText = str_replace(['&', '<', '>'], ['[&]', '[lt]', '[gt]'], $strText);
// Remove multiple line feeds
$strText = preg_replace('@\n\n+@', "\n\n", $strText);
@@ -383,7 +373,7 @@ protected function sendNotificationMail($objRecommendation)
// Convert the recommendation to plain text
$strText = strip_tags($strText);
$strText = StringUtil::decodeEntities($strText);
- $strText = str_replace(array('[&]', '[lt]', '[gt]'), array('&', '<', '>'), $strText);
+ $strText = str_replace(['[&]', '[lt]', '[gt]'], ['&', '<', '>'], $strText);
// Add the recommendation details
$objEmail->text = sprintf(
@@ -415,7 +405,7 @@ protected function sendVerificationMail($arrData, $id)
{
/** @var OptIn $optIn */
$optIn = System::getContainer()->get('contao.opt-in');
- $optInToken = $optIn->create('rec', $arrData['email'], array('tl_recommendation'=>array($id)));
+ $optInToken = $optIn->create('rec', $arrData['email'], ['tl_recommendation'=> [$id]]);
// Prepare the simple token data
$arrTokenData = $arrData;
@@ -455,7 +445,7 @@ protected function verifyRecommendation()
return;
}
- $arrRecommendations = array();
+ $arrRecommendations = [];
foreach ($arrIds as $intId)
{
@@ -492,7 +482,7 @@ protected function verifyRecommendation()
// Log activity
$logger = System::getContainer()->get('monolog.logger.contao');
- $logger->log(LogLevel::INFO, 'Recommendation ID ' . $objRecommendation->id . ' (' . Idna::decodeEmail($objRecommendation->email) . ') has been verified', array('contao' => new ContaoContext(__METHOD__, TL_ACCESS)));
+ $logger->log(LogLevel::INFO, 'Recommendation ID ' . $objRecommendation->id . ' (' . Idna::decodeEmail($objRecommendation->email) . ') has been verified', ['contao' => new ContaoContext(__METHOD__, TL_ACCESS)]);
// Redirect to the jumpTo page
if (($objTarget = $this->objModel->getRelated('recommendation_activateJumpTo')) instanceof PageModel)
diff --git a/src/Resources/contao/modules/ModuleRecommendationList.php b/contao/modules/ModuleRecommendationList.php
similarity index 98%
rename from src/Resources/contao/modules/ModuleRecommendationList.php
rename to contao/modules/ModuleRecommendationList.php
index b414791..5fd1155 100644
--- a/src/Resources/contao/modules/ModuleRecommendationList.php
+++ b/contao/modules/ModuleRecommendationList.php
@@ -114,7 +114,7 @@ protected function compile()
$blnFeatured = null;
}
- $this->Template->recommendations = array();
+ $this->Template->recommendations = [];
$this->Template->empty = $GLOBALS['TL_LANG']['MSC']['emptyRecommendationList'];
// Get the total number of items
@@ -257,6 +257,6 @@ protected function fetchItems($recommendationArchives, $blnFeatured, $limit, $of
$order .= "$t.date DESC";
}
- return RecommendationModel::findPublishedByPids($recommendationArchives, $blnFeatured, $limit, $offset, $minRating, array('order'=>$order));
+ return RecommendationModel::findPublishedByPids($recommendationArchives, $blnFeatured, $limit, $offset, $minRating, ['order'=>$order]);
}
}
diff --git a/src/Resources/contao/modules/ModuleRecommendationReader.php b/contao/modules/ModuleRecommendationReader.php
similarity index 100%
rename from src/Resources/contao/modules/ModuleRecommendationReader.php
rename to contao/modules/ModuleRecommendationReader.php
diff --git a/src/Resources/contao/templates/modules/mod_recommendationform.html5 b/contao/templates/modules/mod_recommendationform.html5
similarity index 100%
rename from src/Resources/contao/templates/modules/mod_recommendationform.html5
rename to contao/templates/modules/mod_recommendationform.html5
diff --git a/src/Resources/contao/templates/modules/mod_recommendationlist.html5 b/contao/templates/modules/mod_recommendationlist.html5
similarity index 100%
rename from src/Resources/contao/templates/modules/mod_recommendationlist.html5
rename to contao/templates/modules/mod_recommendationlist.html5
diff --git a/src/Resources/contao/templates/modules/mod_recommendationreader.html5 b/contao/templates/modules/mod_recommendationreader.html5
similarity index 100%
rename from src/Resources/contao/templates/modules/mod_recommendationreader.html5
rename to contao/templates/modules/mod_recommendationreader.html5
diff --git a/src/Resources/contao/templates/recommendation/recommendation_default.html5 b/contao/templates/recommendation/recommendation_default.html5
similarity index 100%
rename from src/Resources/contao/templates/recommendation/recommendation_default.html5
rename to contao/templates/recommendation/recommendation_default.html5
diff --git a/src/Resources/contao/templates/recommendation/recommendation_full.html5 b/contao/templates/recommendation/recommendation_full.html5
similarity index 100%
rename from src/Resources/contao/templates/recommendation/recommendation_full.html5
rename to contao/templates/recommendation/recommendation_full.html5
diff --git a/src/Resources/contao/templates/recommendation/recommendation_latest.html5 b/contao/templates/recommendation/recommendation_latest.html5
similarity index 100%
rename from src/Resources/contao/templates/recommendation/recommendation_latest.html5
rename to contao/templates/recommendation/recommendation_latest.html5
diff --git a/src/ContaoManager/Plugin.php b/src/ContaoManager/Plugin.php
index ba93dbd..f7c583c 100644
--- a/src/ContaoManager/Plugin.php
+++ b/src/ContaoManager/Plugin.php
@@ -26,12 +26,12 @@ class Plugin implements BundlePluginInterface
/**
* {@inheritdoc}
*/
- public function getBundles(ParserInterface $parser)
+ public function getBundles(ParserInterface $parser): array
{
return [
BundleConfig::create(ContaoRecommendationBundle::class)
+ ->setReplace(['recommendation'])
->setLoadAfter([ContaoCoreBundle::class])
- ->setReplace(['recommendation']),
];
}
}
diff --git a/src/ContaoRecommendationBundle.php b/src/ContaoRecommendationBundle.php
index 462578f..065b109 100644
--- a/src/ContaoRecommendationBundle.php
+++ b/src/ContaoRecommendationBundle.php
@@ -17,4 +17,8 @@
*/
class ContaoRecommendationBundle extends Bundle
{
+ public function getPath(): string
+ {
+ return \dirname(__DIR__);
+ }
}
diff --git a/src/Resources/contao/dca/tl_recommendation_settings.php b/src/Resources/contao/dca/tl_recommendation_settings.php
deleted file mode 100644
index 6c81a7c..0000000
--- a/src/Resources/contao/dca/tl_recommendation_settings.php
+++ /dev/null
@@ -1,41 +0,0 @@
- array
- (
- 'dataContainer' => 'File',
- 'closed' => true
- ),
-
- // Palettes
- 'palettes' => array
- (
- 'default' => '{recommendation_legend},recommendationDefaultImage,recommendationActiveColor;'
- ),
-
- // Fields
- 'fields' => array
- (
- 'recommendationDefaultImage' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation_settings']['recommendationDefaultImage'],
- 'inputType' => 'fileTree',
- 'eval' => array('fieldType'=>'radio', 'filesOnly'=>true, 'isGallery'=>true, 'extensions'=>Contao\Config::get('validImageTypes'), 'tl_class'=>'clr')
- ),
- 'recommendationActiveColor' => array
- (
- 'label' => &$GLOBALS['TL_LANG']['tl_recommendation_settings']['recommendationActiveColor'],
- 'inputType' => 'text',
- 'eval' => array('maxlength'=>6, 'multiple'=>true, 'size'=>1, 'colorpicker'=>true, 'isHexColor'=>true, 'decodeEntities'=>true, 'tl_class'=>'w50 wizard'),
- )
- )
-);
diff --git a/src/Resources/contao/dca/tl_user.php b/src/Resources/contao/dca/tl_user.php
deleted file mode 100644
index 88907c4..0000000
--- a/src/Resources/contao/dca/tl_user.php
+++ /dev/null
@@ -1,37 +0,0 @@
-addLegend('recommendation_legend', 'amg_legend', Contao\CoreBundle\DataContainer\PaletteManipulator::POSITION_BEFORE)
- ->addField(array('recommendations', 'recommendationp'), 'recommendation_legend', Contao\CoreBundle\DataContainer\PaletteManipulator::POSITION_APPEND)
- ->applyToPalette('extend', 'tl_user')
- ->applyToPalette('custom', 'tl_user')
-;
-
-// Add fields to tl_user_group
-$GLOBALS['TL_DCA']['tl_user']['fields']['recommendations'] = array
-(
- 'label' => &$GLOBALS['TL_LANG']['tl_user']['recommendations'],
- 'exclude' => true,
- 'inputType' => 'checkbox',
- 'foreignKey' => 'tl_recommendation_archive.title',
- 'eval' => array('multiple'=>true),
- 'sql' => "blob NULL"
-);
-
-$GLOBALS['TL_DCA']['tl_user']['fields']['recommendationp'] = array
-(
- 'label' => &$GLOBALS['TL_LANG']['tl_user']['recommendationp'],
- 'exclude' => true,
- 'inputType' => 'checkbox',
- 'options' => array('create', 'delete'),
- 'reference' => &$GLOBALS['TL_LANG']['MSC'],
- 'eval' => array('multiple'=>true),
- 'sql' => "blob NULL"
-);
diff --git a/src/Resources/contao/languages/de/tl_user_group.xlf b/src/Resources/contao/languages/de/tl_user_group.xlf
deleted file mode 100644
index a2d719b..0000000
--- a/src/Resources/contao/languages/de/tl_user_group.xlf
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
- Bewertungsrechte
-
-
-
-
diff --git a/src/Resources/contao/languages/en/tl_user_group.xlf b/src/Resources/contao/languages/en/tl_user_group.xlf
deleted file mode 100644
index e79a5e2..0000000
--- a/src/Resources/contao/languages/en/tl_user_group.xlf
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
From 3c91ed1d29e1076fe0b7b84a0b5f8c486e27e18a Mon Sep 17 00:00:00 2001
From: Sebastian Zoglowek <55794780+zoglo@users.noreply.github.com>
Date: Wed, 31 May 2023 16:40:22 +0200
Subject: [PATCH 03/19] Prepare DataContainerListener for recommendations and
archive
---
contao/dca/tl_recommendation.php | 475 +-----------------
contao/dca/tl_recommendation_archive.php | 25 +-
.../de/tl_recommendation_archive.xlf | 2 +-
.../en/tl_recommendation_archive.xlf | 2 +-
contao/modules/ModuleRecommendationReader.php | 2 +-
src/ContaoRecommendationPermissions.php | 12 +
.../DataContainer/DataContainerListener.php | 209 ++++++++
7 files changed, 256 insertions(+), 471 deletions(-)
create mode 100644 src/ContaoRecommendationPermissions.php
create mode 100644 src/EventListener/DataContainer/DataContainerListener.php
diff --git a/contao/dca/tl_recommendation.php b/contao/dca/tl_recommendation.php
index 4a47eda..0937f76 100644
--- a/contao/dca/tl_recommendation.php
+++ b/contao/dca/tl_recommendation.php
@@ -6,17 +6,20 @@
* (c) https://www.oveleon.de/
*/
+use Contao\DataContainer;
+use Contao\DC_Table;
+use Oveleon\ContaoRecommendationBundle\EventListener\DataContainer\DataContainerListener;
use Oveleon\ContaoRecommendationBundle\RecommendationArchiveModel;
$GLOBALS['TL_DCA']['tl_recommendation'] = [
// Config
'config' => [
- 'dataContainer' => 'Table',
+ 'dataContainer' => DC_Table::class,
'ptable' => 'tl_recommendation_archive',
'switchToEdit' => true,
'enableVersioning' => true,
'onload_callback' => [
- ['tl_recommendation', 'checkPermission'],
+ [DataContainerListener::class, 'checkRecommendationPermission'],
['tl_recommendation', 'generateSitemap']
],
'oncut_callback' => [
@@ -26,7 +29,7 @@
['tl_recommendation', 'scheduleUpdate']
],
'onsubmit_callback' => [
- ['tl_recommendation', 'adjustTime'],
+ [DataContainerListener::class, 'adjustTime'],
['tl_recommendation', 'scheduleUpdate']
],
'oninvalidate_cache_tags_callback' => [
@@ -44,7 +47,7 @@
// List
'list' => [
'sorting' => [
- 'mode' => 4,
+ 'mode' => DataContainer::MODE_PARENT,
'fields' => ['date DESC'],
'headerFields' => ['title', 'jumpTo', 'tstamp', 'protected'],
'panelLayout' => 'filter;sort,search,limit',
@@ -77,14 +80,13 @@
'attributes' => 'onclick="if(!confirm(\'' . ($GLOBALS['TL_LANG']['MSC']['deleteConfirm'] ?? null) . '\'))return false;Backend.getScrollOffset()"'
],
'toggle' => [
+ 'href' => 'act=toggle&field=published',
'icon' => 'visible.svg',
- 'attributes' => 'onclick="Backend.getScrollOffset();return AjaxRequest.toggleVisibility(this,%s)"',
- 'button_callback' => ['tl_recommendation', 'toggleIcon']
+ 'showInHeader' => true
],
'feature' => [
+ 'href' => 'act=toggle&field=featured',
'icon' => 'featured.svg',
- 'attributes' => 'onclick="Backend.getScrollOffset();return AjaxRequest.toggleFeatured(this,%s)"',
- 'button_callback' => ['tl_recommendation', 'iconFeatured']
],
'show' => [
'href' => 'act=show',
@@ -115,7 +117,7 @@
'exclude' => true,
'search' => true,
'sorting' => true,
- 'flag' => 1,
+ 'flag' => DataContainer::SORT_INITIAL_LETTER_ASC,
'inputType' => 'text',
'eval' => ['maxlength'=>255, 'tl_class'=>'w50 clr'],
'sql' => "varchar(255) NOT NULL default ''"
@@ -126,7 +128,7 @@
'inputType' => 'text',
'eval' => ['rgxp'=>'alias', 'doNotCopy'=>true, 'unique'=>true, 'maxlength'=>128, 'tl_class'=>'w50'],
'save_callback' => [
- ['tl_recommendation', 'generateAlias']
+ [DataContainerListener::class, 'generateRecommendationAlias']
],
'sql' => "varchar(255) BINARY NOT NULL default ''"
],
@@ -134,7 +136,7 @@
'exclude' => true,
'search' => true,
'sorting' => true,
- 'flag' => 1,
+ 'flag' => DataContainer::SORT_INITIAL_LETTER_ASC,
'inputType' => 'text',
'eval' => ['doNotCopy'=>true, 'mandatory'=>true, 'maxlength'=>128, 'tl_class'=>'w50'],
'sql' => "varchar(128) NOT NULL default ''"
@@ -150,7 +152,7 @@
'exclude' => true,
'search' => true,
'sorting' => true,
- 'flag' => 1,
+ 'flag' => DataContainer::SORT_INITIAL_LETTER_ASC,
'inputType' => 'text',
'eval' => ['doNotCopy'=>true, 'maxlength'=>128, 'tl_class'=>'w50'],
'sql' => "varchar(128) NOT NULL default ''"
@@ -160,11 +162,11 @@
'exclude' => true,
'filter' => true,
'sorting' => true,
- 'flag' => 8,
+ 'flag' => DataContainer::SORT_MONTH_DESC,
'inputType' => 'text',
'eval' => ['rgxp'=>'date', 'mandatory'=>true, 'doNotCopy'=>true, 'datepicker'=>true, 'tl_class'=>'w50 wizard'],
'load_callback' => [
- ['tl_recommendation', 'loadDate']
+ [DataContainerListener::class, 'loadDate']
],
'sql' => "int(10) unsigned NOT NULL default 0"
],
@@ -174,7 +176,7 @@
'inputType' => 'text',
'eval' => ['rgxp'=>'time', 'mandatory'=>true, 'doNotCopy'=>true, 'tl_class'=>'w50'],
'load_callback' => [
- ['tl_recommendation', 'loadTime']
+ [DataContainerListener::class, 'loadTime']
],
'sql' => "int(10) unsigned NOT NULL default 0"
],
@@ -237,7 +239,7 @@
'published' => [
'exclude' => true,
'filter' => true,
- 'flag' => 1,
+ 'flag' => DataContainer::SORT_INITIAL_LETTER_ASC,
'inputType' => 'checkbox',
'eval' => ['doNotCopy'=>true],
'sql' => "char(1) NOT NULL default ''"
@@ -273,191 +275,6 @@ public function __construct()
$this->import('Contao\BackendUser', 'User');
}
- /**
- * Check permissions to edit table tl_recommendation
- *
- * @throws Contao\CoreBundle\Exception\AccessDeniedException
- */
- public function checkPermission()
- {
- if ($this->User->isAdmin)
- {
- return;
- }
-
- // Set the root IDs
- if (empty($this->User->recommendations) || !is_array($this->User->recommendations))
- {
- $root = [0];
- }
- else
- {
- $root = $this->User->recommendations;
- }
-
- $id = strlen(Contao\Input::get('id')) ? Contao\Input::get('id') : CURRENT_ID;
-
- // Check current action
- switch (Contao\Input::get('act'))
- {
- case 'paste':
- case 'select':
- if (!in_array(CURRENT_ID, $root))
- {
- throw new Contao\CoreBundle\Exception\AccessDeniedException('Not enough permissions to access recommendation archive ID ' . $id . '.');
- }
- break;
-
- case 'create':
- if (!Contao\Input::get('pid') || !in_array(Contao\Input::get('pid'), $root))
- {
- throw new Contao\CoreBundle\Exception\AccessDeniedException('Not enough permissions to create recommendation item in recommendation archive ID ' . Input::get('pid') . '.');
- }
- break;
-
- case 'cut':
- case 'copy':
- if (Contao\Input::get('act') == 'cut' && Contao\Input::get('mode') == 1)
- {
- $objArchive = $this->Database->prepare("SELECT pid FROM tl_recommendation WHERE id=?")
- ->limit(1)
- ->execute(Contao\Input::get('pid'));
-
- if ($objArchive->numRows < 1)
- {
- throw new Contao\CoreBundle\Exception\AccessDeniedException('Invalid recommendation item ID ' . Contao\Input::get('pid') . '.');
- }
-
- $pid = $objArchive->pid;
- }
- else
- {
- $pid = Input::get('pid');
- }
-
- if (!in_array($pid, $root))
- {
- throw new Contao\CoreBundle\Exception\AccessDeniedException('Not enough permissions to ' . Contao\Input::get('act') . ' recommendation item ID ' . $id . ' to recommendation archive ID ' . $pid . '.');
- }
- // no break
-
- case 'edit':
- case 'show':
- case 'delete':
- case 'toggle':
- case 'feature':
- $objArchive = $this->Database->prepare("SELECT pid FROM tl_recommendation WHERE id=?")
- ->limit(1)
- ->execute($id);
-
- if ($objArchive->numRows < 1)
- {
- throw new Contao\CoreBundle\Exception\AccessDeniedException('Invalid recommendation item ID ' . $id . '.');
- }
-
- if (!in_array($objArchive->pid, $root))
- {
- throw new Contao\CoreBundle\Exception\AccessDeniedException('Not enough permissions to ' . Contao\Input::get('act') . ' recommendation item ID ' . $id . ' of recommendation archive ID ' . $objArchive->pid . '.');
- }
- break;
-
- case 'editAll':
- case 'deleteAll':
- case 'overrideAll':
- case 'cutAll':
- case 'copyAll':
- if (!in_array($id, $root))
- {
- throw new Contao\CoreBundle\Exception\AccessDeniedException('Not enough permissions to access recommendation archive ID ' . $id . '.');
- }
-
- $objArchive = $this->Database->prepare("SELECT id FROM tl_recommendation WHERE pid=?")
- ->execute($id);
-
- /** @var Symfony\Component\HttpFoundation\Session\SessionInterface $objSession */
- $objSession = Contao\System::getContainer()->get('session');
-
- $session = $objSession->all();
- $session['CURRENT']['IDS'] = array_intersect((array) $session['CURRENT']['IDS'], $objArchive->fetchEach('id'));
- $objSession->replace($session);
- break;
-
- default:
- if (Contao\Input::get('act'))
- {
- throw new Contao\CoreBundle\Exception\AccessDeniedException('Invalid command "' . Contao\Input::get('act') . '".');
- }
-
- if (!in_array($id, $root))
- {
- throw new Contao\CoreBundle\Exception\AccessDeniedException('Not enough permissions to access recommendation archive ID ' . $id . '.');
- }
- break;
- }
- }
-
- /**
- * Auto-generate the recommendation alias if it has not been set yet
- *
- * @param mixed $varValue
- * @param Contao\DataContainer $dc
- *
- * @return string
- *
- * @throws Exception
- */
- public function generateAlias($varValue, Contao\DataContainer $dc)
- {
- $autoAlias = false;
-
- // Generate alias if title is set
- if ($varValue == '' && !empty($dc->activeRecord->title))
- {
- $autoAlias = true;
- $varValue = Contao\StringUtil::generateAlias($dc->activeRecord->title);
- }
-
- $objAlias = $this->Database->prepare("SELECT id FROM tl_recommendation WHERE alias=? AND alias!='' AND id!=?")
- ->execute($varValue, $dc->id);
-
- // Check whether the recommendation alias exists
- if ($objAlias->numRows)
- {
- if (!$autoAlias)
- {
- throw new Exception(sprintf($GLOBALS['TL_LANG']['ERR']['aliasExists'], $varValue));
- }
-
- $varValue .= '-' . $dc->id;
- }
-
- return $varValue;
- }
-
- /**
- * Set the timestamp to 00:00:00
- *
- * @param integer $value
- *
- * @return integer
- */
- public function loadDate($value)
- {
- return strtotime(date('Y-m-d', $value) . ' 00:00:00');
- }
-
- /**
- * Set the timestamp to 1970-01-01
- *
- * @param integer $value
- *
- * @return integer
- */
- public function loadTime($value)
- {
- return strtotime('1970-01-01 ' . date('H:i:s', $value));
- }
-
/**
* List a recommendation record
*
@@ -475,25 +292,6 @@ public function listRecommendations($arrRow)
return '' . $arrRow['author'] . ' [' . Date::parse(Config::get('datimFormat'), $arrRow['date']) . ']
';
}
- /**
- * Adjust start end end time of the event based on date, span, startTime and endTime
- *
- * @param Contao\DataContainer $dc
- */
- public function adjustTime(Contao\DataContainer $dc)
- {
- // Return if there is no active record (override all)
- if (!$dc->activeRecord)
- {
- return;
- }
-
- $arrSet['date'] = strtotime(date('Y-m-d', $dc->activeRecord->date) . ' tl_recommendation.php' . date('H:i:s', $dc->activeRecord->time));
- $arrSet['time'] = $arrSet['date'];
-
- $this->Database->prepare("UPDATE tl_recommendation %s WHERE id=?")->set($arrSet)->execute($dc->id);
- }
-
/**
* Check for modified recommendation and update the XML files if necessary
*/
@@ -542,243 +340,6 @@ public function scheduleUpdate(Contao\DataContainer $dc)
$objSession->set('recommendation_updater', array_unique($session));
}
- /**
- * Return the "feature/unfeature element" button
- *
- * @param array $row
- * @param string $href
- * @param string $label
- * @param string $title
- * @param string $icon
- * @param string $attributes
- *
- * @return string
- */
- public function iconFeatured($row, $href, $label, $title, $icon, $attributes)
- {
- if (strlen(Contao\Input::get('fid')))
- {
- $this->toggleFeatured(Contao\Input::get('fid'), (Input::get('state') == 1), (@func_get_arg(12) ?: null));
- $this->redirect($this->getReferer());
- }
-
- // Check permissions AFTER checking the fid, so hacking attempts are logged
- if (!$this->User->hasAccess('tl_recommendation::featured', 'alexf'))
- {
- return '';
- }
-
- $href .= '&fid='.$row['id'].'&state='.($row['featured'] ? '' : 1);
-
- if (!$row['featured'])
- {
- $icon = 'featured_.svg';
- }
-
- return ''.Contao\Image::getHtml($icon, $label, 'data-state="' . ($row['featured'] ? 1 : 0) . '"').' ';
- }
-
- /**
- * Feature/unfeature a recommendation
- *
- * @param integer $intId
- * @param boolean $blnVisible
- * @param Contao\DataContainer $dc
- *
- * @throws Contao\CoreBundle\Exception\AccessDeniedException
- */
- public function toggleFeatured($intId, $blnVisible, Contao\DataContainer $dc=null)
- {
- // Check permissions to edit
- Contao\Input::setGet('id', $intId);
- Contao\Input::setGet('act', 'feature');
- $this->checkPermission();
-
- // Check permissions to feature
- if (!$this->User->hasAccess('tl_recommendation::featured', 'alexf'))
- {
- throw new Contao\CoreBundle\Exception\AccessDeniedException('Not enough permissions to feature/unfeature recommendation ID ' . $intId . '.');
- }
-
- $objVersions = new Contao\Versions('tl_recommendation', $intId);
- $objVersions->initialize();
-
- // Trigger the save_callback
- if (is_array($GLOBALS['TL_DCA']['tl_recommendation']['fields']['featured']['save_callback'] ?? null))
- {
- foreach ($GLOBALS['TL_DCA']['tl_recommendation']['fields']['featured']['save_callback'] as $callback)
- {
- if (is_array($callback))
- {
- $this->import($callback[0]);
- $blnVisible = $this->{$callback[0]}->{$callback[1]}($blnVisible, $dc);
- }
- elseif (is_callable($callback))
- {
- $blnVisible = $callback($blnVisible, $this);
- }
- }
- }
-
- // Update the database
- $this->Database->prepare("UPDATE tl_recommendation SET tstamp=". time() .", featured='" . ($blnVisible ? 1 : '') . "' WHERE id=?")
- ->execute($intId);
-
- $objVersions->create();
-
- if ($dc)
- {
- $dc->invalidateCacheTags();
- }
- }
-
- /**
- * Return the "toggle visibility" button
- *
- * @param array $row
- * @param string $href
- * @param string $label
- * @param string $title
- * @param string $icon
- * @param string $attributes
- *
- * @return string
- */
- public function toggleIcon($row, $href, $label, $title, $icon, $attributes)
- {
- if (strlen(Input::get('tid')))
- {
- $this->toggleVisibility(Contao\Input::get('tid'), (Contao\Input::get('state') == 1), (func_num_args() <= 12 ? null : func_get_arg(12)));
- $this->redirect($this->getReferer());
- }
-
- // Check permissions AFTER checking the tid, so hacking attempts are logged
- if (!$this->User->hasAccess('tl_recommendation::published', 'alexf'))
- {
- return '';
- }
-
- $href .= '&tid=' . $row['id'] . '&state=' . ($row['published'] ? '' : 1);
-
- if (!$row['published'])
- {
- $icon = 'invisible.svg';
- }
-
- return '' . Image::getHtml($icon, $label, 'data-state="' . ($row['published'] ? 1 : 0) . '"') . ' ';
- }
-
- /**
- * Disable/enable a recommendation
- *
- * @param integer $intId
- * @param boolean $blnVisible
- * @param Contao\DataContainer $dc
- */
- public function toggleVisibility($intId, $blnVisible, Contao\DataContainer $dc=null)
- {
- // Set the ID and action
- Contao\Input::setGet('id', $intId);
- Contao\Input::setGet('act', 'toggle');
-
- if ($dc)
- {
- $dc->id = $intId;
- }
-
- // Trigger the onload_callback
- if (is_array($GLOBALS['TL_DCA']['tl_recommendation']['config']['onload_callback'] ?? null))
- {
- foreach ($GLOBALS['TL_DCA']['tl_recommendation']['config']['onload_callback'] as $callback)
- {
- if (is_array($callback))
- {
- $this->import($callback[0]);
- $this->{$callback[0]}->{$callback[1]}($dc);
- }
- elseif (is_callable($callback))
- {
- $callback($dc);
- }
- }
- }
-
- // Check the field access
- if (!$this->User->hasAccess('tl_recommendation::published', 'alexf'))
- {
- throw new Contao\CoreBundle\Exception\AccessDeniedException('Not enough permissions to publish/unpublish recommendation ID ' . $intId . '.');
- }
-
- // Set the current record
- if ($dc)
- {
- $objRow = $this->Database->prepare("SELECT * FROM tl_recommendation WHERE id=?")
- ->limit(1)
- ->execute($intId);
-
- if ($objRow->numRows)
- {
- $dc->activeRecord = $objRow;
- }
- }
-
- $objVersions = new Contao\Versions('tl_recommendation', $intId);
- $objVersions->initialize();
-
- // Trigger the save_callback
- if (is_array($GLOBALS['TL_DCA']['tl_recommendation']['fields']['published']['save_callback'] ?? null))
- {
- foreach ($GLOBALS['TL_DCA']['tl_recommendation']['fields']['published']['save_callback'] as $callback)
- {
- if (is_array($callback))
- {
- $this->import($callback[0]);
- $blnVisible = $this->{$callback[0]}->{$callback[1]}($blnVisible, $dc);
- }
- elseif (is_callable($callback))
- {
- $blnVisible = $callback($blnVisible, $dc);
- }
- }
- }
-
- $time = time();
-
- // Update the database
- $this->Database->prepare("UPDATE tl_recommendation SET tstamp=$time, published='" . ($blnVisible ? '1' : '') . "' WHERE id=?")
- ->execute($intId);
-
- if ($dc)
- {
- $dc->activeRecord->tstamp = $time;
- $dc->activeRecord->published = ($blnVisible ? '1' : '');
- }
-
- // Trigger the onsubmit_callback
- if (is_array($GLOBALS['TL_DCA']['tl_recommendation']['config']['onsubmit_callback'] ?? null))
- {
- foreach ($GLOBALS['TL_DCA']['tl_recommendation']['config']['onsubmit_callback'] as $callback)
- {
- if (is_array($callback))
- {
- $this->import($callback[0]);
- $this->{$callback[0]}->{$callback[1]}($dc);
- }
- elseif (is_callable($callback))
- {
- $callback($dc);
- }
- }
- }
-
- $objVersions->create();
-
- if ($dc)
- {
- $dc->invalidateCacheTags();
- }
- }
-
/**
* @param Contao\DataContainer $dc
*
diff --git a/contao/dca/tl_recommendation_archive.php b/contao/dca/tl_recommendation_archive.php
index 066517e..b0ffa0d 100644
--- a/contao/dca/tl_recommendation_archive.php
+++ b/contao/dca/tl_recommendation_archive.php
@@ -6,10 +6,14 @@
* (c) https://www.oveleon.de/
*/
+use Contao\DataContainer;
+use Contao\DC_Table;
+use Contao\PageModel;
+
$GLOBALS['TL_DCA']['tl_recommendation_archive'] = [
// Config
'config' => [
- 'dataContainer' => 'Table',
+ 'dataContainer' => DC_Table::class,
'ctable' => ['tl_recommendation'],
'switchToEdit' => true,
'enableVersioning' => true,
@@ -35,9 +39,9 @@
// List
'list' => [
'sorting' => [
- 'mode' => 1,
+ 'mode' => DataContainer::MODE_SORTED,
'fields' => ['title'],
- 'flag' => 1,
+ 'flag' => DataContainer::SORT_INITIAL_LETTER_ASC,
'panelLayout' => 'filter;search,limit'
],
'label' => [
@@ -58,25 +62,25 @@
]
],
'operations' => [
- 'edit' => [
- 'href' => 'table=tl_recommendation',
- 'icon' => 'edit.svg'
- ],
'editheader' => [
'href' => 'act=edit',
'icon' => 'header.svg',
- 'button_callback' => ['tl_recommendation_archive', 'editHeader']
+ //'button_callback' => ['tl_recommendation_archive', 'editHeader']
+ ],
+ 'edit' => [
+ 'href' => 'table=tl_recommendation',
+ 'icon' => 'edit.svg'
],
'copy' => [
'href' => 'act=copy',
'icon' => 'copy.svg',
- 'button_callback' => ['tl_recommendation_archive', 'copyArchive']
+ //'button_callback' => ['tl_recommendation_archive', 'copyArchive']
],
'delete' => [
'href' => 'act=delete',
'icon' => 'delete.svg',
'attributes' => 'onclick="if(!confirm(\'' . ($GLOBALS['TL_LANG']['MSC']['deleteConfirm'] ?? null) . '\'))return false;Backend.getScrollOffset()"',
- 'button_callback' => ['tl_recommendation_archive', 'deleteArchive']
+ //'button_callback' => ['tl_recommendation_archive', 'deleteArchive']
],
'show' => [
'href' => 'act=show',
@@ -144,7 +148,6 @@
*/
class tl_recommendation_archive extends Contao\Backend
{
-
/**
* Import the back end user object
*/
diff --git a/contao/languages/de/tl_recommendation_archive.xlf b/contao/languages/de/tl_recommendation_archive.xlf
index fee7720..dade3fa 100644
--- a/contao/languages/de/tl_recommendation_archive.xlf
+++ b/contao/languages/de/tl_recommendation_archive.xlf
@@ -6,7 +6,7 @@
Titel
-
+
Bitte geben Sie den Archiv-Titel ein.
diff --git a/contao/languages/en/tl_recommendation_archive.xlf b/contao/languages/en/tl_recommendation_archive.xlf
index d44fc23..966798d 100644
--- a/contao/languages/en/tl_recommendation_archive.xlf
+++ b/contao/languages/en/tl_recommendation_archive.xlf
@@ -5,7 +5,7 @@
-
+
diff --git a/contao/modules/ModuleRecommendationReader.php b/contao/modules/ModuleRecommendationReader.php
index 465d6db..e534e78 100644
--- a/contao/modules/ModuleRecommendationReader.php
+++ b/contao/modules/ModuleRecommendationReader.php
@@ -85,7 +85,7 @@ protected function compile()
$this->Template->referer = 'javascript:history.go(-1)';
$this->Template->back = $GLOBALS['TL_LANG']['MSC']['goBack'];
- // Get the news item
+ // Get the recommendation item
$objRecommendation = RecommendationModel::findPublishedByParentAndIdOrAlias(Input::get('items'), $this->recommendation_archives);
if (null === $objRecommendation)
diff --git a/src/ContaoRecommendationPermissions.php b/src/ContaoRecommendationPermissions.php
new file mode 100644
index 0000000..6d2aa2f
--- /dev/null
+++ b/src/ContaoRecommendationPermissions.php
@@ -0,0 +1,12 @@
+activeRecord)
+ {
+ return;
+ }
+
+ $arrSet['date'] = strtotime(date('Y-m-d', $dc->activeRecord->date) . ' ' . date('H:i:s', $dc->activeRecord->time));
+ $arrSet['time'] = $arrSet['date'];
+
+ $db = Database::getInstance();
+ $db->prepare("UPDATE tl_recommendation %s WHERE id=?")->set($arrSet)->execute($dc->id);
+ }
+
+ /**
+ * @throws Exception
+ */
+ public function generateRecommendationAlias($varValue, DataContainer $dc)
+ {
+ $db = Database::getInstance();
+
+ $aliasExists = function (string $alias) use ($dc, $db): bool
+ {
+ return $db->prepare("SELECT id FROM tl_recommendation WHERE alias=? AND id!=?")->execute($alias, $dc->id)->numRows > 0;
+ };
+
+ // Generate alias if there is none
+ if (!$varValue)
+ {
+ $varValue = System::getContainer()->get('contao.slug')->generate($dc->activeRecord->title, RecommendationArchiveModel::findByPk($dc->activeRecord->pid)->jumpTo, $aliasExists);
+ }
+ elseif (preg_match('/^[1-9]\d*$/', $varValue))
+ {
+ throw new Exception(sprintf($GLOBALS['TL_LANG']['ERR']['aliasNumeric'], $varValue));
+ }
+ elseif ($aliasExists($varValue))
+ {
+ throw new Exception(sprintf($GLOBALS['TL_LANG']['ERR']['aliasExists'], $varValue));
+ }
+
+ return $varValue;
+
+ }
+
+ public function checkRecommendationPermission(DataContainer $dc)
+ {
+ $objUser = Controller::getContainer()->get('security.helper')->getUser();
+
+ if ($objUser->isAdmin)
+ {
+ return;
+ }
+
+ // Set the root IDs
+ if (empty($objUser->recommendations) || !is_array($objUser->recommendations))
+ {
+ $root = [0];
+ }
+ else
+ {
+ $root = $objUser->recommendations;
+ }
+
+ $id = strlen(Input::get('id')) ? Input::get('id') : $dc->currentPid;
+ $db = Database::getInstance();
+
+ // Check current action
+ switch (Input::get('act'))
+ {
+ case 'paste':
+ case 'select':
+ // Check currentPid here (see #247)
+ if (!in_array($dc->currentPid, $root))
+ {
+ throw new AccessDeniedException('Not enough permissions to access recommendation archive ID ' . $id . '.');
+ }
+ break;
+
+ case 'create':
+ if (!Input::get('pid') || !in_array(Input::get('pid'), $root))
+ {
+ throw new AccessDeniedException('Not enough permissions to create recommendation items in recommendation archive ID ' . Input::get('pid') . '.');
+ }
+ break;
+
+ case 'cut':
+ case 'copy':
+ if (Input::get('act') == 'cut' && Input::get('mode') == 1)
+ {
+ $objArchive = $db->prepare("SELECT pid FROM tl_recommendation WHERE id=?")
+ ->limit(1)
+ ->execute(Input::get('pid'));
+
+ if ($objArchive->numRows < 1)
+ {
+ throw new AccessDeniedException('Invalid recommendation item ID ' . Input::get('pid') . '.');
+ }
+
+ $pid = $objArchive->pid;
+ }
+ else
+ {
+ $pid = Input::get('pid');
+ }
+
+ if (!in_array($pid, $root))
+ {
+ throw new AccessDeniedException('Not enough permissions to ' . Input::get('act') . ' recommendation item ID ' . $id . ' to recommendation archive ID ' . $pid . '.');
+ }
+ // no break
+
+ case 'edit':
+ case 'show':
+ case 'delete':
+ case 'toggle':
+ $objArchive = $db->prepare("SELECT pid FROM tl_recommendation WHERE id=?")
+ ->limit(1)
+ ->execute($id);
+
+ if ($objArchive->numRows < 1)
+ {
+ throw new AccessDeniedException('Invalid recommendation item ID ' . $id . '.');
+ }
+
+ if (!in_array($objArchive->pid, $root))
+ {
+ throw new AccessDeniedException('Not enough permissions to ' . Input::get('act') . ' recommendation item ID ' . $id . ' of recommendation archive ID ' . $objArchive->pid . '.');
+ }
+ break;
+
+ case 'editAll':
+ case 'deleteAll':
+ case 'overrideAll':
+ case 'cutAll':
+ case 'copyAll':
+ if (!in_array($id, $root))
+ {
+ throw new AccessDeniedException('Not enough permissions to access recommendation archive ID ' . $id . '.');
+ }
+
+ $objArchive = $db->prepare("SELECT id FROM tl_recommendation WHERE pid=?")
+ ->execute($id);
+
+ $objSession = System::getContainer()->get('request_stack')->getSession();
+
+ $session = $objSession->all();
+ $session['CURRENT']['IDS'] = array_intersect((array) $session['CURRENT']['IDS'], $objArchive->fetchEach('id'));
+ $objSession->replace($session);
+ break;
+
+ default:
+ if (Input::get('act'))
+ {
+ throw new AccessDeniedException('Invalid command "' . Input::get('act') . '".');
+ }
+
+ if (!in_array($id, $root))
+ {
+ throw new AccessDeniedException('Not enough permissions to access recommendation archive ID ' . $id . '.');
+ }
+ break;
+ }
+ }
+}
From 2298b438e6fef04eb72dd98a3b4f2e68ced41486 Mon Sep 17 00:00:00 2001
From: Sebastian Zoglowek <55794780+zoglo@users.noreply.github.com>
Date: Wed, 31 May 2023 17:05:14 +0200
Subject: [PATCH 04/19] Register DataContainerListener
---
config/services.yaml | 9 +++++++++
.../ContaoRecommendationExtension.php | 20 +++++++++++++++++++
2 files changed, 29 insertions(+)
create mode 100644 config/services.yaml
create mode 100644 src/DependencyInjection/ContaoRecommendationExtension.php
diff --git a/config/services.yaml b/config/services.yaml
new file mode 100644
index 0000000..e31ca06
--- /dev/null
+++ b/config/services.yaml
@@ -0,0 +1,9 @@
+services:
+ _defaults:
+ autowire: true
+ autoconfigure: true
+ public: true
+
+ Oveleon\ContaoRecommendationBundle\:
+ resource: '../src/'
+ exclude: '../src/{Model,DependencyInjection,Resources}'
diff --git a/src/DependencyInjection/ContaoRecommendationExtension.php b/src/DependencyInjection/ContaoRecommendationExtension.php
new file mode 100644
index 0000000..947e245
--- /dev/null
+++ b/src/DependencyInjection/ContaoRecommendationExtension.php
@@ -0,0 +1,20 @@
+load('services.yaml');
+ }
+}
From b21dc22dbf0499f952cbe76bd12a094119553368 Mon Sep 17 00:00:00 2001
From: Sebastian Zoglowek <55794780+zoglo@users.noreply.github.com>
Date: Wed, 31 May 2023 17:05:30 +0200
Subject: [PATCH 05/19] Add featured and publish toggle
---
contao/dca/tl_recommendation.php | 2 ++
1 file changed, 2 insertions(+)
diff --git a/contao/dca/tl_recommendation.php b/contao/dca/tl_recommendation.php
index 0937f76..5f67a63 100644
--- a/contao/dca/tl_recommendation.php
+++ b/contao/dca/tl_recommendation.php
@@ -226,6 +226,7 @@
],
'featured' => [
'exclude' => true,
+ 'toggle' => true,
'filter' => true,
'inputType' => 'checkbox',
'eval' => ['tl_class'=>'w50 m12'],
@@ -238,6 +239,7 @@
],
'published' => [
'exclude' => true,
+ 'toggle' => true,
'filter' => true,
'flag' => DataContainer::SORT_INITIAL_LETTER_ASC,
'inputType' => 'checkbox',
From 69194b033cf6b9859cd963f7c4c23bb6e88fd168 Mon Sep 17 00:00:00 2001
From: Sebastian Zoglowek <55794780+zoglo@users.noreply.github.com>
Date: Wed, 31 May 2023 22:37:11 +0200
Subject: [PATCH 06/19] Rewrite DataContainer listeners
---
.../RecommendationArchiveListener.php | 151 ++++++++++++++++++
...istener.php => RecommendationListener.php} | 85 +++++++++-
2 files changed, 231 insertions(+), 5 deletions(-)
create mode 100644 src/EventListener/DataContainer/RecommendationArchiveListener.php
rename src/EventListener/DataContainer/{DataContainerListener.php => RecommendationListener.php} (71%)
diff --git a/src/EventListener/DataContainer/RecommendationArchiveListener.php b/src/EventListener/DataContainer/RecommendationArchiveListener.php
new file mode 100644
index 0000000..f511a84
--- /dev/null
+++ b/src/EventListener/DataContainer/RecommendationArchiveListener.php
@@ -0,0 +1,151 @@
+get('security.helper')->isGranted(ContaoCorePermissions::USER_CAN_EDIT_FIELDS_OF_TABLE, 'tl_recommendation_archive') ? '' . Image::getHtml($icon, $label) . ' ' : Image::getHtml(preg_replace('/\.svg$/i', '_.svg', $icon)) . ' ';
+ }
+
+ /**
+ * Return the copy archive button
+ */
+ public function copyArchive(array $row, string $href, string $label, string $title, string $icon, string $attributes): string
+ {
+ return System::getContainer()->get('security.helper')->isGranted(ContaoRecommendationPermissions::USER_CAN_CREATE_ARCHIVES) ? '' . Image::getHtml($icon, $label) . ' ' : Image::getHtml(preg_replace('/\.svg$/i', '_.svg', $icon)) . ' ';
+ }
+
+ /**
+ * Return the delete archive button
+ */
+ public function deleteArchive(array $row, string $href, string $label, string $title, string $icon, string $attributes): string
+ {
+ return System::getContainer()->get('security.helper')->isGranted(ContaoRecommendationPermissions::USER_CAN_DELETE_ARCHIVES) ? '' . Image::getHtml($icon, $label) . ' ' : Image::getHtml(preg_replace('/\.svg$/i', '_.svg', $icon)) . ' ';
+ }
+
+ /**
+ * Add the new archive to the permissions
+ */
+ public function adjustPermissions(int|string $insertId): void
+ {
+ // The oncreate_callback passes $insertId as second argument
+ if (func_num_args() == 4)
+ {
+ $insertId = func_get_arg(1);
+ }
+
+ $objUser = Controller::getContainer()->get('security.helper')->getUser();
+
+ if ($objUser->isAdmin)
+ {
+ return;
+ }
+
+ // Set root IDs
+ if (empty($objUser->recommendations) || !is_array($objUser->recommendations))
+ {
+ $root = [0];
+ }
+ else
+ {
+ $root = $objUser->recommendations;
+ }
+
+ // The archive is enabled already
+ if (in_array($insertId, $root))
+ {
+ return;
+ }
+
+ /** @var AttributeBagInterface $objSessionBag */
+ $objSessionBag = System::getContainer()->get('request_stack')->getSession()->getBag('contao_backend');
+
+ $arrNew = $objSessionBag->get('new_records');
+
+ if (is_array($arrNew['tl_recommendation_archive']) && in_array($insertId, $arrNew['tl_recommendation_archive']))
+ {
+ $db = Database::getInstance();
+
+ // Add the permissions on group level
+ if ($objUser->inherit != 'custom')
+ {
+ $objGroup = $db->execute("SELECT id, recommendations, recommendationp FROM tl_user_group WHERE id IN(" . implode(',', array_map('\intval', $objUser->groups)) . ")");
+
+ while ($objGroup->next())
+ {
+ $arrRecommendationp = StringUtil::deserialize($objGroup->recommendationp);
+
+ if (is_array($arrRecommendationp) && in_array('create', $arrRecommendationp))
+ {
+ $arrRecommendations = StringUtil::deserialize($objGroup->recommendations, true);
+ $arrRecommendations[] = $insertId;
+
+ $db->prepare("UPDATE tl_user_group SET recommendations=? WHERE id=?")
+ ->execute(serialize($arrRecommendations), $objGroup->id);
+ }
+ }
+ }
+
+ // Add the permissions on user level
+ if ($objUser->inherit != 'group')
+ {
+ $objUser = $db->prepare("SELECT recommendations, recommendationp FROM tl_user WHERE id=?")
+ ->limit(1)
+ ->execute($objUser->id);
+
+ $arrRecommendationp = StringUtil::deserialize($objUser->recommendationp);
+
+ if (is_array($arrRecommendationp) && in_array('create', $arrRecommendationp))
+ {
+ $arrRecommendations = StringUtil::deserialize($objUser->recommendations, true);
+ $arrRecommendations[] = $insertId;
+
+ $db->prepare("UPDATE tl_user SET recommendations=? WHERE id=?")
+ ->execute(serialize($arrRecommendations), $objUser->id);
+ }
+ }
+
+ // Add the new element to the user object
+ $root[] = $insertId;
+ $objUser->recommendations = $root;
+ }
+ }
+
+ public function addSitemapCacheInvalidationTag(DataContainer $dc, array $tags): array
+ {
+ $pageModel = PageModel::findWithDetails($dc->activeRecord->jumpTo);
+
+ if ($pageModel === null)
+ {
+ return $tags;
+ }
+
+ return array_merge($tags, ['contao.sitemap.' . $pageModel->rootId]);
+ }
+}
diff --git a/src/EventListener/DataContainer/DataContainerListener.php b/src/EventListener/DataContainer/RecommendationListener.php
similarity index 71%
rename from src/EventListener/DataContainer/DataContainerListener.php
rename to src/EventListener/DataContainer/RecommendationListener.php
index 1b051a2..0e7f98b 100644
--- a/src/EventListener/DataContainer/DataContainerListener.php
+++ b/src/EventListener/DataContainer/RecommendationListener.php
@@ -2,19 +2,24 @@
namespace Oveleon\ContaoRecommendationBundle\EventListener\DataContainer;
+use Contao\Automator;
+use Contao\Config;
use Contao\Controller;
use Contao\CoreBundle\Exception\AccessDeniedException;
use Contao\CoreBundle\Framework\ContaoFramework;
use Contao\Database;
use Contao\DataContainer;
+use Contao\Date;
use Contao\Input;
+use Contao\PageModel;
use Contao\System;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Exception;
use Oveleon\ContaoRecommendationBundle\RecommendationArchiveModel;
+use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Security\Core\Security;
-class DataContainerListener
+class RecommendationListener
{
public function __construct(
protected ContaoFramework $framework,
@@ -40,9 +45,8 @@ public function loadTime(int $value): bool|int
/**
* Adjust start and end time of the event based on date, span, startTime and endTime
- * @throws Exception
*/
- public function adjustTime(DataContainer $dc)
+ public function adjustTime(DataContainer $dc): void
{
// Return if there is no active record (override all)
if (!$dc->activeRecord)
@@ -84,7 +88,6 @@ public function generateRecommendationAlias($varValue, DataContainer $dc)
}
return $varValue;
-
}
public function checkRecommendationPermission(DataContainer $dc)
@@ -114,7 +117,7 @@ public function checkRecommendationPermission(DataContainer $dc)
{
case 'paste':
case 'select':
- // Check currentPid here (see #247)
+ // Check currentPid
if (!in_array($dc->currentPid, $root))
{
throw new AccessDeniedException('Not enough permissions to access recommendation archive ID ' . $id . '.');
@@ -206,4 +209,76 @@ public function checkRecommendationPermission(DataContainer $dc)
break;
}
}
+
+ /**
+ * List a recommendation record
+ */
+ public function listRecommendations(array $arrRow): string
+ {
+ if(!$arrRow['verified'])
+ {
+ return '' . $arrRow['author'] . ' [' . ($GLOBALS['TL_LANG']['tl_recommendation']['notVerified'] ?? null) . ']
';
+ }
+
+ return '' . $arrRow['author'] . ' [' . Date::parse(Config::get('datimFormat'), $arrRow['date']) . ']
';
+ }
+
+ /**
+ * Check for modified recommendation and update the XML files if necessary
+ */
+ public function generateSitemap(): void
+ {
+ /** @var SessionInterface $objSession */
+ $objSession = System::getContainer()->get('session');
+
+ $session = $objSession->get('recommendation_updater');
+
+ if (empty($session) || !is_array($session))
+ {
+ return;
+ }
+
+ $automator = new Automator();
+ $automator->generateSitemap();
+
+ $objSession->set('recommendation_updater', null);
+ }
+
+ /**
+ * Schedule a recommendation update
+ *
+ * This method is triggered when a single recommendation or multiple recommendations
+ * are modified (edit/editAll), moved (cut/cutAll) or deleted (delete/deleteAll).
+ * Since duplicated items are unpublished by default, it is not necessary to
+ * schedule updates on copyAll as well.
+ */
+ public function scheduleUpdate(DataContainer $dc): void
+ {
+ // Return if there is no ID
+ if (!$dc->activeRecord || !$dc->activeRecord->pid || Input::get('act') == 'copy')
+ {
+ return;
+ }
+
+ /** @var SessionInterface $objSession */
+ $objSession = System::getContainer()->get('session');
+
+ // Store the ID in the session
+ $session = $objSession->get('recommendation_updater');
+ $session[] = $dc->activeRecord->pid;
+ $objSession->set('recommendation_updater', array_unique($session));
+ }
+
+ public function addSitemapCacheInvalidationTag(DataContainer $dc, array $tags): array
+ {
+ $archiveModel = RecommendationArchiveModel::findByPk($dc->activeRecord->pid);
+ $pageModel = PageModel::findWithDetails($archiveModel->jumpTo);
+
+ if ($pageModel === null)
+ {
+ return $tags;
+ }
+
+ return array_merge($tags, ['contao.sitemap.' . $pageModel->rootId]);
+ }
}
From 8fce6564bb9a06e4ab7b5ed2864afe13151fd7d9 Mon Sep 17 00:00:00 2001
From: Sebastian Zoglowek <55794780+zoglo@users.noreply.github.com>
Date: Wed, 31 May 2023 22:37:52 +0200
Subject: [PATCH 07/19] Register Cron and SitemapListener
---
contao/config/config.php | 32 +++----
src/Cron/PurgeRecommendationsCron.php | 38 ++++++++
src/EventListener/SitemapListener.php | 126 ++++++++++++++++++++++++++
3 files changed, 177 insertions(+), 19 deletions(-)
create mode 100644 src/Cron/PurgeRecommendationsCron.php
create mode 100644 src/EventListener/SitemapListener.php
diff --git a/contao/config/config.php b/contao/config/config.php
index a69b991..94433de 100644
--- a/contao/config/config.php
+++ b/contao/config/config.php
@@ -3,22 +3,22 @@
declare(strict_types=1);
use Contao\ArrayUtil;
+use Oveleon\ContaoRecommendationBundle\ModuleRecommendationForm;
+use Oveleon\ContaoRecommendationBundle\ModuleRecommendationList;
+use Oveleon\ContaoRecommendationBundle\ModuleRecommendationReader;
+use Oveleon\ContaoRecommendationBundle\RecommendationArchiveModel;
+use Oveleon\ContaoRecommendationBundle\RecommendationModel;
// Back end modules
ArrayUtil::arrayInsert($GLOBALS['BE_MOD']['content'], 5, [
'recommendation' => [
- 'tables' => [
- 'tl_recommendation_archive',
- 'tl_recommendation'
- ]
+ 'tables' => ['tl_recommendation_archive', 'tl_recommendation']
]
]);
ArrayUtil::arrayInsert($GLOBALS['BE_MOD']['system'], 3, [
'recommendation_settings' => [
- 'tables' => [
- 'tl_recommendation_settings'
- ],
+ 'tables' => ['tl_recommendation_settings'],
'hideInNavigation' => true
]
]);
@@ -26,22 +26,16 @@
// Front end modules
ArrayUtil::arrayInsert($GLOBALS['FE_MOD'], 2, [
'recommendation' => [
- 'recommendationlist' => 'Oveleon\ContaoRecommendationBundle\ModuleRecommendationList',
- 'recommendationreader' => 'Oveleon\ContaoRecommendationBundle\ModuleRecommendationReader',
- 'recommendationform' => 'Oveleon\ContaoRecommendationBundle\ModuleRecommendationForm',
+ 'recommendationform' => ModuleRecommendationForm::class,
+ 'recommendationlist' => ModuleRecommendationList::class,
+ 'recommendationreader' => ModuleRecommendationReader::class
]
]);
-// Models
-$GLOBALS['TL_MODELS']['tl_recommendation'] = 'Oveleon\ContaoRecommendationBundle\RecommendationModel';
-$GLOBALS['TL_MODELS']['tl_recommendation_archive'] = 'Oveleon\ContaoRecommendationBundle\RecommendationArchiveModel';
-
// Add permissions
$GLOBALS['TL_PERMISSIONS'][] = 'recommendations';
$GLOBALS['TL_PERMISSIONS'][] = 'recommendationp';
-// Cron jobs
-$GLOBALS['TL_CRON']['daily']['purgeRecommendations'] = ['Oveleon\ContaoRecommendationBundle\Recommendation', 'purgeRecommendations'];
-
-// Register hooks
-$GLOBALS['TL_HOOKS']['getSearchablePages'][] = ['Oveleon\ContaoRecommendationBundle\Recommendation', 'getSearchablePages'];
+// Models
+$GLOBALS['TL_MODELS']['tl_recommendation'] = RecommendationModel::class;
+$GLOBALS['TL_MODELS']['tl_recommendation_archive'] = RecommendationArchiveModel::class;
diff --git a/src/Cron/PurgeRecommendationsCron.php b/src/Cron/PurgeRecommendationsCron.php
new file mode 100644
index 0000000..a04fd3f
--- /dev/null
+++ b/src/Cron/PurgeRecommendationsCron.php
@@ -0,0 +1,38 @@
+framework->initialize();
+
+ $recommendations = $this->framework->getAdapter(RecommendationModel::class)->findExpiredRecommendations();
+
+ if (null === $recommendations)
+ {
+ return;
+ }
+
+ /** @var RecommendationModel $recommendation */
+ foreach ($recommendations as $recommendation)
+ {
+ $recommendation->delete();
+ }
+
+ $this->logger?->info('Purged the unactivated recommendations');
+ }
+}
diff --git a/src/EventListener/SitemapListener.php b/src/EventListener/SitemapListener.php
new file mode 100644
index 0000000..6fd311b
--- /dev/null
+++ b/src/EventListener/SitemapListener.php
@@ -0,0 +1,126 @@
+framework->createInstance(Database::class)->getChildRecords($event->getRootPageIds(), 'tl_page');
+
+ // Early return here in the unlikely case that there are no pages
+ if (empty($arrRoot))
+ {
+ return;
+ }
+
+ $arrPages = [];
+ $time = time();
+
+ // Get all recommendation archives
+ $objArchives = $this->framework->getAdapter(RecommendationArchiveModel::class)->findByProtected('');
+
+ if (null === $objArchives)
+ {
+ return;
+ }
+
+ // Walk through each recommendation archive
+ foreach ($objArchives as $objArchive)
+ {
+ // Skip recommendation archives without target page
+ if (!$objArchive->jumpTo)
+ {
+ continue;
+ }
+
+ // Skip recommendation archives outside the root nodes
+ if (!\in_array($objArchive->jumpTo, $arrRoot, true))
+ {
+ continue;
+ }
+
+ $objParent = $this->framework->getAdapter(PageModel::class)->findWithDetails($objArchive->jumpTo);
+
+ // The target page does not exist
+ if (null === $objParent)
+ {
+ continue;
+ }
+
+ // The target page has not been published
+ if (!$objParent->published || ($objParent->start && $objParent->start > $time) || ($objParent->stop && $objParent->stop <= $time))
+ {
+ continue;
+ }
+
+ // The target page is protected
+ if ($objParent->protected)
+ {
+ continue;
+ }
+
+ // The target page is exempt from the sitemap
+ if ('noindex,nofollow' === $objParent->robots)
+ {
+ continue;
+ }
+
+ // Get the items
+ $objRecommendations = $this->framework->getAdapter(RecommendationModel::class)->findPublishedByPid($objArchive->id);
+
+ if (null === $objRecommendations)
+ {
+ continue;
+ }
+
+ foreach ($objRecommendations as $objRecommendation)
+ {
+ $arrPages[] = $objParent->getAbsoluteUrl('/' . ($objRecommendation->alias ?: $objRecommendation->id));
+ }
+ }
+
+ foreach ($arrPages as $strUrl)
+ {
+ $this->addUrlToDefaultUrlSet($strUrl, $event);
+ }
+ }
+
+ private function addUrlToDefaultUrlSet(string $url, $event): self
+ {
+ $sitemap = $event->getDocument();
+ $urlSet = $sitemap->getElementsByTagNameNS('https://www.sitemaps.org/schemas/sitemap/0.9', 'urlset')->item(0);
+
+ if (null === $urlSet)
+ {
+ return $this;
+ }
+
+ $loc = $sitemap->createElement('loc', $url);
+ $urlEl = $sitemap->createElement('url');
+ $urlEl->appendChild($loc);
+ $urlSet->appendChild($urlEl);
+
+ $sitemap->appendChild($urlSet);
+
+ return $this;
+ }
+}
From 4d58250445c33b7d52fabbbffcb653d1f09d5db0 Mon Sep 17 00:00:00 2001
From: Sebastian Zoglowek <55794780+zoglo@users.noreply.github.com>
Date: Wed, 31 May 2023 22:38:41 +0200
Subject: [PATCH 08/19] Update DCAs
---
contao/dca/tl_module.php | 22 +-
contao/dca/tl_recommendation.php | 125 +---------
contao/dca/tl_recommendation_archive.php | 279 +----------------------
3 files changed, 23 insertions(+), 403 deletions(-)
diff --git a/contao/dca/tl_module.php b/contao/dca/tl_module.php
index ef4df7f..cbc5f86 100644
--- a/contao/dca/tl_module.php
+++ b/contao/dca/tl_module.php
@@ -7,6 +7,7 @@
*/
use Contao\System;
+use Contao\Controller;
System::loadLanguageFile('tl_recommendation');
System::loadLanguageFile('tl_recommendation_notification');
@@ -174,15 +175,8 @@
'sql' => "varchar(64) NOT NULL default ''"
];
-
-/**
- * Provide miscellaneous methods that are used by the data configuration array.
- *
- * @author Fabian Ekert
- */
class tl_module_recommendation extends Contao\Backend
{
-
/**
* Import the back end user object
*/
@@ -194,10 +188,8 @@ public function __construct()
/**
* Get all recommendation archives and return them as array
- *
- * @return array
*/
- public function getRecommendationArchives()
+ public function getRecommendationArchives(): array
{
if (!$this->User->isAdmin && !is_array($this->User->recommendations))
{
@@ -220,10 +212,8 @@ public function getRecommendationArchives()
/**
* Get all recommendation reader modules and return them as array
- *
- * @return array
*/
- public function getReaderModules()
+ public function getReaderModules(): array
{
$arrModules = [];
$objModules = $this->Database->execute("SELECT m.id, m.name, t.name AS theme FROM tl_module m LEFT JOIN tl_theme t ON m.pid=t.id WHERE m.type='recommendationreader' ORDER BY t.name, m.name");
@@ -238,12 +228,8 @@ public function getReaderModules()
/**
* Load the default recommendation activation text
- *
- * @param mixed $varValue
- *
- * @return mixed
*/
- public function getRecommendationActivationDefault($varValue)
+ public function getRecommendationActivationDefault(mixed $varValue): mixed
{
if (trim($varValue) === '')
{
diff --git a/contao/dca/tl_recommendation.php b/contao/dca/tl_recommendation.php
index 5f67a63..28f655b 100644
--- a/contao/dca/tl_recommendation.php
+++ b/contao/dca/tl_recommendation.php
@@ -8,8 +8,7 @@
use Contao\DataContainer;
use Contao\DC_Table;
-use Oveleon\ContaoRecommendationBundle\EventListener\DataContainer\DataContainerListener;
-use Oveleon\ContaoRecommendationBundle\RecommendationArchiveModel;
+use Oveleon\ContaoRecommendationBundle\EventListener\DataContainer\RecommendationListener;
$GLOBALS['TL_DCA']['tl_recommendation'] = [
// Config
@@ -19,21 +18,21 @@
'switchToEdit' => true,
'enableVersioning' => true,
'onload_callback' => [
- [DataContainerListener::class, 'checkRecommendationPermission'],
- ['tl_recommendation', 'generateSitemap']
+ [RecommendationListener::class, 'checkRecommendationPermission'],
+ [RecommendationListener::class, 'generateSitemap']
],
'oncut_callback' => [
- ['tl_recommendation', 'scheduleUpdate']
+ [RecommendationListener::class, 'scheduleUpdate']
],
'ondelete_callback' => [
- ['tl_recommendation', 'scheduleUpdate']
+ [RecommendationListener::class, 'scheduleUpdate']
],
'onsubmit_callback' => [
- [DataContainerListener::class, 'adjustTime'],
- ['tl_recommendation', 'scheduleUpdate']
+ [RecommendationListener::class, 'adjustTime'],
+ [RecommendationListener::class, 'scheduleUpdate']
],
'oninvalidate_cache_tags_callback' => [
- ['tl_recommendation', 'addSitemapCacheInvalidationTag'],
+ [RecommendationListener::class, 'addSitemapCacheInvalidationTag'],
],
'sql' => [
'keys' => [
@@ -51,7 +50,7 @@
'fields' => ['date DESC'],
'headerFields' => ['title', 'jumpTo', 'tstamp', 'protected'],
'panelLayout' => 'filter;sort,search,limit',
- 'child_record_callback' => ['tl_recommendation', 'listRecommendations'],
+ 'child_record_callback' => [RecommendationListener::class, 'listRecommendations'],
'child_record_class' => 'no_padding'
],
'global_operations' => [
@@ -128,7 +127,7 @@
'inputType' => 'text',
'eval' => ['rgxp'=>'alias', 'doNotCopy'=>true, 'unique'=>true, 'maxlength'=>128, 'tl_class'=>'w50'],
'save_callback' => [
- [DataContainerListener::class, 'generateRecommendationAlias']
+ [RecommendationListener::class, 'generateRecommendationAlias']
],
'sql' => "varchar(255) BINARY NOT NULL default ''"
],
@@ -166,7 +165,7 @@
'inputType' => 'text',
'eval' => ['rgxp'=>'date', 'mandatory'=>true, 'doNotCopy'=>true, 'datepicker'=>true, 'tl_class'=>'w50 wizard'],
'load_callback' => [
- [DataContainerListener::class, 'loadDate']
+ [RecommendationListener::class, 'loadDate']
],
'sql' => "int(10) unsigned NOT NULL default 0"
],
@@ -176,7 +175,7 @@
'inputType' => 'text',
'eval' => ['rgxp'=>'time', 'mandatory'=>true, 'doNotCopy'=>true, 'tl_class'=>'w50'],
'load_callback' => [
- [DataContainerListener::class, 'loadTime']
+ [RecommendationListener::class, 'loadTime']
],
'sql' => "int(10) unsigned NOT NULL default 0"
],
@@ -260,103 +259,3 @@
]
]
];
-
-/**
- * Provide miscellaneous methods that are used by the data configuration array.
- *
- * @author Fabian Ekert
- */
-class tl_recommendation extends Contao\Backend
-{
- /**
- * Import the back end user object
- */
- public function __construct()
- {
- parent::__construct();
- $this->import('Contao\BackendUser', 'User');
- }
-
- /**
- * List a recommendation record
- *
- * @param array $arrRow
- *
- * @return string
- */
- public function listRecommendations($arrRow)
- {
- if(!$arrRow['verified'])
- {
- return '' . $arrRow['author'] . ' [' . $GLOBALS['TL_LANG']['tl_recommendation']['notVerified'] . ']
';
- }
-
- return '' . $arrRow['author'] . ' [' . Date::parse(Config::get('datimFormat'), $arrRow['date']) . ']
';
- }
-
- /**
- * Check for modified recommendation and update the XML files if necessary
- */
- public function generateSitemap()
- {
- /** @var Symfony\Component\HttpFoundation\Session\SessionInterface $objSession */
- $objSession = Contao\System::getContainer()->get('session');
-
- $session = $objSession->get('recommendation_updater');
-
- if (empty($session) || !is_array($session))
- {
- return;
- }
-
- $this->import('Contao\Automator', 'Automator');
- $this->Automator->generateSitemap();
-
- $objSession->set('recommendation_updater', null);
- }
-
- /**
- * Schedule a recommendation update
- *
- * This method is triggered when a single recommendation or multiple recommendations
- * are modified (edit/editAll), moved (cut/cutAll) or deleted (delete/deleteAll).
- * Since duplicated items are unpublished by default, it is not necessary to
- * schedule updates on copyAll as well.
- *
- * @param Contao\DataContainer $dc
- */
- public function scheduleUpdate(Contao\DataContainer $dc)
- {
- // Return if there is no ID
- if (!$dc->activeRecord || !$dc->activeRecord->pid || Contao\Input::get('act') == 'copy')
- {
- return;
- }
-
- /** @var Symfony\Component\HttpFoundation\Session\SessionInterface $objSession */
- $objSession = Contao\System::getContainer()->get('session');
-
- // Store the ID in the session
- $session = $objSession->get('recommendation_updater');
- $session[] = $dc->activeRecord->pid;
- $objSession->set('recommendation_updater', array_unique($session));
- }
-
- /**
- * @param Contao\DataContainer $dc
- *
- * @return array
- */
- public function addSitemapCacheInvalidationTag($dc, array $tags)
- {
- $archiveModel = RecommendationArchiveModel::findByPk($dc->activeRecord->pid);
- $pageModel = Contao\PageModel::findWithDetails($archiveModel->jumpTo);
-
- if ($pageModel === null)
- {
- return $tags;
- }
-
- return array_merge($tags, ['contao.sitemap.' . $pageModel->rootId]);
- }
-}
diff --git a/contao/dca/tl_recommendation_archive.php b/contao/dca/tl_recommendation_archive.php
index b0ffa0d..fe5a269 100644
--- a/contao/dca/tl_recommendation_archive.php
+++ b/contao/dca/tl_recommendation_archive.php
@@ -8,7 +8,7 @@
use Contao\DataContainer;
use Contao\DC_Table;
-use Contao\PageModel;
+use Oveleon\ContaoRecommendationBundle\EventListener\DataContainer\RecommendationArchiveListener;
$GLOBALS['TL_DCA']['tl_recommendation_archive'] = [
// Config
@@ -17,17 +17,14 @@
'ctable' => ['tl_recommendation'],
'switchToEdit' => true,
'enableVersioning' => true,
- 'onload_callback' => [
- ['tl_recommendation_archive', 'checkPermission']
- ],
'oncreate_callback' => [
- ['tl_recommendation_archive', 'adjustPermissions']
+ [RecommendationArchiveListener::class, 'adjustPermissions']
],
'oncopy_callback' => [
- ['tl_recommendation_archive', 'adjustPermissions']
+ [RecommendationArchiveListener::class, 'adjustPermissions']
],
'oninvalidate_cache_tags_callback' => [
- ['tl_recommendation_archive', 'addSitemapCacheInvalidationTag'],
+ [RecommendationArchiveListener::class, 'addSitemapCacheInvalidationTag'],
],
'sql' => [
'keys' => [
@@ -65,7 +62,7 @@
'editheader' => [
'href' => 'act=edit',
'icon' => 'header.svg',
- //'button_callback' => ['tl_recommendation_archive', 'editHeader']
+ 'button_callback' => [RecommendationArchiveListener::class, 'editHeader']
],
'edit' => [
'href' => 'table=tl_recommendation',
@@ -74,13 +71,13 @@
'copy' => [
'href' => 'act=copy',
'icon' => 'copy.svg',
- //'button_callback' => ['tl_recommendation_archive', 'copyArchive']
+ 'button_callback' => [RecommendationArchiveListener::class, 'copyArchive']
],
'delete' => [
'href' => 'act=delete',
'icon' => 'delete.svg',
'attributes' => 'onclick="if(!confirm(\'' . ($GLOBALS['TL_LANG']['MSC']['deleteConfirm'] ?? null) . '\'))return false;Backend.getScrollOffset()"',
- //'button_callback' => ['tl_recommendation_archive', 'deleteArchive']
+ 'button_callback' => [RecommendationArchiveListener::class, 'deleteArchive']
],
'show' => [
'href' => 'act=show',
@@ -140,265 +137,3 @@
]
]
];
-
-/**
- * Provide miscellaneous methods that are used by the data configuration array.
- *
- * @author Fabian Ekert
- */
-class tl_recommendation_archive extends Contao\Backend
-{
- /**
- * Import the back end user object
- */
- public function __construct()
- {
- parent::__construct();
- $this->import('Contao\BackendUser', 'User');
- }
-
- /**
- * Check permissions to edit table tl_recommendation_archive
- *
- * @throws Contao\CoreBundle\Exception\AccessDeniedException
- */
- public function checkPermission()
- {
- if ($this->User->isAdmin)
- {
- return;
- }
-
- // Set root IDs
- if (empty($this->User->recommendations) || !is_array($this->User->recommendations))
- {
- $root = [0];
- }
- else
- {
- $root = $this->User->recommendations;
- }
-
- $GLOBALS['TL_DCA']['tl_recommendation_archive']['list']['sorting']['root'] = $root;
-
- // Check permissions to add archives
- if (!$this->User->hasAccess('create', 'recommendationp'))
- {
- $GLOBALS['TL_DCA']['tl_recommendation_archive']['config']['closed'] = true;
- $GLOBALS['TL_DCA']['tl_recommendation_archive']['config']['notCreatable'] = true;
- $GLOBALS['TL_DCA']['tl_recommendation_archive']['config']['notCopyable'] = true;
- }
-
- // Check permissions to delete calendars
- if (!$this->User->hasAccess('delete', 'recommendationp'))
- {
- $GLOBALS['TL_DCA']['tl_recommendation_archive']['config']['notDeletable'] = true;
- }
-
- /** @var Symfony\Component\HttpFoundation\Session\SessionInterface $objSession */
- $objSession = Contao\System::getContainer()->get('session');
-
- // Check current action
- switch (Contao\Input::get('act'))
- {
- case 'select':
- // Allow
- break;
-
- case 'create':
- if (!$this->User->hasAccess('create', 'recommendationp'))
- {
- throw new Contao\CoreBundle\Exception\AccessDeniedException('Not enough permissions to create recommendation archives.');
- }
- break;
-
- case 'edit':
- case 'copy':
- case 'delete':
- case 'show':
- if (!in_array(Contao\Input::get('id'), $root) || (Contao\Input::get('act') == 'delete' && !$this->User->hasAccess('delete', 'recommendationp')))
- {
- throw new Contao\CoreBundle\Exception\AccessDeniedException('Not enough permissions to ' . Contao\Input::get('act') . ' recommendation archive ID ' . Contao\Input::get('id') . '.');
- }
- break;
-
- case 'editAll':
- case 'deleteAll':
- case 'overrideAll':
- case 'copyAll':
- $session = $objSession->all();
-
- if (Contao\Input::get('act') == 'deleteAll' && !$this->User->hasAccess('delete', 'recommendationp'))
- {
- $session['CURRENT']['IDS'] = [];
- }
- else
- {
- $session['CURRENT']['IDS'] = array_intersect((array) $session['CURRENT']['IDS'], $root);
- }
- $objSession->replace($session);
- break;
-
- default:
- if (strlen(Contao\Input::get('act')))
- {
- throw new Contao\CoreBundle\Exception\AccessDeniedException('Not enough permissions to ' . Input::get('act') . ' recommendation archives.');
- }
- break;
- }
- }
-
- /**
- * Add the new archive to the permissions
- *
- * @param $insertId
- */
- public function adjustPermissions($insertId)
- {
- // The oncreate_callback passes $insertId as second argument
- if (func_num_args() == 4)
- {
- $insertId = func_get_arg(1);
- }
-
- if ($this->User->isAdmin)
- {
- return;
- }
-
- // Set root IDs
- if (empty($this->User->recommendations) || !is_array($this->User->recommendations))
- {
- $root = [0];
- }
- else
- {
- $root = $this->User->recommendations;
- }
-
- // The archive is enabled already
- if (in_array($insertId, $root))
- {
- return;
- }
-
- /** @var Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface $objSessionBag */
- $objSessionBag = Contao\System::getContainer()->get('session')->getBag('contao_backend');
-
- $arrNew = $objSessionBag->get('new_records');
-
- if (is_array($arrNew['tl_recommendation_archive']) && in_array($insertId, $arrNew['tl_recommendation_archive']))
- {
- // Add the permissions on group level
- if ($this->User->inherit != 'custom')
- {
- $objGroup = $this->Database->execute("SELECT id, recommendations, recommendationp FROM tl_user_group WHERE id IN(" . implode(',', array_map('\intval', $this->User->groups)) . ")");
-
- while ($objGroup->next())
- {
- $arrRecommendationp = Contao\StringUtil::deserialize($objGroup->recommendationp);
-
- if (is_array($arrRecommendationp) && in_array('create', $arrRecommendationp))
- {
- $arrRecommendations = Contao\StringUtil::deserialize($objGroup->recommendations, true);
- $arrRecommendations[] = $insertId;
-
- $this->Database->prepare("UPDATE tl_user_group SET recommendations=? WHERE id=?")
- ->execute(serialize($arrRecommendations), $objGroup->id);
- }
- }
- }
-
- // Add the permissions on user level
- if ($this->User->inherit != 'group')
- {
- $objUser = $this->Database->prepare("SELECT recommendations, recommendationp FROM tl_user WHERE id=?")
- ->limit(1)
- ->execute($this->User->id);
-
- $arrRecommendationp = Contao\StringUtil::deserialize($objUser->recommendationp);
-
- if (is_array($arrRecommendationp) && in_array('create', $arrRecommendationp))
- {
- $arrRecommendations = Contao\StringUtil::deserialize($objUser->recommendations, true);
- $arrRecommendations[] = $insertId;
-
- $this->Database->prepare("UPDATE tl_user SET recommendations=? WHERE id=?")
- ->execute(serialize($arrRecommendations), $this->User->id);
- }
- }
-
- // Add the new element to the user object
- $root[] = $insertId;
- $this->User->recommendations = $root;
- }
- }
-
- /**
- * Return the edit header button
- *
- * @param array $row
- * @param string $href
- * @param string $label
- * @param string $title
- * @param string $icon
- * @param string $attributes
- *
- * @return string
- */
- public function editHeader($row, $href, $label, $title, $icon, $attributes)
- {
- return $this->User->canEditFieldsOf('tl_recommendation_archive') ? ''.Contao\Image::getHtml($icon, $label).' ' : Contao\Image::getHtml(preg_replace('/\.svg$/i', '_.svg', $icon)) . ' tl_recommendation_archive.php';
- }
-
- /**
- * Return the copy archive button
- *
- * @param array $row
- * @param string $href
- * @param string $label
- * @param string $title
- * @param string $icon
- * @param string $attributes
- *
- * @return string
- */
- public function copyArchive($row, $href, $label, $title, $icon, $attributes)
- {
- return $this->User->hasAccess('create', 'recommendationp') ? ''.Contao\Image::getHtml($icon, $label).' ' : Contao\Image::getHtml(preg_replace('/\.svg$/i', '_.svg', $icon)) . ' tl_recommendation_archive.php';
- }
-
- /**
- * Return the delete archive button
- *
- * @param array $row
- * @param string $href
- * @param string $label
- * @param string $title
- * @param string $icon
- * @param string $attributes
- *
- * @return string
- */
- public function deleteArchive($row, $href, $label, $title, $icon, $attributes)
- {
- return $this->User->hasAccess('delete', 'recommendationp') ? ''.Contao\Image::getHtml($icon, $label).' ' : Contao\Image::getHtml(preg_replace('/\.svg$/i', '_.svg', $icon)) . ' tl_recommendation_archive.php';
- }
-
- /**
- * @param Contao\DataContainer $dc
- *
- * @return array
- */
- public function addSitemapCacheInvalidationTag($dc, array $tags)
- {
- $pageModel = PageModel::findWithDetails($dc->activeRecord->jumpTo);
-
- if ($pageModel === null)
- {
- return $tags;
- }
-
- return array_merge($tags, ['contao.sitemap.' . $pageModel->rootId]);
- }
-}
From 8e7cf17318f1c152139c919b5f36c54eb9c2eb6b Mon Sep 17 00:00:00 2001
From: Sebastian Zoglowek <55794780+zoglo@users.noreply.github.com>
Date: Wed, 31 May 2023 22:39:15 +0200
Subject: [PATCH 09/19] Add class-aliases
---
contao/models/RecommendationArchiveModel.php | 4 ++--
contao/models/RecommendationModel.php | 4 ++--
contao/modules/ModuleRecommendation.php | 5 ++---
contao/modules/ModuleRecommendationForm.php | 3 +++
contao/modules/ModuleRecommendationList.php | 4 ++--
contao/modules/ModuleRecommendationReader.php | 4 ++--
6 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/contao/models/RecommendationArchiveModel.php b/contao/models/RecommendationArchiveModel.php
index b9fe6ad..c78e8da 100644
--- a/contao/models/RecommendationArchiveModel.php
+++ b/contao/models/RecommendationArchiveModel.php
@@ -46,8 +46,6 @@
* @method static integer countByJumpTo($val, array $opt=array())
* @method static integer countByProtected($val, array $opt=array())
* @method static integer countByGroups($val, array $opt=array())
- *
- * @author Fabian Ekert
*/
class RecommendationArchiveModel extends Model
{
@@ -58,3 +56,5 @@ class RecommendationArchiveModel extends Model
*/
protected static $strTable = 'tl_recommendation_archive';
}
+
+class_alias(RecommendationArchiveModel::class, 'RecommendationArchiveModel');
diff --git a/contao/models/RecommendationModel.php b/contao/models/RecommendationModel.php
index 9bcd114..12bfe81 100644
--- a/contao/models/RecommendationModel.php
+++ b/contao/models/RecommendationModel.php
@@ -104,8 +104,6 @@
* @method static integer countByPublished($val, array $opt=array())
* @method static integer countByStart($val, array $opt=array())
* @method static integer countByStop($val, array $opt=array())
- *
- * @author Fabian Ekert
*/
class RecommendationModel extends Model
{
@@ -289,3 +287,5 @@ public static function findExpiredRecommendations(array $arrOptions=array())
return static::createCollectionFromDbResult($objResult, $t);
}
}
+
+class_alias(RecommendationModel::class, 'RecommendationModel');
diff --git a/contao/modules/ModuleRecommendation.php b/contao/modules/ModuleRecommendation.php
index 40cee75..81b38dc 100644
--- a/contao/modules/ModuleRecommendation.php
+++ b/contao/modules/ModuleRecommendation.php
@@ -25,9 +25,6 @@
*
* @property string $recommendation_template
* @property mixed $recommendation_metaFields
- *
- * @author Fabian Ekert
- * @author Sebastian Zoglowek
*/
abstract class ModuleRecommendation extends Module
{
@@ -56,6 +53,7 @@ protected function sortOutProtected($arrArchives)
{
if ($objArchive->protected)
{
+ // ToDo: rewrite for contao ^5.x
if (!FE_USER_LOGGED_IN)
{
continue;
@@ -320,6 +318,7 @@ protected function isExternal($strPath)
*/
protected function addInternalImage($objModel, $objRecommendation, &$objTemplate)
{
+ // ToDo: rewrite for contao ^5.x
if ($objModel !== null && is_file(TL_ROOT . '/' . $objModel->path))
{
$objTemplate->addInternalImage = true;
diff --git a/contao/modules/ModuleRecommendationForm.php b/contao/modules/ModuleRecommendationForm.php
index 0308fab..d63f81a 100644
--- a/contao/modules/ModuleRecommendationForm.php
+++ b/contao/modules/ModuleRecommendationForm.php
@@ -481,6 +481,7 @@ protected function verifyRecommendation()
$optInToken->confirm();
// Log activity
+ // ToDo: rewrite for contao ^5.x
$logger = System::getContainer()->get('monolog.logger.contao');
$logger->log(LogLevel::INFO, 'Recommendation ID ' . $objRecommendation->id . ' (' . Idna::decodeEmail($objRecommendation->email) . ') has been verified', ['contao' => new ContaoContext(__METHOD__, TL_ACCESS)]);
@@ -502,3 +503,5 @@ protected function verifyRecommendation()
}
}
}
+
+class_alias(ModuleRecommendationForm::class, 'ModuleRecommendationForm');
diff --git a/contao/modules/ModuleRecommendationList.php b/contao/modules/ModuleRecommendationList.php
index 5fd1155..4feeb41 100644
--- a/contao/modules/ModuleRecommendationList.php
+++ b/contao/modules/ModuleRecommendationList.php
@@ -24,8 +24,6 @@
* @property array $recommendation_archives
* @property string $recommendation_featured
* @property string $recommendation_order
- *
- * @author Fabian Ekert
*/
class ModuleRecommendationList extends ModuleRecommendation
{
@@ -260,3 +258,5 @@ protected function fetchItems($recommendationArchives, $blnFeatured, $limit, $of
return RecommendationModel::findPublishedByPids($recommendationArchives, $blnFeatured, $limit, $offset, $minRating, ['order'=>$order]);
}
}
+
+class_alias(ModuleRecommendationList::class, 'ModuleRecommendationList');
diff --git a/contao/modules/ModuleRecommendationReader.php b/contao/modules/ModuleRecommendationReader.php
index e534e78..1752d10 100644
--- a/contao/modules/ModuleRecommendationReader.php
+++ b/contao/modules/ModuleRecommendationReader.php
@@ -21,8 +21,6 @@
* Front end module "recommendation reader".
*
* @property array $recommendation_archives
- *
- * @author Fabian Ekert
*/
class ModuleRecommendationReader extends ModuleRecommendation
{
@@ -100,3 +98,5 @@ protected function compile()
$this->Template->recommendation = $arrRecommendation;
}
}
+
+class_alias(ModuleRecommendationReader::class, 'ModuleRecommendationReader');
From 7ce0c92471e8c0532a697963195437f917646534 Mon Sep 17 00:00:00 2001
From: Sebastian Zoglowek <55794780+zoglo@users.noreply.github.com>
Date: Wed, 31 May 2023 22:39:38 +0200
Subject: [PATCH 10/19] Remove unnecessary Recommendation-class (now in
DataContainer listeners)
---
contao/classes/Recommendation.php | 141 ------------------------------
1 file changed, 141 deletions(-)
delete mode 100644 contao/classes/Recommendation.php
diff --git a/contao/classes/Recommendation.php b/contao/classes/Recommendation.php
deleted file mode 100644
index 815ef37..0000000
--- a/contao/classes/Recommendation.php
+++ /dev/null
@@ -1,141 +0,0 @@
-
- */
-class Recommendation extends Backend
-{
- /**
- * Purge recommendations that have not been activated within 24 hours
- */
- public function purgeRecommendations()
- {
- $objRecommendation = RecommendationModel::findExpiredRecommendations();
-
- if ($objRecommendation === null)
- {
- return;
- }
-
- while ($objRecommendation->next())
- {
- $objRecommendation->delete();
- }
-
- // Add a log entry
- $logger = System::getContainer()->get('monolog.logger.contao');
- $logger->log(LogLevel::INFO, 'Purged the unactivated recommendations', array('contao' => new ContaoContext(__METHOD__, TL_CRON)));
- }
-
- /**
- * Add Recommendations to the indexer
- *
- * @param array $arrPages
- * @param integer $intRoot
- * @param boolean $blnIsSitemap
- *
- * @return array
- */
- public function getSearchablePages($arrPages, $intRoot=0, $blnIsSitemap=false)
- {
- $arrRoot = array();
-
- if ($intRoot > 0)
- {
- $arrRoot = $this->Database->getChildRecords($intRoot, 'tl_page');
- }
-
- $arrProcessed = array();
- $time = time();
-
- // Get all categories
- $objRecommendationArchive = RecommendationArchiveModel::findByProtected('');
-
- // Walk through each archive
- if ($objRecommendationArchive !== null)
- {
- while($objRecommendationArchive->next())
- {
- // Skip archives without a target page
- if (!$objRecommendationArchive->jumpTo)
- {
- continue;
- }
-
- // Skip archives outside the root nodes
- if (!empty($arrRoot) && !\in_array($objRecommendationArchive->jumpTo, $arrRoot))
- {
- continue;
- }
-
- // Get the URL of the jumpTo page
- if (!isset($arrProcessed[$objRecommendationArchive->jumpTo]))
- {
- $objParent = PageModel::findWithDetails($objRecommendationArchive->jumpTo);
-
- // The target page does not exist
- if ($objParent === null)
- {
- continue;
- }
-
- // The target page has not been published
- if (!$objParent->published || ($objParent->start && $objParent->start > $time) || ($objParent->stop && $objParent->stop <= $time))
- {
- continue;
- }
-
- if($blnIsSitemap)
- {
- // The target page is protected
- if ($objParent->protected)
- {
- continue;
- }
-
- // the target page is exempt from the sitemap
- if ($objParent->robots == 'noindex,nofollow')
- {
- continue;
- }
- }
-
- // Generate the URL
- $arrProcessed[$objRecommendationArchive->jumpTo] = $objParent->getAbsoluteUrl(Config::get('useAutoItem') ? '/%s' : '/items/%s');
- }
-
- $strUrl = $arrProcessed[$objRecommendationArchive->jumpTo];
-
- // Get the items
- $objItems = RecommendationModel::findPublishedByPid($objRecommendationArchive->id);
-
- if($objItems !== null)
- {
- while ($objItems->next())
- {
- $arrPages[] = sprintf(preg_replace('/%(?!s)/', '%%', $strUrl), ($objItems->alias ?: $objItems->id));
- }
- }
- }
- }
-
- return $arrPages;
- }
-}
From 3fef0b078c17412620a686dcc3d740c3314835cc Mon Sep 17 00:00:00 2001
From: Sebastian Zoglowek <55794780+zoglo@users.noreply.github.com>
Date: Wed, 31 May 2023 22:40:19 +0200
Subject: [PATCH 11/19] Move permissions, add new keywords and add authors to
composer.json
---
composer.json | 16 ++++++++++++++--
src/ContaoManager/Plugin.php | 5 -----
src/ContaoRecommendationBundle.php | 5 -----
src/ContaoRecommendationPermissions.php | 12 ------------
src/Security/ContaoRecommendationPermissions.php | 12 ++++++++++++
5 files changed, 26 insertions(+), 24 deletions(-)
delete mode 100644 src/ContaoRecommendationPermissions.php
create mode 100644 src/Security/ContaoRecommendationPermissions.php
diff --git a/composer.json b/composer.json
index e390bef..0f5a244 100644
--- a/composer.json
+++ b/composer.json
@@ -4,7 +4,9 @@
"description": "Recommendation integration for Contao 4 Open Source CMS",
"keywords": [
"contao",
- "recommendation-bundle"
+ "recommendation-bundle",
+ "recommendation",
+ "reviews"
],
"homepage": "https://www.oveleon.de/",
"license": "MIT",
@@ -13,11 +15,21 @@
"name": "Oveleon",
"homepage": "https://oveleon.de/",
"role": "Developer"
+ },
+ {
+ "name": "Sebastian Zoglowek",
+ "homepage": "https://github.com/zoglo",
+ "role": "Developer"
+ },
+ {
+ "name": "Fabian Ekert",
+ "homepage": "https://github.com/eki89",
+ "role": "Developer"
}
],
"require": {
"php": "^8.1",
- "contao/core-bundle": "^4.13"
+ "contao/core-bundle": "^4.13 || ^5.1"
},
"require-dev": {
"contao/manager-plugin": "^2.0"
diff --git a/src/ContaoManager/Plugin.php b/src/ContaoManager/Plugin.php
index f7c583c..d32d03c 100644
--- a/src/ContaoManager/Plugin.php
+++ b/src/ContaoManager/Plugin.php
@@ -16,11 +16,6 @@
use Contao\ManagerPlugin\Bundle\Parser\ParserInterface;
use Oveleon\ContaoRecommendationBundle\ContaoRecommendationBundle;
-/**
- * Plugin for the Contao Manager.
- *
- * @author Fabian Ekert
- */
class Plugin implements BundlePluginInterface
{
/**
diff --git a/src/ContaoRecommendationBundle.php b/src/ContaoRecommendationBundle.php
index 065b109..fbc6ae7 100644
--- a/src/ContaoRecommendationBundle.php
+++ b/src/ContaoRecommendationBundle.php
@@ -10,11 +10,6 @@
use Symfony\Component\HttpKernel\Bundle\Bundle;
-/**
- * Configures the Contao recommendation bundle.
- *
- * @author Fabian Ekert
- */
class ContaoRecommendationBundle extends Bundle
{
public function getPath(): string
diff --git a/src/ContaoRecommendationPermissions.php b/src/ContaoRecommendationPermissions.php
deleted file mode 100644
index 6d2aa2f..0000000
--- a/src/ContaoRecommendationPermissions.php
+++ /dev/null
@@ -1,12 +0,0 @@
-
Date: Wed, 31 May 2023 23:58:50 +0200
Subject: [PATCH 12/19] Move Models and change global variables
---
contao/config/config.php | 4 +-
contao/dca/tl_recommendation_settings.php | 7 +-
contao/modules/ModuleRecommendation.php | 103 +++++-------------
contao/modules/ModuleRecommendationForm.php | 45 +++-----
contao/modules/ModuleRecommendationList.php | 12 +-
contao/modules/ModuleRecommendationReader.php | 2 +
src/Cron/PurgeRecommendationsCron.php | 2 +-
.../DataContainer/RecommendationListener.php | 6 +-
src/EventListener/SitemapListener.php | 4 +-
.../Model}/RecommendationArchiveModel.php | 2 +-
.../Model}/RecommendationModel.php | 42 +------
11 files changed, 66 insertions(+), 163 deletions(-)
rename {contao/models => src/Model}/RecommendationArchiveModel.php (98%)
rename {contao/models => src/Model}/RecommendationModel.php (83%)
diff --git a/contao/config/config.php b/contao/config/config.php
index 94433de..36e49be 100644
--- a/contao/config/config.php
+++ b/contao/config/config.php
@@ -6,8 +6,8 @@
use Oveleon\ContaoRecommendationBundle\ModuleRecommendationForm;
use Oveleon\ContaoRecommendationBundle\ModuleRecommendationList;
use Oveleon\ContaoRecommendationBundle\ModuleRecommendationReader;
-use Oveleon\ContaoRecommendationBundle\RecommendationArchiveModel;
-use Oveleon\ContaoRecommendationBundle\RecommendationModel;
+use Oveleon\ContaoRecommendationBundle\Model\RecommendationArchiveModel;
+use Oveleon\ContaoRecommendationBundle\Model\RecommendationModel;
// Back end modules
ArrayUtil::arrayInsert($GLOBALS['BE_MOD']['content'], 5, [
diff --git a/contao/dca/tl_recommendation_settings.php b/contao/dca/tl_recommendation_settings.php
index 9be3b28..5772b6f 100644
--- a/contao/dca/tl_recommendation_settings.php
+++ b/contao/dca/tl_recommendation_settings.php
@@ -6,11 +6,14 @@
* (c) https://www.oveleon.de/
*/
+use Contao\Config;
+use Contao\DC_File;
+
$GLOBALS['TL_DCA']['tl_recommendation_settings'] = [
// Config
'config' => [
- 'dataContainer' => 'File',
+ 'dataContainer' => DC_File::class,
'closed' => true
],
@@ -23,7 +26,7 @@
'fields' => [
'recommendationDefaultImage' => [
'inputType' => 'fileTree',
- 'eval' => ['fieldType'=>'radio', 'filesOnly'=>true, 'isGallery'=>true, 'extensions'=>Contao\Config::get('validImageTypes'), 'tl_class'=>'clr']
+ 'eval' => ['fieldType'=>'radio', 'filesOnly'=>true, 'isGallery'=>true, 'extensions'=> Config::get('validImageTypes'), 'tl_class'=>'clr']
],
'recommendationActiveColor' => [
'inputType' => 'text',
diff --git a/contao/modules/ModuleRecommendation.php b/contao/modules/ModuleRecommendation.php
index 81b38dc..160f0bc 100644
--- a/contao/modules/ModuleRecommendation.php
+++ b/contao/modules/ModuleRecommendation.php
@@ -10,15 +10,18 @@
use Contao\Config;
use Contao\Controller;
+use Contao\CoreBundle\Security\ContaoCorePermissions;
use Contao\Date;
use Contao\FilesModel;
use Contao\FrontendTemplate;
-use Contao\FrontendUser;
use Contao\Model\Collection;
use Contao\Module;
use Contao\PageModel;
use Contao\StringUtil;
use Contao\System;
+use Exception;
+use Oveleon\ContaoRecommendationBundle\Model\RecommendationModel;
+use Oveleon\ContaoRecommendationBundle\Model\RecommendationArchiveModel;
/**
* Parent class for recommendation modules.
@@ -28,43 +31,28 @@
*/
abstract class ModuleRecommendation extends Module
{
-
/**
* Sort out protected archives
- *
- * @param array $arrArchives
- *
- * @return array
*/
- protected function sortOutProtected($arrArchives)
+ protected function sortOutProtected(array $arrArchives): array
{
if (empty($arrArchives) || !\is_array($arrArchives))
{
return $arrArchives;
}
- $this->import(FrontendUser::class, 'User');
$objArchive = RecommendationArchiveModel::findMultipleByIds($arrArchives);
$arrArchives = [];
if ($objArchive !== null)
{
+ $security = System::getContainer()->get('security.helper');
+
while ($objArchive->next())
{
- if ($objArchive->protected)
+ if ($objArchive->protected && !$security->isGranted(ContaoCorePermissions::MEMBER_IN_GROUPS, StringUtil::deserialize($objArchive->groups, true)))
{
- // ToDo: rewrite for contao ^5.x
- if (!FE_USER_LOGGED_IN)
- {
- continue;
- }
-
- $groups = StringUtil::deserialize($objArchive->groups);
-
- if (empty($groups) || !\is_array($groups) || !\count(array_intersect($groups, $this->User->groups)))
- {
- continue;
- }
+ continue;
}
$arrArchives[] = $objArchive->id;
@@ -76,21 +64,13 @@ protected function sortOutProtected($arrArchives)
/**
* Parse an item and return it as string
- *
- * @param RecommendationModel $objRecommendation
- * @param RecommendationArchiveModel $objRecommendationArchive
- * @param string $strClass
- * @param integer $intCount
- *
- * @return string
*/
- protected function parseRecommendation($objRecommendation, $objRecommendationArchive, $strClass='', $intCount=0)
+ protected function parseRecommendation(RecommendationModel $objRecommendation, RecommendationArchiveModel $objRecommendationArchive, string $strClass='', int $intCount=0): string
{
- /** @var FrontendTemplate|object $objTemplate */
$objTemplate = new FrontendTemplate($this->recommendation_template ?: 'recommendation_default');
$objTemplate->setData($objRecommendation->row());
- if ($objRecommendation->cssClass != '')
+ if ($objRecommendation->cssClass)
{
$strClass = ' ' . $objRecommendation->cssClass . $strClass;
}
@@ -187,12 +167,8 @@ protected function parseRecommendation($objRecommendation, $objRecommendationArc
/**
* Parse one or more items and return them as array
- *
- * @param Collection $objRecommendations
- *
- * @return array
*/
- protected function parseRecommendations($objRecommendations)
+ protected function parseRecommendations(Collection $objRecommendations): array
{
$limit = $objRecommendations->count();
@@ -220,12 +196,8 @@ protected function parseRecommendations($objRecommendations)
/**
* Return the meta fields of a recommendation as array
- *
- * @param RecommendationModel $objRecommendation
- *
- * @return array
*/
- protected function getMetaFields($objRecommendation)
+ protected function getMetaFields(RecommendationModel $objRecommendation): array
{
$meta = StringUtil::deserialize($this->recommendation_metaFields);
@@ -261,15 +233,8 @@ protected function getMetaFields($objRecommendation)
/**
* Generate a link and return it as string
- *
- * @param string $strLink
- * @param RecommendationModel $objRecommendation
- * @param string $strTitle
- * @param boolean $blnIsReadMore
- *
- * @return string
*/
- protected function generateLink($strLink, $objRecommendation, $strTitle, $blnIsReadMore=false)
+ protected function generateLink(string $strLink, RecommendationModel $objRecommendation, string $strTitle, bool $blnIsReadMore=false): string
{
return sprintf('%s%s',
$this->generateRecommendationUrl($objRecommendation),
@@ -280,28 +245,20 @@ protected function generateLink($strLink, $objRecommendation, $strTitle, $blnIsR
/**
* Generate a URL and return it as string
- *
- * @param RecommendationModel $objRecommendation
- *
- * @return string
*/
- protected function generateRecommendationUrl($objRecommendation)
+ protected function generateRecommendationUrl(RecommendationModel $objRecommendation): string
{
$objPage = PageModel::findByPk($objRecommendation->getRelated('pid')->jumpTo);
- return ampersand($objPage->getFrontendUrl((Config::get('useAutoItem') ? '/' : '/items/') . ($objRecommendation->alias ?: $objRecommendation->id)));
+ return StringUtil::ampersand($objPage->getFrontendUrl((Config::get('useAutoItem') ? '/' : '/items/') . ($objRecommendation->alias ?: $objRecommendation->id)));
}
/**
* Check whether path is external
- *
- * @param string $strPath The file path
- *
- * @return boolean
*/
- protected function isExternal($strPath)
+ protected function isExternal(string $strPath): bool
{
- if (substr($strPath, 0, 7) == 'http://' || substr($strPath, 0, 8) == 'https://')
+ if (str_starts_with($strPath, 'http://') || str_starts_with($strPath, 'https://'))
{
return true;
}
@@ -316,10 +273,10 @@ protected function isExternal($strPath)
* @param RecommendationModel $objRecommendation The recommendation model
* @param FrontendTemplate $objTemplate The frontend template
*/
- protected function addInternalImage($objModel, $objRecommendation, &$objTemplate)
+ protected function addInternalImage($objModel, $objRecommendation, &$objTemplate): void
{
- // ToDo: rewrite for contao ^5.x
- if ($objModel !== null && is_file(TL_ROOT . '/' . $objModel->path))
+ // ToDo: Contao 5.x compatibility
+ if ($objModel !== null && is_file(System::getContainer()->getParameter('kernel.project_dir') . '/' . $objModel->path))
{
$objTemplate->addInternalImage = true;
@@ -343,17 +300,14 @@ protected function addInternalImage($objModel, $objRecommendation, &$objTemplate
}
/**
- * Parses a timestamp into a human readable string
- *
- * @param string $strDateTime
- *
- * @return string
+ * Parses a timestamp into a human-readable string
+ * @throws Exception
*/
- protected function getElapsedTime($strDateTime)
+ protected function getElapsedTime(string $strDateTime): string
{
$objElapsedTime = (new \DateTime($strDateTime))->diff(new \DateTime());
- if(($years = $objElapsedTime->y) > 0)
+ if (($years = $objElapsedTime->y) > 0)
{
return $this->translateElapsedTime($years, 'year');
}
@@ -381,13 +335,8 @@ protected function getElapsedTime($strDateTime)
/**
* Translates elapsed time
- *
- * @param integer $value
- * @param string $strUnit
- *
- * @return string
*/
- protected function translateElapsedTime($value, $strUnit = 'justNow')
+ protected function translateElapsedTime(int $value, string $strUnit = 'justNow'): string
{
return sprintf($GLOBALS['TL_LANG']['tl_recommendation'][$strUnit][!($value>1)], $value);
}
diff --git a/contao/modules/ModuleRecommendationForm.php b/contao/modules/ModuleRecommendationForm.php
index d63f81a..aaf017a 100644
--- a/contao/modules/ModuleRecommendationForm.php
+++ b/contao/modules/ModuleRecommendationForm.php
@@ -10,7 +10,6 @@
use Contao\BackendTemplate;
use Contao\CoreBundle\Exception\InternalServerErrorException;
-use Contao\CoreBundle\Monolog\ContaoContext;
use Contao\CoreBundle\OptIn\OptIn;
use Contao\Email;
use Contao\Environment;
@@ -21,7 +20,6 @@
use Contao\StringUtil;
use Contao\System;
use Contao\Widget;
-use Psr\Log\LogLevel;
/**
* Front end module "recommendation form".
@@ -55,7 +53,7 @@ class ModuleRecommendationForm extends ModuleRecommendation
*
* @return string
*/
- public function generate()
+ public function generate(): string
{
$request = System::getContainer()->get('request_stack')->getCurrentRequest();
@@ -84,7 +82,7 @@ public function generate()
/**
* Generate the module
*/
- protected function compile()
+ protected function compile(): void
{
System::loadLanguageFile('tl_recommendation');
System::loadLanguageFile('tl_recommendation_notification');
@@ -225,12 +223,12 @@ protected function compile()
$this->Template->formId = $strFormId;
$this->Template->hasError = $doNotSubmit;
- $session = System::getContainer()->get('session');
+ $objSession = System::getContainer()->get('request_stack')->getSession();
// Do not index or cache the page with the confirmation message
- if ($session->isStarted())
+ if ($objSession->isStarted())
{
- $flashBag = $session->getFlashBag();
+ $flashBag = $objSession->getFlashBag();
if ($flashBag->has('recommendation_added'))
{
@@ -298,7 +296,7 @@ protected function compile()
}
else
{
- $session->getFlashBag()->set('recommendation_added', $this->getFlashBagMessage());
+ $objSession->getFlashBag()->set('recommendation_added', $this->getFlashBagMessage());
}
$this->reload();
@@ -307,12 +305,8 @@ protected function compile()
/**
* Convert line feeds to
tags
- *
- * @param string $strText
- *
- * @return string
*/
- public function convertLineFeeds($strText)
+ public function convertLineFeeds(string $strText): string
{
$strText = preg_replace('/\r?\n/', '
', $strText);
@@ -335,10 +329,8 @@ public function convertLineFeeds($strText)
/**
* Get flashbag message
- *
- * @return string
*/
- protected function getFlashBagMessage()
+ protected function getFlashBagMessage(): string
{
// Confirmation e-mail
if ($this->recommendation_activate)
@@ -358,10 +350,8 @@ protected function getFlashBagMessage()
/**
* Sends a notification to the administrator
- *
- * @param RecommendationModel $objRecommendation
*/
- protected function sendNotificationMail($objRecommendation)
+ protected function sendNotificationMail(RecommendationModel $objRecommendation): void
{
$strText = $objRecommendation->text;
@@ -397,11 +387,8 @@ protected function sendNotificationMail($objRecommendation)
/**
* Send the verification mail
- *
- * @param array $arrData
- * @param integer $id
*/
- protected function sendVerificationMail($arrData, $id)
+ protected function sendVerificationMail(array $arrData, int $id): void
{
/** @var OptIn $optIn */
$optIn = System::getContainer()->get('contao.opt-in');
@@ -409,19 +396,20 @@ protected function sendVerificationMail($arrData, $id)
// Prepare the simple token data
$arrTokenData = $arrData;
- $arrTokenData['token'] = $optInToken->getIdentifier();
- $arrTokenData['domain'] = Idna::decode(Environment::get('host'));
- $arrTokenData['link'] = Idna::decode(Environment::get('base')) . Environment::get('request') . ((strpos(Environment::get('request'), '?') !== false) ? '&' : '?') . 'token=' . $optInToken->getIdentifier();
+ $arrTokenData['token'] = $optInToken->getIdentifier();
+ $arrTokenData['domain'] = Idna::decode(Environment::get('host'));
+ $arrTokenData['link'] = Idna::decode(Environment::get('base')) . Environment::get('request') . ((str_contains(Environment::get('request'), '?')) ? '&' : '?') . 'token=' . $optInToken->getIdentifier();
$arrTokenData['channel'] = '';
// Send the token
+ // ToDo: Contao 5.x compatibility (parseSimpleTokens)
$optInToken->send(sprintf($GLOBALS['TL_LANG']['tl_recommendation_notification']['email_activation'][0], Idna::decode(Environment::get('host'))), StringUtil::parseSimpleTokens($this->recommendation_activateText, $arrTokenData));
}
/**
* Verifies the recommendation
*/
- protected function verifyRecommendation()
+ protected function verifyRecommendation(): void
{
$this->Template = new FrontendTemplate('mod_message');
@@ -481,9 +469,8 @@ protected function verifyRecommendation()
$optInToken->confirm();
// Log activity
- // ToDo: rewrite for contao ^5.x
$logger = System::getContainer()->get('monolog.logger.contao');
- $logger->log(LogLevel::INFO, 'Recommendation ID ' . $objRecommendation->id . ' (' . Idna::decodeEmail($objRecommendation->email) . ') has been verified', ['contao' => new ContaoContext(__METHOD__, TL_ACCESS)]);
+ $logger?->info('Recommendation ID ' . $objRecommendation->id . ' (' . Idna::decodeEmail($objRecommendation->email) . ') has been verified');
// Redirect to the jumpTo page
if (($objTarget = $this->objModel->getRelated('recommendation_activateJumpTo')) instanceof PageModel)
diff --git a/contao/modules/ModuleRecommendationList.php b/contao/modules/ModuleRecommendationList.php
index 4feeb41..4bb7264 100644
--- a/contao/modules/ModuleRecommendationList.php
+++ b/contao/modules/ModuleRecommendationList.php
@@ -17,6 +17,7 @@
use Contao\Pagination;
use Contao\StringUtil;
use Contao\System;
+use Oveleon\ContaoRecommendationBundle\Model\RecommendationModel;
/**
* Front end module "recommendation list".
@@ -27,7 +28,6 @@
*/
class ModuleRecommendationList extends ModuleRecommendation
{
-
/**
* Template
* @var string
@@ -39,7 +39,7 @@ class ModuleRecommendationList extends ModuleRecommendation
*
* @return string
*/
- public function generate()
+ public function generate(): string
{
$request = System::getContainer()->get('request_stack')->getCurrentRequest();
@@ -201,14 +201,6 @@ protected function countItems($recommendationArchives, $blnFeatured, $minRating)
/**
* Fetch the matching items
- *
- * @param array $recommendationArchives
- * @param boolean $blnFeatured
- * @param integer $limit
- * @param integer $offset
- * @param integer $minRating
- *
- * @return Collection|RecommendationModel|null
*/
protected function fetchItems($recommendationArchives, $blnFeatured, $limit, $offset, $minRating)
{
diff --git a/contao/modules/ModuleRecommendationReader.php b/contao/modules/ModuleRecommendationReader.php
index 1752d10..1e5aca5 100644
--- a/contao/modules/ModuleRecommendationReader.php
+++ b/contao/modules/ModuleRecommendationReader.php
@@ -16,6 +16,8 @@
use Contao\Input;
use Contao\StringUtil;
use Contao\System;
+use Oveleon\ContaoRecommendationBundle\Model\RecommendationArchiveModel;
+use Oveleon\ContaoRecommendationBundle\Model\RecommendationModel;
/**
* Front end module "recommendation reader".
diff --git a/src/Cron/PurgeRecommendationsCron.php b/src/Cron/PurgeRecommendationsCron.php
index a04fd3f..aebb7e8 100644
--- a/src/Cron/PurgeRecommendationsCron.php
+++ b/src/Cron/PurgeRecommendationsCron.php
@@ -6,7 +6,7 @@
use Contao\CoreBundle\DependencyInjection\Attribute\AsCronJob;
use Contao\CoreBundle\Framework\ContaoFramework;
-use Oveleon\ContaoRecommendationBundle\RecommendationModel;
+use Oveleon\ContaoRecommendationBundle\Model\RecommendationModel;
use Psr\Log\LoggerInterface;
#[AsCronJob('daily')]
diff --git a/src/EventListener/DataContainer/RecommendationListener.php b/src/EventListener/DataContainer/RecommendationListener.php
index 0e7f98b..c68e2a3 100644
--- a/src/EventListener/DataContainer/RecommendationListener.php
+++ b/src/EventListener/DataContainer/RecommendationListener.php
@@ -15,7 +15,7 @@
use Contao\System;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Exception;
-use Oveleon\ContaoRecommendationBundle\RecommendationArchiveModel;
+use Oveleon\ContaoRecommendationBundle\Model\RecommendationArchiveModel;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Security\Core\Security;
@@ -229,7 +229,7 @@ public function listRecommendations(array $arrRow): string
public function generateSitemap(): void
{
/** @var SessionInterface $objSession */
- $objSession = System::getContainer()->get('session');
+ $objSession = System::getContainer()->get('request_stack')->getSession();
$session = $objSession->get('recommendation_updater');
@@ -261,7 +261,7 @@ public function scheduleUpdate(DataContainer $dc): void
}
/** @var SessionInterface $objSession */
- $objSession = System::getContainer()->get('session');
+ $objSession = System::getContainer()->get('request_stack')->getSession();
// Store the ID in the session
$session = $objSession->get('recommendation_updater');
diff --git a/src/EventListener/SitemapListener.php b/src/EventListener/SitemapListener.php
index 6fd311b..2434ddc 100644
--- a/src/EventListener/SitemapListener.php
+++ b/src/EventListener/SitemapListener.php
@@ -9,8 +9,8 @@
use Contao\CoreBundle\Framework\ContaoFramework;
use Contao\Database;
use Contao\PageModel;
-use Oveleon\ContaoRecommendationBundle\RecommendationArchiveModel;
-use Oveleon\ContaoRecommendationBundle\RecommendationModel;
+use Oveleon\ContaoRecommendationBundle\Model\RecommendationArchiveModel;
+use Oveleon\ContaoRecommendationBundle\Model\RecommendationModel;
use Terminal42\ServiceAnnotationBundle\Annotation\ServiceTag;
/**
diff --git a/contao/models/RecommendationArchiveModel.php b/src/Model/RecommendationArchiveModel.php
similarity index 98%
rename from contao/models/RecommendationArchiveModel.php
rename to src/Model/RecommendationArchiveModel.php
index c78e8da..a283ac5 100644
--- a/contao/models/RecommendationArchiveModel.php
+++ b/src/Model/RecommendationArchiveModel.php
@@ -6,7 +6,7 @@
* (c) https://www.oveleon.de/
*/
-namespace Oveleon\ContaoRecommendationBundle;
+namespace Oveleon\ContaoRecommendationBundle\Model;
use Contao\Model;
use Contao\Model\Collection;
diff --git a/contao/models/RecommendationModel.php b/src/Model/RecommendationModel.php
similarity index 83%
rename from contao/models/RecommendationModel.php
rename to src/Model/RecommendationModel.php
index 12bfe81..e4dd912 100644
--- a/contao/models/RecommendationModel.php
+++ b/src/Model/RecommendationModel.php
@@ -6,7 +6,7 @@
* (c) https://www.oveleon.de/
*/
-namespace Oveleon\ContaoRecommendationBundle;
+namespace Oveleon\ContaoRecommendationBundle\Model;
use Contao\Database;
use Contao\Date;
@@ -107,7 +107,6 @@
*/
class RecommendationModel extends Model
{
-
/**
* Table name
* @var string
@@ -116,14 +115,8 @@ class RecommendationModel extends Model
/**
* Find a published recommendation from one or more recommendation archives by its ID or alias
- *
- * @param mixed $varId The numeric ID or alias name
- * @param array $arrPids An array of parent IDs
- * @param array $arrOptions An optional options array
- *
- * @return RecommendationModel|null The model or null if there are no recommendations
*/
- public static function findPublishedByParentAndIdOrAlias($varId, $arrPids, array $arrOptions=array())
+ public static function findPublishedByParentAndIdOrAlias(mixed $varId, $arrPids, array $arrOptions=array()): ?RecommendationModel
{
if (empty($arrPids) || !\is_array($arrPids))
{
@@ -145,13 +138,8 @@ public static function findPublishedByParentAndIdOrAlias($varId, $arrPids, array
/**
* Find published recommendations with the default redirect target by their parent ID
- *
- * @param integer $intPid The recommendation archive ID
- * @param array $arrOptions An optional options array
- *
- * @return Collection|RecommendationModel[]|RecommendationModel|null A collection of models or null if there are no recommendations
*/
- public static function findPublishedByPid($intPid, array $arrOptions=array())
+ public static function findPublishedByPid(int $intPid, array $arrOptions=array()): Collection|RecommendationModel|array|null
{
$t = static::$strTable;
$arrColumns = ["$t.pid=? AND $t.verified='1'"];
@@ -172,16 +160,8 @@ public static function findPublishedByPid($intPid, array $arrOptions=array())
/**
* Find published recommendations by their parent ID
- *
- * @param array $arrPids An array of recommendation archive IDs
- * @param boolean $blnFeatured If true, return only featured recommendations, if false, return only unfeatured recommendations
- * @param integer $intLimit An optional limit
- * @param integer $intOffset An optional offset
- * @param array $arrOptions An optional options array
- *
- * @return Collection|RecommendationModel[]|RecommendationModel|null A collection of models or null if there are no recommendations
*/
- public static function findPublishedByPids($arrPids, $blnFeatured=null, $intLimit=0, $intOffset=0, $minRating=null, array $arrOptions=array())
+ public static function findPublishedByPids($arrPids, bool $blnFeatured=null, int $intLimit=0, int $intOffset=0, $minRating=null, array $arrOptions=array()): Collection|RecommendationModel|array|null
{
if (empty($arrPids) || !\is_array($arrPids))
{
@@ -224,14 +204,8 @@ public static function findPublishedByPids($arrPids, $blnFeatured=null, $intLimi
/**
* Count published recommendations by their parent ID
- *
- * @param array $arrPids An array of recommendation archive IDs
- * @param boolean $blnFeatured If true, return only featured recommendations, if false, return only unfeatured recommendations
- * @param array $arrOptions An optional options array
- *
- * @return integer The number of recommendations
*/
- public static function countPublishedByPids($arrPids, $blnFeatured=null, $minRating=null, array $arrOptions=array())
+ public static function countPublishedByPids($arrPids, bool $blnFeatured=null, $minRating=null, array $arrOptions=array()): int
{
if (empty($arrPids) || !\is_array($arrPids))
{
@@ -266,12 +240,8 @@ public static function countPublishedByPids($arrPids, $blnFeatured=null, $minRat
/**
* Find registrations that have not been activated for more than 24 hours
- *
- * @param array $arrOptions An optional options array
- *
- * @return Collection|RecommendationModel[]|RecommendationModel|null A collection of models or null if there are no expired recommendations
*/
- public static function findExpiredRecommendations(array $arrOptions=array())
+ public static function findExpiredRecommendations(array $arrOptions=array()): Collection|RecommendationModel|array|null
{
$t = static::$strTable;
$objDatabase = Database::getInstance();
From 5446ed3bd92b1668b8d4c5f5e2d8b2f1b14c174b Mon Sep 17 00:00:00 2001
From: Sebastian Zoglowek
Date: Thu, 1 Jun 2023 12:21:08 +0200
Subject: [PATCH 13/19] Add referrer to module recommendation form and change
opt_in service
---
contao/modules/ModuleRecommendationForm.php | 57 ++++++++++---------
.../modules/mod_recommendationform.html5 | 2 +-
2 files changed, 32 insertions(+), 27 deletions(-)
diff --git a/contao/modules/ModuleRecommendationForm.php b/contao/modules/ModuleRecommendationForm.php
index aaf017a..a5d76a3 100644
--- a/contao/modules/ModuleRecommendationForm.php
+++ b/contao/modules/ModuleRecommendationForm.php
@@ -20,6 +20,8 @@
use Contao\StringUtil;
use Contao\System;
use Contao\Widget;
+use Oveleon\ContaoRecommendationBundle\Model\RecommendationArchiveModel;
+use Oveleon\ContaoRecommendationBundle\Model\RecommendationModel;
/**
* Front end module "recommendation form".
@@ -37,8 +39,6 @@
* @property integer $jumpTo
* @property boolean $recommendation_activate
* @property string $recommendation_activateText
- *
- * @author Sebastian Zoglowek
*/
class ModuleRecommendationForm extends ModuleRecommendation
{
@@ -60,11 +60,11 @@ public function generate(): string
if ($request && System::getContainer()->get('contao.routing.scope_matcher')->isBackendRequest($request))
{
$objTemplate = new BackendTemplate('be_wildcard');
- $objTemplate->wildcard = '### ' . mb_strtoupper($GLOBALS['TL_LANG']['FMD']['recommendationform'][0], 'UTF-8') . ' ###';
+ $objTemplate->wildcard = '### ' . $GLOBALS['TL_LANG']['FMD']['recommendationform'][0] . ' ###';
$objTemplate->title = $this->headline;
$objTemplate->id = $this->id;
$objTemplate->link = $this->name;
- $objTemplate->href = 'contao/main.php?do=themes&table=tl_module&act=edit&id=' . $this->id;
+ $objTemplate->href = StringUtil::specialcharsUrl(System::getContainer()->get('router')->generate('contao_backend', array('do'=>'themes', 'table'=>'tl_module', 'act'=>'edit', 'id'=>$this->id)));
return $objTemplate->parse();
}
@@ -143,7 +143,7 @@ protected function compile(): void
];
// Captcha
- if (!$this->recommendation_disableCaptcha == true)
+ if (!$this->recommendation_disableCaptcha)
{
$arrFields['captcha'] = [
'name' => 'captcha',
@@ -172,8 +172,8 @@ protected function compile(): void
}
$doNotSubmit = false;
- $arrWidgets = [];
- $strFormId = 'recommendation_' . $this->id;
+ $arrWidgets = [];
+ $strFormId = 'recommendation_' . $this->id;
// Optional recommendation form fields
$arrOptionalFormFields = StringUtil::deserialize($this->recommendation_optionalFormFields, true);
@@ -182,7 +182,7 @@ protected function compile(): void
foreach ($arrFields as $fieldName => $arrField)
{
// Check for optional form fields
- if(($arrField['eval']['optional'] ?? null) && !\in_array($fieldName, $arrOptionalFormFields))
+ if (($arrField['eval']['optional'] ?? null) && !\in_array($fieldName, $arrOptionalFormFields))
{
continue;
}
@@ -218,10 +218,11 @@ protected function compile(): void
$arrWidgets[$arrField['name']] = $objWidget;
}
- $this->Template->fields = $arrWidgets;
- $this->Template->submit = $GLOBALS['TL_LANG']['tl_recommendation']['recommendation_submit'];
- $this->Template->formId = $strFormId;
- $this->Template->hasError = $doNotSubmit;
+ $this->Template->fields = $arrWidgets;
+ $this->Template->submit = $GLOBALS['TL_LANG']['tl_recommendation']['recommendation_submit'];
+ $this->Template->formId = $strFormId;
+ $this->Template->hasError = $doNotSubmit;
+ $this->Template->requestToken = System::getContainer()->get('contao.csrf.token_manager')->getDefaultTokenValue();
$objSession = System::getContainer()->get('request_stack')->getSession();
@@ -252,8 +253,7 @@ protected function compile(): void
$strText = preg_replace('/(href|src|on[a-z]+)="[^"]*(contao\/main\.php|typolight\/main\.php|javascript|vbscri?pt|script|alert|document|cookie|window)[^"]*"+/i', '$1="#"', $strText);
// Prepare the record
- $arrData = array
- (
+ $arrData = [
'tstamp' => $time,
'pid' => $this->recommendation_archive,
'title' => $arrWidgets['title']->value ?: '',
@@ -267,7 +267,7 @@ protected function compile(): void
'text' => $this->convertLineFeeds($strText),
'rating' => $arrWidgets['rating']->value,
'published' => $this->recommendation_moderate ? '' : 1
- );
+ ];
// Store the recommendation
$objRecommendation = new RecommendationModel();
@@ -316,13 +316,12 @@ public function convertLineFeeds(string $strText): string
$strText = '' . $strText . '
';
}
- $arrReplace = array
- (
+ $arrReplace = [
'@
\s?
\s?@' => "
\n", // Convert two linebreaks into a new paragraph
'@\s?
@' => '', // Remove BR tags before closing P tags
'@ '
@' => '
' // Do not nest DIVs inside paragraphs
- );
+ ];
return preg_replace(array_keys($arrReplace), array_values($arrReplace), $strText);
}
@@ -356,8 +355,8 @@ protected function sendNotificationMail(RecommendationModel $objRecommendation):
$strText = $objRecommendation->text;
$objEmail = new Email();
- $objEmail->from = $GLOBALS['TL_ADMIN_EMAIL'];
- $objEmail->fromName = $GLOBALS['TL_ADMIN_NAME'];
+ $objEmail->from = $GLOBALS['TL_ADMIN_EMAIL'] ?? null;
+ $objEmail->fromName = $GLOBALS['TL_ADMIN_NAME'] ?? null;
$objEmail->subject = sprintf($GLOBALS['TL_LANG']['tl_recommendation_notification']['email_subject'], Idna::decode(Environment::get('host')));
// Convert the recommendation to plain text
@@ -390,8 +389,10 @@ protected function sendNotificationMail(RecommendationModel $objRecommendation):
*/
protected function sendVerificationMail(array $arrData, int $id): void
{
+ $container = System::getContainer();
+
/** @var OptIn $optIn */
- $optIn = System::getContainer()->get('contao.opt-in');
+ $optIn = $container->get('contao.opt_in');
$optInToken = $optIn->create('rec', $arrData['email'], ['tl_recommendation'=> [$id]]);
// Prepare the simple token data
@@ -402,8 +403,7 @@ protected function sendVerificationMail(array $arrData, int $id): void
$arrTokenData['channel'] = '';
// Send the token
- // ToDo: Contao 5.x compatibility (parseSimpleTokens)
- $optInToken->send(sprintf($GLOBALS['TL_LANG']['tl_recommendation_notification']['email_activation'][0], Idna::decode(Environment::get('host'))), StringUtil::parseSimpleTokens($this->recommendation_activateText, $arrTokenData));
+ $optInToken->send(sprintf($GLOBALS['TL_LANG']['tl_recommendation_notification']['email_activation'][0], Idna::decode(Environment::get('host'))), $container->get('contao.string.simple_token_parser')->parse($this->recommendation_activateText, $arrTokenData));
}
/**
@@ -414,10 +414,16 @@ protected function verifyRecommendation(): void
$this->Template = new FrontendTemplate('mod_message');
/** @var OptIn $optin */
- $optIn = System::getContainer()->get('contao.opt-in');
+ $optIn = System::getContainer()->get('contao.opt_in');
// Find an unconfirmed token
- if ((!$optInToken = $optIn->find(Input::get('token'))) || !$optInToken->isValid() || \count($arrRelated = $optInToken->getRelatedRecords()) < 1 || key($arrRelated) != 'tl_recommendation' || \count($arrIds = current($arrRelated)) < 1)
+ if (
+ (!$optInToken = $optIn->find(Input::get('token'))) ||
+ !$optInToken->isValid() ||
+ \count($arrRelated = $optInToken->getRelatedRecords()) < 1 ||
+ key($arrRelated) != 'tl_recommendation' ||
+ \count($arrIds = current($arrRelated)) < 1
+ )
{
$this->Template->type = 'error';
$this->Template->message = $GLOBALS['TL_LANG']['MSC']['invalidToken'];
@@ -459,7 +465,6 @@ protected function verifyRecommendation(): void
$objRecommendation->verified = 1;
$objRecommendation->save();
-
// Notify system administrator via e-mail
if ($this->recommendation_notify)
{
diff --git a/contao/templates/modules/mod_recommendationform.html5 b/contao/templates/modules/mod_recommendationform.html5
index 0adb651..3eb51a8 100644
--- a/contao/templates/modules/mod_recommendationform.html5
+++ b/contao/templates/modules/mod_recommendationform.html5
@@ -10,7 +10,7 @@