Révision a45e4bc1
Ajouté par Assos Assos il y a environ 9 ans
drupal7/sites/all/modules/webform/CHANGELOG.txt | ||
---|---|---|
1 |
Webform 2.x Changelog |
|
2 |
--------------------- |
|
3 |
|
|
4 |
2.x to 3.0 |
|
5 |
---------- |
|
6 |
- Module directory structure moved around. |
|
7 |
- Webform configuration moved to an entirely separate tab. |
|
8 |
- E-mail templates are now editable by administrators. |
|
9 |
- Conditional fields. |
|
10 |
- Submissions may be saved as a draft and resumed later. |
|
11 |
- Webform may now be attached to any content type. |
|
12 |
- Public API for allowing other modules to provide components. |
|
13 |
- Public API for interacting with submission save, insert, update, and delete. |
|
14 |
- New rendering capabilities for HTML presentation of submissions and e-mails. |
|
15 |
- Print module support. |
|
16 |
- Basic Views module support. |
|
17 |
- Popup calendar support on Date components (with Date Popup module). |
|
18 |
- New Mollom module integration. |
|
19 |
|
|
20 |
1.x to 2.0 |
|
21 |
---------- |
|
22 |
- Redirect POST option removed. |
|
23 |
- Webform components moved to the "Form components" tab when editing. |
|
24 |
- Webform node structure changed. All webform additions to the node are placed in $node->webform. |
|
25 |
- Clone option added to components. |
|
26 |
- Database storage improved to be more consistent and efficient. |
|
27 |
- Additional e-mails may be sent by modifying the $node->webform['additional_emails'] variable in the Additional Validation field. |
|
28 |
- The values of select and hidden fields may receive e-mails by using the option in Conditional e-mail recipients field. |
|
29 |
- E-mail from name, from address, and from subject may be entered in a text field. |
|
30 |
- The complete webform may be shown in the teaser view of a node. |
|
31 |
- Submit button text may be changed. |
|
32 |
- Theme function theme_webform_create_mailmessage() has been renamed to theme_webform_mail_message(). |
|
33 |
- $cid parameter added to theme_webform_mail_message() to create unique e-mails depending on a particular recipient or component. |
|
34 |
- Theme function theme_webform_mail_headers added. |
|
35 |
- Component descriptions are textareas rather than textfields. |
|
36 |
- _webform_filtervalues() has been renamed to _webform_filter_values. |
|
37 |
|
drupal7/sites/all/modules/webform/README.txt | ||
---|---|---|
1 | 1 |
Description |
2 | 2 |
----------- |
3 | 3 |
This module adds a webform content type to your Drupal site. |
4 |
A webform can be a questionnaire, contact or request form. These can be used
|
|
4 |
A webform can be a questionnaire, contact or request form. These can be used |
|
5 | 5 |
by visitor to make contact or to enable a more complex survey than polls |
6 |
provide. Submissions from a webform are saved in a database table and
|
|
6 |
provide. Submissions from a webform are saved in a database table and |
|
7 | 7 |
can optionally be mailed to e-mail addresses upon submission. |
8 | 8 |
|
9 | 9 |
Requirements |
10 | 10 |
------------ |
11 | 11 |
Drupal 7.x |
12 |
See https://www.drupal.org/project/webform for additional requirements. |
|
12 | 13 |
|
13 | 14 |
Installation |
14 | 15 |
------------ |
... | ... | |
23 | 24 |
|
24 | 25 |
Upgrading from previous versions |
25 | 26 |
-------------------------------- |
26 |
Note that if you are upgrading from a Drupal 6 installation of Webform, you MUST |
|
27 |
have been running Webform 3.x on your Drupal 6 site before upgrading to Drupal |
|
28 |
7 and Webform 3.x. You cannot upgrade directly from Webform 6.x-2.x to Webform |
|
29 |
7.x-3.x. |
|
27 |
Note that you must be running the latest 3.x version of Webform (for either |
|
28 |
Drupal 6 or Drupal 7) before upgrading to Webform 4.x. |
|
30 | 29 |
|
31 |
1. Copy the entire webform directory the Drupal modules directory. |
|
30 |
If you have contributed modules, custom modules, or theming on your Webforms, |
|
31 |
please read over the documentation for upgrading your code for Webform 4.x at |
|
32 |
https://drupal.org/node/1609324. |
|
32 | 33 |
|
33 |
2. Login as the FIRST user or change the $access_check in update.php to FALSE |
|
34 |
1. MAKE A DATABASE BACKUP. Upgrading to Webform 4.x makes a signficant number of |
|
35 |
database changes. If you encounter an error and need to downgrade, you must |
|
36 |
restore the previous database. You can make a database backup with your |
|
37 |
hosting provider, using the Backup and Migrate module, or from the command |
|
38 |
line. |
|
34 | 39 |
|
35 |
3. Run update.php (at http://www.example.com/update.php) |
|
40 |
2. Copy the entire webform directory the Drupal modules directory, replacing the |
|
41 |
old copy of Webform. DO NOT KEEP THE OLD COPY in the same directory or |
|
42 |
anywhere Drupal could possibily find it. Delete it from the server. |
|
43 |
|
|
44 |
3. Login as an administrative user or change the $update_free_access in |
|
45 |
update.php to TRUE. |
|
46 |
|
|
47 |
4. Run update.php (at http://www.example.com/update.php). |
|
36 | 48 |
|
37 | 49 |
Support |
38 | 50 |
------- |
drupal7/sites/all/modules/webform/THEMING.txt | ||
---|---|---|
66 | 66 |
<li><a href="<?php print url('node/'. $node->nid . '/submission/'. $sid)?>">View your submission</a></li> |
67 | 67 |
<li><a href="<?php print url('node/'. $node->nid . '/submission/'. $sid .'/edit')?>">Edit your submission</a></li> |
68 | 68 |
</ul> |
69 |
|
|
69 |
|
|
70 | 70 |
<?php /* End sample webform confirmation page */ ?> |
71 | 71 |
|
72 | 72 |
- You may edit the webform-confirmation.tpl.php file in your theme directory, |
... | ... | |
111 | 111 |
use webform-submission-[node id here].tpl.php for individual nodes if desired. |
112 | 112 |
Note that the contents of this template are used not only for display of |
113 | 113 |
submissions in the Webform interface but also in e-mails when printing out |
114 |
the %email_values token.
|
|
114 |
the [submission:values] token.
|
|
115 | 115 |
|
drupal7/sites/all/modules/webform/components/date.inc | ||
---|---|---|
15 | 15 |
'pid' => 0, |
16 | 16 |
'weight' => 0, |
17 | 17 |
'value' => '', |
18 |
'mandatory' => 0,
|
|
18 |
'required' => 0,
|
|
19 | 19 |
'extra' => array( |
20 | 20 |
'timezone' => 'user', |
21 |
'exclude' => array(), |
|
21 | 22 |
'start_date' => '-2 years', |
22 | 23 |
'end_date' => '+2 years', |
23 | 24 |
'year_textfield' => 0, |
... | ... | |
25 | 26 |
'title_display' => 0, |
26 | 27 |
'description' => '', |
27 | 28 |
'private' => FALSE, |
29 |
'analysis' => FALSE, |
|
28 | 30 |
), |
29 | 31 |
); |
30 | 32 |
} |
... | ... | |
73 | 75 |
'#access' => variable_get('configurable_timezones', 1), |
74 | 76 |
); |
75 | 77 |
|
78 |
$form['extra']['exclude'] = array( |
|
79 |
'#type' => 'checkboxes', |
|
80 |
'#title' => t('Hide'), |
|
81 |
'#default_value' => $component['extra']['exclude'], |
|
82 |
'#options' => array( |
|
83 |
'day' => t('Day'), |
|
84 |
'month' => t('Month'), |
|
85 |
'year' => t('Year'), |
|
86 |
), |
|
87 |
'#description' => t('A hidden day or month will be set to 1. A hidden year will be set to the year of the default value.'), |
|
88 |
'#weight' => 3, |
|
89 |
); |
|
90 |
|
|
76 | 91 |
$form['display']['datepicker'] = array( |
77 | 92 |
'#type' => 'checkbox', |
78 | 93 |
'#title' => t('Enable popup calendar'), |
... | ... | |
110 | 125 |
'#parents' => array('extra', 'end_date'), |
111 | 126 |
); |
112 | 127 |
|
128 |
$form['#validate'] = array('_webform_edit_date_validate'); |
|
113 | 129 |
return $form; |
114 | 130 |
} |
115 | 131 |
|
132 |
/** |
|
133 |
* Implements hook_form_id_validate. |
|
134 |
* |
|
135 |
* Warns user about hiding all the date fields and not using the date picker. |
|
136 |
*/ |
|
137 |
function _webform_edit_date_validate($form, &$form_state) { |
|
138 |
// Reduce checkbox values to simple non-associative array of values. |
|
139 |
form_set_value($form['extra']['exclude'], array_filter(array_values($form_state['values']['extra']['exclude'])), $form_state); |
|
140 |
|
|
141 |
// Note that Drupal 7 doesn't support setting errors no checkboxes due to |
|
142 |
// browser issues. @see https://www.drupal.org/node/222380 |
|
143 |
if (count($form_state['values']['extra']['exclude']) == 3) { |
|
144 |
form_set_error('extra][exclude', 'The day, month and year can\'t all be hidden.'); |
|
145 |
} |
|
146 |
if ($form_state['values']['extra']['exclude'] == array('month')) { |
|
147 |
form_set_error('extra][exclude', 'You cannot hide just the month.'); |
|
148 |
} |
|
149 |
|
|
150 |
// Validate that the start and end dates are valid. Don't validate the default |
|
151 |
// date because with token substitution, it might not be valid at component |
|
152 |
// definition time. Also note that validation was introduced in 7.x-4.8 and |
|
153 |
// previously-defined webform may have invalid start and end dates. |
|
154 |
foreach (array('start_date', 'end_date') as $field) { |
|
155 |
if (trim($form_state['values']['extra'][$field]) && !($date[$field] = webform_strtodate('c', $form_state['values']['extra'][$field]))) { |
|
156 |
form_set_error("extra][$field", t('The @field could not be interpreted in <a href="http://www.gnu.org/software/tar/manual/html_chapter/Date-input-formats.html">GNU Date Input Format</a>.', |
|
157 |
array('@field' => $form['validation'][$field]['#title']))); |
|
158 |
} |
|
159 |
} |
|
160 |
if (!empty($date['start_date']) && !empty($date['end_date']) && $date['end_date'] < $date['start_date']) { |
|
161 |
form_set_error('extra][end_date', t('The End date must be on or after the Start date.')); |
|
162 |
} |
|
163 |
} |
|
164 |
|
|
116 | 165 |
/** |
117 | 166 |
* Implements _webform_render_component(). |
118 | 167 |
*/ |
119 |
function _webform_render_date($component, $value = NULL, $filter = TRUE) { |
|
168 |
function _webform_render_date($component, $value = NULL, $filter = TRUE, $submission = NULL) {
|
|
120 | 169 |
$node = isset($component['nid']) ? node_load($component['nid']) : NULL; |
121 | 170 |
|
122 | 171 |
$element = array( |
123 | 172 |
'#type' => 'date', |
124 |
'#title' => $filter ? _webform_filter_xss($component['name']) : $component['name'],
|
|
173 |
'#title' => $filter ? webform_filter_xss($component['name']) : $component['name'], |
|
125 | 174 |
'#title_display' => $component['extra']['title_display'] ? $component['extra']['title_display'] : 'before', |
126 | 175 |
'#weight' => $component['weight'], |
127 |
'#description' => $filter ? _webform_filter_descriptions($component['extra']['description'], $node) : $component['extra']['description'],
|
|
128 |
'#required' => $component['mandatory'],
|
|
176 |
'#description' => $filter ? webform_filter_descriptions($component['extra']['description'], $node) : $component['extra']['description'], |
|
177 |
'#required' => $component['required'],
|
|
129 | 178 |
'#start_date' => trim($component['extra']['start_date']), |
130 | 179 |
'#end_date' => trim($component['extra']['end_date']), |
180 |
'#reference_timestamp' => $submission && $submission->completed ? $submission->completed : NULL, |
|
131 | 181 |
'#year_textfield' => $component['extra']['year_textfield'], |
132 |
'#default_value' => $filter ? _webform_filter_values($component['value'], $node, NULL, NULL, FALSE) : $component['value'],
|
|
182 |
'#default_value' => $filter ? webform_replace_tokens($component['value'], $node) : $component['value'],
|
|
133 | 183 |
'#timezone' => $component['extra']['timezone'], |
184 |
'#exclude' => $component['extra']['exclude'], |
|
134 | 185 |
'#process' => array('webform_expand_date'), |
135 | 186 |
'#theme' => 'webform_date', |
136 | 187 |
'#theme_wrappers' => array('webform_element'), |
... | ... | |
160 | 211 |
* Form API #process function for Webform date fields. |
161 | 212 |
*/ |
162 | 213 |
function webform_expand_date($element) { |
214 |
$timezone = $element['#timezone'] != 'user' ? NULL : 'user'; |
|
215 |
|
|
163 | 216 |
// Accept a string or array value for #default_value. |
164 | 217 |
if (!empty($element['#default_value']) && is_string($element['#default_value'])) { |
165 |
$timezone = $element['#timezone'] != 'user' ? NULL : 'user'; |
|
166 | 218 |
$timestring = webform_strtodate('c', $element['#default_value'], $timezone); |
167 | 219 |
$element['#default_value'] = webform_date_array($timestring, 'date'); |
168 | 220 |
} |
... | ... | |
190 | 242 |
// Let Drupal do it's normal expansion. |
191 | 243 |
$element = form_process_date($element); |
192 | 244 |
|
245 |
// Convert relative dates to absolute and calculate the year, month and day. |
|
246 |
$timezone = $element['#timezone'] != 'user' ? NULL : 'user'; |
|
247 |
foreach (array('start', 'end') as $start_end) { |
|
248 |
$element_field = &$element["#{$start_end}_date"]; |
|
249 |
$element_field = $element_field ? webform_strtodate('Y-m-d', $element_field, $timezone, $element['#reference_timestamp']) : ''; |
|
250 |
if ($element_field) { |
|
251 |
$parts = explode('-', $element_field); |
|
252 |
} |
|
253 |
else { |
|
254 |
$parts = $start_end == 'start' ? array(webform_strtodate('Y', '-2 years'), 1, 1) : array(webform_strtodate('Y', '+2 years'), 12, 31); |
|
255 |
$element_field = ''; |
|
256 |
} |
|
257 |
unset($element_field); // Drop PHP reference. |
|
258 |
$parts[3] = $parts[0] . '-' . $parts[1] . '-' . $parts[2]; |
|
259 |
$range[$start_end] = array_combine(array('year', 'month', 'day', 'date'), $parts); |
|
260 |
} |
|
261 |
|
|
262 |
// The start date is not guaranteeed to be early than the end date for |
|
263 |
// historical reasons. |
|
264 |
if ($range['start']['date'] > $range['end']['date']) { |
|
265 |
$temp = $range['start']; |
|
266 |
$range['start'] = $range['end']; |
|
267 |
$range['end'] = $temp; |
|
268 |
} |
|
269 |
|
|
270 |
// Restrict the months and days when not all options are valid choices. |
|
271 |
if ($element['#start_date'] && $element['#end_date']) { |
|
272 |
$delta_months = ($range['end']['year'] * 12 + $range['end']['month']) - ($range['start']['year'] * 12 + $range['start']['month']); |
|
273 |
if ($delta_months < 11) { |
|
274 |
// There are 10 or fewer months between the start and end date. If there |
|
275 |
// were 11, then every month would be possible, and the menu select |
|
276 |
// should not be pruned. |
|
277 |
$month_options = &$element['month']['#options']; |
|
278 |
if ($range['start']['month'] <= $range['end']['month']) { |
|
279 |
$month_options = array_intersect_key($month_options, array_flip(range($range['start']['month'], $range['end']['month']))); |
|
280 |
} |
|
281 |
else { |
|
282 |
$month_options = array_intersect_key($month_options, array_flip(range($range['start']['month'], 12))) + |
|
283 |
array_intersect_key($month_options, array_flip(range(1, $range['end']['month']))); |
|
284 |
} |
|
285 |
unset($month_options); // Drop PHP reference. |
|
286 |
if ($delta_months <= 1) { |
|
287 |
// The start and end date are either on the same month or consequtive |
|
288 |
// months. See if the days should be pruned. |
|
289 |
$day_options = &$element['day']['#options']; |
|
290 |
if ($range['start']['month'] == $range['end']['month']) { |
|
291 |
// Range is within the same month. The days are a simple range from |
|
292 |
// start day to end day. |
|
293 |
$day_options = array_intersect_key($day_options, array_flip(range($range['start']['day'], $range['end']['day']))); |
|
294 |
} |
|
295 |
elseif ($range['start']['day'] > $range['end']['day'] + 1) { |
|
296 |
// Range spans two months and at least one day would be omitted. |
|
297 |
$days_in_month = date('t', mktime(0, 0, 0, $range['start']['month'], 1, $range['start']['year'])); |
|
298 |
$day_options = array_intersect_key($day_options, array_flip(range($range['start']['day'], $days_in_month))) + |
|
299 |
array_intersect_key($day_options, array_flip(range(1, $range['end']['day']))); |
|
300 |
} |
|
301 |
unset($day_options); // Drop PHP reference. |
|
302 |
} |
|
303 |
} |
|
304 |
} |
|
305 |
|
|
193 | 306 |
// Set default values. |
194 | 307 |
foreach ($default_values as $type => $value) { |
195 | 308 |
switch ($type) { |
196 | 309 |
case 'month': |
197 | 310 |
$none = t('Month'); |
311 |
$hidden_default = 1; |
|
198 | 312 |
break; |
199 | 313 |
case 'day': |
200 | 314 |
$none = t('Day'); |
315 |
$hidden_default = 1; |
|
201 | 316 |
break; |
202 | 317 |
case 'year': |
203 | 318 |
$none = t('Year'); |
319 |
$hidden_default = !empty($element['#default_value']['year']) ? $element['#default_value']['year'] : webform_strtodate('Y', 'today', $timezone); |
|
204 | 320 |
break; |
205 | 321 |
} |
206 | 322 |
unset($element[$type]['#value']); |
207 | 323 |
$element[$type]['#title'] = $none; |
208 | 324 |
$element[$type]['#title_display'] = 'invisible'; |
209 |
$element[$type]['#default_value'] = isset($default_values[$type]) ? $default_values[$type] : NULL;
|
|
325 |
$element[$type]['#default_value'] = $default_values[$type];
|
|
210 | 326 |
$element[$type]['#options'] = array('' => $none) + $element[$type]['#options']; |
211 |
}
|
|
212 |
|
|
213 |
// Convert relative dates to absolute ones.
|
|
214 |
foreach (array('start_date', 'end_date') as $start_end) {
|
|
215 |
$timezone = $element['#timezone'] != 'user' ? NULL : 'user';
|
|
216 |
$date = webform_strtodate('Y-m-d', $element['#' . $start_end], $timezone);
|
|
217 |
$element['#' . $start_end] = $date ? $date : '';
|
|
327 |
if (in_array($type, $element['#exclude'])) {
|
|
328 |
$element[$type] += array( |
|
329 |
'#prefix' => '<div class="webform-date-field-wrapper element-invisible">',
|
|
330 |
'#suffix' => '</div>',
|
|
331 |
);
|
|
332 |
$element[$type]['#default_value'] = $hidden_default;
|
|
333 |
}
|
|
218 | 334 |
} |
219 | 335 |
|
220 | 336 |
// Tweak the year field. |
... | ... | |
225 | 341 |
unset($element['year']['#options']); |
226 | 342 |
} |
227 | 343 |
elseif ($element['#start_date'] || $element['#end_date']) { |
228 |
$start_year = $element['#start_date'] ? webform_strtodate('Y', $element['#start_date']) : webform_strtodate('Y', '-2 years'); |
|
229 |
$end_year = $element['#end_date'] ? webform_strtodate('Y', $element['#end_date']) : webform_strtodate('Y', '+2 years'); |
|
230 |
$element['year']['#options'] = array('' => t('Year')) + drupal_map_assoc(range($start_year, $end_year)); |
|
344 |
$element['year']['#options'] = array('' => t('Year')) + drupal_map_assoc(range($range['start']['year'], $range['end']['year'])); |
|
231 | 345 |
} |
232 | 346 |
|
233 | 347 |
return $element; |
... | ... | |
250 | 364 |
$element['day']['#attributes']['class'][] = 'error'; |
251 | 365 |
} |
252 | 366 |
|
367 |
// Add HTML5 required attribute, if needed. |
|
368 |
if ($element['#required']) { |
|
369 |
$element['year']['#attributes']['required'] = 'required'; |
|
370 |
$element['month']['#attributes']['required'] = 'required'; |
|
371 |
$element['day']['#attributes']['required'] = 'required'; |
|
372 |
} |
|
373 |
|
|
253 | 374 |
$class = array('webform-container-inline'); |
254 | 375 |
|
255 | 376 |
// Add the JavaScript calendar if available (provided by Date module package). |
... | ... | |
280 | 401 |
* Element validation for Webform date fields. |
281 | 402 |
*/ |
282 | 403 |
function webform_validate_date($element, $form_state) { |
283 |
// Check if the user filled the required fields. |
|
284 |
foreach (array('day', 'month', 'year') as $field_type) { |
|
285 |
if (!is_numeric($element[$field_type]['#value']) && $element['#required']) { |
|
286 |
form_error($element, t('!name field is required.', array('!name' => $element['#title']))); |
|
404 |
if ($element['month']['#value'] !== '' || $element['day']['#value'] !== '' || $element['year']['#value'] !== '') { |
|
405 |
// Check that each part of the date has been filled in. |
|
406 |
foreach (array('day', 'month', 'year') as $field_type) { |
|
407 |
if (empty($element[$field_type]['#value'])) { |
|
408 |
form_error($element[$field_type], t('!part in !name is missing.', array('!name' => $element['#title'], '!part' => $element[$field_type]['#title']))); |
|
409 |
$missing_fields = TRUE; |
|
410 |
} |
|
411 |
} |
|
412 |
if (isset($missing_fields)) { |
|
287 | 413 |
return; |
288 | 414 |
} |
289 |
} |
|
290 | 415 |
|
291 |
if ($element['month']['#value'] !== '' || $element['day']['#value'] !== '' || $element['year']['#value'] !== '') { |
|
292 | 416 |
// Check for a valid date. |
293 |
if (!checkdate((int) $element['month']['#value'], (int) $element['day']['#value'], (int) $element['year']['#value'])) {
|
|
417 |
if (!checkdate($element['month']['#value'], $element['day']['#value'], $element['year']['#value'])) {
|
|
294 | 418 |
form_error($element, t('Entered !name is not a valid date.', array('!name' => $element['#title']))); |
295 | 419 |
return; |
296 | 420 |
} |
... | ... | |
299 | 423 |
$timestamp = strtotime($element['year']['#value'] . '-' . $element['month']['#value'] . '-' . $element['day']['#value']); |
300 | 424 |
$format = webform_date_format('short'); |
301 | 425 |
|
302 |
// Flip start and end if needed. |
|
426 |
// Flip start and end if needed. Prior to 7.x-4.8, it was possible to save |
|
427 |
// a date component with the end date earlier than the start date. |
|
303 | 428 |
$date1 = strtotime($element['#start_date']); |
304 | 429 |
$date2 = strtotime($element['#end_date']); |
305 | 430 |
if ($date1 !== FALSE && $date2 !== FALSE) { |
... | ... | |
312 | 437 |
} |
313 | 438 |
|
314 | 439 |
// Check that the date is after the start date. |
315 |
if ($start_date !== FALSE) { |
|
316 |
if ($timestamp < $start_date) { |
|
317 |
form_error($element, t('The entered date must be @start_date or later.', array('@start_date' => date($format, $start_date)))); |
|
318 |
} |
|
440 |
if ($start_date !== FALSE && $timestamp < $start_date) { |
|
441 |
form_error($element, t('The entered date must be @start_date or later.', array('@start_date' => date($format, $start_date)))); |
|
319 | 442 |
} |
320 | 443 |
|
321 | 444 |
// Check that the date is before the end date. |
322 |
if ($end_date !== FALSE) { |
|
323 |
if ($timestamp > $end_date) { |
|
324 |
form_error($element, t('The entered date must be @end_date or earlier.', array('@end_date' => date($format, $end_date)))); |
|
325 |
} |
|
445 |
if ($end_date !== FALSE && $timestamp > $end_date) { |
|
446 |
form_error($element, t('The entered date must be @end_date or earlier.', array('@end_date' => date($format, $end_date)))); |
|
326 | 447 |
} |
327 | 448 |
} |
449 |
elseif ($element['#required']) { |
|
450 |
form_error($element, t('!name field is required.', array('!name' => $element['#title']))); |
|
451 |
} |
|
328 | 452 |
} |
329 | 453 |
|
330 | 454 |
/** |
... | ... | |
338 | 462 |
/** |
339 | 463 |
* Implements _webform_display_component(). |
340 | 464 |
*/ |
341 |
function _webform_display_date($component, $value, $format = 'html') { |
|
465 |
function _webform_display_date($component, $value, $format = 'html', $submission = array()) {
|
|
342 | 466 |
$value = webform_date_array(isset($value[0]) ? $value[0] : '', 'date'); |
343 | 467 |
|
344 | 468 |
return array( |
345 | 469 |
'#title' => $component['name'], |
470 |
'#title_display' => $component['extra']['title_display'] ? $component['extra']['title_display'] : 'before', |
|
346 | 471 |
'#weight' => $component['weight'], |
347 | 472 |
'#theme' => 'webform_display_date', |
348 | 473 |
'#theme_wrappers' => $format == 'html' ? array('webform_element') : array('webform_element_text'), |
349 | 474 |
'#format' => $format, |
475 |
'#exclude' => $component['extra']['exclude'], |
|
476 |
|
|
350 | 477 |
'#value' => $value, |
351 | 478 |
'#translatable' => array('title'), |
352 | 479 |
); |
... | ... | |
360 | 487 |
$output = ' '; |
361 | 488 |
if ($element['#value']['year'] && $element['#value']['month'] && $element['#value']['day']) { |
362 | 489 |
$timestamp = webform_strtotime($element['#value']['month'] . '/' . $element['#value']['day'] . '/' . $element['#value']['year']); |
363 |
$format = webform_date_format('medium');
|
|
490 |
$format = webform_date_format(NULL, $element['#exclude']);
|
|
364 | 491 |
$output = format_date($timestamp, 'custom', $format, 'UTC'); |
365 | 492 |
} |
366 | 493 |
|
... | ... | |
370 | 497 |
/** |
371 | 498 |
* Implements _webform_analysis_component(). |
372 | 499 |
*/ |
373 |
function _webform_analysis_date($component, $sids = array()) { |
|
500 |
function _webform_analysis_date($component, $sids = array(), $single = FALSE, $join = NULL) {
|
|
374 | 501 |
$query = db_select('webform_submitted_data', 'wsd', array('fetch' => PDO::FETCH_ASSOC)) |
375 | 502 |
->fields('wsd', array('no', 'data')) |
376 |
->condition('nid', $component['nid']) |
|
377 |
->condition('cid', $component['cid']) |
|
378 |
->orderBy('sid'); |
|
503 |
->condition('wsd.nid', $component['nid'])
|
|
504 |
->condition('wsd.cid', $component['cid'])
|
|
505 |
->orderBy('wsd.sid');
|
|
379 | 506 |
|
380 | 507 |
if (count($sids)) { |
381 |
$query->condition('sid', $sids, 'IN'); |
|
508 |
$query->condition('wsd.sid', $sids, 'IN'); |
|
509 |
} |
|
510 |
|
|
511 |
if ($join) { |
|
512 |
$query->innerJoin($join, 'ws2_', 'wsd.sid = ws2_.sid'); |
|
382 | 513 |
} |
383 | 514 |
|
384 | 515 |
$result = $query->execute(); |
... | ... | |
396 | 527 |
$nonblanks = count($dates); |
397 | 528 |
$rows[0] = array(t('Left Blank'), ($submissions - $nonblanks)); |
398 | 529 |
$rows[1] = array(t('User entered value'), $nonblanks); |
399 |
return $rows; |
|
530 |
|
|
531 |
return array( |
|
532 |
'table_rows' => $rows, |
|
533 |
); |
|
400 | 534 |
} |
401 | 535 |
|
402 | 536 |
/** |
... | ... | |
405 | 539 |
function _webform_table_date($component, $value) { |
406 | 540 |
if ($value[0]) { |
407 | 541 |
$timestamp = webform_strtotime($value[0]); |
408 |
$format = webform_date_format('short'); |
|
542 |
$format = webform_date_format('short', $component['extra']['exclude']);
|
|
409 | 543 |
return format_date($timestamp, 'custom', $format, 'UTC'); |
410 | 544 |
} |
411 | 545 |
else { |
... | ... | |
420 | 554 |
$header = array(); |
421 | 555 |
$header[0] = ''; |
422 | 556 |
$header[1] = ''; |
423 |
$header[2] = $component['name']; |
|
557 |
$header[2] = $export_options['header_keys'] ? $component['form_key'] : $component['name'];
|
|
424 | 558 |
return $header; |
425 | 559 |
} |
426 | 560 |
|
... | ... | |
430 | 564 |
function _webform_csv_data_date($component, $export_options, $value) { |
431 | 565 |
if ($value[0]) { |
432 | 566 |
$timestamp = webform_strtotime($value[0]); |
433 |
$format = webform_date_format('short'); |
|
567 |
if (!empty($export_options['iso8601_date'])) { |
|
568 |
$format = 'Y-m-d'; // ISO 8601 date: 2004-02-12 |
|
569 |
} |
|
570 |
else { |
|
571 |
$format = webform_date_format('short'); |
|
572 |
} |
|
434 | 573 |
return format_date($timestamp, 'custom', $format, 'UTC'); |
435 | 574 |
} |
436 | 575 |
else { |
drupal7/sites/all/modules/webform/components/email.inc | ||
---|---|---|
15 | 15 |
'pid' => 0, |
16 | 16 |
'weight' => 0, |
17 | 17 |
'value' => '', |
18 |
'mandatory' => 0,
|
|
18 |
'required' => 0,
|
|
19 | 19 |
'extra' => array( |
20 |
'multiple' => 0, |
|
21 |
'format' => 'short', |
|
20 | 22 |
'width' => '', |
21 | 23 |
'unique' => 0, |
22 | 24 |
'disabled' => 0, |
23 | 25 |
'title_display' => 0, |
24 | 26 |
'description' => '', |
27 |
'placeholder' => '', |
|
25 | 28 |
'attributes' => array(), |
26 | 29 |
'private' => FALSE, |
30 |
'analysis' => FALSE, |
|
27 | 31 |
), |
28 | 32 |
); |
29 | 33 |
} |
... | ... | |
52 | 56 |
'#type' => 'textfield', |
53 | 57 |
'#title' => t('Default value'), |
54 | 58 |
'#default_value' => $component['value'], |
55 |
'#description' => t('The default value of the field.') . theme('webform_token_help'), |
|
59 |
'#description' => t('The default value of the field.') . ' ' . theme('webform_token_help'),
|
|
56 | 60 |
'#size' => 60, |
57 | 61 |
'#maxlength' => 127, |
58 | 62 |
'#weight' => 0, |
59 |
'#attributes' => ($component['value'] == '%useremail' && count(form_get_errors()) == 0) ? array('disabled' => TRUE) : array(),
|
|
63 |
'#attributes' => ($component['value'] == '[current-user:mail]' && count(form_get_errors()) == 0) ? array('disabled' => TRUE) : array(),
|
|
60 | 64 |
'#id' => 'email-value', |
61 | 65 |
); |
62 | 66 |
$form['user_email'] = array( |
63 | 67 |
'#type' => 'checkbox', |
64 | 68 |
'#title' => t('User email as default'), |
65 |
'#default_value' => $component['value'] == '%useremail' ? 1 : 0,
|
|
69 |
'#default_value' => $component['value'] == '[current-user:mail]' ? 1 : 0,
|
|
66 | 70 |
'#description' => t('Set the default value of this field to the user email, if he/she is logged in.'), |
67 |
'#attributes' => array('onclick' => 'getElementById("email-value").value = (this.checked ? "%useremail" : ""); getElementById("email-value").disabled = this.checked;'),
|
|
71 |
'#attributes' => array('onclick' => 'getElementById("email-value").value = (this.checked ? "[current-user:mail]" : ""); getElementById("email-value").disabled = this.checked;'),
|
|
68 | 72 |
'#weight' => 0, |
69 | 73 |
'#element_validate' => array('_webform_edit_email_validate'), |
70 | 74 |
); |
75 |
$form['extra']['multiple'] = array( |
|
76 |
'#type' => 'checkbox', |
|
77 |
'#title' => t('Multiple'), |
|
78 |
'#default_value' => $component['extra']['multiple'], |
|
79 |
'#description' => t('Allow multiple e-mail addresses, separated by commas.'), |
|
80 |
'#weight' => 0, |
|
81 |
); |
|
82 |
if (webform_variable_get('webform_email_address_format') == 'long') { |
|
83 |
$form['extra']['format'] = array( |
|
84 |
'#type' => 'radios', |
|
85 |
'#title' => t('Format'), |
|
86 |
'#options' => array( |
|
87 |
'long' => t('Allow long format: "Example Name" <name@example.com>'), |
|
88 |
'short' => t('Short format only: name@example.com'), |
|
89 |
), |
|
90 |
'#default_value' => $component['extra']['format'], |
|
91 |
'#description' => t('Not all servers support the "long" format.'), |
|
92 |
); |
|
93 |
} |
|
71 | 94 |
$form['display']['width'] = array( |
72 | 95 |
'#type' => 'textfield', |
73 | 96 |
'#title' => t('Width'), |
... | ... | |
77 | 100 |
'#maxlength' => 10, |
78 | 101 |
'#parents' => array('extra', 'width'), |
79 | 102 |
); |
103 |
$form['display']['placeholder'] = array( |
|
104 |
'#type' => 'textfield', |
|
105 |
'#title' => t('Placeholder'), |
|
106 |
'#default_value' => $component['extra']['placeholder'], |
|
107 |
'#description' => t('The placeholder will be shown in the field until the user starts entering a value.') . ' ' . t('Often used for example values, such as "john@example.com".'), |
|
108 |
'#parents' => array('extra', 'placeholder'), |
|
109 |
); |
|
80 | 110 |
$form['display']['disabled'] = array( |
81 | 111 |
'#type' => 'checkbox', |
82 | 112 |
'#title' => t('Disabled'), |
... | ... | |
103 | 133 |
*/ |
104 | 134 |
function _webform_edit_email_validate($element, &$form_state) { |
105 | 135 |
if ($form_state['values']['user_email']) { |
106 |
$form_state['values']['value'] = '%useremail';
|
|
136 |
$form_state['values']['value'] = '[current-user:mail]';
|
|
107 | 137 |
} |
108 | 138 |
} |
109 | 139 |
|
110 | 140 |
/** |
111 | 141 |
* Implements _webform_render_component(). |
112 | 142 |
*/ |
113 |
function _webform_render_email($component, $value = NULL, $filter = TRUE) { |
|
143 |
function _webform_render_email($component, $value = NULL, $filter = TRUE, $submission = NULL) {
|
|
114 | 144 |
global $user; |
115 | 145 |
$node = isset($component['nid']) ? node_load($component['nid']) : NULL; |
116 | 146 |
|
117 | 147 |
$element = array( |
118 | 148 |
'#type' => 'webform_email', |
119 |
'#title' => $filter ? _webform_filter_xss($component['name']) : $component['name'],
|
|
149 |
'#title' => $filter ? webform_filter_xss($component['name']) : $component['name'], |
|
120 | 150 |
'#title_display' => $component['extra']['title_display'] ? $component['extra']['title_display'] : 'before', |
121 |
'#default_value' => $filter ? _webform_filter_values($component['value'], $node) : $component['value'],
|
|
122 |
'#required' => $component['mandatory'],
|
|
151 |
'#default_value' => $filter ? webform_replace_tokens($component['value'], $node) : $component['value'],
|
|
152 |
'#required' => $component['required'],
|
|
123 | 153 |
'#weight' => $component['weight'], |
124 |
'#description' => $filter ? _webform_filter_descriptions($component['extra']['description'], $node) : $component['extra']['description'],
|
|
154 |
'#description' => $filter ? webform_filter_descriptions($component['extra']['description'], $node) : $component['extra']['description'], |
|
125 | 155 |
'#attributes' => $component['extra']['attributes'], |
126 | 156 |
'#element_validate' => array('_webform_validate_email'), |
127 | 157 |
'#theme_wrappers' => array('webform_element'), |
128 | 158 |
'#translatable' => array('title', 'description'), |
129 | 159 |
); |
130 | 160 |
|
161 |
if ($component['required']) { |
|
162 |
$element['#attributes']['required'] = 'required'; |
|
163 |
} |
|
164 |
|
|
131 | 165 |
// Add an e-mail class for identifying the difference from normal textfields. |
132 | 166 |
$element['#attributes']['class'][] = 'email'; |
133 | 167 |
|
... | ... | |
136 | 170 |
$element['#element_validate'][] = 'webform_validate_unique'; |
137 | 171 |
} |
138 | 172 |
|
139 |
if (isset($value)) { |
|
173 |
if ($component['extra']['format'] == 'long') { |
|
174 |
// html5 email elements enforce short-form email validation in addition to |
|
175 |
// pattern validation. This means that long format email addresses must be |
|
176 |
// rendered as text. |
|
177 |
$element['#attributes']['type'] = 'text'; |
|
178 |
|
|
179 |
// html5 patterns have implied delimters and start and end patterns. |
|
180 |
// The are also case sensitive, not global, and not multi-line. |
|
181 |
// See https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation |
|
182 |
// See http://stackoverflow.com/questions/19605773/html5-email-validation |
|
183 |
$address = '[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*'; |
|
184 |
$name = '("[^<>"]*?"|[^<>",]*?)'; |
|
185 |
$short_long = "($name *<$address>|$address)"; |
|
186 |
$element['#attributes']['pattern'] = $component['extra']['multiple'] |
|
187 |
? "$short_long(, *$short_long)*" |
|
188 |
: $short_long; |
|
189 |
} |
|
190 |
elseif ($component['extra']['multiple']) { |
|
191 |
$element['#attributes']['multiple'] = 'multiple'; |
|
192 |
} |
|
193 |
|
|
194 |
if (isset($value[0])) { |
|
140 | 195 |
$element['#default_value'] = $value[0]; |
141 | 196 |
} |
142 | 197 |
|
198 |
if ($component['extra']['placeholder']) { |
|
199 |
$element['#attributes']['placeholder'] = $component['extra']['placeholder']; |
|
200 |
} |
|
201 |
|
|
143 | 202 |
if ($component['extra']['disabled']) { |
144 | 203 |
if ($filter) { |
145 | 204 |
$element['#attributes']['readonly'] = 'readonly'; |
... | ... | |
193 | 252 |
*/ |
194 | 253 |
function _webform_validate_email($form_element, &$form_state) { |
195 | 254 |
$component = $form_element['#webform_component']; |
196 |
$value = trim($form_element['#value']);
|
|
197 |
if ($value !== '' && !valid_email_address($value)) {
|
|
198 |
form_error($form_element, t('%value is not a valid email address.', array('%value' => $value)));
|
|
199 |
}
|
|
200 |
else {
|
|
201 |
form_set_value($form_element, $value, $form_state);
|
|
202 |
}
|
|
255 |
$format = webform_variable_get('webform_email_address_format') == 'long' ? $component['extra']['format'] : 'short';
|
|
256 |
webform_email_validate($form_element['#value'],
|
|
257 |
implode('][', $form_element ['#parents']),
|
|
258 |
TRUE, // Required validation is done elsewhere.
|
|
259 |
$component['extra']['multiple'],
|
|
260 |
FALSE, // No tokens are allowed in user input.
|
|
261 |
$format);
|
|
203 | 262 |
} |
204 | 263 |
|
205 | 264 |
/** |
206 | 265 |
* Implements _webform_display_component(). |
207 | 266 |
*/ |
208 |
function _webform_display_email($component, $value, $format = 'html') { |
|
267 |
function _webform_display_email($component, $value, $format = 'html', $submission = array()) {
|
|
209 | 268 |
return array( |
210 | 269 |
'#title' => $component['name'], |
270 |
'#title_display' => $component['extra']['title_display'] ? $component['extra']['title_display'] : 'before', |
|
211 | 271 |
'#weight' => $component['weight'], |
212 | 272 |
'#theme' => 'webform_display_email', |
213 | 273 |
'#theme_wrappers' => $format == 'html' ? array('webform_element') : array('webform_element_text'), |
... | ... | |
229 | 289 |
/** |
230 | 290 |
* Implements _webform_analysis_component(). |
231 | 291 |
*/ |
232 |
function _webform_analysis_email($component, $sids = array()) { |
|
292 |
function _webform_analysis_email($component, $sids = array(), $single = FALSE, $join = NULL) {
|
|
233 | 293 |
$query = db_select('webform_submitted_data', 'wsd', array('fetch' => PDO::FETCH_ASSOC)) |
234 | 294 |
->fields('wsd', array('no', 'data')) |
235 |
->condition('nid', $component['nid']) |
|
236 |
->condition('cid', $component['cid']); |
|
295 |
->condition('wsd.nid', $component['nid'])
|
|
296 |
->condition('wsd.cid', $component['cid']);
|
|
237 | 297 |
|
238 | 298 |
if (count($sids)) { |
239 |
$query->condition('sid', $sids, 'IN'); |
|
299 |
$query->condition('wsd.sid', $sids, 'IN'); |
|
300 |
} |
|
301 |
|
|
302 |
if ($join) { |
|
303 |
$query->innerJoin($join, 'ws2_', 'wsd.sid = ws2_.sid'); |
|
240 | 304 |
} |
241 | 305 |
|
242 | 306 |
$nonblanks = 0; |
... | ... | |
254 | 318 |
|
255 | 319 |
$rows[0] = array(t('Left Blank'), ($submissions - $nonblanks)); |
256 | 320 |
$rows[1] = array(t('User entered value'), $nonblanks); |
257 |
$rows[2] = array(t('Average submission length in words (ex blanks)'), ($nonblanks != 0 ? number_format($wordcount/$nonblanks, 2) : '0')); |
|
258 |
return $rows; |
|
321 |
|
|
322 |
$other[0] = array(t('Average submission length in words (ex blanks)'), ($nonblanks != 0 ? number_format($wordcount/$nonblanks, 2) : '0')); |
|
323 |
|
|
324 |
return array( |
|
325 |
'table_rows' => $rows, |
|
326 |
'other_data' => $other, |
|
327 |
); |
|
328 |
|
|
259 | 329 |
} |
260 | 330 |
|
261 | 331 |
/** |
... | ... | |
273 | 343 |
$header = array(); |
274 | 344 |
$header[0] = ''; |
275 | 345 |
$header[1] = ''; |
276 |
$header[2] = $component['name']; |
|
346 |
$header[2] = $export_options['header_keys'] ? $component['form_key'] : $component['name'];
|
|
277 | 347 |
return $header; |
278 | 348 |
} |
279 | 349 |
|
drupal7/sites/all/modules/webform/components/fieldset.inc | ||
---|---|---|
51 | 51 |
/** |
52 | 52 |
* Implements _webform_render_component(). |
53 | 53 |
*/ |
54 |
function _webform_render_fieldset($component, $value = NULL, $filter = TRUE) { |
|
54 |
function _webform_render_fieldset($component, $value = NULL, $filter = TRUE, $submission = NULL) {
|
|
55 | 55 |
$node = isset($component['nid']) ? node_load($component['nid']) : NULL; |
56 | 56 |
|
57 | 57 |
$element = array( |
58 | 58 |
'#type' => 'fieldset', |
59 |
'#title' => $filter ? _webform_filter_xss($component['name']) : $component['name'],
|
|
59 |
'#title' => $filter ? webform_filter_xss($component['name']) : $component['name'], |
|
60 | 60 |
'#title_display' => $component['extra']['title_display'] ? $component['extra']['title_display'] : NULL, |
61 | 61 |
'#weight' => $component['weight'], |
62 |
'#description' => $filter ? _webform_filter_descriptions($component['extra']['description'], $node) : $component['extra']['description'],
|
|
62 |
'#description' => $filter ? webform_filter_descriptions($component['extra']['description'], $node) : $component['extra']['description'], |
|
63 | 63 |
'#collapsible' => $component['extra']['collapsible'], |
64 | 64 |
'#collapsed' => $component['extra']['collapsed'], |
65 | 65 |
'#attributes' => array('class' => array('webform-component-fieldset')), |
... | ... | |
71 | 71 |
} |
72 | 72 |
|
73 | 73 |
/** |
74 |
* Pre-render function to set a fieldset ID.
|
|
74 |
* Pre-render function to set a unique fieldset class name.
|
|
75 | 75 |
*/ |
76 | 76 |
function webform_fieldset_prerender($element) { |
77 |
$element['#id'] = 'webform-component-' . str_replace('_', '-', implode('--', array_slice($element['#parents'], 1))); |
|
77 |
$element['#id'] = NULL; |
|
78 |
$element['#attributes']['class'][] = 'webform-component--' . str_replace('_', '-', implode('--', array_slice($element['#parents'], 1))); |
|
78 | 79 |
return $element; |
79 | 80 |
} |
80 | 81 |
|
81 | 82 |
/** |
82 | 83 |
* Implements _webform_display_component(). |
83 | 84 |
*/ |
84 |
function _webform_display_fieldset($component, $value, $format = 'html') { |
|
85 |
function _webform_display_fieldset($component, $value, $format = 'html', $submission = array()) {
|
|
85 | 86 |
if ($format == 'text') { |
86 | 87 |
$element = array( |
87 | 88 |
'#title' => $component['name'], |
drupal7/sites/all/modules/webform/components/file.inc | ||
---|---|---|
12 | 12 |
return array( |
13 | 13 |
'name' => '', |
14 | 14 |
'form_key' => NULL, |
15 |
'mandatory' => 0,
|
|
15 |
'required' => 0,
|
|
16 | 16 |
'pid' => 0, |
17 | 17 |
'weight' => 0, |
18 | 18 |
'extra' => array( |
... | ... | |
21 | 21 |
'addextensions' => '', |
22 | 22 |
'size' => '2 MB', |
23 | 23 |
), |
24 |
'rename' => '', |
|
24 | 25 |
'scheme' => 'public', |
25 | 26 |
'directory' => '', |
26 | 27 |
'progress_indicator' => 'throbber', |
... | ... | |
28 | 29 |
'description' => '', |
29 | 30 |
'attributes' => array(), |
30 | 31 |
'private' => FALSE, |
32 |
'analysis' => FALSE, |
|
31 | 33 |
), |
32 | 34 |
); |
33 | 35 |
} |
... | ... | |
45 | 47 |
'render element' => 'element', |
46 | 48 |
'file' => 'components/file.inc', |
47 | 49 |
), |
50 |
'webform_managed_file' => array( |
|
51 |
'render element' => 'element', |
|
52 |
'file' => 'components/file.inc', |
|
53 |
), |
|
48 | 54 |
); |
49 | 55 |
} |
50 | 56 |
|
... | ... | |
77 | 83 |
'js' => array(drupal_get_path('module', 'webform') . '/js/webform-admin.js'), |
78 | 84 |
'css' => array(drupal_get_path('module', 'webform') . '/css/webform-admin.css'), |
79 | 85 |
), |
86 |
'#type' => 'webform_file_extensions', |
|
80 | 87 |
'#weight' => 2, |
81 | 88 |
); |
82 | 89 |
|
... | ... | |
99 | 106 |
'#default_value' => array_intersect($current_types, $types), |
100 | 107 |
); |
101 | 108 |
|
102 |
$types = array('txt', 'rtf', 'html', 'odf', 'pdf', 'doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'xml');
|
|
109 |
$types = array('txt', 'rtf', 'html', 'pdf', 'doc', 'docx', 'odt', 'ppt', 'pptx', 'odp', 'xls', 'xlsx', 'ods', 'xml');
|
|
103 | 110 |
$form['validation']['extensions']['types']['documents'] = array( |
104 | 111 |
'#type' => 'checkboxes', |
105 | 112 |
'#title' => t('Documents'), |
... | ... | |
149 | 156 |
'#type' => 'textfield', |
150 | 157 |
'#title' => t('Upload directory'), |
151 | 158 |
'#default_value' => $component['extra']['directory'], |
152 |
'#description' => t('You may optionally specify a sub-directory to store your files.'), |
|
159 |
'#description' => t('You may optionally specify a sub-directory to store your files.') . ' ' . theme('webform_token_help'),
|
|
153 | 160 |
'#weight' => 5, |
154 | 161 |
'#field_prefix' => 'webform/', |
155 | 162 |
); |
156 | 163 |
|
164 |
$form['extra']['rename'] = array( |
|
165 |
'#type' => 'textfield', |
|
166 |
'#title' => t('Rename files'), |
|
167 |
'#default_value' => $component['extra']['rename'], |
|
168 |
'#description' => t('You may optionally use tokens to create a pattern used to rename files upon submission. Omit the extension; it will be added automatically.') . ' ' . theme('webform_token_help', array('groups' => array('node', 'submission'))), |
|
169 |
'#weight' => 6, |
|
170 |
'#element_validate' => array('_webform_edit_file_rename_validate'), |
|
171 |
); |
|
172 |
|
|
157 | 173 |
$form['display']['progress_indicator'] = array( |
158 | 174 |
'#type' => 'radios', |
159 | 175 |
'#title' => t('Progress indicator'), |
... | ... | |
185 | 201 |
return $form; |
186 | 202 |
} |
187 | 203 |
|
204 |
/** |
|
205 |
* A Form API element validate function to ensure that the rename string is |
|
206 |
* either empty or contains at least one token. |
|
207 |
*/ |
|
208 |
function _webform_edit_file_rename_validate($element, &$form_state, $form) { |
|
209 |
$rename = trim($form_state['values']['extra']['rename']); |
|
210 |
form_set_value($element, $rename, $form_state); |
|
211 |
if (strlen($rename) && !count(token_scan($rename))) { |
|
212 |
form_error($element, t('To create unique file names, use at least one token in the file name pattern.')); |
|
213 |
} |
|
214 |
} |
|
215 |
|
|
188 | 216 |
/** |
189 | 217 |
* A Form API element validate function to check filesize is valid. |
190 | 218 |
*/ |
... | ... | |
213 | 241 |
$directory = $element['extra']['directory']['#value']; |
214 | 242 |
|
215 | 243 |
$destination_dir = file_stream_wrapper_uri_normalize($scheme . '://webform/' . $directory); |
244 |
$tokenized_dir = drupal_strtolower(webform_replace_tokens($destination_dir, $element['#node'])); |
|
216 | 245 |
|
217 | 246 |
// Sanity check input to prevent use parent (../) directories. |
218 |
if (preg_match('/\.\.[\/\\\]/', $destination_dir . '/')) {
|
|
219 |
form_error($element['extra']['directory'], t('The save directory %directory is not valid.', array('%directory' => $directory)));
|
|
247 |
if (preg_match('/\.\.[\/\\\]/', $tokenized_dir . '/')) {
|
|
248 |
form_error($element['extra']['directory'], t('The save directory %directory is not valid.', array('%directory' => $tokenized_dir)));
|
|
220 | 249 |
} |
221 | 250 |
else { |
222 |
$destination_success = file_prepare_directory($destination_dir, FILE_CREATE_DIRECTORY); |
|
223 |
if (!$destination_success) { |
|
224 |
form_error($element['extra']['directory'], t('The save directory %directory could not be created. Check that the webform files directory is writable.', array('%directory' => $directory))); |
|
251 |
if (!file_prepare_directory($tokenized_dir, FILE_CREATE_DIRECTORY)) { |
|
252 |
form_error($element['extra']['directory'], t('The save directory %directory could not be created. Check that the webform files directory is writable.', array('%directory' => $tokenized_dir))); |
|
225 | 253 |
} |
226 | 254 |
} |
227 | 255 |
|
... | ... | |
241 | 269 |
foreach (array_keys($element['types'][$category]['#value']) as $extension) { |
242 | 270 |
if ($element['types'][$category][$extension]['#value']) { |
243 | 271 |
$extensions[] = $extension; |
272 |
// jpeg is an exception. It is allowed anytime jpg is allowed. |
|
273 |
if ($extension == 'jpg') { |
|
274 |
$extensions[] = 'jpeg'; |
|
275 |
} |
|
244 | 276 |
} |
245 | 277 |
} |
246 | 278 |
} |
... | ... | |
302 | 334 |
/** |
303 | 335 |
* Implements _webform_render_component(). |
304 | 336 |
*/ |
305 |
function _webform_render_file($component, $value = NULL, $filter = TRUE) { |
|
337 |
function _webform_render_file($component, $value = NULL, $filter = TRUE, $submission = NULL) {
|
|
306 | 338 |
$node = isset($component['nid']) ? node_load($component['nid']) : NULL; |
307 | 339 |
|
308 | 340 |
// Cap the upload size according to the PHP limit. |
... | ... | |
314 | 346 |
|
315 | 347 |
$element = array( |
316 | 348 |
'#type' => 'managed_file', |
317 |
'#title' => $filter ? _webform_filter_xss($component['name']) : $component['name'], |
|
349 |
'#theme' => 'webform_managed_file', |
|
350 |
'#title' => $filter ? webform_filter_xss($component['name']) : $component['name'], |
|
318 | 351 |
'#title_display' => $component['extra']['title_display'] ? $component['extra']['title_display'] : 'before', |
319 |
'#required' => $component['mandatory'],
|
|
352 |
'#required' => $component['required'],
|
|
320 | 353 |
'#default_value' => isset($value[0]) ? $value[0] : NULL, |
321 | 354 |
'#attributes' => $component['extra']['attributes'], |
322 | 355 |
'#upload_validators' => array( |
... | ... | |
324 | 357 |
'file_validate_extensions' => array(implode(' ', $component['extra']['filtering']['types'])), |
325 | 358 |
), |
326 | 359 |
'#pre_render' => array_merge(element_info_property('managed_file', '#pre_render'), array('webform_file_allow_access')), |
327 |
'#upload_location' => $component['extra']['scheme'] . '://webform/' . $component['extra']['directory'], |
|
360 |
'#upload_location' => $component['extra']['scheme'] . '://webform/' . ($filter |
|
361 |
? drupal_strtolower(webform_replace_tokens($component['extra']['directory'], $node)) |
|
362 |
: $component['extra']['directory']), |
|
328 | 363 |
'#progress_indicator' => $component['extra']['progress_indicator'], |
329 |
'#description' => $filter ? _webform_filter_descriptions($component['extra']['description'], $node) : $component['extra']['description'],
|
|
364 |
'#description' => $filter ? webform_filter_descriptions($component['extra']['description'], $node) : $component['extra']['description'], |
|
330 | 365 |
'#weight' => $component['weight'], |
331 | 366 |
'#theme_wrappers' => array('webform_element'), |
332 | 367 |
'#translatable' => array('title', 'description'), |
333 | 368 |
); |
334 | 369 |
|
370 |
if ($filter) { |
|
371 |
$element['#description'] = theme('file_upload_help', array('description' => $element['#description'], 'upload_validators' => $element['#upload_validators'])); |
|
372 |
} |
|
373 |
|
|
335 | 374 |
return $element; |
336 | 375 |
} |
337 | 376 |
|
377 |
/** |
|
378 |
* Returns HTML for a webform managed file element. |
|
379 |
* |
|
380 |
* See #2495821 and #2497909. The core theme_file_managed_file creates a |
|
381 |
* wrapper around the element with the element's id, thereby creating 2 elements |
|
382 |
* with the same id. |
|
383 |
* |
|
384 |
* @param $variables |
|
385 |
* An associative array containing: |
|
386 |
* - element: A render element representing the file. |
|
387 |
* |
|
388 |
*/ |
|
389 |
function theme_webform_managed_file($variables) { |
|
390 |
$element = $variables['element']; |
|
391 |
|
|
392 |
$attributes = array(); |
|
393 |
|
|
394 |
// For webform use, do not add the id to the wrapper. |
|
395 |
//if (isset($element['#id'])) { |
|
396 |
// $attributes['id'] = $element['#id']; |
|
397 |
//} |
|
398 |
|
|
399 |
if (!empty($element['#attributes']['class'])) { |
|
400 |
$attributes['class'] = (array) $element['#attributes']['class']; |
|
401 |
} |
|
402 |
$attributes['class'][] = 'form-managed-file'; |
|
403 |
|
|
404 |
// This wrapper is required to apply JS behaviors and CSS styling. |
|
405 |
$output = ''; |
|
406 |
$output .= '<div' . drupal_attributes($attributes) . '>'; |
|
407 |
$output .= drupal_render_children($element); |
|
408 |
$output .= '</div>'; |
|
409 |
return $output; |
|
410 |
} |
|
411 |
|
|
412 |
|
|
338 | 413 |
/** |
339 | 414 |
* Implements _webform_submit_component(). |
340 | 415 |
*/ |
341 | 416 |
function _webform_submit_file($component, $value) { |
342 |
if (is_array($value)) { |
|
343 |
return !empty($value['fid']) ? $value['fid'] : ''; |
|
344 |
} |
|
345 |
else { |
|
346 |
return !empty($value) ? $value : ''; |
|
417 |
$fid = is_array($value) |
|
418 |
? (!empty($value['fid']) ? $value['fid'] : '') |
|
419 |
: (!empty($value) ? $value : ''); |
|
420 |
// Extend access to this file, even if the submission has not been saved yet. This may happen when |
|
421 |
// previewing a private file which was selected but not explicitly uploaded, and then previewed. |
|
422 |
if ($fid) { |
|
423 |
$_SESSION['webform_files'][$fid] = $fid; |
|
347 | 424 |
} |
425 |
return $fid; |
|
348 | 426 |
} |
349 | 427 |
|
350 | 428 |
/** |
... | ... | |
369 | 447 |
/** |
370 | 448 |
* Implements _webform_display_component(). |
371 | 449 |
*/ |
372 |
function _webform_display_file($component, $value, $format = 'html') { |
|
450 |
function _webform_display_file($component, $value, $format = 'html', $submission = array()) {
|
|
373 | 451 |
$fid = isset($value[0]) ? $value[0] : NULL; |
374 | 452 |
return array( |
375 | 453 |
'#title' => $component['name'], |
454 |
'#title_display' => $component['extra']['title_display'] ? $component['extra']['title_display'] : 'before', |
|
376 | 455 |
'#value' => $fid ? webform_get_file($fid) : NULL, |
377 | 456 |
'#weight' => $component['weight'], |
378 | 457 |
'#theme' => 'webform_display_file', |
... | ... | |
417 | 496 |
/** |
418 | 497 |
* Implements _webform_analysis_component(). |
419 | 498 |
*/ |
420 |
function _webform_analysis_file($component, $sids = array()) { |
|
499 |
function _webform_analysis_file($component, $sids = array(), $single = FALSE, $join = NULL) {
|
|
421 | 500 |
$query = db_select('webform_submitted_data', 'wsd', array('fetch' => PDO::FETCH_ASSOC)) |
422 | 501 |
->fields('wsd', array('no', 'data')) |
423 |
->condition('nid', $component['nid']) |
|
424 |
->condition('cid', $component['cid']); |
|
502 |
->condition('wsd.nid', $component['nid'])
|
|
503 |
->condition('wsd.cid', $component['cid']);
|
|
425 | 504 |
|
426 | 505 |
if (count($sids)) { |
427 |
$query->condition('sid', $sids, 'IN'); |
|
506 |
$query->condition('wsd.sid', $sids, 'IN'); |
|
507 |
} |
|
508 |
|
|
509 |
if ($join) { |
|
510 |
$query->innerJoin($join, 'ws2_', 'wsd.sid = ws2_.sid'); |
|
428 | 511 |
} |
429 | 512 |
|
430 | 513 |
$nonblanks = 0; |
... | ... | |
443 | 526 |
|
444 | 527 |
$rows[0] = array(t('Left Blank'), ($submissions - $nonblanks)); |
445 | 528 |
$rows[1] = array(t('User uploaded file'), $nonblanks); |
446 |
$rows[2] = array(t('Average uploaded file size'), ($sizetotal != 0 ? (int) (($sizetotal/$nonblanks)/1024) . ' KB' : '0')); |
|
447 |
return $rows; |
|
529 |
$other[0] = array(t('Average uploaded file size'), ($sizetotal != 0 ? (int) (($sizetotal/$nonblanks)/1024) . ' KB' : '0')); |
|
530 |
return array( |
|
531 |
'table_rows' => $rows, |
|
532 |
'other_data' => $other, |
|
533 |
); |
|
448 | 534 |
} |
449 | 535 |
|
450 | 536 |
/** |
... | ... | |
467 | 553 |
$header = array(); |
468 | 554 |
// Two columns in header. |
469 | 555 |
$header[0] = array('', ''); |
470 |
$header[1] = array($component['name'], ''); |
|
556 |
$header[1] = array($export_options['header_keys'] ? $component['form_key'] : $component['name'], '');
|
|
471 | 557 |
$header[2] = array(t('Name'), t('Filesize (KB)')); |
472 | 558 |
return $header; |
473 | 559 |
} |
... | ... | |
530 | 616 |
} |
531 | 617 |
} |
532 | 618 |
|
619 |
/** |
|
620 |
* Rename any files which are eligible for renaming, if this submission is being |
|
621 |
* submitted for the first time. |
|
622 |
*/ |
|
623 |
function webform_file_rename($node, $submission) { |
|
624 |
if (isset($submission->file_usage)) { |
|
625 |
foreach ($submission->file_usage['renameable'] as $cid => $fids) { |
|
626 |
foreach ($fids as $fid) { |
|
627 |
webform_file_process_rename($node, $submission, $node->webform['components'][$cid], $fid); |
|
628 |
} |
|
629 |
} |
|
630 |
} |
|
631 |
} |
|
632 |
|
|
633 |
|
|
634 |
/** |
|
635 |
* Renames the uploaded file name using tokens. |
|
636 |
* |
|
637 |
* @param $node |
|
638 |
* The webform node object. |
|
639 |
* @param $submission |
|
640 |
* The webform submission object. |
|
641 |
* @param $component |
|
642 |
* Component settings array for which fid is going to be processed. |
|
643 |
* @param $fid |
|
644 |
* A file id to be processed. |
|
645 |
*/ |
|
646 |
function webform_file_process_rename($node, $submission, $component, $fid) { |
|
647 |
$file = webform_get_file($fid); |
|
648 |
|
|
649 |
if ($file) { |
|
650 |
// Get the destination uri. |
|
651 |
$destination_dir = $component['extra']['scheme'] . '://webform/' . drupal_strtolower(webform_replace_tokens($component['extra']['directory'], $node)); |
|
652 |
$destination_dir = file_stream_wrapper_uri_normalize($destination_dir); |
|
653 |
|
|
654 |
// Get the file extension. |
|
655 |
$info = pathinfo($file->uri); |
|
656 |
$extension = $info['extension']; |
|
657 |
|
|
658 |
// Prepare new file name without extension. |
|
659 |
$new_file_name = webform_replace_tokens($component['extra']['rename'], $node, $submission, NULL, TRUE); |
|
660 |
$new_file_name = trim($new_file_name); |
|
661 |
$new_file_name = _webform_transliterate($new_file_name); |
|
662 |
$new_file_name = str_replace('/', '_', $new_file_name); |
|
663 |
$new_file_name = preg_replace('/[^a-zA-Z0-9_\- ]/', '', $new_file_name); |
|
664 |
if (strlen($new_file_name)) { |
|
665 |
// Prepare the new uri with new filename. |
|
666 |
$destination = "$destination_dir/$new_file_name.$extension"; |
|
667 |
|
|
668 |
// Compare the uri and Rename the file name. |
|
669 |
if ($file->uri != $destination) { |
|
670 |
file_move($file, $destination, FILE_EXISTS_RENAME); |
|
671 |
} |
|
672 |
} |
|
673 |
} |
|
674 |
} |
drupal7/sites/all/modules/webform/components/grid.inc | ||
---|---|---|
15 | 15 |
return array( |
16 | 16 |
'name' => '', |
17 | 17 |
'form_key' => NULL, |
18 |
'mandatory' => 0,
|
|
18 |
'required' => 0,
|
|
19 | 19 |
'pid' => 0, |
20 | 20 |
'weight' => 0, |
21 |
'value' => '', |
|
21 | 22 |
'extra' => array( |
22 | 23 |
'options' => '', |
23 | 24 |
'questions' => '', |
24 | 25 |
'optrand' => 0, |
25 | 26 |
'qrand' => 0, |
27 |
'unique' => 0, |
|
26 | 28 |
'title_display' => 0, |
27 | 29 |
'custom_option_keys' => 0, |
28 | 30 |
'custom_question_keys' => 0, |
31 |
'sticky' => TRUE, |
|
29 | 32 |
'description' => '', |
30 | 33 |
'private' => FALSE, |
34 |
'analysis' => TRUE, |
|
31 | 35 |
), |
32 | 36 |
); |
33 | 37 |
} |
... | ... | |
67 | 71 |
$form['options']['options'] = array( |
68 | 72 |
'#type' => 'options', |
69 | 73 |
'#options' => _webform_select_options_from_text($component['extra']['options'], TRUE), |
70 |
'#optgroups' => FALSE, |
|
71 |
'#default_value' => FALSE, |
|
72 |
'#default_value_allowed' => FALSE, |
|
74 |
'#default_value' => $component['value'], |
|
75 |
'#default_value_allowed' => TRUE, |
|
73 | 76 |
'#optgroups' => FALSE, |
74 | 77 |
'#key_type' => 'mixed', |
75 | 78 |
'#key_type_toggle' => t('Customize option keys (Advanced)'), |
76 | 79 |
'#key_type_toggled' => $component['extra']['custom_option_keys'], |
80 |
'#default_value_pattern' => '^%.+\[.+\]$', |
|
77 | 81 |
); |
78 | 82 |
|
79 | 83 |
$form['questions'] = array( |
... | ... | |
90 | 94 |
'#optgroups' => FALSE, |
91 | 95 |
'#default_value' => FALSE, |
92 | 96 |
'#default_value_allowed' => FALSE, |
93 |
'#optgroups' => FALSE, |
|
94 | 97 |
'#key_type' => 'mixed', |
95 | 98 |
'#key_type_toggle' => t('Customize question keys (Advanced)'), |
96 | 99 |
'#key_type_toggled' => $component['extra']['custom_question_keys'], |
... | ... | |
101 | 104 |
'#type' => 'textarea', |
102 | 105 |
'#title' => t('Options'), |
103 | 106 |
'#default_value' => $component['extra']['options'], |
104 |
'#description' => t('Options to select across the top. One option per line. <strong>Key-value pairs MUST be specified as "safe_key|Some readable option"</strong>. Use of only alphanumeric characters and underscores is recommended in keys.') . theme('webform_token_help'), |
|
107 |
'#description' => t('Options to select across the top. One option per line. <strong>Key-value pairs MUST be specified as "safe_key|Some readable option"</strong>. Use of only alphanumeric characters and underscores is recommended in keys.') . ' ' . theme('webform_token_help'),
|
|
105 | 108 |
'#cols' => 60, |
106 | 109 |
'#rows' => 5, |
107 | 110 |
'#weight' => -3, |
... | ... | |
113 | 116 |
'#type' => 'textarea', |
114 | 117 |
'#title' => t('Questions'), |
115 | 118 |
'#default_value' => $component['extra']['questions'], |
116 |
'#description' => t('Questions list down the side of the grid. One question per line. <strong>Key-value pairs MUST be specified as "safe_key|Some readable option"</strong>. Use of only alphanumeric characters and underscores is recommended in keys.') . theme('webform_token_help'),
|
|
119 |
'#description' => t('Questions list down the side of the grid. One question per line. <strong>Key-value pairs MUST be specified as "safe_key|Some readable question"</strong>. For a heading column on the right, append "|" and the right-side heading. Use of only alphanumeric characters and underscores is recommended in keys.') . ' ' . theme('webform_token_help'),
|
|
117 | 120 |
'#cols' => 60, |
118 | 121 |
'#rows' => 5, |
119 | 122 |
'#weight' => -2, |
... | ... | |
121 | 124 |
'#wysiwyg' => FALSE, |
122 | 125 |
'#element_validate' => array('_webform_edit_validate_select'), |
123 | 126 |
); |
127 |
$form['value'] = array( |
|
128 |
'#type' => 'textfield', |
|
129 |
'#title' => t('Default value'), |
|
130 |
'#default_value' => $component['value'], |
|
131 |
'#description' => t('The default option of the grid identified by its key.') . ' ' . theme('webform_token_help'), |
|
132 |
'#size' => 60, |
|
133 |
'#maxlength' => 1024, |
|
134 |
'#weight' => 1, |
|
135 |
); |
|
124 | 136 |
} |
125 | 137 |
|
126 | 138 |
$form['display']['optrand'] = array( |
... | ... | |
137 | 149 |
'#description' => t('Randomize the order of the questions on the side when they are displayed in the form.'), |
138 | 150 |
'#parents' => array('extra', 'qrand') |
139 | 151 |
); |
152 |
$form['display']['sticky'] = array( |
|
153 |
'#type' => 'checkbox', |
|
154 |
'#title' => t('Sticky table header'), |
|
155 |
'#default_value' => $component['extra']['sticky'], |
|
156 |
'#description' => t('Use a sticky (non-scrolling) table header.'), |
|
157 |
'#parents' => array('extra', 'sticky') |
|
158 |
); |
|
159 |
|
|
160 |
$form['validation']['unique'] = array( |
|
161 |
'#type' => 'checkbox', |
|
162 |
'#title' => t('Unique'), |
|
163 |
'#return_value' => 1, |
|
164 |
'#description' => t('Check that all entered values for this field are unique. The same value is not allowed to be used twice.'), |
|
165 |
'#weight' => 1, |
|
166 |
'#default_value' => $component['extra']['unique'], |
|
167 |
'#parents' => array('extra', 'unique'), |
|
168 |
); |
|
169 |
|
|
140 | 170 |
return $form; |
141 | 171 |
} |
142 | 172 |
|
143 | 173 |
/** |
144 | 174 |
* Implements _webform_render_component(). |
145 | 175 |
*/ |
146 |
function _webform_render_grid($component, $value = NULL, $filter = TRUE) { |
|
176 |
function _webform_render_grid($component, $value = NULL, $filter = TRUE, $submission = NULL) {
|
|
147 | 177 |
$node = isset($component['nid']) ? node_load($component['nid']) : NULL; |
148 | 178 |
|
179 |
$questions = _webform_select_options_from_text($component['extra']['questions'], TRUE); |
|
180 |
$options = _webform_select_options_from_text($component['extra']['options'], TRUE); |
|
181 |
if ($filter) { |
|
182 |
$questions = _webform_select_replace_tokens($questions, $node); |
|
183 |
$options = _webform_select_replace_tokens($options, $node); |
|
184 |
} |
|
185 |
|
|
149 | 186 |
$element = array( |
150 | 187 |
'#type' => 'webform_grid', |
151 |
'#title' => $filter ? _webform_filter_xss($component['name']) : $component['name'],
|
|
188 |
'#title' => $filter ? webform_filter_xss($component['name']) : $component['name'], |
|
152 | 189 |
'#title_display' => $component['extra']['title_display'] ? $component['extra']['title_display'] : 'before', |
153 |
'#required' => $component['mandatory'],
|
|
190 |
'#required' => $component['required'],
|
|
154 | 191 |
'#weight' => $component['weight'], |
155 |
'#description' => $filter ? _webform_filter_descriptions($component['extra']['description'], $node) : $component['extra']['description'], |
|
156 |
'#grid_questions' => _webform_select_options_from_text($component['extra']['questions'], TRUE), |
|
157 |
'#grid_options' => _webform_select_options_from_text($component['extra']['options'], TRUE), |
|
192 |
'#description' => $filter ? webform_filter_descriptions($component['extra']['description'], $node) : $component['extra']['description'], |
|
193 |
'#grid_questions' => $questions, |
|
194 |
'#grid_options' => $options, |
|
195 |
'#default_value' => isset($value) || !strlen($component['value']) ? $value : array_fill_keys(array_keys($questions), $component['value']), |
|
196 |
'#grid_default' => $component['value'], |
|
158 | 197 |
'#optrand' => $component['extra']['optrand'], |
159 | 198 |
'#qrand' => $component['extra']['qrand'], |
199 |
'#sticky' => $component['extra']['sticky'], |
|
160 | 200 |
'#theme' => 'webform_grid', |
161 | 201 |
'#theme_wrappers' => array('webform_element'), |
162 | 202 |
'#process' => array('webform_expand_grid'), |
163 | 203 |
'#translatable' => array('title', 'description', 'grid_options', 'grid_questions'), |
164 | 204 |
); |
165 | 205 |
|
166 |
if ($value) { |
|
167 |
$element['#default_value'] = $value; |
|
206 |
// Enforce uniqueness. |
|
207 |
if ($component['extra']['unique']) { |
|
208 |
$element['#element_validate'][] = '_webform_edit_grid_unique_validate'; |
|
168 | 209 |
} |
169 | 210 |
|
170 | 211 |
return $element; |
... | ... | |
199 | 240 |
'#webform_validated' => FALSE, |
200 | 241 |
'#translatable' => array('title'), |
201 | 242 |
); |
243 |
|
|
244 |
// Add HTML5 required attribute, if needed. |
|
245 |
if ($element['#required']) { |
|
246 |
$element[$key]['#attributes']['required'] = 'required'; |
|
247 |
} |
|
202 | 248 |
} |
203 | 249 |
} |
204 | 250 |
|
... | ... | |
218 | 264 |
/** |
219 | 265 |
* Implements _webform_display_component(). |
220 | 266 |
*/ |
221 |
function _webform_display_grid($component, $value, $format = 'html') { |
|
267 |
function _webform_display_grid($component, $value, $format = 'html', $submission = array()) { |
|
268 |
$node = node_load($component['nid']); |
|
222 | 269 |
$questions = _webform_select_options_from_text($component['extra']['questions'], TRUE); |
270 |
$questions = _webform_select_replace_tokens($questions, $node); |
|
223 | 271 |
$options = _webform_select_options_from_text($component['extra']['options'], TRUE); |
272 |
$options = _webform_select_replace_tokens($options, $node); |
|
224 | 273 |
|
225 | 274 |
$element = array( |
226 | 275 |
'#title' => $component['name'], |
276 |
'#title_display' => $component['extra']['title_display'] ? $component['extra']['title_display'] : 'before', |
|
227 | 277 |
'#weight' => $component['weight'], |
228 | 278 |
'#format' => $format, |
229 | 279 |
'#grid_questions' => $questions, |
230 | 280 |
'#grid_options' => $options, |
281 |
'#sticky' => $component['extra']['sticky'], |
|
231 | 282 |
'#theme' => 'webform_display_grid', |
232 | 283 |
'#theme_wrappers' => $format == 'html' ? array('webform_element') : array('webform_element_text'), |
233 | 284 |
'#sorted' => TRUE, |
... | ... | |
257 | 308 |
$format = $element['#format']; |
258 | 309 |
|
259 | 310 |
if ($format == 'html') { |
311 |
$right_titles = _webform_grid_right_titles($element); |
|
260 | 312 |
$rows = array(); |
261 |
$header = array(array('data' => '', 'class' => array('webform-grid-question'))); |
|
313 |
$title = array('data' => '', 'class' => array('webform-grid-question')); |
|
314 |
$header = array($title); |
|
262 | 315 |
foreach ($element['#grid_options'] as $option) { |
263 |
$header[] = array('data' => _webform_filter_xss($option), 'class' => array('checkbox', 'webform-grid-option')); |
|
316 |
$header[] = array('data' => webform_filter_xss($option), 'class' => array('checkbox', 'webform-grid-option')); |
|
317 |
} |
|
318 |
if ($right_titles) { |
|
319 |
$header[] = $title; |
|
264 | 320 |
} |
265 | 321 |
foreach ($element['#grid_questions'] as $question_key => $question) { |
266 | 322 |
$row = array(); |
267 |
$row[] = array('data' => _webform_filter_xss($question), 'class' => array('webform-grid-question')); |
|
323 |
$questions = explode('|', $question, 2); |
|
324 |
$row[] = array('data' => webform_filter_xss($questions[0]), 'class' => array('webform-grid-question')); |
|
268 | 325 |
foreach ($element['#grid_options'] as $option_value => $option_label) { |
269 | 326 |
if (strcmp($element[$question_key]['#value'], $option_value) == 0) { |
270 | 327 |
$row[] = array('data' => '<strong>X</strong>', 'class' => array('checkbox', 'webform-grid-option')); |
... | ... | |
273 | 330 |
$row[] = array('data' => ' ', 'class' => array('checkbox', 'webform-grid-option')); |
274 | 331 |
} |
275 | 332 |
} |
333 |
if ($right_titles) { |
|
334 |
$row[] = array('data' => isset($questions[1]) ? webform_filter_xss($questions[1]) : '', 'class' => array('webform-grid-question')); |
|
335 |
} |
|
276 | 336 |
$rows[] = $row; |
277 | 337 |
} |
278 | 338 |
|
279 | 339 |
$option_count = count($header) - 1; |
280 |
$output = theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('class' => array('webform-grid', 'webform-grid-' . $option_count)))); |
|
340 |
$output = theme('table', array('header' => $header, 'rows' => $rows, 'sticky' => $element['#sticky'], 'attributes' => array('class' => array('webform-grid', 'webform-grid-' . $option_count))));
|
|
281 | 341 |
} |
282 | 342 |
else { |
283 | 343 |
$items = array(); |
284 | 344 |
foreach (element_children($element) as $key) { |
285 |
$items[] = ' - ' . $element[$key]['#title'] . ': ' . (isset($element['#grid_options'][$element[$key]['#value']]) ? $element['#grid_options'][$element[$key]['#value']] : ''); |
|
345 |
$items[] = ' - ' . _webform_grid_question_header($element[$key]['#title']) . ': ' . |
|
346 |
(isset($element['#grid_options'][$element[$key]['#value']]) ? $element['#grid_options'][$element[$key]['#value']] : ''); |
|
286 | 347 |
} |
287 | 348 |
$output = implode("\n", $items); |
288 | 349 |
} |
... | ... | |
293 | 354 |
/** |
294 | 355 |
* Implements _webform_analysis_component(). |
295 | 356 |
*/ |
296 |
function _webform_analysis_grid($component, $sids = array()) { |
|
357 |
function _webform_analysis_grid($component, $sids = array(), $single = FALSE, $join = NULL) {
|
|
297 | 358 |
// Generate the list of options and questions. |
298 |
$options = _webform_select_options_from_text($component['extra']['options'], TRUE);
|
|
359 |
$node = node_load($component['nid']);
|
|
299 | 360 |
$questions = _webform_select_options_from_text($component['extra']['questions'], TRUE); |
361 |
$questions = _webform_select_replace_tokens($questions, $node); |
|
362 |
$options = _webform_select_options_from_text($component['extra']['options'], TRUE); |
|
363 |
$options = _webform_select_replace_tokens($options, $node); |
|
300 | 364 |
|
301 | 365 |
// Generate a lookup table of results. |
302 | 366 |
$query = db_select('webform_submitted_data', 'wsd') |
303 | 367 |
->fields('wsd', array('no', 'data')) |
304 |
->condition('nid', $component['nid']) |
|
305 |
->condition('cid', $component['cid']) |
|
306 |
->condition('data', '', '<>') |
|
307 |
->groupBy('no') |
|
308 |
->groupBy('data'); |
|
309 |
$query->addExpression('COUNT(sid)', 'datacount'); |
|
368 |
->condition('wsd.nid', $component['nid'])
|
|
369 |
->condition('wsd.cid', $component['cid'])
|
|
370 |
->condition('wsd.data', '', '<>')
|
|
371 |
->groupBy('wsd.no')
|
|
372 |
->groupBy('wsd.data');
|
|
373 |
$query->addExpression('COUNT(wsd.sid)', 'datacount');
|
|
310 | 374 |
|
311 | 375 |
if (count($sids)) { |
312 |
$query->condition('sid', $sids, 'IN'); |
|
376 |
$query->condition('wsd.sid', $sids, 'IN'); |
|
377 |
} |
|
378 |
|
|
379 |
if ($join) { |
|
380 |
$query->innerJoin($join, 'ws2_', 'wsd.sid = ws2_.sid'); |
|
313 | 381 |
} |
314 | 382 |
|
315 | 383 |
$result = $query->execute(); |
... | ... | |
324 | 392 |
|
325 | 393 |
// Add options as a header row. |
326 | 394 |
foreach ($options as $option) { |
327 |
$header[] = _webform_filter_xss($option);
|
|
395 |
$header[] = webform_filter_xss($option); |
|
328 | 396 |
} |
329 | 397 |
|
330 | 398 |
// Add questions as each row. |
331 | 399 |
foreach ($questions as $qkey => $question) { |
332 |
$row = array(_webform_filter_xss($question));
|
|
400 |
$row = array(webform_filter_xss($question)); |
|
333 | 401 |
foreach ($options as $okey => $option) { |
334 | 402 |
$row[] = !empty($counts[$qkey][$okey]) ? $counts[$qkey][$okey] : 0; |
335 | 403 |
} |
336 | 404 |
$rows[] = $row; |
337 | 405 |
} |
338 |
$output = theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('class' => array('webform-grid')))); |
|
339 |
|
|
340 | 406 |
|
341 |
return array(array(array('data' => $output, 'colspan' => 2))); |
|
407 |
return array( |
|
408 |
'table_header' => $header, |
|
409 |
'table_rows' => $rows, |
|
410 |
); |
|
342 | 411 |
} |
343 | 412 |
|
344 | 413 |
/** |
345 | 414 |
* Implements _webform_table_component(). |
346 | 415 |
*/ |
347 | 416 |
function _webform_table_grid($component, $value) { |
417 |
$node = node_load($component['nid']); |
|
348 | 418 |
$questions = _webform_select_options_from_text($component['extra']['questions'], TRUE); |
419 |
$questions = _webform_select_replace_tokens($questions, $node); |
|
349 | 420 |
$options = _webform_select_options_from_text($component['extra']['options'], TRUE); |
421 |
$options = _webform_select_replace_tokens($options, $node); |
Formats disponibles : Unified diff
Update webform to 4.10