franck@0
|
1 <?php |
franck@0
|
2 /** |
franck@0
|
3 * @file |
franck@0
|
4 * This module will allow you to add calculated fields to views tables |
franck@0
|
5 * and compute (SUM, COUNT, AVG, etc) columns of numeric data in a views table. |
franck@0
|
6 */ |
franck@0
|
7 function views_calc_views_api() { |
franck@0
|
8 return array( |
franck@0
|
9 'api' => 2, |
franck@0
|
10 'path' => drupal_get_path('module', 'views_calc'), |
franck@0
|
11 ); |
franck@0
|
12 } |
franck@0
|
13 |
franck@0
|
14 function views_calc_theme() { |
franck@0
|
15 $path = drupal_get_path('module', 'views_calc'); |
franck@0
|
16 return array( |
franck@0
|
17 'views_calc_ui_table' => array( |
franck@0
|
18 'arguments' => array('form' => NULL), |
franck@0
|
19 'file' => 'theme.inc', |
franck@0
|
20 ), |
franck@0
|
21 ); |
franck@0
|
22 } |
franck@0
|
23 |
franck@0
|
24 /** |
franck@0
|
25 * Implementation of hook_help(). |
franck@0
|
26 */ |
franck@0
|
27 function views_calc_help($section, $arg) { |
franck@0
|
28 switch ($section) { |
franck@0
|
29 case 'admin/settings/views_calc': |
franck@0
|
30 case 'admin/settings/views_calc/fields': |
franck@0
|
31 return t('<p>Set up calculation fields. Calculation fields will be displayed in the views fields list and can be added to any view.</p>'); |
franck@0
|
32 case 'admin/settings/views_calc/settings': |
franck@0
|
33 return t('Put one operator on each line. To avoid the possibility of SQL injection, calculation text will only allow these values, numbers, and field names. Make sure this list includes any text other than field names that should be allowed in the calculation fields.'); |
franck@0
|
34 case 'admin/help#views_calc': |
franck@0
|
35 return t('<ul> <li>Go to admin/settings/views_calc to create calculations.</li> <li>The \'Fields\' tab will allow you to create calculated fields that can be inserted into any view. The calculations can include the value of any Views field, combined with numbers, arithmatic operations, and common SQL functions like ROUND() or MIN(). Each available field has a shortcut name like %Node:Title. Create SQL snippets like (%Node:Field1 + 84600) or ROUND(%Node:Field2 / 3). </li> <li>The \'Columns\' tab allows you to set column calculations. The column totals are added in the view itself by using the style \'Views Calc Table\' and setting the fields in the table that should have column totals.</li> <li>The \'Settings\' tab allows you to add new functions to the list of allowable functions. </ul>'); |
franck@0
|
36 } |
franck@0
|
37 } |
franck@0
|
38 |
franck@0
|
39 /** |
franck@0
|
40 * Default SQL operator alternatives. |
franck@0
|
41 * |
franck@0
|
42 * The ones allowed in this system are stored in the |
franck@0
|
43 * variable views_calc_operators, and can be changed |
franck@0
|
44 * at admin/settings/views_calc. |
franck@0
|
45 * |
franck@0
|
46 */ |
franck@0
|
47 function _views_calc_operators() { |
franck@0
|
48 $default = array('+', '-', '*', '/', '(', ')', ',', "'", 'CONCAT', 'MIN', 'MAX', 'ROUND', 'NOW()'); |
franck@0
|
49 $operators = variable_get('views_calc_operators', implode("\n", $default)); |
franck@0
|
50 return explode("\n", $operators); |
franck@0
|
51 |
franck@0
|
52 } |
franck@0
|
53 |
franck@0
|
54 /** |
franck@0
|
55 * Column calculation alternatives |
franck@0
|
56 */ |
franck@0
|
57 function _views_calc_calc_options() { |
franck@0
|
58 return array('COUNT' => 'Count', 'SUM' => 'Sum', 'AVG' => 'Average', 'MIN' => 'Minimum', 'MAX' => 'Maximum'); |
franck@0
|
59 } |
franck@0
|
60 |
franck@0
|
61 /** |
franck@0
|
62 * Result format options |
franck@0
|
63 */ |
franck@0
|
64 function _views_calc_format_options() { |
franck@0
|
65 $options = array( |
franck@0
|
66 'none' => '', |
franck@0
|
67 'integer' => 'intval', |
franck@0
|
68 'decimal (1)' => 'number_format:1', |
franck@0
|
69 'decimal (2)' => 'number_format:2', |
franck@0
|
70 'shortdate' => 'format_date:small', |
franck@0
|
71 'mediumdate' => 'format_date', |
franck@0
|
72 'longdate' => 'format_date:large', |
franck@0
|
73 'custom' => '', |
franck@0
|
74 ); |
franck@0
|
75 return $options; |
franck@0
|
76 } |
franck@0
|
77 |
franck@0
|
78 /** |
franck@0
|
79 * Implementation of hook_perm(). |
franck@0
|
80 * |
franck@0
|
81 * The permission 'administer views calc' has rights to alter the SQL |
franck@0
|
82 * operators that can be used in calculations. |
franck@0
|
83 * |
franck@0
|
84 * The permission 'create views calc' has rights to create calculated |
franck@0
|
85 * fields and set calculation columns on views. |
franck@0
|
86 */ |
franck@0
|
87 function views_calc_perm() { |
franck@0
|
88 return array('create views calc', 'administer views calc'); |
franck@0
|
89 } |
franck@0
|
90 |
franck@0
|
91 function views_calc_menu() { |
franck@0
|
92 |
franck@0
|
93 $items = array(); |
franck@0
|
94 $items['admin/settings/views_calc'] = array( |
franck@0
|
95 'title' => t('Views Calc'), |
franck@0
|
96 'description' => t('Set Views Calc fields and columns.'), |
franck@0
|
97 'type' => MENU_NORMAL_ITEM, |
franck@0
|
98 'weight' => 10, |
franck@0
|
99 'priority' => 1, |
franck@0
|
100 'page callback' => 'drupal_get_form', |
franck@0
|
101 'page arguments' => array('views_calc_fields_form'), |
franck@0
|
102 'access arguments' => array('create views calc'), |
franck@0
|
103 ); |
franck@0
|
104 $items['admin/settings/views_calc/fields'] = array( |
franck@0
|
105 'title' => t('Fields'), |
franck@0
|
106 'type' => MENU_DEFAULT_LOCAL_TASK, |
franck@0
|
107 'weight' => 5, |
franck@0
|
108 'priority' => 1, |
franck@0
|
109 'page callback' => 'drupal_get_form', |
franck@0
|
110 'page arguments' => array('views_calc_fields_form'), |
franck@0
|
111 'access arguments' => array('create views calc'), |
franck@0
|
112 ); |
franck@0
|
113 $items['admin/settings/views_calc/settings'] = array( |
franck@0
|
114 'title' => t('Settings'), |
franck@0
|
115 'type' => MENU_LOCAL_TASK, |
franck@2
|
116 'weight' => 6, |
franck@0
|
117 'priority' => 1, |
franck@0
|
118 'page callback' => 'drupal_get_form', |
franck@0
|
119 'page arguments' => array('views_calc_settings_form'), |
franck@0
|
120 'access arguments' => array('administer views calc'), |
franck@0
|
121 ); |
franck@2
|
122 $items['admin/settings/views_calc/export'] = array( |
franck@2
|
123 'title' => 'Export fields', |
franck@2
|
124 'page callback' => 'drupal_get_form', |
franck@2
|
125 'page arguments' => array('views_calc_export_form'), |
franck@2
|
126 'access arguments' => array('create views calc'), |
franck@2
|
127 'type' => MENU_LOCAL_TASK, |
franck@2
|
128 'weight' => 7, |
franck@2
|
129 ); |
franck@2
|
130 $items['admin/settings/views_calc/import'] = array( |
franck@2
|
131 'title' => 'Import fields', |
franck@2
|
132 'page callback' => 'drupal_get_form', |
franck@2
|
133 'page arguments' => array('views_calc_import_form'), |
franck@2
|
134 'access arguments' => array('create views calc'), |
franck@2
|
135 'type' => MENU_LOCAL_TASK, |
franck@2
|
136 'weight' => 8, |
franck@2
|
137 ); |
franck@2
|
138 |
franck@0
|
139 return $items; |
franck@0
|
140 } |
franck@0
|
141 |
franck@0
|
142 /** |
franck@0
|
143 * Implementation of hook_settings() |
franck@0
|
144 */ |
franck@0
|
145 function views_calc_settings_form() { |
franck@0
|
146 drupal_set_title(t('Views Calc')); |
franck@0
|
147 $operators = _views_calc_operators(); |
franck@0
|
148 $form['views_calc_operators'] = array( |
franck@0
|
149 '#type' => 'textarea', |
franck@0
|
150 '#default_value' => implode("\n", $operators), |
franck@0
|
151 '#title' => t('Allowable functions and operators'), |
franck@0
|
152 '#rows' => intval(sizeof($operators) + 2), |
franck@0
|
153 ); |
franck@0
|
154 $form['submit'] = array( |
franck@0
|
155 '#type' => 'submit', |
franck@0
|
156 '#value' => t('Save'), |
franck@0
|
157 ); |
franck@0
|
158 return $form; |
franck@0
|
159 } |
franck@0
|
160 |
franck@0
|
161 function views_calc_settings_form_submit($form, &$form_state) { |
franck@0
|
162 $form_values = $form_state['values']; |
franck@0
|
163 variable_set('views_calc_operators', $form_values['views_calc_operators']); |
franck@0
|
164 } |
franck@0
|
165 |
franck@0
|
166 /** |
franck@0
|
167 * Views Calc Fields tab on views list. |
franck@0
|
168 */ |
franck@0
|
169 function views_calc_fields_form() { |
franck@0
|
170 $i = 0; |
franck@2
|
171 $substitutions = array(); |
franck@2
|
172 $help = t('<p>The specific fields that are available in any view depend on the base table used for that view.</p>'); |
franck@2
|
173 require_once(drupal_get_path('module', 'views') .'/includes/admin.inc'); |
franck@2
|
174 $base_tables = views_fetch_base_tables(); |
franck@2
|
175 foreach ($base_tables as $base => $data) { |
franck@2
|
176 $base_subs = _views_calc_substitutions($base); |
franck@2
|
177 $substitutions += $base_subs; |
franck@2
|
178 $fieldset = array( |
franck@2
|
179 '#title' => t('Base table: !name', array('!name' => t($data['title']))), |
franck@2
|
180 '#value' => theme('item_list', $base_subs), |
franck@2
|
181 '#collapsible' => TRUE, |
franck@2
|
182 '#collapsed' => TRUE, |
franck@2
|
183 ); |
franck@2
|
184 $help .= theme('fieldset', $fieldset); |
franck@2
|
185 } |
franck@0
|
186 |
franck@0
|
187 // display current views calcs fields |
franck@0
|
188 $fields = _views_calc_fields(); |
franck@0
|
189 while ($field = db_fetch_array($fields)) { |
franck@0
|
190 $form[] = views_calc_field_form_item($i, $field, $substitutions); |
franck@0
|
191 $i++; |
franck@0
|
192 } |
franck@0
|
193 // add blank fields for more calcs |
franck@0
|
194 for ($x = $i + 1; $x < $i + 2; $x++) { |
franck@0
|
195 $field = array(); |
franck@0
|
196 $form[] = views_calc_field_form_item($i, $field, $substitutions); |
franck@0
|
197 } |
franck@0
|
198 $form['#prefix'] = '<div class="views-calc-field-settings">'; |
franck@2
|
199 $form['#suffix'] = '</div><div class="views-calc-field-names"><strong>Field Substitutions</strong><div class="form-item">'. $help .'</div></div>'; |
franck@0
|
200 $form['submit'] = array( |
franck@0
|
201 '#type' => 'submit', |
franck@0
|
202 '#value' => t('Save'), |
franck@0
|
203 ); |
franck@0
|
204 return $form; |
franck@0
|
205 } |
franck@0
|
206 |
franck@0
|
207 /** |
franck@0
|
208 * A form element for an individual calculated field. |
franck@0
|
209 */ |
franck@0
|
210 function views_calc_field_form_item($i, $field, $substitutions) { |
franck@0
|
211 if (empty($field)) { |
franck@0
|
212 $field = array('cid' => 0, 'label' => '', 'tablelist' => '', 'calc' => '', 'format' => '', 'custom' => ''); |
franck@0
|
213 } |
franck@2
|
214 require_once(drupal_get_path('module', 'views') .'/includes/admin.inc'); |
franck@2
|
215 $options = array(); |
franck@2
|
216 $base_tables = views_fetch_base_tables(); |
franck@2
|
217 foreach ($base_tables as $base => $data) { |
franck@2
|
218 $options[$base] = t($data['title']); |
franck@2
|
219 } |
franck@0
|
220 $form['group'][$i] = array( |
franck@0
|
221 '#type' => 'fieldset', |
franck@0
|
222 '#tree' => TRUE, |
franck@0
|
223 '#title' => t('Field: ') . !empty($field['label']) ? $field['label'] : t('New'), |
franck@0
|
224 '#collapsible' => TRUE, |
franck@0
|
225 '#collapsed' => FALSE, |
franck@0
|
226 ); |
franck@0
|
227 $form['group'][$i]['cid'] = array( |
franck@0
|
228 '#type' => 'hidden', |
franck@0
|
229 '#value' => intval($field['cid']), |
franck@0
|
230 ); |
franck@0
|
231 $form['group'][$i]['tablelist'] = array( |
franck@0
|
232 '#type' => 'hidden', |
franck@0
|
233 '#value' => $field['tablelist'], |
franck@0
|
234 ); |
franck@2
|
235 $form['group'][$i]['base'] = array( |
franck@2
|
236 '#type' => 'select', |
franck@2
|
237 '#title' => t('Base table'), |
franck@2
|
238 '#options' => $options, |
franck@2
|
239 '#default_value' => !empty($field['base']) && array_key_exists($field['base'], $options) ? $field['base'] : 'node', |
franck@2
|
240 '#description' => t('The base table for this field.'), |
franck@2
|
241 ); |
franck@0
|
242 $form['group'][$i]['label'] = array( |
franck@0
|
243 '#type' => 'textfield', |
franck@0
|
244 '#title' => t('Label'), |
franck@0
|
245 '#field_prefix' => 'ViewsCalc: ', |
franck@0
|
246 '#default_value' => str_replace('ViewsCalc: ', '', $field['label']), |
franck@0
|
247 '#description' => t('The views field name for this field (i.e. Views Calc: My Calculation).'), |
franck@0
|
248 ); |
franck@0
|
249 $form['group'][$i]['calc'] = array( |
franck@0
|
250 '#type' => 'textarea', |
franck@0
|
251 '#title' => t('Calculation'), |
franck@0
|
252 '#default_value' => strtr($field['calc'], $substitutions), |
franck@2
|
253 '#description' => t("<p>The query operation to be performed, using numbers, field substitutions, and ". implode(' ', _views_calc_operators()) .". Leave spaces between parentheses and field names, i.e. 'CONCAT( %field1, ' ', %field2 )'. <strong>". t('Note that all fields must be from the base table selected above! You cannot combine fields from different base tables.') ."</strong></p>"), |
franck@0
|
254 ); |
franck@0
|
255 $form['group'][$i]['format'] = array( |
franck@0
|
256 '#type' => 'select', |
franck@0
|
257 '#title' => t('Format'), |
franck@0
|
258 '#default_value' => $field['format'], |
franck@0
|
259 '#options' => drupal_map_assoc(array_keys(_views_calc_format_options())), |
franck@0
|
260 '#description' => t('The format of the result of this calculation.'), |
franck@0
|
261 ); |
franck@0
|
262 $form['group'][$i]['custom'] = array( |
franck@0
|
263 '#type' => 'textfield', |
franck@0
|
264 '#title' => t('Custom function'), |
franck@0
|
265 '#default_value' => $field['custom'], |
franck@0
|
266 '#description' => t('The function to call for a custom format.'), |
franck@0
|
267 ); |
franck@0
|
268 return $form; |
franck@0
|
269 } |
franck@0
|
270 |
franck@0
|
271 /** |
franck@0
|
272 * Validate the views calc settings |
franck@0
|
273 */ |
franck@0
|
274 function views_calc_fields_form_validate($form, &$form_state) { |
franck@0
|
275 $form_values = $form_state['values']; |
franck@0
|
276 $edit = $form_values; |
franck@0
|
277 foreach ($edit as $delta => $item) { |
franck@0
|
278 if ($item['calc'] == '' || !is_numeric($delta)) { |
franck@0
|
279 // remove blank fields, don't save them |
franck@2
|
280 continue; |
franck@2
|
281 } |
franck@2
|
282 else { |
franck@0
|
283 // Remove all valid values from calc, if anything is left over, it is invalid. |
franck@0
|
284 |
franck@0
|
285 // First, remove all field names. |
franck@0
|
286 $repl = array(); |
franck@0
|
287 $patterns = array(); |
franck@2
|
288 $base = $item['base']; |
franck@2
|
289 foreach (_views_calc_substitutions($base) as $key => $value) { |
franck@0
|
290 $key = trim($value); |
franck@0
|
291 $count = strlen($value); |
franck@0
|
292 $replace = preg_quote($value); |
franck@0
|
293 $patterns[] = "`(^|[^\\\\\\\\])". $replace ."`"; |
franck@0
|
294 $repl[] = '${1}'; |
franck@0
|
295 } |
franck@0
|
296 $remaining = trim(preg_replace($patterns, $repl, $item['calc'])); |
franck@2
|
297 |
franck@0
|
298 // Next, remove functions and numbers. |
franck@0
|
299 $repl = array(); |
franck@0
|
300 $patterns = array(); |
franck@0
|
301 foreach (_views_calc_replacements() as $value) { |
franck@0
|
302 $patterns[] = "`(^|[^\\\\\\\\])". preg_quote(trim($value)) ."`"; |
franck@0
|
303 $repl[] = '${1}'; |
franck@0
|
304 } |
franck@0
|
305 $remaining = trim(preg_replace($patterns, $repl, $remaining)); |
franck@0
|
306 if (!empty($remaining)) { |
franck@0
|
307 form_set_error($form_values[$delta]['calc'], t('The values %remaining in %field are not allowed.', array('%remaining' => $remaining, '%field' => $item['label']))); |
franck@0
|
308 } |
franck@0
|
309 } |
franck@0
|
310 } |
franck@0
|
311 } |
franck@0
|
312 |
franck@0
|
313 /** |
franck@0
|
314 * Save the views calc field settings |
franck@0
|
315 */ |
franck@0
|
316 function views_calc_fields_form_submit($form, &$form_state) { |
franck@2
|
317 $edit = $form_state['values']; |
franck@2
|
318 $form_values = array(); |
franck@0
|
319 foreach ($edit as $delta => $value) { |
franck@2
|
320 // If this is some form item we don't care about, skip it. |
franck@2
|
321 if (!is_array($value) || !is_numeric($delta)) { |
franck@2
|
322 continue; |
franck@2
|
323 } |
franck@2
|
324 $value['calc'] = trim($value['calc']); |
franck@2
|
325 if (empty($value['calc'])) { |
franck@0
|
326 // remove blank fields, don't save them |
franck@2
|
327 if (!empty($value['cid'])) { |
franck@2
|
328 db_query("DELETE FROM {views_calc_fields} WHERE cid=%d", $value['cid']); |
franck@2
|
329 } |
franck@0
|
330 |
franck@0
|
331 } |
franck@0
|
332 else { |
franck@0
|
333 $tables = array(); |
franck@0
|
334 $form_values[$delta]['label'] = $value['label']; |
franck@0
|
335 $form_values[$delta]['format'] = $value['format']; |
franck@0
|
336 $form_values[$delta]['custom'] = $value['custom']; |
franck@0
|
337 $form_values[$delta]['calc'] = $value['calc']; |
franck@2
|
338 $form_values[$delta]['base'] = $value['base']; |
franck@0
|
339 |
franck@0
|
340 // Substitute field names back into the calculation. |
franck@0
|
341 $matches = array(); |
franck@2
|
342 $base = $value['base']; |
franck@2
|
343 foreach (_views_calc_substitutions($base) as $key => $value) { |
franck@0
|
344 $label_patterns[] = "`(^|[^\\\\\\\\])". preg_quote($value) ."`"; |
franck@0
|
345 $value_patterns[] = "`(^|[^\\\\\\\\])". preg_quote($key) ."`"; |
franck@0
|
346 $repl[] = '${1}'. $key; |
franck@0
|
347 } |
franck@0
|
348 $form_values[$delta]['calc'] = preg_replace($label_patterns, $repl, $form_values[$delta]['calc']); |
franck@0
|
349 |
franck@0
|
350 // Extract the fields and table names from the calculation. |
franck@0
|
351 $tables = array(); |
franck@0
|
352 $fields = array(); |
franck@0
|
353 foreach ($value_patterns as $pattern) { |
franck@0
|
354 if (preg_match($pattern, $form_values[$delta]['calc'], $results)) { |
franck@2
|
355 $fields[trim($results[0])] = trim($results[0]); |
franck@0
|
356 $tmp = explode('.', trim($results[0])); |
franck@0
|
357 if (trim($tmp[0])) { |
franck@0
|
358 $tables[trim($tmp[0])] = trim($tmp[0]); |
franck@0
|
359 } |
franck@0
|
360 } |
franck@0
|
361 } |
franck@0
|
362 $form_values[$delta]['tablelist'] = implode(',', $tables); |
franck@0
|
363 $form_values[$delta]['fieldlist'] = implode(',', $fields); |
franck@0
|
364 } |
franck@0
|
365 } |
franck@2
|
366 |
franck@2
|
367 foreach ((array) $form_values as $delta => $value) { |
franck@2
|
368 if (empty($value['cid'])) { |
franck@0
|
369 drupal_write_record('views_calc_fields', $value); |
franck@0
|
370 } |
franck@0
|
371 else { |
franck@0
|
372 drupal_write_record('views_calc_fields', $value, array('cid')); |
franck@0
|
373 } |
franck@0
|
374 } |
franck@0
|
375 views_invalidate_cache(); |
franck@0
|
376 drupal_set_message(t('Views Calc fields were updated.')); |
franck@0
|
377 } |
franck@0
|
378 |
franck@0
|
379 /** |
franck@0
|
380 * Wrapper function to make sure this function will always work. |
franck@0
|
381 */ |
franck@0
|
382 function views_calc_views_fetch_fields($base, $type) { |
franck@0
|
383 if (!module_exists('views')) { |
franck@0
|
384 return array(); |
franck@0
|
385 } |
franck@0
|
386 require_once('./'. drupal_get_path('module', 'views') .'/includes/admin.inc'); |
franck@0
|
387 return views_fetch_fields($base, $type); |
franck@0
|
388 } |
franck@0
|
389 |
franck@0
|
390 /** |
franck@0
|
391 * Field substitutions for calculations. |
franck@0
|
392 */ |
franck@0
|
393 function _views_calc_substitutions($base = 'node') { |
franck@0
|
394 $fields = views_calc_views_fetch_fields($base, 'field'); |
franck@0
|
395 $substitutions['node.nid'] = '%Node.nid'; |
franck@0
|
396 $substitutions['node.uid'] = '%Node.uid'; |
franck@0
|
397 foreach ($fields as $key => $field) { |
franck@0
|
398 // For now, omit calculated fields from available fields list. |
franck@0
|
399 // Doing caculations on calculated fields will require some |
franck@0
|
400 // complex additional logic, especially if they are nested |
franck@0
|
401 // several levels deep. |
franck@0
|
402 if (substr($key, 0, 4) != '.cid') { |
franck@0
|
403 $substitutions[$key] = '%'. str_replace(' ', '', $key); |
franck@0
|
404 } |
franck@0
|
405 } |
franck@0
|
406 return $substitutions; |
franck@0
|
407 } |
franck@0
|
408 |
franck@0
|
409 /** |
franck@0
|
410 * Views calc fields result object |
franck@0
|
411 */ |
franck@0
|
412 function _views_calc_fields() { |
franck@0
|
413 return db_query("SELECT * FROM {views_calc_fields}"); |
franck@0
|
414 } |
franck@0
|
415 |
franck@0
|
416 /** |
franck@0
|
417 * An array of allowable calculation values. |
franck@0
|
418 */ |
franck@0
|
419 function _views_calc_replacements() { |
franck@0
|
420 $operators = array_filter(_views_calc_operators(), 'trim'); |
franck@0
|
421 $numbers = range(0, 9); |
franck@0
|
422 return array_merge($operators, $numbers); |
franck@2
|
423 } |
franck@2
|
424 |
franck@2
|
425 |
franck@2
|
426 /** |
franck@2
|
427 * Field export form. |
franck@2
|
428 */ |
franck@2
|
429 function views_calc_export_form() { |
franck@2
|
430 |
franck@2
|
431 $fields = _views_calc_fields(); |
franck@2
|
432 $string = ''; |
franck@2
|
433 while ($field = db_fetch_array($fields)) { |
franck@2
|
434 $base = $field['base']; |
franck@2
|
435 $substitutions = _views_calc_substitutions($base); |
franck@2
|
436 $field['calc'] = strtr($field['calc'], $substitutions); |
franck@2
|
437 $string .= "\$fields[] = ". var_export((array) $field, TRUE) .";\n"; |
franck@2
|
438 } |
franck@2
|
439 |
franck@2
|
440 $form['#prefix'] = t('This form will export Views Calc custom fields.'); |
franck@2
|
441 $form['macro'] = array( |
franck@2
|
442 '#type' => 'textarea', |
franck@2
|
443 '#rows' => 20, |
franck@2
|
444 '#title' => t('Export data'), |
franck@2
|
445 '#default_value' => $string, |
franck@2
|
446 '#description' => t('This is an export of the custom Views Calc fields. Paste this text into a Views Calc import box to import these fields into another installation. This will only work if the other installation uses the same base tables required by these fields.'), |
franck@2
|
447 ); |
franck@2
|
448 return $form; |
franck@2
|
449 } |
franck@2
|
450 |
franck@2
|
451 /** |
franck@2
|
452 * Field import form. |
franck@2
|
453 */ |
franck@2
|
454 function views_calc_import_form(&$form_state, $type_name = '') { |
franck@2
|
455 $form['#prefix'] = t('This form will import Views Calc custom fields.'); |
franck@2
|
456 $form['macro'] = array( |
franck@2
|
457 '#type' => 'textarea', |
franck@2
|
458 '#rows' => 20, |
franck@2
|
459 '#title' => t('Import data'), |
franck@2
|
460 '#required' => TRUE, |
franck@2
|
461 '#description' => t('Paste the text created by a Views Calc export into this field.'), |
franck@2
|
462 ); |
franck@2
|
463 $form['submit'] = array( |
franck@2
|
464 '#type' => 'submit', |
franck@2
|
465 '#value' => t('Import'), |
franck@2
|
466 ); |
franck@2
|
467 // Read in a file if there is one and set it as the default macro value. |
franck@2
|
468 if (isset($_REQUEST['macro_file']) && $file = file_get_contents($_REQUEST['macro_file'])) { |
franck@2
|
469 $form['macro']['#default_value'] = $file; |
franck@2
|
470 if (isset($_REQUEST['type_name'])) { |
franck@2
|
471 $form['type_name']['#default_value'] = $_REQUEST['type_name']; |
franck@2
|
472 } |
franck@2
|
473 $form['#prefix'] .= '<p class="error">'. t('A file has been pre-loaded for import.') .'</p>'; |
franck@2
|
474 } |
franck@2
|
475 $form['#redirect'] = 'admin/settings/views_calc'; |
franck@2
|
476 return $form; |
franck@2
|
477 } |
franck@2
|
478 |
franck@2
|
479 /** |
franck@2
|
480 * Submit handler for import form. |
franck@2
|
481 */ |
franck@2
|
482 function views_calc_import_form_submit($form, &$form_state) { |
franck@2
|
483 $form_values = $form_state['values']; |
franck@2
|
484 $fields = NULL; |
franck@2
|
485 |
franck@2
|
486 // Use '@' to suppress errors about undefined constants in the macro. |
franck@2
|
487 @eval($form_values['macro']); |
franck@2
|
488 |
franck@2
|
489 if (empty($fields) || !is_array($fields)) { |
franck@2
|
490 return; |
franck@2
|
491 } |
franck@2
|
492 |
franck@2
|
493 foreach ($fields as $delta => $field) { |
franck@2
|
494 // Don't over-write existing fields, create new ones. |
franck@2
|
495 $fields[$delta]['cid'] = NULL; |
franck@2
|
496 } |
franck@2
|
497 |
franck@2
|
498 // Run the values thru drupal_execute() so they are properly validated. |
franck@2
|
499 $form_state = array('values' => $fields); |
franck@2
|
500 drupal_execute('views_calc_fields_form', $form_state); |
franck@2
|
501 |
franck@0
|
502 } |