Browse code

Use advanced editable field selection in module configuration

Benjamin Roth authored on07/02/2020 14:42:09
Showing5 changed files
... ...
@@ -1,5 +1,5 @@
1 1
 {
2
-  "name":"esalesmedia/contao-formilicious",
2
+  "name":"esalesmedia/contao-formilicious2",
3 3
   "description":"Extends the Contao forms to easily create multi column forms.",
4 4
   "keywords":["contao", "form", "columns"],
5 5
   "type":"contao-module",
... ...
@@ -13,6 +13,7 @@
13 13
   "require":{
14 14
     "php": "^7.1",
15 15
     "contao/core-bundle": "^4.8",
16
+    "contao-community-alliance/composer-plugin": "~2.4 || ~3.0",
16 17
     "menatwork/contao-multicolumnwizard-bundle": "^3.4"
17 18
   },
18 19
   "require-dev": {
... ...
@@ -2,6 +2,7 @@
2 2
 ; List modules which are required to be loaded beforehand
3 3
 ;;
4 4
 requires[] = "core"
5
+requires[] = "multicolumnwizard"
5 6
 
6 7
 ;;
7 8
 ; Configure what you want the autoload creator to register
... ...
@@ -18,44 +18,230 @@
18 18
  */
19 19
 $GLOBALS['TL_DCA']['tl_module']['fields']['editable'] = array
20 20
 (
21
-	'label'                   => &$GLOBALS['TL_LANG']['tl_module']['editable'],
22
-	'exclude'                 => true,
23
-	'inputType'               => 'multiColumnWizard',
24
-//	'options_callback'        => array('tl_module', 'getEditableMemberProperties'),
25
-	'eval' 			          => array
26
-	(
27
-		'columnFields' => array
28
-		(
29
-			'eSM_editable' => array
30
-			(
31
-				'label'                 => &$GLOBALS['TL_LANG']['tl_module']['eSM_editable_field'],
32
-				'exclude'               => true,
33
-				'inputType'             => 'select',
34
-				'options_callback'      => array('tl_module', 'getEditableMemberProperties'),
35
-				'eval'                  => array('style'=>'width:250px', 'includeBlankOption'=>true, 'chosen'=>true, 'mandatory'=>true)
36
-			),
37
-			'eSM_class' => array
38
-			(
39
-				'label'                 => &$GLOBALS['TL_LANG']['tl_module']['eSM_editable_col'],
40
-				'exclude'               => true,
41
-				'inputType'             => 'select',
42
-				'options'               => array(10, 11, 15, '16_5', 20, 22, 25, 30, 33, 35, 40, 44, 45, 50, 55, 60, 65, 66, 70, 75, 80, 85, 90, 95, 100),
43
-				'eval'                  => array('style'=>'width:50px', 'includeBlankOption'=>true)
44
-			),
45
-			'eSM_clr' => array
46
-			(
47
-				'label'                 => &$GLOBALS['TL_LANG']['tl_module']['eSM_editable_clear'],
48
-				'exclude'               => true,
49
-				'inputType'             => 'checkbox'
50
-			),
51
-			'eSM_mandatory' => array
52
-			(
53
-				'label'                 => &$GLOBALS['TL_LANG']['tl_module']['eSM_editable_mandatory'],
54
-				'exclude'               => true,
55
-				'inputType'             => 'checkbox'
56
-			)
57
-		),
58
-		'tl_class' => ''
59
-	),
60
-	'sql'                     => "blob NULL"
61
-);
62 21
\ No newline at end of file
22
+  'exclude'               => true,
23
+  'inputType'             => 'multiColumnWizard',
24
+  'eval'                  => array
25
+  (
26
+    'tl_class'          =>'clr',
27
+    'columnsCallback'   => array('formilicious_tl_module', 'onCoAddressFieldsColumnsCallback'),
28
+    'buttons'           => array('copy'=>false, 'delete'=>false,'new'=>false),
29
+    'dragAndDrop'       => true,
30
+  ),
31
+  'sql'                   => 'blob NULL',
32
+  'load_callback'           => array
33
+  (
34
+    array('formilicious_tl_module','onLoadCoAddressFields')
35
+  ),
36
+  'save_callback'           => array
37
+  (
38
+    array('formilicious_tl_module','onSaveCoAddressFields')
39
+  )
40
+);
41
+
42
+class formilicious_tl_module extends \Backend
43
+{
44
+  /**
45
+   * @return array
46
+   */
47
+  public function getMandatoryMemberFields() : array
48
+  {
49
+    \Controller::loadDataContainer('tl_member');
50
+    $arrFields = array();
51
+    $arrDCA    = &$GLOBALS['TL_DCA']['tl_member']['fields'];
52
+    foreach ($arrDCA as $field => $config) {
53
+      $mandatory = $config['eval']['mandatory'];
54
+      if ($mandatory) {
55
+        $arrFields[] = $field;
56
+      }
57
+    }
58
+    return $arrFields;
59
+  }
60
+
61
+  /**
62
+   * For each call, return the name of the next attribute in the wizard (for input_field_callback)
63
+   *
64
+   * @param \Widget|object $objWidget
65
+   *
66
+   * @return string
67
+   */
68
+  public function onFieldnameInputFieldCallback($objWidget)
69
+  {
70
+    \System::loadLanguageFile('tl_member');
71
+    \Controller::loadDataContainer('tl_member');
72
+
73
+    static $arrValues;
74
+    static $strWidget;
75
+    static $i = 0;
76
+    if ($objWidget->name !== $strWidget) {
77
+      $strWidget = $objWidget->name;
78
+      $arrValues = $objWidget->value;
79
+      $i         = 0;
80
+    }
81
+    $arrField = array_shift($arrValues);
82
+    $strName  = $arrField['name'];
83
+
84
+    return sprintf(
85
+      '<input type="hidden" name="%s[%s][name]" id="ctrl_%s_row%s_name" value="%s"><div style="width:300px">%s' . ($GLOBALS['TL_DCA']['tl_member']['fields'][$strName]['eval']['mandatory'] ? '<span class="mandatory">*</span>' : '') . ' <span style="color:#b3b3b3; padding-left:3px;">[%s]</span></div>',
86
+      $objWidget->name,
87
+      $i,
88
+      $objWidget->name,
89
+      $i++,
90
+      $strName,
91
+      ($GLOBALS['TL_DCA']['tl_member']['fields'][$strName]['label'][0] ? : ($GLOBALS['TL_LANG']['tl_member'][$strName][0] ? : $strName)),
92
+      $strName
93
+    );
94
+  }
95
+
96
+  /**
97
+   * Return list of MultiColumnWizard columns
98
+   *
99
+   * @param MultiColumnWizard|object $objWidget
100
+   *
101
+   * @return array
102
+   */
103
+  public function onCoAddressFieldsColumnsCallback(\MultiColumnWizard $objWidget)
104
+  {
105
+    \Controller::loadDataContainer('tl_member');
106
+    $arrValues   = $objWidget->value;
107
+
108
+    if (!empty($arrValues) && \is_array($arrValues)) {
109
+      $arrMandatory = $this->getMandatoryMemberFields();
110
+
111
+      foreach ($arrValues as $i => $field) {
112
+        if (\in_array($field['name'], $arrMandatory, true)) {
113
+          $objWidget->addDataToFieldAtIndex($i, 'enabled', array('value'=>1,'eval' => array('disabled' => true)));
114
+        }
115
+      }
116
+    }
117
+
118
+    return array
119
+    (
120
+      'enabled'   => array
121
+      (
122
+        'inputType' => 'checkbox',
123
+        'eval'      => array('hideHead' => true),
124
+      ),
125
+      'name'      => array
126
+      (
127
+        'input_field_callback' => array('formilicious_tl_module', 'onFieldnameInputFieldCallback'),
128
+        'eval'                 => array('hideHead' => true, 'tl_class' => 'mcwUpdateFields'),
129
+      ),
130
+      'mandatory' => array
131
+      (
132
+        'label'     => &$GLOBALS['TL_LANG']['tl_module']['sr_co_addressFields']['mandatory'],
133
+        'inputType' => 'select',
134
+        'options'   => array('yes', 'no'),
135
+        'reference' => &$GLOBALS['TL_LANG']['MSC'],
136
+        'eval'      => array('style' => 'width:80px', 'includeBlankOption' => true, 'blankOptionLabel' => &$GLOBALS['TL_LANG']['tl_iso_producttype']['attributes']['default']),
137
+      ),
138
+      'eSM_fl_class'  => array
139
+      (
140
+        'label'     => &$GLOBALS['TL_LANG']['tl_module']['sr_co_addressFields']['eSM_fl_class'],
141
+        'inputType' => 'text',
142
+        'eval'      => array('style' => 'width:80px'),
143
+      ),
144
+      'eSM_fl_width'  => array
145
+      (
146
+        'label'     => &$GLOBALS['TL_LANG']['tl_module']['sr_co_addressFields']['eSM_fl_width'],
147
+        'inputType' => 'select',
148
+        'default'   => 100,
149
+        'options'   => array(10, 11, 15, '16_5', 20, 22, 25, 30, 33, 35, 40, 44, 45, 50, 55, 60, 65, 66, 70, 75, 80, 85, 90, 95, 100),
150
+        'eval'      => array('style' => 'width:80px'),
151
+      ),
152
+      'eSM_fl_clear'   => array
153
+      (
154
+        'label'     => &$GLOBALS['TL_LANG']['tl_module']['sr_co_addressFields']['eSM_fl_clear'],
155
+        'inputType' => 'checkbox',
156
+      ),
157
+    );
158
+  }
159
+
160
+  /**
161
+   * Generate list of fields and add missing ones from DCA
162
+   *
163
+   * @param mixed          $varValue
164
+   * @param \DataContainer $dc
165
+   *
166
+   * @return array
167
+   */
168
+  public function onLoadCoAddressFields($varValue, $dc)
169
+  {
170
+    \Controller::loadDataContainer('tl_member');
171
+    $arrDCA      = &$GLOBALS['TL_DCA']['tl_member']['fields'];
172
+    $arrFields   = array();
173
+    $arrValues   = \StringUtil::deserialize($varValue);
174
+    $arrMandatory    = $this->getMandatoryMemberFields();
175
+
176
+    if (!\is_array($arrValues)) {
177
+      $arrValues = array();
178
+    }
179
+
180
+    foreach ($arrValues as $arrField) {
181
+      $strName = $arrField['name'];
182
+      if ($strName == ''
183
+        || !isset($arrDCA[$strName])
184
+        || $arrDCA[$strName]['eval']['feEditable'] == ''
185
+      ) {
186
+        continue;
187
+      }
188
+      if (\in_array($strName, $arrMandatory, true))
189
+      {
190
+        $arrField['enabled'] = '1';
191
+      }
192
+      $arrFields[$arrField['name']] = $arrField;
193
+    }
194
+
195
+    foreach (array_diff_key($arrDCA, $arrFields) as $strName => $arrField) {
196
+      if ($arrField['eval']['feEditable'] == ''
197
+      ) {
198
+        continue;
199
+      }
200
+
201
+      $arrFields[$strName] = array(
202
+        'enabled' => \in_array($strName, $arrMandatory, true) ? '1' : '',
203
+        'name'    => $strName,
204
+      );
205
+    }
206
+
207
+    return array_values($arrFields);
208
+  }
209
+
210
+  /**
211
+   * save_callback to sort attribute wizard fields by enabled and drag'n drop
212
+   *
213
+   * @param mixed  $varValue The widget value
214
+   * @param object $dc       The DataContainer object
215
+   *
216
+   * @return string
217
+   */
218
+  public function onSaveCoAddressFields($varValue, $dc)
219
+  {
220
+    $arrLegends  = array();
221
+    $arrFields   = \StringUtil::deserialize($varValue);
222
+    if (empty($arrFields) || !\is_array($arrFields)) {
223
+      return $varValue;
224
+    }
225
+    $arrMandatory = $this->getMandatoryMemberFields();
226
+
227
+    foreach ($arrFields as $k => $arrField) {
228
+      if (\in_array($arrField['name'], $arrMandatory, true)) {
229
+        $arrFields[$k]['enabled'] = '1';
230
+      }
231
+    }
232
+    uksort($arrFields, function ($a, $b) use ($arrFields) {
233
+      if ($arrFields[$a]['enabled'] && !$arrFields[$b]['enabled']) {
234
+        return -1;
235
+      } elseif ($arrFields[$b]['enabled'] && !$arrFields[$a]['enabled']) {
236
+        return 1;
237
+      } else {
238
+        return ($a > $b) ? +1 : -1;
239
+      }
240
+    });
241
+    $arrValues = array();
242
+    foreach (array_values($arrFields) as $pos => $arrConfig) {
243
+      $arrConfig['position']         = $pos;
244
+      $arrValues[$arrConfig['name']] = $arrConfig;
245
+    }
246
+    return serialize($arrValues);
247
+  }
248
+}
63 249
\ No newline at end of file
... ...
@@ -59,15 +59,19 @@ class ModulePersonalData extends \Contao\ModulePersonalData
59 59
     foreach ($this->editable as $key=>$fielddata)
60 60
     {
61 61
       // Split formilicious editable data in single vars
62
-      list($field, $fieldWidth, $fieldClr, $fieldMandatory) = array_values($fielddata);
62
+      list($active, $field, $fieldMandatory, $fieldClass, $fieldWidth, $fieldClr, $position) = array_values($fielddata);
63
+
64
+      if (!$active)
65
+      {
66
+        continue;
67
+      }
68
+
69
+      $GLOBALS['TL_DCA']['tl_member']['fields'][$field]['eval']['eSM_fl_class'] = $fieldClass;
63 70
       $GLOBALS['TL_DCA']['tl_member']['fields'][$field]['eval']['eSM_fl_width'] = $fieldWidth;
64 71
       $GLOBALS['TL_DCA']['tl_member']['fields'][$field]['eval']['eSM_fl_clear'] = $fieldClr;
65 72
       if ($fieldMandatory)
66 73
       {
67
-        $GLOBALS['TL_DCA']['tl_member']['fields'][$field]['eval']['mandatory'] = $fieldMandatory;
68
-      } else {
69
-        $GLOBALS['TL_DCA']['tl_member']['fields'][$field]['eval']['mandatory'] = false;
70
-
74
+        $GLOBALS['TL_DCA']['tl_member']['fields'][$field]['eval']['mandatory'] = $fieldMandatory == 'yes' ? true : false;
71 75
       }
72 76
       $arrEditable[$key] = $field;
73 77
     }
... ...
@@ -53,20 +53,23 @@ class ModuleRegistration extends \Contao\ModuleRegistration
53 53
     \System::loadLanguageFile('tl_member');
54 54
     $this->loadDataContainer('tl_member');
55 55
 
56
-
57 56
     $arrEditable = [];
58 57
     foreach ($this->editable as $key=>$fielddata)
59 58
     {
60 59
       // Split formilicious editable data in single vars
61
-      list($field, $fieldWidth, $fieldClr, $fieldMandatory) = array_values($fielddata);
60
+      list($active, $field, $fieldMandatory, $fieldClass, $fieldWidth, $fieldClr, $position) = array_values($fielddata);
61
+
62
+      if (!$active)
63
+      {
64
+        continue;
65
+      }
66
+
67
+      $GLOBALS['TL_DCA']['tl_member']['fields'][$field]['eval']['eSM_fl_class'] = $fieldClass;
62 68
       $GLOBALS['TL_DCA']['tl_member']['fields'][$field]['eval']['eSM_fl_width'] = $fieldWidth;
63 69
       $GLOBALS['TL_DCA']['tl_member']['fields'][$field]['eval']['eSM_fl_clear'] = $fieldClr;
64 70
       if ($fieldMandatory)
65 71
       {
66
-        $GLOBALS['TL_DCA']['tl_member']['fields'][$field]['eval']['mandatory'] = $fieldMandatory;
67
-      } else {
68
-        $GLOBALS['TL_DCA']['tl_member']['fields'][$field]['eval']['mandatory'] = false;
69
-
72
+        $GLOBALS['TL_DCA']['tl_member']['fields'][$field]['eval']['mandatory'] = $fieldMandatory == 'yes' ? true : false;
70 73
       }
71 74
       $arrEditable[$key] = $field;
72 75
     }