├── .gitignore
├── uninstall.sql
├── .php-cs-fixer.dist.php
├── lib
├── rex_global_settings_list.php
├── input
│ ├── text.php
│ ├── colorpicker.php
│ ├── textarea.php
│ ├── rgbacolorpicker.php
│ ├── linkbutton.php
│ ├── linklistbutton.php
│ ├── select.php
│ ├── mediabutton.php
│ ├── medialistbutton.php
│ ├── datetime.php
│ ├── time.php
│ └── date.php
├── rex_var_global_var.php
├── utils
│ └── global_settings_helper.php
├── table_manager.php
├── handler
│ ├── global_settings_handler.php
│ └── handler.php
├── input.php
├── rex_global_settings.php
└── table_expander.php
├── .tools
└── bootstrap.php
├── pages
├── help.readme.php
├── help.license.php
├── help.changelog.php
├── index.php
├── settings.php
└── field.php
├── composer.json
├── phpunit.xml.dist
├── .github
└── workflows
│ ├── publish-to-redaxo.yml
│ ├── default.config.yml.github-action.diff
│ ├── code-style.yml
│ └── phppest.yml
├── package.yml
├── LICENSE.md
├── _install.sql
├── update.php
├── tests
└── global_settings_test.php
├── assets
├── js
│ └── global_settings.js
└── css
│ ├── global_settings.css
│ └── spectrum.css
├── install.php
├── boot.php
├── README.md
├── CHANGELOG.md
├── lang
├── en_gb.lang
├── sv_se.lang
├── de_de.lang
└── es_es.lang
└── functions
└── function_global_settings.php
/.gitignore:
--------------------------------------------------------------------------------
1 | /.phpunit.result.cache
2 | /vendor
3 | /.idea/
4 | /.php-cs-fixer.cache
--------------------------------------------------------------------------------
/uninstall.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE IF EXISTS `%TABLE_PREFIX%global_settings_field`;
2 | DROP TABLE IF EXISTS `%TABLE_PREFIX%global_settings_type`;
3 | DROP TABLE IF EXISTS `%TABLE_PREFIX%global_settings`;
4 |
--------------------------------------------------------------------------------
/.php-cs-fixer.dist.php:
--------------------------------------------------------------------------------
1 | in(__DIR__)
7 | ->exclude('tests')
8 | ;
9 |
10 | return (new Redaxo\PhpCsFixerConfig\Config())
11 | ->setFinder($finder)
12 | ;
13 |
--------------------------------------------------------------------------------
/lib/rex_global_settings_list.php:
--------------------------------------------------------------------------------
1 | setAttribute('class', 'form-control');
9 | $this->setAttribute('type', 'text');
10 | }
11 |
12 | public function getHtml()
13 | {
14 | $value = htmlspecialchars((string) $this->value);
15 | return 'getAttributeString() . ' value="' . $value . '" />';
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/pages/help.readme.php:
--------------------------------------------------------------------------------
1 | getPath('README.md'));
4 | [$toc, $content] = rex_markdown::factory()->parseWithToc($data);
5 | $fragment = new rex_fragment();
6 | $fragment->setVar('content', $content, false);
7 | $fragment->setVar('toc', $toc, false);
8 | $content = $fragment->parse('core/page/docs.php');
9 |
10 | $fragment = new rex_fragment();
11 | $fragment->setVar('title', $this->i18n('help_readme'), false);
12 | $fragment->setVar('body', $content, false);
13 | echo $fragment->parse('core/page/section.php');
14 |
--------------------------------------------------------------------------------
/pages/help.license.php:
--------------------------------------------------------------------------------
1 | parseWithToc(rex_file::require($this->getPath('LICENSE.md')), 2, 3, false);
4 |
5 | $fragment = new rex_fragment();
6 | $fragment->setVar('content', $Content, false);
7 | $fragment->setVar('toc', $Toc, false);
8 | $content = $fragment->parse('core/page/docs.php');
9 |
10 | $fragment = new rex_fragment();
11 | $fragment->setVar('title', $this->i18n('help_license'));
12 | $fragment->setVar('body', $content, false);
13 |
14 | echo $fragment->parse('core/page/section.php');
15 |
--------------------------------------------------------------------------------
/pages/help.changelog.php:
--------------------------------------------------------------------------------
1 | parseWithToc(rex_file::require($this->getPath('CHANGELOG.md')), 2, 3, false);
4 |
5 | $fragment = new rex_fragment();
6 | $fragment->setVar('content', $Content, false);
7 | $fragment->setVar('toc', $Toc, false);
8 | $content = $fragment->parse('core/page/docs.php');
9 |
10 | $fragment = new rex_fragment();
11 | $fragment->setVar('title', $this->i18n('help_changelog'));
12 | $fragment->setVar('body', $content, false);
13 |
14 | echo $fragment->parse('core/page/section.php');
15 |
--------------------------------------------------------------------------------
/lib/input/colorpicker.php:
--------------------------------------------------------------------------------
1 | setAttribute('class', 'form-control rex-global-settings-color-picker');
9 | $this->setAttribute('type', 'text');
10 | }
11 |
12 | public function getHtml()
13 | {
14 | $value = htmlspecialchars($this->value);
15 | return 'getAttributeString() . ' value="' . $value . '" />';
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "license": "MIT",
3 | "scripts": {
4 | "test": "./vendor/bin/pest --testdox",
5 | "cs-dry": "php-cs-fixer fix -v --ansi --dry-run --config=.php-cs-fixer.dist.php",
6 | "cs-fix": "php-cs-fixer fix -v --ansi --config=.php-cs-fixer.dist.php"
7 | },
8 | "require-dev": {
9 | "pestphp/pest": "^1.22",
10 | "psr/log": "1.1.4",
11 | "redaxo/php-cs-fixer-config": "^2.0",
12 | "friendsofphp/php-cs-fixer": "^3.14"
13 | },
14 | "config": {
15 | "allow-plugins": {
16 | "pestphp/pest-plugin": true
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/lib/input/textarea.php:
--------------------------------------------------------------------------------
1 | setAttribute('class', 'form-control');
9 | $this->setAttribute('cols', '50');
10 | $this->setAttribute('rows', '6');
11 | }
12 |
13 | public function getHtml()
14 | {
15 | $value = htmlspecialchars($this->value);
16 | return '';
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/lib/input/rgbacolorpicker.php:
--------------------------------------------------------------------------------
1 | setAttribute('class', 'form-control rex-global-settings-rgba-color-picker');
9 | $this->setAttribute('data-preferred-format', 'rgb');
10 | $this->setAttribute('data-show-alpha', 'true');
11 | $this->setAttribute('type', 'text');
12 | }
13 |
14 | public function getHtml()
15 | {
16 | $value = htmlspecialchars($this->value);
17 | return 'getAttributeString() . ' value="' . $value . '" />';
18 | }
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/pages/index.php:
--------------------------------------------------------------------------------
1 |
8 | *
9 | * For the full copyright and license information, please view the LICENSE
10 | * file that was distributed with this source code.
11 | */
12 | class rex_var_global_var extends rex_var
13 | {
14 | protected function getOutput()
15 | {
16 | $var = $this->getParsedArg('var', null, true);
17 | if (null === $var) {
18 | return false;
19 | }
20 |
21 | if ('1' == $this->getArg('empty')) {
22 | $method = 'getDefaultValue';
23 | } else {
24 | $method = 'getString';
25 | }
26 |
27 | return "rex_global_settings::$method($var)";
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
all|user|admin1:all|2:user|3:adminSELECT label,id FROM my_table WHERE a=4(DB2) SELECT label,id FROM my_table WHERE a=4
39 | global_settings_field_params_notice_4 = Examples:all|user|admin1:all|2:user|3:adminSELECT label,id FROM my_table WHERE a=4(DB2) SELECT label,id FROM my_table WHERE a=4
40 | global_settings_field_params_notice_5 = Examples:all|user|admin1:all|2:user|3:adminSELECT label,id FROM my_table WHERE a=4(DB2) SELECT label,id FROM my_table WHERE a=4
41 | global_settings_field_params_notice_6 = Example:category="1" types="gif,jpg" preview="1"
42 | global_settings_field_params_notice_7 = Example:category="1" types="gif,jpg" preview="1"
43 | global_settings_field_params_notice_8 = Example:category="1"
44 | global_settings_field_params_notice_9 = Example:category="1"
45 |
46 | global_settings_field_attributes_notice = Example:style="color:red;" multiple="multiple" class="my_css_class" perm="admin[]"
47 | global_settings_field_label_notice = Code run on field editstring $fieldName, string $fieldValue, rex_sql $field
48 |
49 | global_settings_field_error_name = Please fill in the field name!
50 | global_settings_field_error_unique_name = A field with this name already exists!
51 | global_settings_field_error_unique_type = A type with this name already exists!
52 | global_settings_field_error_chars_name = The field name contains invalid symbols (use A-Z, 0-9 and _)!
53 | global_settings_field_error_invalid_prefix = Invalid Prefix!
54 | global_settings_field_error_invalid_type = Invalid Type!
55 | global_settings_field_error_invalid_length = Invalid field length!
56 | global_settings_field_error_invalid_name = Invalid field name!
57 | global_settings_field_error_invalid_fieldid = Invalid field id!
58 | global_settings_field_error_invalid_typeid = Invalid type id!
59 | global_settings_field_error_deleted = Couldn't delete the field!
60 | global_settings_field_successfull_deleted = Field deleted successfully!
61 | global_settings_field_successfull_saved = Data successfully saved!
62 |
63 | global_settings_default_fields_create = Create default fields
64 | global_settings_default_fields_created = Default fields created successfully!
65 |
66 | global_settings_edit_global_settings = Edit global settings
67 | global_settings_metadata_saved = Global settings saved
68 |
69 | global_settings_media_in_use_glob = Global Settings (Metadata)
70 |
71 | global_settings_callback_lang_indep_field = Field independent of language
72 |
73 | global_settings_save_settings = Save settings
74 |
--------------------------------------------------------------------------------
/lang/sv_se.lang:
--------------------------------------------------------------------------------
1 | global_settings_settings = Inställningar
2 | global_settings_fields = Fält
3 | global_settings_help = Hjälp
4 | global_settings_help_readme = Readme
5 | global_settings_help_changelog = Changelog
6 | global_settings_help_license = Licens
7 |
8 | global_settings_title = Globala inställnigar
9 | global_settings_global_settings_not_found = Inga fält hittades
10 |
11 | global_settings_field_list_caption = Fält
12 |
13 | global_settings_field_fieldset = Redigera/skapa fält
14 | global_settings_field_label_prefix = Prefix
15 | global_settings_field_label_title = Fältnamn
16 | global_settings_field_label_name = Spaltnamn
17 | global_settings_field_label_function = Funktion
18 | global_settings_field_label_functions = Funktioner
19 | global_settings_field_label_id = Id
20 | global_settings_field_label_type = Fälttyp
21 | global_settings_field_label_note = Notis
22 | global_settings_field_label_attributes = Fältattribut
23 | global_settings_field_label_callback = Callback
24 | global_settings_field_label_callback_templates = Callback mallar
25 | global_settings_field_label_default = Standard värde
26 | global_settings_field_label_nullable = Obligatoriskt fält
27 | global_settings_field_label_params = Parameter
28 | global_settings_field_label_priority = Fältpostition
29 | global_settings_field_label_restrictions = Endast tillgängligt i följande kategorier
30 | global_settings_field_label_no_restrictions = Finns i alla kategorier
31 |
32 | global_settings_field_notice_title = Prefixet "translate:" översätter värdet via I18N
33 |
34 | global_settings_field_first_priority = Vid början
35 | global_settings_field_after_priority = Efter fält "{0}"
36 |
37 | global_settings_field_params_notice_3 = Exempel: all|user|admin 1: all|2:user|3:adminSELECT labelt,id FROM my_table WHERE a=4 (DB2) SELECT label,id FROM my_table WHERE a=4
38 | global_settings_field_params_notice_4 = Exempel: all|user|admin 1: all|2:user|3:adminSELECT labelt,id FROM my_table WHERE a=4 (DB2) SELECT label,id FROM my_table WHERE a=4
39 | global_settings_field_params_notice_5 = Exempel: all|user|admin 1: all|2:user|3:adminSELECT labelt,id FROM my_table WHERE a=4 (DB2) SELECT label,id FROM my_table WHERE a=4
40 | global_settings_field_params_notice_6 = Exempel: category = "1" types = "gif, jpg" preview = "1" code>
41 | global_settings_field_params_notice_7 = Exempel:
category = "1" types = "gif, jpg" preview = "1" code>
42 | global_settings_field_params_notice_8 = Exempel:
category = "1" code>
43 | global_settings_field_params_notice_9 = Exempel:
category = "1" code>
44 |
45 | global_settings_field_attributes_notice = Exempel:
style = "color: red;" multiple = "multiple" class= "my_css_class" perm = "admin []" code>
46 | global_settings_field_label_notice = Code som körs när värdet på fältet ändras.
Läsbara variabler: string $fieldName, string $fieldValue, rex_sql $field
47 |
48 | global_settings_field_error_name = Ange kolumnnamn!
49 | global_settings_field_error_unique_name = Det angivna kolumnnamnet finns redan!
50 | global_settings_field_error_unique_type = Det angivna typnamnet finns redan!
51 | global_settings_field_error_chars_name = Kolumnnamnet innehåller ogiltiga tecken (tillåtna är A-Z, 0-9 och _)!
52 | global_settings_field_error_invalid_prefix = Det angivna prefixet är ogiltigt!
53 | global_settings_field_error_invalid_type = Den angivna typen är ogiltig!
54 | global_settings_field_error_invalid_length = Den angivna fältlängden är ogiltig!
55 | global_settings_field_error_invalid_name = Det angivna kolumnnamnet är ogiltig!
56 | global_settings_field_error_invalid_fieldid = Den angivna fält-id är ogiltig!
57 | global_settings_field_error_invalid_typeid = Den angivna typ-id är ogiltig!
58 | global_settings_field_error_deleted = Fältet raderades inte!
59 | global_settings_field_successfull_deleted = Fältet raderas framgångsrikt!
60 | global_settings_field_successfull_saved = Data sparas framgångsrikt!
61 |
62 | global_settings_default_fields_create = Skapa standardfält
63 | global_settings_default_fields_created = Standardfält skapade framgångsrikt!
64 |
65 | global_settings_edit_global_settings = Redigera globala inställningar
66 | global_settings_metadata_saved = Globala inställningarna sparades
67 |
68 | global_settings_media_in_use_glob = Globala inställningar (Metadata)
69 |
70 | global_settings_callback_lang_indep_field = Språkoberoende fält
71 |
72 | global_settings_save_settings = Spara inställningarna
73 |
74 |
75 |
--------------------------------------------------------------------------------
/lang/de_de.lang:
--------------------------------------------------------------------------------
1 | global_settings_settings = Einstellungen
2 | global_settings_fields = Felder
3 | global_settings_help = Hilfe
4 | global_settings_help_readme = Readme
5 | global_settings_help_changelog = Changelog
6 | global_settings_help_license = Lizenz
7 |
8 | global_settings_title = Globale Einstellungen
9 | global_settings_global_settings_not_found = Es wurden keine Felder gefunden
10 |
11 | global_settings_field_list_caption = Felder
12 |
13 | global_settings_field_fieldset = Feld bearbeiten/erstellen
14 | global_settings_field_label_prefix = Prefix
15 | global_settings_field_label_title = Feldbezeichnung
16 | global_settings_field_label_output = Ausgabe
17 | global_settings_field_label_name = Spaltenname
18 | global_settings_field_label_function = Funktion
19 | global_settings_field_label_functions = Funktionen
20 | global_settings_field_label_id = Id
21 | global_settings_field_label_type = Feldtyp
22 | global_settings_field_label_note = Notiz
23 | global_settings_field_label_attributes = HTML-Attribute
24 | global_settings_field_label_callback = Callback
25 | global_settings_field_label_callback_templates = Callback-Vorlagen
26 | global_settings_field_label_default = Standardwert
27 | global_settings_field_label_nullable = Pflichtfeld
28 | global_settings_field_label_params = Parameter
29 | global_settings_field_label_priority = Feldposition
30 | global_settings_field_label_restrictions = Nur in folgenden Kategorien verfügbar
31 | global_settings_field_label_no_restrictions = In allen Kategorien verfügbar
32 |
33 | global_settings_field_notice_title = Prefix "translate:" übersetzt den Wert via I18N
34 |
35 | global_settings_field_first_priority = Am Anfang
36 | global_settings_field_after_priority = Nach dem Feld "{0}"
37 |
38 | global_settings_field_params_notice_3 = Beispiele:
a) all|user|admin
b) 1:all|2:user|3:admin
c) SELECT label,id FROM my_table WHERE a=4
d) (DB2) SELECT label,id FROM my_table WHERE a=4
39 | global_settings_field_params_notice_4 = Beispiele:
a) all|user|admin
b) 1:all|2:user|3:admin
c) SELECT label,id FROM my_table WHERE a=4
d) (DB2) SELECT label,id FROM my_table WHERE a=4
40 | global_settings_field_params_notice_5 = Beispiele:
a) all|user|admin
b) 1:all|2:user|3:admin
c) SELECT label,id FROM my_table WHERE a=4
d) (DB2) SELECT label,id FROM my_table WHERE a=4
41 | global_settings_field_params_notice_6 = Beispiel:
category="1" types="gif,jpg" preview="1"
42 | global_settings_field_params_notice_7 = Beispiel:
category="1" types="gif,jpg" preview="1"
43 | global_settings_field_params_notice_8 = Beispiel:
category="1"
44 | global_settings_field_params_notice_9 = Beispiel:
category="1"
45 |
46 | global_settings_field_attributes_notice = Beispiel:
style="color:red;" multiple="multiple" class="my_css_class" perm="admin[]"
47 | global_settings_field_label_notice = Code der ausgeführt wird, wenn der Wert des Feldes geändert wird.
Lesbare Variablen: string $fieldName, string $fieldValue, rex_sql $field
48 |
49 | global_settings_field_error_name = Bitte Spaltennamen eingeben!
50 | global_settings_field_error_unique_name = Der angegebene Spaltenname existiert schon!
51 | global_settings_field_error_unique_type = Der angegebene Typename existiert schon!
52 | global_settings_field_error_chars_name = Der Spaltennamen enthält ungültige Zeichen (Erlaubt sind A-Z, 0-9 und _)!
53 | global_settings_field_error_invalid_prefix = Der angegebene Prefix ist ungültig!
54 | global_settings_field_error_invalid_type = Der angegebene Type ist ungültig!
55 | global_settings_field_error_invalid_length = Die angegebene Feldlänge ist ungültig!
56 | global_settings_field_error_invalid_name = Der angegebene Spaltenname ist ungültig!
57 | global_settings_field_error_invalid_fieldid = Die angegebene Feld-Id ist ungültig!
58 | global_settings_field_error_invalid_typeid = Die angegebene Type-Id ist ungültig!
59 | global_settings_field_error_deleted = Feld wurde nicht gelöscht!
60 | global_settings_field_successfull_deleted = Feld erfolgreich gelöscht!
61 | global_settings_field_successfull_saved = Daten erfolgreich gespeichert!
62 |
63 | global_settings_default_fields_create = Standardfelder erstellen
64 | global_settings_default_fields_created = Standardfelder erfolgreich erstellt!
65 |
66 | global_settings_edit_global_settings = Globale Einstellungen bearbeiten
67 | global_settings_metadata_saved = Die Globalen Einstellungen wurden gespeichert.
68 |
69 | global_settings_media_in_use_glob = Globale Einstellungen (Metadaten)
70 |
71 | global_settings_callback_lang_indep_field = Sprachunabhängiges Feld
72 |
73 | global_settings_save_settings = Einstellungen speichern
74 |
75 |
76 |
--------------------------------------------------------------------------------
/lang/es_es.lang:
--------------------------------------------------------------------------------
1 | global_settings_settings = Ajustes
2 | global_settings_fields = Campos
3 | global_settings_help = Ayuda
4 | global_settings_help_readme = Léame
5 | global_settings_help_changelog = Cambios
6 | global_settings_help_license = Licencia
7 |
8 | global_settings_title = Configuraciones globales
9 | global_settings_global_settings_not_found = No se encontraron campos
10 |
11 | global_settings_field_list_caption = campos
12 |
13 | global_settings_field_fieldset = Editar / crear campo
14 | global_settings_field_label_prefix = prefijo
15 | global_settings_field_label_title = Nombre del campo
16 | global_settings_field_label_name = nombre de la columna
17 | global_settings_field_label_function = función
18 | global_settings_field_label_functions = características
19 | global_settings_field_label_id = identificación
20 | global_settings_field_label_type = tipo de campo
21 | global_settings_field_label_note = Nota
22 | global_settings_field_label_attributes = atributos de campo
23 | global_settings_field_label_callback = devolución de llamada
24 | global_settings_field_label_callback_templates = Plantillas de devolución de llamada
25 | global_settings_field_label_default = defecto
26 | global_settings_field_label_nullable = campo obligatorio
27 | global_settings_field_label_params = parámetro
28 | global_settings_field_label_priority = posición en el campo
29 | global_settings_field_label_restrictions = Solo disponible en las siguientes categorías
30 | global_settings_field_label_no_restrictions = Disponible en todas las categorias
31 |
32 | global_settings_field_notice_title = El prefijo "traducir:" traduce el valor a través de I18N
33 |
34 | global_settings_field_first_priority = Al principio
35 | global_settings_field_after_priority = Después del campo "{0}"
36 |
37 | global_settings_field_params_notice_3 = Ejemplos:
a) todos | usuario | admin código>
b) 1: todos | 2: usuario | 3: admin código>
c) etiqueta SELECT, id FROM my_table WHERE a = 4 code>
d) (DB2) SELECT label, id FROM my_table WHERE a = 4 code>
38 | global_settings_field_params_notice_4 = Ejemplos:
a) todos | usuario | admin código>
b) 1: todos | 2: usuario | 3: admin código>
c) etiqueta SELECT, id FROM my_table WHERE a = 4 code>
d) (DB2) SELECT label, id FROM my_table WHERE a = 4 code>
39 | global_settings_field_params_notice_5 = Ejemplos:
a) todos | usuario | admin código>
b) 1: todos | 2: usuario | 3: admin código>
c) etiqueta SELECT, id FROM my_table WHERE a = 4 code>
d) (DB2) SELECT label, id FROM my_table WHERE a = 4 code>
40 | global_settings_field_params_notice_6 = Ejemplo:
category = "1" types = "gif, jpg" preview = "1" code>
41 | global_settings_field_params_notice_7 = Ejemplo:
category = "1" types = "gif, jpg" preview = "1" code>
42 | global_settings_field_params_notice_8 = Ejemplo:
category = "1" code>
43 | global_settings_field_params_notice_9 = Ejemplo:
category = "1" code>
44 |
45 | global_settings_field_attributes_notice = Ejemplo:
style = "color: red;" multiple = "multiple" class = "my_css_class" perm = "admin []" code>
46 | global_settings_field_label_notice = Código ejecutado cuando se cambia el valor del campo.
Variables legibles: string $ fieldName, string $ fieldValue, rex_sql $ field code>
47 |
48 | global_settings_field_error_name = Por favor ingrese el nombre de la columna!
49 | global_settings_field_error_unique_name = ¡El nombre de columna especificado ya existe!
50 | global_settings_field_error_unique_type = ¡El nombre de tipo especificado ya existe!
51 | global_settings_field_error_chars_name = ¡El nombre de la columna contiene caracteres no válidos (los permitidos son A-Z, 0-9 y _)!
52 | global_settings_field_error_invalid_prefix = ¡El prefijo especificado no es válido!
53 | global_settings_field_error_invalid_type = ¡El tipo especificado no es válido!
54 | global_settings_field_error_invalid_length = ¡La longitud del campo especificado no es válida!
55 | global_settings_field_error_invalid_name = ¡El nombre de columna especificado no es válido!
56 | global_settings_field_error_invalid_fieldid = ¡La ID de campo especificada no es válida!
57 | global_settings_field_error_invalid_typeid = ¡El Id. De tipo especificado no es válido!
58 | global_settings_field_error_deleted = ¡El campo no fue eliminado!
59 | global_settings_field_successfull_deleted = ¡Campo eliminado con éxito!
60 | global_settings_field_successfull_saved = ¡Datos guardados con éxito!
61 |
62 | global_settings_default_fields_create = Crear campos estándar
63 | global_settings_default_fields_created = ¡Campos estándar creados con éxito!
64 |
65 | global_settings_edit_global_settings = Editar configuración global
66 | global_settings_metadata_saved = La configuración global se ha guardado.
67 |
68 | global_settings_media_in_use_glob = Configuración global (metadatos)
69 |
70 | global_settings_callback_lang_indep_field = Campo independiente del idioma
71 |
72 | global_settings_save_settings = Guardar configuración
73 |
--------------------------------------------------------------------------------
/lib/rex_global_settings.php:
--------------------------------------------------------------------------------
1 | getArray('SELECT * FROM ' . rex::getTablePrefix() . 'global_settings');
25 |
26 | if (is_array($result)) {
27 | // build globalValues array based on clang then key/value
28 | for ($i = 0; $i < count($result); ++$i) {
29 | $clangId = $result[$i]['clang'];
30 | unset($result[$i]['clang']);
31 |
32 | self::$globalValues[$clangId] = $result[$i];
33 | }
34 |
35 | // create cache dir if necessary
36 | $dataCache = rex_path::addonCache('global_settings');
37 |
38 | if (!file_exists($dataCache)) {
39 | if (!mkdir($dataCache, rex::getDirPerm(), true)) {
40 | throw new Exception('Dir "' . $dataCache . '" could not be created! Check if server permissions are set correctly.');
41 | }
42 | }
43 |
44 | // store in cachefile for next time
45 | if (!file_put_contents(self::$cacheFile, 'setDebug(0)->setQuery('UPDATE ' . rex::getTablePrefix() . 'global_settings SET ' . $field . ' = :value WHERE clang = :clang', [':value' => $value, ':clang' => $clangId]);
91 | self::deleteCache();
92 | return true;
93 | }
94 | return false;
95 |
96 | }
97 |
98 | public static function getDefaultString($field, $allowEmpty = false)
99 | {
100 | return self::getDefaultValue($field, $allowEmpty);
101 | }
102 |
103 | public static function getString($field, $clangId = null, $allowEmpty = false)
104 | {
105 | return self::getValue($field, $clangId, $allowEmpty);
106 | }
107 |
108 | protected static function getEmptyFieldOutput($field, $value, $allowEmpty)
109 | {
110 | if (!$allowEmpty && '' == $value) {
111 | return '{{ ' . self::getStrippedField($field) . ' }}';
112 | }
113 | return $value;
114 |
115 | }
116 |
117 | public static function getStrippedField($field)
118 | {
119 | if (str_starts_with($field, self::FIELD_PREFIX)) {
120 | $field = substr($field, strlen(self::FIELD_PREFIX));
121 | }
122 |
123 | return $field;
124 | }
125 |
126 | public static function getFieldDefinition($field)
127 | {
128 | $field = self::FIELD_PREFIX . self::getStrippedField($field);
129 | $sql = rex_sql::factory();
130 | $result = $sql->getArray('SELECT * FROM ' . rex::getTablePrefix() . 'global_settings_field WHERE name = :name', ['name' => $field]);
131 | return $result[0];
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/pages/field.php:
--------------------------------------------------------------------------------
1 | Parameter
19 | if (empty($prefix)) {
20 | throw new rex_exception('Fehler: Prefix nicht definiert!');
21 | }
22 |
23 | if (empty($metaTable)) {
24 | throw new rex_exception('Fehler: metaTable nicht definiert!');
25 | }
26 |
27 | $Basedir = __DIR__;
28 | $field_id = rex_request('field_id', 'int');
29 |
30 | // ------------------------------> Feld loeschen
31 | if ('delete' == $func) {
32 | $field_id = rex_request('field_id', 'int', 0);
33 | if (0 != $field_id) {
34 | if (rex_global_settings_delete_field($field_id)) {
35 | rex_extension::registerPoint(new rex_extension_point('GLOBAL_SETTINGS_CHANGED'));
36 |
37 | echo rex_view::success(rex_i18n::msg('global_settings_field_successfull_deleted'));
38 | } else {
39 | echo rex_view::error(rex_i18n::msg('global_settings_field_error_deleted'));
40 | }
41 | }
42 | $func = '';
43 | }
44 |
45 | // ------------------------------> Eintragsliste
46 | if ('' == $func) {
47 | echo rex_api_function::getMessage();
48 |
49 | $title = rex_i18n::msg('global_settings_field_list_caption');
50 |
51 | // replace LIKE wildcards
52 | $likePrefix = str_replace(['_', '%'], ['\_', '\%'], $prefix);
53 |
54 | $list = rex_global_settings_list::factory('SELECT id, name, title FROM ' . rex::getTablePrefix() . 'global_settings_field WHERE `name` LIKE "' . $likePrefix . '%" ORDER BY priority');
55 | $list->addTableAttribute('class', 'table-striped');
56 |
57 | $tdIcon = '';
58 | $thIcon = '';
59 | $list->addColumn($thIcon, $tdIcon, 0, ['###VALUE### ', '###VALUE### ']);
60 | $list->setColumnParams($thIcon, ['func' => 'edit', 'field_id' => '###id###']);
61 |
62 | $list->removeColumn('id');
63 |
64 | $list->setColumnLabel('id', rex_i18n::msg('global_settings_field_label_id'));
65 | $list->setColumnLayout('id', ['###VALUE### ', '###VALUE### ']);
66 |
67 | $list->setColumnLabel('name', rex_i18n::msg('global_settings_field_label_name'));
68 | $list->setColumnLayout('name', ['###VALUE### ', '###VALUE### ']);
69 | $list->setColumnParams('name', ['func' => 'edit', 'field_id' => '###id###']);
70 |
71 | $list->setColumnLabel('title', rex_i18n::msg('global_settings_field_label_title'));
72 | $list->setColumnLayout('title', ['###VALUE### ', '###VALUE### ']);
73 |
74 | $list->addColumn('output', '');
75 | $list->setColumnLayout('output', ['' . rex_i18n::msg('global_settings_field_label_output') . ' ', '<?= rex_global_settings::getValue(\'###name###\'); ?> ']);
76 |
77 | $list->addColumn(rex_i18n::msg('global_settings_field_label_functions'), ' ' . rex_i18n::msg('edit'));
78 | $list->setColumnLayout(rex_i18n::msg('global_settings_field_label_functions'), ['###VALUE### ', '###VALUE### ']);
79 | $list->setColumnParams(rex_i18n::msg('global_settings_field_label_functions'), ['func' => 'edit', 'field_id' => '###id###']);
80 | $list->addLinkAttribute(rex_i18n::msg('global_settings_field_label_functions'), 'class', 'rex-edit');
81 |
82 | $list->addColumn('delete', ' ' . rex_i18n::msg('delete'));
83 | $list->setColumnLayout('delete', ['', '###VALUE### ']);
84 | $list->setColumnParams('delete', ['func' => 'delete', 'field_id' => '###id###']);
85 | $list->addLinkAttribute('delete', 'data-confirm', rex_i18n::msg('delete') . ' ?');
86 | $list->addLinkAttribute('delete', 'class', 'rex-delete');
87 |
88 | $list->setNoRowsMessage(rex_i18n::msg('global_settings_global_settings_not_found'));
89 |
90 | $content .= $list->get();
91 |
92 | $fragment = new rex_fragment();
93 | $fragment->setVar('title', $title);
94 |
95 | if (in_array($prefix, ['art_', 'med_'])) {
96 | $defaultFields = sprintf(
97 | '',
98 | rex_url::currentBackendPage(['rex-api-call' => 'global_settings_default_fields_create', 'type' => $subpage]),
99 | rex_i18n::msg('global_settings_default_fields_create'),
100 | );
101 | $fragment->setVar('options', $defaultFields, false);
102 | }
103 |
104 | $fragment->setVar('content', $content, false);
105 | $content = $fragment->parse('core/page/section.php');
106 | } // ------------------------------> Formular
107 | elseif ('edit' == $func || 'add' == $func) {
108 | $title = rex_i18n::msg('global_settings_field_fieldset');
109 | $form = new rex_global_settings_table_expander($prefix, $metaTable, rex::getTablePrefix() . 'global_settings_field', 'id=' . $field_id);
110 |
111 | if ('edit' == $func) {
112 | $form->addParam('field_id', $field_id);
113 | }
114 |
115 | $content .= $form->get();
116 |
117 | $fragment = new rex_fragment();
118 | $fragment->setVar('class', 'edit', false);
119 | $fragment->setVar('title', $title);
120 | $fragment->setVar('body', $content, false);
121 | $content = $fragment->parse('core/page/section.php');
122 | }
123 |
124 | echo $content;
125 |
--------------------------------------------------------------------------------
/functions/function_global_settings.php:
--------------------------------------------------------------------------------
1 | getParams();
6 | $newClangId = $params['clang']->getId();
7 |
8 | $sql = rex_sql::factory();
9 | $sql->setQuery('INSERT INTO `' . rex::getTablePrefix() . 'global_settings` (`clang`) VALUES (' . $newClangId . ')');
10 | }
11 |
12 | function rex_global_settings_clang_deleted($ep)
13 | {
14 | $params = $ep->getParams();
15 | $id = $params['id'];
16 |
17 | $sql = rex_sql::factory();
18 | $sql->setQuery('DELETE FROM `' . rex::getTablePrefix() . 'global_settings` WHERE `clang` = ' . $id);
19 | }
20 |
21 | function rex_global_settings_check_langs()
22 | {
23 | foreach (rex_clang::getAll() as $clang) {
24 | $sql = rex_sql::factory();
25 | $sql->setQuery('SELECT `clang` FROM ' . rex::getTablePrefix() . 'global_settings WHERE `clang` = ' . $clang->getId());
26 |
27 | switch ($sql->getRows()) {
28 | case 0:
29 | $sql = rex_sql::factory();
30 | $sql->setQuery('INSERT INTO `' . rex::getTablePrefix() . 'global_settings` (`clang`) VALUES (' . $clang->getId() . ')');
31 | break;
32 | case 1:
33 | // clang is in the database
34 | break;
35 | default:
36 | throw new Exception('global_settings: clang #' . $clang->getId() . ' is ' . $sql->getRows() . 'x in the database, only once allowed.');
37 | }
38 | }
39 | }
40 |
41 | /**
42 | * Fügt einen neuen Feldtyp ein.
43 | *
44 | * Gibt beim Erfolg die Id des Feldes zurück, bei Fehler die Fehlermeldung
45 | */
46 | function rex_global_settings_add_field_type($label, $dbtype, $dblength)
47 | {
48 | if (!is_string($label) || empty($label)) {
49 | return rex_i18n::msg('global_settings_field_error_invalid_name');
50 | }
51 |
52 | if (!is_string($dbtype) || empty($dbtype)) {
53 | return rex_i18n::msg('global_settings_field_error_invalid_type');
54 | }
55 |
56 | if (!is_int($dblength) || empty($dblength)) {
57 | return rex_i18n::msg('global_settings_field_error_invalid_length');
58 | }
59 |
60 | $qry = 'SELECT * FROM ' . rex::getTablePrefix() . 'global_settings_type WHERE label=:label LIMIT 1';
61 | $sql = rex_sql::factory();
62 | $sql->setQuery($qry, [':label' => $label]);
63 | if (0 != $sql->getRows()) {
64 | return rex_i18n::msg('global_settings_field_error_unique_type');
65 | }
66 |
67 | $sql->setTable(rex::getTablePrefix() . 'global_settings_type');
68 | $sql->setValue('label', $label);
69 | $sql->setValue('dbtype', $dbtype);
70 | $sql->setValue('dblength', $dblength);
71 |
72 | $sql->insert();
73 | return $sql->getLastId();
74 | }
75 |
76 | /**
77 | * Löscht einen Feldtyp.
78 | *
79 | * Gibt beim Erfolg true zurück, sonst eine Fehlermeldung
80 | */
81 | function rex_global_settings_delete_field_type($field_type_id)
82 | {
83 | if (!is_int($field_type_id) || empty($field_type_id)) {
84 | return rex_i18n::msg('global_settings_field_error_invalid_typeid');
85 | }
86 |
87 | $sql = rex_sql::factory();
88 | $sql->setTable(rex::getTablePrefix() . 'global_settings_type');
89 | $sql->setWhere(['id' => $field_type_id]);
90 |
91 | $sql->delete();
92 | return 1 == $sql->getRows();
93 | }
94 |
95 | /**
96 | * Fügt ein MetaFeld hinzu und legt dafür eine Spalte in der MetaTable an.
97 | */
98 | function rex_global_settings_add_field($title, $name, $priority, $attributes, $type, $default, $params = null, $validate = null, $restrictions = '')
99 | {
100 | $prefix = rex_global_settings_meta_prefix($name);
101 | $metaTable = rex_global_settings_meta_table($prefix);
102 |
103 | // Prefix korrekt?
104 | if (!$metaTable) {
105 | return rex_i18n::msg('global_settings_field_error_invalid_prefix');
106 | }
107 |
108 | // TypeId korrekt?
109 | $qry = 'SELECT * FROM ' . rex::getTablePrefix() . 'global_settings_type WHERE id=' . $type . ' LIMIT 2';
110 | $sql = rex_sql::factory();
111 | $typeInfos = $sql->getArray($qry);
112 |
113 | if (1 != $sql->getRows()) {
114 | return rex_i18n::msg('global_settings_field_error_invalid_type');
115 | }
116 |
117 | $fieldDbType = $typeInfos[0]['dbtype'];
118 | $fieldDbLength = $typeInfos[0]['dblength'];
119 |
120 | // Spalte existiert schon?
121 | $sql->setQuery('SELECT * FROM ' . $metaTable . ' LIMIT 1');
122 | if (in_array($name, $sql->getFieldnames())) {
123 | return rex_i18n::msg('global_settings_field_error_unique_name');
124 | }
125 |
126 | // Spalte extiert laut global_settings_field?
127 | $qry = 'SELECT * FROM ' . rex::getTablePrefix() . 'global_settings_field WHERE name=:name LIMIT 1';
128 | $sql = rex_sql::factory();
129 | $sql->setQuery($qry, [':name' => $name]);
130 | if (0 != $sql->getRows()) {
131 | return rex_i18n::msg('global_settings_field_error_unique_name');
132 | }
133 |
134 | $sql->setTable(rex::getTablePrefix() . 'global_settings_field');
135 | $sql->setValue('title', $title);
136 | $sql->setValue('name', $name);
137 | $sql->setValue('priority', $priority);
138 | $sql->setValue('attributes', $attributes);
139 | $sql->setValue('type_id', $type);
140 | $sql->setValue('default', $default);
141 | $sql->setValue('params', $params);
142 | $sql->setValue('validate', $validate);
143 | $sql->setValue('restrictions', $restrictions);
144 | $sql->addGlobalUpdateFields();
145 | $sql->addGlobalCreateFields();
146 |
147 | $sql->insert();
148 |
149 | // replace LIKE wildcards
150 | $prefix = str_replace(['_', '%'], ['\_', '\%'], $prefix);
151 |
152 | rex_sql_util::organizePriorities(rex::getTablePrefix() . 'global_settings_field', 'priority', 'name LIKE "' . $prefix . '%"', 'priority, updatedate');
153 |
154 | $tableManager = new rex_global_settings_table_manager($metaTable);
155 | return $tableManager->addColumn($name, $fieldDbType, $fieldDbLength, $default);
156 | }
157 |
158 | function rex_global_settings_delete_field($fieldIdOrName)
159 | {
160 | // Löschen anhand der FieldId
161 | if (is_int($fieldIdOrName)) {
162 | $fieldQry = 'SELECT * FROM ' . rex::getTablePrefix() . 'global_settings_field WHERE id=:idOrName LIMIT 2';
163 | $invalidField = rex_i18n::msg('global_settings_field_error_invalid_fieldid');
164 | } // Löschen anhand des Feldnames
165 | elseif (is_string($fieldIdOrName)) {
166 | $fieldQry = 'SELECT * FROM ' . rex::getTablePrefix() . 'global_settings_field WHERE name=:idOrName LIMIT 2';
167 | $invalidField = rex_i18n::msg('global_settings_field_error_invalid_name');
168 | } else {
169 | throw new InvalidArgumentException('global_settings: Unexpected type for $fieldIdOrName!');
170 | }
171 | // Feld existiert?
172 | $sql = rex_sql::factory();
173 | $sql->setQuery($fieldQry, [':idOrName' => $fieldIdOrName]);
174 |
175 | if (1 != $sql->getRows()) {
176 | return $invalidField;
177 | }
178 |
179 | $name = $sql->getValue('name');
180 | $field_id = $sql->getValue('id');
181 |
182 | $prefix = rex_global_settings_meta_prefix($name);
183 | $metaTable = rex_global_settings_meta_table($prefix);
184 |
185 | // Spalte existiert?
186 | $sql->setQuery('SELECT * FROM ' . $metaTable . ' LIMIT 1');
187 | if (!in_array($name, $sql->getFieldnames())) {
188 | return rex_i18n::msg('global_settings_field_error_invalid_name');
189 | }
190 |
191 | $sql->setTable(rex::getTablePrefix() . 'global_settings_field');
192 | $sql->setWhere(['id' => $field_id]);
193 |
194 | $sql->delete();
195 |
196 | $tableManager = new rex_global_settings_table_manager($metaTable);
197 | return $tableManager->deleteColumn($name);
198 | }
199 |
200 | /**
201 | * Extrahiert den Prefix aus dem Namen eine Spalte.
202 | */
203 | function rex_global_settings_meta_prefix($name)
204 | {
205 | if (!is_string($name)) {
206 | return false;
207 | }
208 |
209 | if (($pos = strpos($name, '_')) !== false) {
210 | return substr(strtolower($name), 0, $pos + 1);
211 | }
212 |
213 | return false;
214 | }
215 |
216 | /**
217 | * Gibt die mit dem Prefix verbundenen Tabellennamen zurück.
218 | */
219 | function rex_global_settings_meta_table($prefix)
220 | {
221 | $metaTables = rex_addon::get('global_settings')->getProperty('metaTables', []);
222 |
223 | if (isset($metaTables[$prefix])) {
224 | return $metaTables[$prefix];
225 | }
226 |
227 | return false;
228 | }
229 |
230 | /**
231 | * Bindet ggf extensions ein.
232 | */
233 | function rex_global_settings_extensions_handler(rex_extension_point $ep)
234 | {
235 | $page = $ep->getSubject();
236 | $mainpage = rex_be_controller::getCurrentPagePart(1);
237 | $mypage = 'global_settings';
238 |
239 | // additional javascripts
240 | if ('global_settings' == $mainpage) {
241 | rex_view::addJsFile(rex_url::addonAssets($mypage, 'js/spectrum.js'));
242 | rex_view::addJsFile(rex_url::addonAssets($mypage, 'js/global_settings.js'));
243 |
244 | rex_view::addCssFile(rex_url::addonAssets($mypage, 'css/spectrum.css'));
245 | rex_view::addCssFile(rex_url::addonAssets($mypage, 'css/global_settings.css'));
246 | }
247 | }
248 |
--------------------------------------------------------------------------------
/lib/table_expander.php:
--------------------------------------------------------------------------------
1 | metaPrefix = $metaPrefix;
11 | $this->tableManager = new rex_global_settings_table_manager($metaTable);
12 |
13 | parent::__construct($tableName, rex_i18n::msg('global_settings_field_fieldset'), $whereCondition, $method, $debug);
14 | }
15 |
16 | public function init()
17 | {
18 | // ----- EXTENSION POINT
19 | // IDs aller Feldtypen bei denen das Parameter-Feld eingeblendet werden soll
20 | $typeFields = rex_extension::registerPoint(new rex_extension_point('GLOBAL_SETTINGS_TYPE_FIELDS', [REX_GLOBAL_SETTINGS_FIELD_SELECT, REX_GLOBAL_SETTINGS_FIELD_RADIO, REX_GLOBAL_SETTINGS_FIELD_CHECKBOX, REX_GLOBAL_SETTINGS_FIELD_REX_MEDIA_WIDGET, REX_GLOBAL_SETTINGS_FIELD_REX_MEDIALIST_WIDGET, REX_GLOBAL_SETTINGS_FIELD_REX_LINK_WIDGET, REX_GLOBAL_SETTINGS_FIELD_REX_LINKLIST_WIDGET]));
21 |
22 | $field = $this->addTextField('name');
23 | $field->setLabel(rex_i18n::msg('global_settings_field_label_name'));
24 | $field->setAttribute('id', 'global-settings-name-field');
25 |
26 | $field = $this->addSelectField('priority');
27 | $field->setLabel(rex_i18n::msg('global_settings_field_label_priority'));
28 | $select = $field->getSelect();
29 | $select->setSize(1);
30 | $select->addOption(rex_i18n::msg('global_settings_field_first_priority'), 1);
31 | // Im Edit Mode das Feld selbst nicht als Position einf�gen
32 | $qry = 'SELECT name,priority FROM ' . $this->tableName . ' WHERE `name` LIKE "' . $this->metaPrefix . '%"';
33 | if ($this->isEditMode()) {
34 | $qry .= ' AND id != ' . $this->getParam('field_id');
35 | }
36 | $qry .= ' ORDER BY priority';
37 | $sql = rex_sql::factory();
38 | $sql->setQuery($qry);
39 | $value = 1;
40 | for ($i = 0; $i < $sql->getRows(); ++$i) {
41 | $value = $sql->getValue('priority') + 1;
42 | $select->addOption(
43 | rex_i18n::rawMsg('global_settings_field_after_priority', rex_global_settings::getStrippedField($sql->getValue('name'))),
44 | $value,
45 | );
46 | $sql->next();
47 | }
48 | if (!$this->isEditMode()) {
49 | $select->setSelected($value);
50 | }
51 |
52 | $field = $this->addTextField('title');
53 | $field->setLabel(rex_i18n::msg('global_settings_field_label_title'));
54 | $field->setNotice(rex_i18n::msg('global_settings_field_notice_title'));
55 |
56 | $field = $this->addTextField('notice');
57 | $field->setLabel(rex_i18n::msg('global_settings_field_label_note'));
58 |
59 | $gq = rex_sql::factory();
60 | $gq->setQuery('SELECT dbtype,id FROM ' . rex::getTablePrefix() . 'global_settings_type');
61 | $textFields = [];
62 | foreach ($gq->getArray() as $f) {
63 | if ('text' == $f['dbtype']) {
64 | $textFields[$f['id']] = $f['id'];
65 | }
66 | }
67 |
68 | $field = $this->addSelectField('type_id');
69 | $field->setLabel(rex_i18n::msg('global_settings_field_label_type'));
70 | $field->setAttribute('onchange', 'gs_checkConditionalFields(this, new Array(' . implode(',', $typeFields) . '), new Array(' . implode(',', $textFields) . '));');
71 | $select = $field->getSelect();
72 | $select->setSize(1);
73 |
74 | $qry = 'SELECT label,id FROM ' . rex::getTablePrefix() . 'global_settings_type';
75 | $select->addSqlOptions($qry);
76 |
77 | $notices = '';
78 | for ($i = 1; $i < REX_GLOBAL_SETTINGS_FIELD_COUNT; ++$i) {
79 | if (rex_i18n::hasMsg('global_settings_field_params_notice_' . $i)) {
80 | $notices .= '' . "\n";
81 | }
82 | }
83 | $notices .= '
84 | ';
88 |
89 | $field = $this->addTextAreaField('params');
90 | $field->setLabel(rex_i18n::msg('global_settings_field_label_params'));
91 | $field->setNotice($notices);
92 |
93 | $field = $this->addTextAreaField('attributes');
94 | $field->setLabel(rex_i18n::msg('global_settings_field_label_attributes'));
95 | $notice = rex_i18n::msg('global_settings_field_attributes_notice') . "\n";
96 | $field->setNotice($notice);
97 |
98 | $field = $this->addTextAreaField('callback');
99 | $field->setLabel(rex_i18n::msg('global_settings_field_label_callback'));
100 | $notice = rex_i18n::msg('global_settings_field_label_notice') . "\n";
101 | $field->setNotice($notice);
102 |
103 | $field = $this->addTextField('default');
104 | $field->setLabel(rex_i18n::msg('global_settings_field_label_default'));
105 |
106 | /*if ('clang_' !== $this->metaPrefix) {
107 | $attributes = [];
108 | $attributes['internal::fieldClass'] = 'rex_form_restrictons_element';
109 | $field = $this->addField('', 'restrictions', null, $attributes);
110 | $field->setLabel(rex_i18n::msg('global_settings_field_label_restrictions'));
111 | $field->setAttribute('size', 10);
112 | $field->setAttribute('class', 'form-control');
113 | }*/
114 |
115 | parent::init();
116 | }
117 |
118 | protected function delete()
119 | {
120 | // Infos zuerst selektieren, da nach parent::delete() nicht mehr in der db
121 | $sql = rex_sql::factory();
122 | $sql->setDebug($this->debug);
123 | $sql->setTable($this->tableName);
124 | $sql->setWhere($this->whereCondition);
125 | $sql->select('name');
126 | $columnName = $sql->getValue('name');
127 |
128 | if (($result = parent::delete()) === true) {
129 | // Prios neu setzen, damit keine lücken entstehen
130 | $this->organizePriorities(1, 2);
131 | return $this->tableManager->deleteColumn($columnName);
132 | }
133 |
134 | return $result;
135 | }
136 |
137 | protected function preSave($fieldsetName, $fieldName, $fieldValue, rex_sql $saveSql)
138 | {
139 | if ($fieldsetName == $this->getFieldsetName() && 'name' == $fieldName) {
140 | // Den Namen mit Prefix speichern
141 | return $this->addPrefix($fieldValue);
142 | }
143 |
144 | return parent::preSave($fieldsetName, $fieldName, $fieldValue, $saveSql);
145 | }
146 |
147 | protected function preView($fieldsetName, $fieldName, $fieldValue)
148 | {
149 | if ($fieldsetName == $this->getFieldsetName() && 'name' == $fieldName) {
150 | // Den Namen ohne Prefix anzeigen
151 | return $this->stripPrefix($fieldValue);
152 | }
153 | return parent::preView($fieldsetName, $fieldName, $fieldValue);
154 | }
155 |
156 | public function addPrefix($string)
157 | {
158 | $lowerString = strtolower($string);
159 | if (substr($lowerString, 0, strlen($this->metaPrefix)) !== $this->metaPrefix) {
160 | return $this->metaPrefix . $string;
161 | }
162 | return $string;
163 | }
164 |
165 | public function stripPrefix($string)
166 | {
167 | $lowerString = strtolower($string ?? '');
168 | if (substr($lowerString, 0, strlen($this->metaPrefix)) === $this->metaPrefix) {
169 | return substr($string, strlen($this->metaPrefix));
170 | }
171 | return $string;
172 | }
173 |
174 | protected function validate()
175 | {
176 | $fieldName = $this->elementPostValue($this->getFieldsetName(), 'name');
177 | if ('' == $fieldName) {
178 | return rex_i18n::msg('global_settings_field_error_name');
179 | }
180 |
181 | if (preg_match('/[^a-zA-Z0-9\_]/', $fieldName)) {
182 | return rex_i18n::msg('global_settings_field_error_chars_name');
183 | }
184 |
185 | // Pruefen ob schon eine Spalte mit dem Namen existiert (nur beim add noetig)
186 | if (!$this->isEditMode()) {
187 | // die tabelle selbst checken
188 | if ($this->tableManager->hasColumn($this->addPrefix($fieldName))) {
189 | return rex_i18n::msg('global_settings_field_error_unique_name');
190 | }
191 |
192 | // das meta-schema checken
193 | $sql = rex_sql::factory();
194 | $sql->setQuery('SELECT * FROM ' . $this->tableName . ' WHERE name="' . $this->addPrefix($fieldName) . '" LIMIT 1');
195 | if (1 == $sql->getRows()) {
196 | return rex_i18n::msg('global_settings_field_error_unique_name');
197 | }
198 | }
199 |
200 | return parent::validate();
201 | }
202 |
203 | protected function save()
204 | {
205 | $fieldName = $this->elementPostValue($this->getFieldsetName(), 'name');
206 |
207 | // Den alten Wert aus der DB holen
208 | // Dies muss hier geschehen, da in parent::save() die Werte fuer die DB mit den
209 | // POST werten ueberschrieben werden!
210 | $fieldOldName = '';
211 | $fieldOldPriority = 9999999999999; // dirty, damit die prio richtig l�uft...
212 | $fieldOldDefault = '';
213 | if (1 == $this->sql->getRows()) {
214 | $fieldOldName = $this->sql->getValue('name');
215 | $fieldOldPriority = $this->sql->getValue('priority');
216 | $fieldOldDefault = $this->sql->getValue('default');
217 | }
218 |
219 | if (parent::save()) {
220 | $this->organizePriorities($this->elementPostValue($this->getFieldsetName(), 'priority'), $fieldOldPriority);
221 |
222 | $fieldName = $this->addPrefix($fieldName);
223 | $fieldType = $this->elementPostValue($this->getFieldsetName(), 'type_id');
224 | $fieldDefault = $this->elementPostValue($this->getFieldsetName(), 'default');
225 |
226 | $sql = rex_sql::factory();
227 | $sql->setDebug($this->debug);
228 | $result = $sql->getArray('SELECT `dbtype`, `dblength` FROM `' . rex::getTablePrefix() . 'global_settings_type` WHERE id=' . $fieldType);
229 | $fieldDbType = $result[0]['dbtype'];
230 | $fieldDbLength = $result[0]['dblength'];
231 |
232 | // TEXT Spalten duerfen in MySQL keine Defaultwerte haben
233 | if ('text' == $fieldDbType) {
234 | $fieldDefault = null;
235 | }
236 |
237 | if ($this->isEditMode()) {
238 | // Spalte in der Tabelle ver�ndern
239 | $tmRes = $this->tableManager->editColumn($fieldOldName, $fieldName, $fieldDbType, $fieldDbLength, $fieldDefault);
240 | } else {
241 | // Spalte in der Tabelle anlegen
242 | $tmRes = $this->tableManager->addColumn($fieldName, $fieldDbType, $fieldDbLength, $fieldDefault);
243 | }
244 | rex_delete_cache();
245 |
246 | if ($tmRes) {
247 | // DefaultWerte setzen
248 | if ($fieldDefault != $fieldOldDefault) {
249 | try {
250 | $upd = rex_sql::factory();
251 | $upd->setDebug($this->debug);
252 | $upd->setTable($this->tableManager->getTableName());
253 | $upd->setWhere([$fieldName => $fieldOldDefault]);
254 | $upd->setValue($fieldName, $fieldDefault);
255 | $upd->update();
256 | return true;
257 | } catch (rex_sql_exception $e) {
258 | return false;
259 | }
260 | }
261 |
262 | // Default werte haben schon zuvor gepasst, daher true zur�ckgeben
263 | return true;
264 | }
265 | }
266 |
267 | return false;
268 | }
269 |
270 | public function getPrefix()
271 | {
272 | return $this->metaPrefix;
273 | }
274 |
275 | protected function organizePriorities($newPrio, $oldPrio)
276 | {
277 | if ($newPrio == $oldPrio) {
278 | return;
279 | }
280 |
281 | // replace LIKE wildcards
282 | $metaPrefix = str_replace(['_', '%'], ['\_', '\%'], $this->metaPrefix);
283 |
284 | rex_sql_util::organizePriorities(
285 | $this->tableName,
286 | 'priority',
287 | 'name LIKE "' . $metaPrefix . '%"',
288 | 'priority, updatedate desc',
289 | );
290 | }
291 | }
292 |
--------------------------------------------------------------------------------
/assets/css/spectrum.css:
--------------------------------------------------------------------------------
1 | /***
2 | Spectrum Colorpicker v1.8.0
3 | https://github.com/bgrins/spectrum
4 | Author: Brian Grinstead
5 | License: MIT
6 | ***/
7 |
8 | .sp-container {
9 | position: absolute;
10 | top: 0;
11 | left: 0;
12 | display: inline-block;
13 | *display: inline;
14 | *zoom: 1;
15 | /* https://github.com/bgrins/spectrum/issues/40 */
16 | z-index: 9999994;
17 | overflow: hidden;
18 | }
19 |
20 | .sp-container.sp-flat {
21 | position: relative;
22 | }
23 |
24 | /* Fix for * { box-sizing: border-box; } */
25 | .sp-container,
26 | .sp-container * {
27 | -webkit-box-sizing: content-box;
28 | -moz-box-sizing: content-box;
29 | box-sizing: content-box;
30 | }
31 |
32 | /* http://ansciath.tumblr.com/post/7347495869/css-aspect-ratio */
33 | .sp-top {
34 | position: relative;
35 | width: 100%;
36 | display: inline-block;
37 | }
38 |
39 | .sp-top-inner {
40 | position: absolute;
41 | top: 0;
42 | left: 0;
43 | bottom: 0;
44 | right: 0;
45 | }
46 |
47 | .sp-color {
48 | position: absolute;
49 | top: 0;
50 | left: 0;
51 | bottom: 0;
52 | right: 20%;
53 | }
54 |
55 | .sp-hue {
56 | position: absolute;
57 | top: 0;
58 | right: 0;
59 | bottom: 0;
60 | left: 84%;
61 | height: 100%;
62 | }
63 |
64 | .sp-clear-enabled .sp-hue {
65 | top: 33px;
66 | height: 77.5%;
67 | }
68 |
69 | .sp-fill {
70 | padding-top: 80%;
71 | }
72 |
73 | .sp-sat, .sp-val {
74 | position: absolute;
75 | top: 0;
76 | left: 0;
77 | right: 0;
78 | bottom: 0;
79 | }
80 |
81 | .sp-alpha-enabled .sp-top {
82 | margin-bottom: 18px;
83 | }
84 |
85 | .sp-alpha-enabled .sp-alpha {
86 | display: block;
87 | }
88 |
89 | .sp-alpha-handle {
90 | position: absolute;
91 | top: -4px;
92 | bottom: -4px;
93 | width: 6px;
94 | left: 50%;
95 | cursor: pointer;
96 | border: 1px solid black;
97 | background: white;
98 | opacity: .8;
99 | }
100 |
101 | .sp-alpha {
102 | display: none;
103 | position: absolute;
104 | bottom: -14px;
105 | right: 0;
106 | left: 0;
107 | height: 8px;
108 | }
109 |
110 | .sp-alpha-inner {
111 | border: solid 1px #333333;
112 | }
113 |
114 | .sp-clear {
115 | display: none;
116 | }
117 |
118 | .sp-clear.sp-clear-display {
119 | background-position: center;
120 | }
121 |
122 | .sp-clear-enabled .sp-clear {
123 | display: block;
124 | position: absolute;
125 | top: 0px;
126 | right: 0;
127 | bottom: 0;
128 | left: 84%;
129 | height: 28px;
130 | }
131 |
132 | /* Don't allow text selection */
133 | .sp-container, .sp-replacer, .sp-preview, .sp-dragger, .sp-slider, .sp-alpha, .sp-clear, .sp-alpha-handle, .sp-container.sp-dragging .sp-input, .sp-container button {
134 | -webkit-user-select: none;
135 | -moz-user-select: -moz-none;
136 | -o-user-select: none;
137 | user-select: none;
138 | }
139 |
140 | .sp-container.sp-input-disabled .sp-input-container {
141 | display: none;
142 | }
143 |
144 | .sp-container.sp-buttons-disabled .sp-button-container {
145 | display: none;
146 | }
147 |
148 | .sp-container.sp-palette-buttons-disabled .sp-palette-button-container {
149 | display: none;
150 | }
151 |
152 | .sp-palette-only .sp-picker-container {
153 | display: none;
154 | }
155 |
156 | .sp-palette-disabled .sp-palette-container {
157 | display: none;
158 | }
159 |
160 | .sp-initial-disabled .sp-initial {
161 | display: none;
162 | }
163 |
164 |
165 | /* Gradients for hue, saturation and value instead of images. Not pretty... but it works */
166 | .sp-sat {
167 | background-image: -webkit-gradient(linear, 0 0, 100% 0, from(#ffffff), to(rgba(204, 154, 129, 0)));
168 | background-image: -webkit-linear-gradient(left, #ffffff, rgba(204, 154, 129, 0));
169 | background-image: -moz-linear-gradient(left, #ffffff, rgba(204, 154, 129, 0));
170 | background-image: -o-linear-gradient(left, #ffffff, rgba(204, 154, 129, 0));
171 | background-image: -ms-linear-gradient(left, #ffffff, rgba(204, 154, 129, 0));
172 | background-image: linear-gradient(to right, #ffffff, rgba(204, 154, 129, 0));
173 | -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr=#FFFFFFFF, endColorstr=#00CC9A81)";
174 | filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr="#FFFFFFFF", endColorstr="#00CC9A81");
175 | }
176 |
177 | .sp-val {
178 | background-image: -webkit-gradient(linear, 0 100%, 0 0, from(#000000), to(rgba(204, 154, 129, 0)));
179 | background-image: -webkit-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0));
180 | background-image: -moz-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0));
181 | background-image: -o-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0));
182 | background-image: -ms-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0));
183 | background-image: linear-gradient(to top, #000000, rgba(204, 154, 129, 0));
184 | -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#00CC9A81, endColorstr=#FF000000)";
185 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#00CC9A81", endColorstr="#FF000000");
186 | }
187 |
188 | .sp-hue {
189 | background: -moz-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
190 | background: -ms-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
191 | background: -o-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
192 | background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), color-stop(0.17, #ffff00), color-stop(0.33, #00ff00), color-stop(0.5, #00ffff), color-stop(0.67, #0000ff), color-stop(0.83, #ff00ff), to(#ff0000));
193 | background: -webkit-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
194 | background: linear-gradient(to bottom, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
195 | }
196 |
197 | /* IE filters do not support multiple color stops.
198 | Generate 6 divs, line them up, and do two color gradients for each.
199 | Yes, really.
200 | */
201 | .sp-1 {
202 | height: 17%;
203 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff0000", endColorstr="#ffff00");
204 | }
205 |
206 | .sp-2 {
207 | height: 16%;
208 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#ffff00", endColorstr="#00ff00");
209 | }
210 |
211 | .sp-3 {
212 | height: 17%;
213 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#00ff00", endColorstr="#00ffff");
214 | }
215 |
216 | .sp-4 {
217 | height: 17%;
218 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#00ffff", endColorstr="#0000ff");
219 | }
220 |
221 | .sp-5 {
222 | height: 16%;
223 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#0000ff", endColorstr="#ff00ff");
224 | }
225 |
226 | .sp-6 {
227 | height: 17%;
228 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff00ff", endColorstr="#ff0000");
229 | }
230 |
231 | .sp-hidden {
232 | display: none !important;
233 | }
234 |
235 | /* Clearfix hack */
236 | .sp-cf:before, .sp-cf:after {
237 | content: "";
238 | display: table;
239 | }
240 |
241 | .sp-cf:after {
242 | clear: both;
243 | }
244 |
245 | .sp-cf {
246 | *zoom: 1;
247 | }
248 |
249 | /* Mobile devices, make hue slider bigger so it is easier to slide */
250 | @media (max-device-width: 480px) {
251 | .sp-color {
252 | right: 40%;
253 | }
254 |
255 | .sp-hue {
256 | left: 63%;
257 | }
258 |
259 | .sp-fill {
260 | padding-top: 60%;
261 | }
262 | }
263 |
264 | .sp-dragger {
265 | border-radius: 5px;
266 | height: 5px;
267 | width: 5px;
268 | border: 1px solid #ffffff;
269 | background: #000000;
270 | cursor: pointer;
271 | position: absolute;
272 | top: 0;
273 | left: 0;
274 | }
275 |
276 | .sp-slider {
277 | position: absolute;
278 | top: 0;
279 | cursor: pointer;
280 | height: 3px;
281 | left: -1px;
282 | right: -1px;
283 | border: 1px solid #000000;
284 | background: white;
285 | opacity: .8;
286 | }
287 |
288 | /*
289 | Theme authors:
290 | Here are the basic themeable display options (colors, fonts, global widths).
291 | See http://bgrins.github.io/spectrum/themes/ for instructions.
292 | */
293 |
294 | .sp-container {
295 | border-radius: 0;
296 | background-color: #ececec;
297 | border: solid 1px #f0c49b;
298 | padding: 0;
299 | }
300 |
301 | .sp-container, .sp-container button, .sp-container input, .sp-color, .sp-hue, .sp-clear {
302 | font: normal 12px "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif;
303 | -webkit-box-sizing: border-box;
304 | -moz-box-sizing: border-box;
305 | -ms-box-sizing: border-box;
306 | box-sizing: border-box;
307 | }
308 |
309 | .sp-top {
310 | margin-bottom: 3px;
311 | }
312 |
313 | .sp-color, .sp-hue, .sp-clear {
314 | border: solid 1px #666666;
315 | }
316 |
317 | /* Input */
318 | .sp-input-container {
319 | float: right;
320 | width: 100px;
321 | margin-bottom: 4px;
322 | }
323 |
324 | .sp-initial-disabled .sp-input-container {
325 | width: 100%;
326 | }
327 |
328 | .sp-input {
329 | font-size: 12px !important;
330 | border: 1px inset;
331 | padding: 4px 5px;
332 | margin: 0;
333 | width: 100%;
334 | background: transparent;
335 | border-radius: 3px;
336 | color: #222222;
337 | }
338 |
339 | .sp-input:focus {
340 | border: 1px solid orange;
341 | }
342 |
343 | .sp-input.sp-validation-error {
344 | border: 1px solid red;
345 | background: #ffdddd;
346 | }
347 |
348 | .sp-picker-container, .sp-palette-container {
349 | float: left;
350 | position: relative;
351 | padding: 10px;
352 | padding-bottom: 300px;
353 | margin-bottom: -290px;
354 | }
355 |
356 | .sp-picker-container {
357 | width: 172px;
358 | border-left: solid 1px #ffffff;
359 | }
360 |
361 | /* Palettes */
362 | .sp-palette-container {
363 | border-right: solid 1px #cccccc;
364 | }
365 |
366 | .sp-palette-only .sp-palette-container {
367 | border: 0;
368 | }
369 |
370 | .sp-palette .sp-thumb-el {
371 | display: block;
372 | position: relative;
373 | float: left;
374 | width: 24px;
375 | height: 15px;
376 | margin: 3px;
377 | cursor: pointer;
378 | border: solid 2px transparent;
379 | }
380 |
381 | .sp-palette .sp-thumb-el:hover, .sp-palette .sp-thumb-el.sp-thumb-active {
382 | border-color: orange;
383 | }
384 |
385 | .sp-thumb-el {
386 | position: relative;
387 | }
388 |
389 | /* Initial */
390 | .sp-initial {
391 | float: left;
392 | border: solid 1px #333333;
393 | }
394 |
395 | .sp-initial span {
396 | width: 30px;
397 | height: 25px;
398 | border: none;
399 | display: block;
400 | float: left;
401 | margin: 0;
402 | }
403 |
404 | .sp-initial .sp-clear-display {
405 | background-position: center;
406 | }
407 |
408 | /* Buttons */
409 | .sp-palette-button-container,
410 | .sp-button-container {
411 | float: right;
412 | }
413 |
414 | /* Replacer (the little preview div that shows up instead of the ) */
415 | .sp-replacer {
416 | margin: 0;
417 | overflow: hidden;
418 | cursor: pointer;
419 | padding: 4px;
420 | display: inline-block;
421 | *zoom: 1;
422 | *display: inline;
423 | border: solid 1px #91765d;
424 | background: #eeeeee;
425 | color: #333333;
426 | vertical-align: middle;
427 | }
428 |
429 | .sp-replacer:hover, .sp-replacer.sp-active {
430 | border-color: #f0c49b;
431 | color: #111111;
432 | }
433 |
434 | .sp-replacer.sp-disabled {
435 | cursor: default;
436 | border-color: silver;
437 | color: silver;
438 | }
439 |
440 | .sp-dd {
441 | padding: 2px 0;
442 | height: 16px;
443 | line-height: 16px;
444 | float: left;
445 | font-size: 10px;
446 | }
447 |
448 | .sp-preview {
449 | position: relative;
450 | width: 25px;
451 | height: 20px;
452 | border: solid 1px #222222;
453 | margin-right: 5px;
454 | float: left;
455 | z-index: 0;
456 | }
457 |
458 | .sp-palette {
459 | *width: 220px;
460 | max-width: 220px;
461 | }
462 |
463 | .sp-palette .sp-thumb-el {
464 | width: 16px;
465 | height: 16px;
466 | margin: 2px 1px;
467 | border: solid 1px #d0d0d0;
468 | }
469 |
470 | .sp-container {
471 | padding-bottom: 0;
472 | }
473 |
474 |
475 | /* Buttons: http://hellohappy.org/css3-buttons/ */
476 | .sp-container button {
477 | background-color: #eeeeee;
478 | background-image: -webkit-linear-gradient(top, #eeeeee, #cccccc);
479 | background-image: -moz-linear-gradient(top, #eeeeee, #cccccc);
480 | background-image: -ms-linear-gradient(top, #eeeeee, #cccccc);
481 | background-image: -o-linear-gradient(top, #eeeeee, #cccccc);
482 | background-image: linear-gradient(to bottom, #eeeeee, #cccccc);
483 | border: 1px solid #cccccc;
484 | border-bottom: 1px solid #bbbbbb;
485 | border-radius: 3px;
486 | color: #333333;
487 | font-size: 14px;
488 | line-height: 1;
489 | padding: 5px 4px;
490 | text-align: center;
491 | text-shadow: 0 1px 0 #eeeeee;
492 | vertical-align: middle;
493 | }
494 |
495 | .sp-container button:hover {
496 | background-color: #dddddd;
497 | background-image: -webkit-linear-gradient(top, #dddddd, #bbbbbb);
498 | background-image: -moz-linear-gradient(top, #dddddd, #bbbbbb);
499 | background-image: -ms-linear-gradient(top, #dddddd, #bbbbbb);
500 | background-image: -o-linear-gradient(top, #dddddd, #bbbbbb);
501 | background-image: linear-gradient(to bottom, #dddddd, #bbbbbb);
502 | border: 1px solid #bbbbbb;
503 | border-bottom: 1px solid #999999;
504 | cursor: pointer;
505 | text-shadow: 0 1px 0 #dddddd;
506 | }
507 |
508 | .sp-container button:active {
509 | border: 1px solid #aaaaaa;
510 | border-bottom: 1px solid #888888;
511 | -webkit-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
512 | -moz-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
513 | -ms-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
514 | -o-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
515 | box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
516 | }
517 |
518 | .sp-cancel {
519 | font-size: 11px;
520 | color: #d93f3f !important;
521 | margin: 0;
522 | padding: 2px;
523 | margin-right: 5px;
524 | vertical-align: middle;
525 | text-decoration: none;
526 |
527 | }
528 |
529 | .sp-cancel:hover {
530 | color: #d93f3f !important;
531 | text-decoration: underline;
532 | }
533 |
534 |
535 | .sp-palette span:hover, .sp-palette span.sp-thumb-active {
536 | border-color: #000000;
537 | }
538 |
539 | .sp-preview, .sp-alpha, .sp-thumb-el {
540 | position: relative;
541 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);
542 | }
543 |
544 | .sp-preview-inner, .sp-alpha-inner, .sp-thumb-inner {
545 | display: block;
546 | position: absolute;
547 | top: 0;
548 | left: 0;
549 | bottom: 0;
550 | right: 0;
551 | }
552 |
553 | .sp-palette .sp-thumb-inner {
554 | background-position: 50% 50%;
555 | background-repeat: no-repeat;
556 | }
557 |
558 | .sp-palette .sp-thumb-light.sp-thumb-active .sp-thumb-inner {
559 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIVJREFUeNpiYBhsgJFMffxAXABlN5JruT4Q3wfi/0DsT64h8UD8HmpIPCWG/KemIfOJCUB+Aoacx6EGBZyHBqI+WsDCwuQ9mhxeg2A210Ntfo8klk9sOMijaURm7yc1UP2RNCMbKE9ODK1HM6iegYLkfx8pligC9lCD7KmRof0ZhjQACDAAceovrtpVBRkAAAAASUVORK5CYII=);
560 | }
561 |
562 | .sp-palette .sp-thumb-dark.sp-thumb-active .sp-thumb-inner {
563 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAMdJREFUOE+tkgsNwzAMRMugEAahEAahEAZhEAqlEAZhEAohEAYh81X2dIm8fKpEspLGvudPOsUYpxE2BIJCroJmEW9qJ+MKaBFhEMNabSy9oIcIPwrB+afvAUFoK4H0tMaQ3XtlrggDhOVVMuT4E5MMG0FBbCEYzjYT7OxLEvIHQLY2zWwQ3D+9luyOQTfKDiFD3iUIfPk8VqrKjgAiSfGFPecrg6HN6m/iBcwiDAo7WiBeawa+Kwh7tZoSCGLMqwlSAzVDhoK+6vH4G0P5wdkAAAAASUVORK5CYII=);
564 | }
565 |
566 | .sp-clear-display {
567 | background-repeat: no-repeat;
568 | background-position: center;
569 | background-image: url(data:image/gif;base64,R0lGODlhFAAUAPcAAAAAAJmZmZ2dnZ6enqKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq/Hx8fLy8vT09PX19ff39/j4+Pn5+fr6+vv7+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAAUABQAAAihAP9FoPCvoMGDBy08+EdhQAIJCCMybCDAAYUEARBAlFiQQoMABQhKUJBxY0SPICEYHBnggEmDKAuoPMjS5cGYMxHW3IiT478JJA8M/CjTZ0GgLRekNGpwAsYABHIypcAgQMsITDtWJYBR6NSqMico9cqR6tKfY7GeBCuVwlipDNmefAtTrkSzB1RaIAoXodsABiZAEFB06gIBWC1mLVgBa0AAOw==);
570 | }
571 |
--------------------------------------------------------------------------------
/lib/handler/handler.php:
--------------------------------------------------------------------------------
1 | reset();
31 | for ($i = 0; $i < $sqlFields->getRows(); $i++, $sqlFields->next()) {
32 | // Umschliessendes Tag von Label und Formularelement
33 | $tag = 'p';
34 | $tag_attr = '';
35 |
36 | $name = $sqlFields->getValue('name');
37 | $notice = $sqlFields->getValue('notice');
38 | $title = $sqlFields->getValue('title');
39 | $params = $sqlFields->getValue('params');
40 | $typeLabel = $sqlFields->getValue('label');
41 | $attr = $sqlFields->getValue('attributes');
42 | $dblength = $sqlFields->getValue('dblength');
43 |
44 | $attrArray = rex_string::split($attr);
45 | if (isset($attrArray['perm']) && 'tab' !== $typeLabel) {
46 | if (!rex::getUser()->hasPerm($attrArray['perm'])) {
47 | continue;
48 | }
49 | unset($attrArray['perm']);
50 | }
51 |
52 | if ('tab' !== $typeLabel && $fieldWithinTab && $hideByTabPerm) {
53 | continue;
54 | }
55 |
56 | $defaultValue = $sqlFields->getValue('default');
57 | if ($activeItem) {
58 | $itemValue = (string) $activeItem->getValue($name);
59 |
60 | if (str_contains($itemValue, '|+|')) {
61 | // Alte notation mit |+| als Trenner
62 | $dbvalues = explode('|+|', (string) $activeItem->getValue($name));
63 | } else {
64 | // Neue Notation mit | als Trenner
65 | $dbvalues = explode('|', (string) $activeItem->getValue($name));
66 | }
67 | } else {
68 | $dbvalues = (array) $sqlFields->getValue('default');
69 | }
70 |
71 | if ('' != $title) {
72 | $label = rex_i18n::translate($title);
73 | } else {
74 | $label = htmlspecialchars($name);
75 | }
76 |
77 | $id = 'rex-global_settings-' . htmlspecialchars(preg_replace('/[^a-zA-Z0-9_-]/', '_', $name));
78 | $labelIt = true;
79 |
80 | $label = '';
81 |
82 | $field = '';
83 |
84 | switch ($typeLabel) {
85 | case 'text':
86 | $tag_attr = ' class="form-control"';
87 |
88 | $rexInput = rex_global_settings_input::factory($typeLabel);
89 | $rexInput->addAttributes($attrArray);
90 | $rexInput->setAttribute('id', $id);
91 | $rexInput->setAttribute('name', $name);
92 | if ($dblength > 0) {
93 | $rexInput->setAttribute('maxlength', $dblength);
94 | }
95 | if ($activeItem) {
96 | $rexInput->setValue($activeItem->getValue($name));
97 | } else {
98 | $rexInput->setValue($defaultValue);
99 | }
100 | $field = $rexInput->getHtml();
101 |
102 | $e = [];
103 | $e['label'] = $label;
104 | $e['field'] = $field;
105 | $e['note'] = $notice;
106 | $fragment = new rex_fragment();
107 | $fragment->setVar('elements', [$e], false);
108 | $field = $fragment->parse('core/form/form.php');
109 |
110 | break;
111 | case 'rgbacolorpicker':
112 | case 'colorpicker':
113 | $tag_attr = ' class="form-control"';
114 |
115 | $rexInput = rex_global_settings_input::factory($typeLabel);
116 | $rexInput->addAttributes($attrArray);
117 | $rexInput->setAttribute('id', $id);
118 | $rexInput->setAttribute('name', $name);
119 | if ($dblength > 0) {
120 | $rexInput->setAttribute('maxlength', $dblength);
121 | }
122 | if ($activeItem) {
123 | $rexInput->setValue($activeItem->getValue($name));
124 | } else {
125 | $rexInput->setValue($defaultValue);
126 | }
127 | $field = $rexInput->getHtml();
128 |
129 | $e = [];
130 | $e['label'] = $label;
131 | $e['field'] = $field;
132 | $e['note'] = $notice;
133 | $fragment = new rex_fragment();
134 | $fragment->setVar('elements', [$e], false);
135 | $field = $fragment->parse('core/form/form.php');
136 |
137 | break;
138 | case 'checkbox':
139 | // Beachte auch default values in multiple fields bei ADD.
140 | // Im EDIT wurde dies bereits vorher gehandelt
141 | if (!$activeItem) {
142 | $defaultValue = explode('|', $defaultValue);
143 | }
144 |
145 | $name .= '[]';
146 | // no break
147 | case 'radio':
148 | $formElements = [];
149 |
150 | $values = [];
151 | if ('SELECT' == rex_sql::getQueryType($params)) {
152 | $sql = rex_sql::factory();
153 | $value_groups = $sql->getDBArray($params, [], PDO::FETCH_NUM);
154 | foreach ($value_groups as $value_group) {
155 | if (isset($value_group[1])) {
156 | $values[$value_group[1]] = $value_group[0];
157 | } else {
158 | $values[$value_group[0]] = $value_group[0];
159 | }
160 | }
161 | } else {
162 | $value_groups = explode('|', $params);
163 | foreach ($value_groups as $value_group) {
164 | // check ob key:value paar
165 | // und der wert beginnt nicht mit "translate:"
166 | if (str_contains($value_group, ':')
167 | && !str_starts_with($value_group, 'translate:')
168 | ) {
169 | $temp = explode(':', $value_group, 2);
170 | $values[$temp[0]] = rex_i18n::translate($temp[1]);
171 | } else {
172 | $values[$value_group] = rex_i18n::translate($value_group);
173 | }
174 | }
175 | }
176 |
177 | $oneValue = (1 == count($values));
178 |
179 | $attrStr = '';
180 | $classAdd = '';
181 | $inline = false;
182 |
183 | if (false !== $key = array_search('inline', $attrArray)) {
184 | $inline = true;
185 | unset($attrArray[$key]);
186 | }
187 | foreach ($attrArray as $key => $value) {
188 | if ('class' == $key) {
189 | $classAdd = ' ' . $value;
190 | } else {
191 | $attrStr = ' ' . $key . '="' . $value . '"';
192 | }
193 | }
194 |
195 | if (!$activeItem) {
196 | $dbvalues = (array) $defaultValue;
197 | }
198 |
199 | foreach ($values as $key => $value) {
200 | // wenn man keine Werte angibt (Boolean Chkbox/Radio)
201 | // Dummy Wert annehmen, damit an/aus unterscheidung funktioniert
202 | if ($oneValue && '' == $key) {
203 | $key = 'true';
204 | }
205 |
206 | $selected = '';
207 | if (in_array($key, $dbvalues)) {
208 | $selected = ' checked="checked"';
209 | }
210 |
211 | $currentId = $id;
212 |
213 | $e = [];
214 | if ($oneValue) {
215 | $e['label'] = $label;
216 | } else {
217 | $currentId .= '-' . htmlspecialchars(preg_replace('/[^a-zA-Z0-9_-]/', '_', $key));
218 | $e['label'] = '';
219 | }
220 | $e['field'] = '';
221 | $formElements[] = $e;
222 | }
223 |
224 | $fragment = new rex_fragment();
225 | $fragment->setVar('elements', $formElements, false);
226 | $fragment->setVar('inline', $inline);
227 |
228 | if ('radio' == $typeLabel) {
229 | $field = $fragment->parse('core/form/radio.php');
230 | } else {
231 | if (!$oneValue) {
232 | $fragment->setVar('grouped', true);
233 | }
234 | $field = $fragment->parse('core/form/checkbox.php');
235 | }
236 |
237 | if (!$oneValue) {
238 | $e = [];
239 | $e['label'] = $label;
240 | $e['field'] = $field;
241 | $e['note'] = $notice;
242 | $fragment = new rex_fragment();
243 | $fragment->setVar('elements', [$e], false);
244 | $field = $fragment->parse('core/form/form.php');
245 | }
246 |
247 | break;
248 | case 'select':
249 | $tag_attr = ' class="form-control"';
250 |
251 | $select = new rex_select();
252 | $select->setStyle('class="form-control"');
253 | $select->setName($name);
254 | $select->setId($id);
255 |
256 | $multiple = false;
257 | foreach ($attrArray as $attr_name => $attr_value) {
258 | if (empty($attr_name)) {
259 | continue;
260 | }
261 |
262 | $select->setAttribute($attr_name, $attr_value);
263 |
264 | if ('multiple' == $attr_name) {
265 | $multiple = true;
266 | $select->setName($name . '[]');
267 | $select->setMultiple();
268 | }
269 | }
270 |
271 | // Beachte auch default values in multiple fields bei ADD.
272 | // Im EDIT wurde dies bereits vorher gehandelt
273 | if ($multiple && !$activeItem) {
274 | $dbvalues = explode('|', $defaultValue);
275 | }
276 |
277 | // hier mit den "raw"-values arbeiten, da die rex_select klasse selbst escaped
278 | $select->setSelected($dbvalues);
279 |
280 | if ('SELECT' == rex_sql::getQueryType($params)) {
281 | // Werte via SQL Laden
282 | $select->addDBSqlOptions($params);
283 | } else {
284 | // Optionen mit | separiert
285 | // eine einzelne Option kann mit key:value separiert werden
286 | $values = [];
287 | $value_groups = explode('|', $params);
288 | foreach ($value_groups as $value_group) {
289 | // check ob key:value paar
290 | // und der wert beginnt nicht mit "translate:"
291 | if (str_contains($value_group, ':')
292 | && !str_starts_with($value_group, 'translate:')
293 | ) {
294 | $temp = explode(':', $value_group, 2);
295 | $values[$temp[0]] = rex_i18n::translate($temp[1]);
296 | } else {
297 | $values[$value_group] = rex_i18n::translate($value_group);
298 | }
299 | }
300 | $select->addOptions($values);
301 | }
302 |
303 | $field .= $select->get();
304 |
305 | $e = [];
306 | $e['label'] = $label;
307 | $e['field'] = $field;
308 | $e['note'] = $notice;
309 | $fragment = new rex_fragment();
310 | $fragment->setVar('elements', [$e], false);
311 | $field = $fragment->parse('core/form/form.php');
312 |
313 | break;
314 | case 'date':
315 | case 'time':
316 | case 'datetime':
317 | $tag_attr = ' class="form-control-date"';
318 |
319 | $active = 0 != $dbvalues[0];
320 | if ('' == $dbvalues[0]) {
321 | $dbvalues[0] = time();
322 | }
323 |
324 | $inputValue = [];
325 | $inputValue['year'] = date('Y', $dbvalues[0]);
326 | $inputValue['month'] = date('n', $dbvalues[0]);
327 | $inputValue['day'] = date('j', $dbvalues[0]);
328 | $inputValue['hour'] = date('G', $dbvalues[0]);
329 | $inputValue['minute'] = date('i', $dbvalues[0]);
330 |
331 | $rexInput = rex_global_settings_input::factory($typeLabel);
332 | $rexInput->addAttributes($attrArray);
333 | $rexInput->setAttribute('id', $id);
334 | $rexInput->setAttribute('name', $name);
335 | $rexInput->setValue($inputValue);
336 | $field = $rexInput->getHtml();
337 |
338 | $checked = $active ? ' checked="checked"' : '';
339 | $field .= '';
340 |
341 | $e = [];
342 | $e['label'] = $label;
343 | $e['field'] = $field;
344 | $e['note'] = $notice;
345 | $fragment = new rex_fragment();
346 | $fragment->setVar('elements', [$e], false);
347 | $field = $fragment->parse('core/form/form.php');
348 |
349 | break;
350 | case 'textarea':
351 | $tag_attr = ' class="form-control"';
352 |
353 | $rexInput = rex_global_settings_input::factory($typeLabel);
354 | $rexInput->addAttributes($attrArray);
355 | $rexInput->setAttribute('id', $id);
356 | $rexInput->setAttribute('name', $name);
357 | if ($activeItem) {
358 | $rexInput->setValue($activeItem->getValue($name));
359 | } else {
360 | $rexInput->setValue($defaultValue);
361 | }
362 | $field = $rexInput->getHtml();
363 |
364 | $e = [];
365 | $e['label'] = $label;
366 | $e['field'] = $field;
367 | $e['note'] = $notice;
368 | $fragment = new rex_fragment();
369 | $fragment->setVar('elements', [$e], false);
370 | $field = $fragment->parse('core/form/form.php');
371 |
372 | break;
373 | case 'legend':
374 | $tag = '';
375 | $tag_attr = '';
376 | $labelIt = false;
377 |
378 | // tabindex entfernen, macht bei einer legend wenig sinn
379 | $attr = preg_replace('@tabindex="[^"]*"@', '', $attr);
380 |
381 | $field = '';
382 |
383 | /**
384 | * add notice to legend.
385 | */
386 | if ($notice) {
387 | $field .= '' . $notice . '
';
388 | }
389 |
390 | break;
391 | case 'tab':
392 | $tag = '';
393 | $tag_attr = '';
394 | $labelIt = false;
395 | $fieldWithinTab = true;
396 | $hideByTabPerm = false;
397 |
398 | if (isset($attrArray['perm'])) {
399 | if (!rex::getUser()->hasPerm($attrArray['perm'])) {
400 | $hideByTabPerm = true;
401 | break;
402 | }
403 | }
404 |
405 | // tabindex entfernen, macht bei einer legend wenig sinn
406 | $attr = preg_replace('@tabindex="[^"]*"@', '', $attr);
407 |
408 | // $field = ' ';
409 |
410 | if (0 == count($tabs)) {
411 | $field = '';
412 | } else {
413 | $field = '';
414 | }
415 |
416 | /**
417 | * add notice to tabs.
418 | */
419 | if ($notice) {
420 | $field .= '' . $notice . '
';
421 | }
422 |
423 | $tabs[] = ['name' => $label, 'id' => $id];
424 |
425 | break;
426 | case 'REX_MEDIA_WIDGET':
427 | $tag = 'div';
428 | $tag_attr = ' class="rex-form-widget"';
429 |
430 | $paramArray = rex_string::split($params);
431 |
432 | $rexInput = rex_global_settings_input::factory('mediabutton');
433 | $rexInput->addAttributes($attrArray);
434 | $rexInput->setButtonId($media_id);
435 | $rexInput->setAttribute('name', $name);
436 | $rexInput->setValue($dbvalues[0]);
437 |
438 | if (isset($paramArray['category'])) {
439 | $rexInput->setCategoryId($paramArray['category']);
440 | }
441 | if (isset($paramArray['types'])) {
442 | $rexInput->setTypes($paramArray['types']);
443 | }
444 | if (isset($paramArray['preview'])) {
445 | $rexInput->setPreview($paramArray['preview']);
446 | }
447 |
448 | $id = $rexInput->getAttribute('id');
449 | $field = $rexInput->getHtml();
450 |
451 | $e = [];
452 | $e['label'] = $label;
453 | $e['field'] = $field;
454 | $e['note'] = $notice;
455 | $fragment = new rex_fragment();
456 | $fragment->setVar('elements', [$e], false);
457 | $field = $fragment->parse('core/form/form.php');
458 |
459 | ++$media_id;
460 | break;
461 | case 'REX_MEDIALIST_WIDGET':
462 | $tag = 'div';
463 | $tag_attr = ' class="rex-form-widget"';
464 |
465 | $paramArray = rex_string::split($params);
466 |
467 | $name .= '[]';
468 | $rexInput = rex_global_settings_input::factory('medialistbutton');
469 | $rexInput->addAttributes($attrArray);
470 | $rexInput->setButtonId($mlist_id);
471 | $rexInput->setAttribute('name', $name);
472 | $rexInput->setValue($dbvalues[0]);
473 |
474 | if (isset($paramArray['category'])) {
475 | $rexInput->setCategoryId($paramArray['category']);
476 | }
477 | if (isset($paramArray['types'])) {
478 | $rexInput->setTypes($paramArray['types']);
479 | }
480 | if (isset($paramArray['preview'])) {
481 | $rexInput->setPreview($paramArray['preview']);
482 | }
483 |
484 | $id = $rexInput->getAttribute('id');
485 | $field = $rexInput->getHtml();
486 |
487 | $e = [];
488 | $e['label'] = $label;
489 | $e['field'] = $field;
490 | $e['note'] = $notice;
491 | $fragment = new rex_fragment();
492 | $fragment->setVar('elements', [$e], false);
493 | $field = $fragment->parse('core/form/form.php');
494 |
495 | ++$mlist_id;
496 | break;
497 | case 'REX_LINK_WIDGET':
498 | $tag = 'div';
499 | $tag_attr = ' class="rex-form-widget"';
500 |
501 | $paramArray = rex_string::split($params);
502 | $category = '';
503 | if (isset($paramArray['category'])) {
504 | $category = $paramArray['category'];
505 | } elseif ($activeItem) {
506 | $category = $activeItem->getValue('category_id');
507 | }
508 |
509 | $rexInput = rex_global_settings_input::factory('linkbutton');
510 | $rexInput->addAttributes($attrArray);
511 | $rexInput->setButtonId($link_id);
512 | $rexInput->setCategoryId($category);
513 | $rexInput->setAttribute('name', $name);
514 | $rexInput->setValue($dbvalues[0]);
515 | $id = $rexInput->getAttribute('id');
516 | $field = $rexInput->getHtml();
517 |
518 | $e = [];
519 | $e['label'] = $label;
520 | $e['field'] = $field;
521 | $e['note'] = $notice;
522 | $fragment = new rex_fragment();
523 | $fragment->setVar('elements', [$e], false);
524 | $field = $fragment->parse('core/form/form.php');
525 |
526 | ++$link_id;
527 | break;
528 | case 'REX_LINKLIST_WIDGET':
529 | $tag = 'div';
530 | $tag_attr = ' class="rex-form-widget"';
531 |
532 | $paramArray = rex_string::split($params);
533 | $category = '';
534 | if (isset($paramArray['category'])) {
535 | $category = $paramArray['category'];
536 | } elseif ($activeItem) {
537 | $category = $activeItem->getValue('category_id');
538 | }
539 |
540 | $name .= '[]';
541 | $rexInput = rex_global_settings_input::factory('linklistbutton');
542 | $rexInput->addAttributes($attrArray);
543 | $rexInput->setButtonId($llist_id);
544 | $rexInput->setCategoryId($category);
545 | $rexInput->setAttribute('name', $name);
546 | $rexInput->setValue(implode(',', $dbvalues));
547 | $id = $rexInput->getAttribute('id');
548 | $field = $rexInput->getHtml();
549 |
550 | $e = [];
551 | $e['label'] = $label;
552 | $e['field'] = $field;
553 | $e['note'] = $notice;
554 | $fragment = new rex_fragment();
555 | $fragment->setVar('elements', [$e], false);
556 | $field = $fragment->parse('core/form/form.php');
557 |
558 | ++$llist_id;
559 | break;
560 | default:
561 | // ----- EXTENSION POINT
562 | [$field, $tag, $tag_attr, $id, $label, $labelIt] =
563 | rex_extension::registerPoint(new rex_extension_point(
564 | 'GLOBAL_SETTINGS_CUSTOM_FIELD',
565 | [
566 | $field,
567 | $tag,
568 | $tag_attr,
569 | $id,
570 | $label,
571 | $labelIt,
572 | 'values' => $dbvalues,
573 | 'rawvalues' => $dbvalues,
574 | 'type' => $typeLabel,
575 | 'sql' => $sqlFields,
576 | ],
577 | ));
578 | }
579 |
580 | $s .= $this->renderFormItem($field, $tag, $tag_attr, $id, $label, $labelIt, $typeLabel);
581 | }
582 |
583 | $out = $s;
584 |
585 | if (count($tabs) > 0) {
586 | $s .= ''; // close tab panel
587 |
588 | $tabControl = '';
589 | $tabControl = '';
602 | $tabControl .= '';
603 | $tabControl .= $s;
604 | $tabControl .= '';
605 |
606 | // add js for persistant tabs (tabs keep position after reload )
607 | $tabControl .= "
608 | ";
620 |
621 | $out = $tabControl;
622 | }
623 |
624 | return str_replace('">' . rex_global_settings::FIELD_PREFIX, '">', $out);
625 | }
626 |
627 | /**
628 | * Übernimmt die gePOSTeten werte in ein rex_sql-Objekt.
629 | *
630 | * @param array $params
631 | * @param rex_sql $sqlSave rex_sql-objekt, in das die aktuellen Werte gespeichert werden sollen
632 | * @param rex_sql $sqlFields rex_sql-objekt, dass die zu verarbeitenden Felder enthält
633 | */
634 | public static function fetchRequestValues(&$params, &$sqlSave, $sqlFields)
635 | {
636 | if ('post' != rex_request_method()) {
637 | return;
638 | }
639 |
640 | $isRestrictedTab = false;
641 |
642 | for ($i = 0; $i < $sqlFields->getRows(); $i++, $sqlFields->next()) {
643 | $fieldName = $sqlFields->getValue('name');
644 | $fieldType = $sqlFields->getValue('type_id');
645 | $fieldAttributes = $sqlFields->getValue('attributes');
646 |
647 | // dont save restricted fields
648 | $attrArray = rex_string::split($fieldAttributes);
649 |
650 | /**
651 | * check if the field is a tab
652 | * check permissions.
653 | */
654 | if (REX_GLOBAL_SETTINGS_FIELD_TAB === $fieldType) {
655 | if (isset($attrArray['perm'])) {
656 | if (!rex::getUser()->hasPerm($attrArray['perm'])) {
657 | $isRestrictedTab = true;
658 | }
659 | } else {
660 | $isRestrictedTab = false;
661 | }
662 | }
663 |
664 | if (isset($attrArray['perm'])) {
665 | if (!rex::getUser()->hasPerm($attrArray['perm'])) {
666 | continue;
667 | }
668 | unset($attrArray['perm']);
669 | }
670 |
671 | if ($isRestrictedTab) {
672 | continue;
673 | }
674 |
675 | // Wert in SQL zum speichern
676 | $saveValue = self::getSaveValue($fieldName, $fieldType, $fieldAttributes);
677 | $sqlSave->setValue($fieldName, $saveValue);
678 |
679 | // Werte im aktuellen Objekt speichern, dass zur Anzeige verwendet wird
680 | if (isset($params['activeItem'])) {
681 | $params['activeItem']->setValue($fieldName, $saveValue);
682 | }
683 | }
684 | }
685 |
686 | /**
687 | * Retrieves the posted value for the given field and converts it into a saveable format.
688 | *
689 | * @param string $fieldName The name of the field
690 | * @param int $fieldType One of the REX_GLOBAL_SETTINGS_FIELD_* constants
691 | * @param string $fieldAttributes The attributes of the field
692 | *
693 | * @return string
694 | */
695 | public static function getSaveValue($fieldName, $fieldType, $fieldAttributes)
696 | {
697 | if ('post' != rex_request_method()) {
698 | return null;
699 | }
700 |
701 | $postValue = rex_post($fieldName, 'array');
702 |
703 | // handle date types with timestamps
704 | if (isset($postValue['year']) && isset($postValue['month']) && isset($postValue['day']) && isset($postValue['hour']) && isset($postValue['minute'])) {
705 | if (isset($postValue['active'])) {
706 | $saveValue = mktime((int) $postValue['hour'], (int) $postValue['minute'], 0, (int) $postValue['month'], (int) $postValue['day'], (int) $postValue['year']);
707 | } else {
708 | $saveValue = 0;
709 | }
710 | } // handle date types without timestamps
711 | elseif (isset($postValue['year']) && isset($postValue['month']) && isset($postValue['day'])) {
712 | if (isset($postValue['active'])) {
713 | $saveValue = mktime(0, 0, 0, (int) $postValue['month'], (int) $postValue['day'], (int) $postValue['year']);
714 | } else {
715 | $saveValue = 0;
716 | }
717 | } // handle time types
718 | elseif (isset($postValue['hour']) && isset($postValue['minute'])) {
719 | if (isset($postValue['active'])) {
720 | $saveValue = mktime((int) $postValue['hour'], (int) $postValue['minute'], 0, 0, 0, 0);
721 | } else {
722 | $saveValue = 0;
723 | }
724 | } else {
725 | if (count($postValue) > 1) {
726 | // Mehrwertige Felder
727 | $saveValue = '|' . implode('|', $postValue) . '|';
728 | } else {
729 | $postValue = $postValue[0] ?? '';
730 | if (REX_GLOBAL_SETTINGS_FIELD_SELECT == $fieldType && str_contains($fieldAttributes, 'multiple')
731 | || REX_GLOBAL_SETTINGS_FIELD_CHECKBOX == $fieldType
732 | ) {
733 | // Mehrwertiges Feld, aber nur ein Wert ausgewählt
734 | $saveValue = '|' . $postValue . '|';
735 | } else {
736 | // Einwertige Felder
737 | $saveValue = $postValue;
738 | }
739 | }
740 | }
741 |
742 | return $saveValue;
743 | }
744 |
745 | /**
746 | * Ermittelt die global_settings felder mit dem Prefix $prefix limitiert auf die Kategorien $restrictions.
747 | *
748 | * @param string $prefix Feldprefix
749 | * @param string $filterCondition SQL Where-Bedingung zum einschränken der Metafelder
750 | *
751 | * @return rex_sql global_settings felder
752 | */
753 | protected static function getSqlFields($prefix, $filterCondition = '')
754 | {
755 | // replace LIKE wildcards
756 | $prefix = str_replace(['_', '%'], ['\_', '\%'], $prefix);
757 |
758 | $qry = 'SELECT
759 | *
760 | FROM
761 | ' . rex::getTablePrefix() . 'global_settings_field p,
762 | ' . rex::getTablePrefix() . 'global_settings_type t
763 | WHERE
764 | `p`.`type_id` = `t`.`id` AND
765 | `p`.`name` LIKE "' . $prefix . '%"
766 | ' . $filterCondition . '
767 | ORDER BY
768 | priority';
769 |
770 | $sqlFields = rex_sql::factory();
771 | // $sqlFields->setDebug();
772 | $sqlFields->setQuery($qry);
773 |
774 | return $sqlFields;
775 | }
776 |
777 | /**
778 | * Erweitert das Meta-Formular um die neuen Meta-Felder.
779 | *
780 | * @param string $prefix Feldprefix
781 | * @param array $params EP Params
782 | *
783 | * @return string
784 | */
785 | public function renderFormAndSave($prefix, array $params)
786 | {
787 | // Beim ADD gibts noch kein activeItem
788 | $activeItem = null;
789 | if (isset($params['activeItem'])) {
790 | $activeItem = $params['activeItem'];
791 | }
792 |
793 | $filterCondition = $this->buildFilterCondition($params);
794 | $sqlFields = $this->getSqlFields($prefix, $filterCondition);
795 | $params = $this->handleSave($params, $sqlFields);
796 |
797 | // trigger callback of sql fields
798 | if ('post' == rex_request_method()) {
799 | $this->fireCallbacks($sqlFields);
800 | }
801 |
802 | return self::renderMetaFields($sqlFields, $params);
803 | }
804 |
805 | protected function fireCallbacks(rex_sql $sqlFields)
806 | {
807 | foreach ($sqlFields as $row) {
808 | if ('' != $row->getValue('callback')) {
809 | // use a small sandbox, so the callback cannot affect our local variables
810 | $sandboxFunc = function ($field) {
811 | // TODO add var to ref the actual table (rex_article,...)
812 | $fieldName = $field->getValue('name');
813 | $fieldType = $field->getValue('type_id');
814 | $fieldAttributes = $field->getValue('attributes');
815 | $fieldValue = self::getSaveValue($fieldName, $fieldType, $fieldAttributes);
816 |
817 | require rex_stream::factory('global_settings/' . $field->getValue('id') . '/callback', $field->getValue('callback'));
818 | };
819 | // pass a clone to the custom handler, so the callback will not change our var
820 | $sandboxFunc(clone $row);
821 | }
822 | }
823 | }
824 |
825 | /**
826 | * Build a SQL Filter String which fits for the current context params.
827 | *
828 | * @param array $params EP Params
829 | */
830 | abstract protected function buildFilterCondition(array $params);
831 |
832 | /**
833 | * Renders a field of the metaform. The rendered html will be returned.
834 | *
835 | * @param string $field The html-source of the field itself
836 | * @param string $tag The html-tag for the elements container, e.g. "p"
837 | * @param string $tag_attr Attributes for the elements container, e.g. " class='rex-widget'"
838 | * @param string $id The id of the field, used for current label or field-specific javascripts
839 | * @param string $label The textlabel of the field
840 | * @param bool $labelIt True when an additional label needs to be rendered, otherweise False
841 | * @param string $inputType The input type, e.g. "checkbox", "radio",..
842 | *
843 | * @return string The rendered html
844 | */
845 | abstract protected function renderFormItem($field, $tag, $tag_attr, $id, $label, $labelIt, $inputType);
846 |
847 | /**
848 | * Retrieves the activeItem from the current context.
849 | * Afterwards the actual metaForm extension will be rendered.
850 | *
851 | * @return string
852 | */
853 | abstract public function extendForm(rex_extension_point $ep);
854 |
855 | /**
856 | * Retrieves the POST values from the metaform, fill it into a rex_sql object and save it to a database table.
857 | */
858 | abstract protected function handleSave(array $params, rex_sql $sqlFields);
859 | }
860 |
--------------------------------------------------------------------------------