View source
<?php
module_load_include('inc', 'availability_calendar', 'availability_calendar');
function availability_calendar_field_widget_month_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
static $new_cid_count = 0;
$item = isset($items[$delta]) ? $items[$delta] : NULL;
$cid = !empty($item['cid']) ? $item['cid'] : 'new' . ++$new_cid_count;
$cvid = availability_calendar_get_cvid();
$name = !empty($item['name']) ? $item['name'] : '';
$settings = $instance['widget']['settings'] + $instance['settings'] + $field['settings'];
$form_state['build_info']['files'][] = array(
'type' => 'inc',
'module' => 'availability_calendar',
'name' => 'availability_calendar.widget',
);
$element = array_merge($element, array(
'#type' => 'fieldset',
'#element_validate' => array(
'availability_calendar_field_widget_month_form_validate',
),
'#attached' => availability_calendar_field_widget_month_attach_js_css($cvid),
));
$element['enabled'] = array(
'#type' => 'checkbox',
'#access' => $settings['allow_disable'],
'#title' => t('Enable the availability calendar'),
'#description' => t("Uncheck the checkbox if you don't want a calendar at all for this @entity", array(
'@entity' => $element['#entity_type'],
)),
'#default_value' => isset($item['enabled']) ? $item['enabled'] : 1,
'#attributes' => array(
'class' => array(
'availability-enable',
),
),
);
$element['calendar_details_div'] = array(
'#type' => 'markup',
'#markup' => '<div class="availability-details">',
);
$element['name'] = array(
'#type' => 'textfield',
'#access' => $settings['add_name'],
'#title' => t('Name'),
'#default_value' => isset($item['name']) ? $item['name'] : '',
);
$element['description'] = array(
'#type' => 'item',
'#title' => t('Availability'),
'#description' => t('<p>To update the calendar: select the new state and the date range to apply it to. Repeat if needed. When finished, click on <em>@button</em>. You can select a date range by clicking on either:</p>
<ul>
<li>The begin and end date of the period you want to change.</li>
<li>A week number to select that whole week at once.</li>
<li>The name of the month to select that whole month at once.</li>
<li>The name of a day of the week to select all those days of the week in that month.</li>
</ul>', array(
'@button' => t('Save'),
)),
);
$allowed_states = availability_calendar_get_states(array_filter($settings['allowed_states']), 'label');
$default_state = array_key_exists($settings['default_state'], $allowed_states) ? $settings['default_state'] : key($allowed_states);
$element['availability_states'] = array(
'#type' => 'radios',
'#title' => t('Select new state'),
'#default_value' => $default_state,
'#options' => $allowed_states,
'#attributes' => array(
'class' => array(
'availability-states',
),
),
);
$element['availability_calendar'] = array(
'#type' => 'markup',
'#theme' => $instance['widget']['type'],
'#markup' => '',
'#cid' => $cid,
'#cvid' => $cvid,
'#name' => $name,
'#settings' => $settings,
);
$element['calendar_details_enddiv'] = array(
'#type' => 'markup',
'#markup' => '</div>',
);
$element['availability_changes'] = array(
'#type' => 'hidden',
'#title' => t('Changes in availability'),
'#default_value' => '',
'#attributes' => array(
'class' => array(
'availability-changes',
),
),
);
$element['cid'] = array(
'#type' => 'hidden',
'#access' => FALSE,
'#default_value' => (int) $cid,
);
$element['cid_unique'] = array(
'#type' => 'hidden',
'#access' => FALSE,
'#default_value' => $cid,
);
return $element;
}
function availability_calendar_field_widget_month_attach_js_css($cvid) {
$result = array(
'js' => array(
drupal_get_path('module', 'availability_calendar') . '/availability_calendar.edit.js',
array(
'data' => array(
'availabilityCalendar' => array(
'editors' => array(
$cvid => array(
'cvid' => $cvid,
),
),
),
),
'type' => 'setting',
),
),
'css' => array(
drupal_get_path('module', 'availability_calendar') . '/availability_calendar.edit.css',
),
);
return $result;
}
function availability_calendar_field_widget_month_form_validate($element, &$form_state) {
$op = isset($form_state['clicked_button']) ? $form_state['clicked_button']['#id'] : '';
if (substr($op, 0, strlen('edit-submit')) === 'edit-submit' && $element['enabled']['#value'] == '1') {
$changes = array();
$is_valid = TRUE;
$lines = explode("\n", $element['availability_changes']['#value']);
array_pop($lines);
foreach ($lines as $line) {
if (!empty($line)) {
$change = availability_calendar_field_widget_month_form_validate_line($line, $element);
if ($change !== FALSE) {
$changes[] = $change;
}
else {
$is_valid = FALSE;
form_error($element, t('The requested calendar changes contain an invalid request.'));
break;
}
}
}
if ($is_valid) {
$form_state['availability_calendar_updates'][] = array(
$element['#field_name'],
$element['#language'],
$element['#delta'],
$element['cid_unique']['#value'],
$changes,
);
}
}
}
function availability_calendar_field_widget_month_form_validate_line($line, $element) {
$parts = explode(' ', trim($line));
if (count($parts) !== 6 || $parts[0] !== 'state:' || $parts[2] !== 'from:' || preg_match('/^[1-2][0-9]{3}-[0-1][0-9]-[0-3][0-9]$/', $parts[3]) !== 1 || $parts[4] !== 'to:' || preg_match('/^[1-2][0-9]{3}-[0-1][0-9]-[0-3][0-9]$/', $parts[5]) !== 1) {
return FALSE;
}
$state = $parts[1];
if (!array_key_exists($state, $element['availability_states']['#options'])) {
return FALSE;
}
$year = date('Y');
$month = date('m');
if (!checkdate(substr($parts[3], 5, 2), substr($parts[3], 8, 2), substr($parts[3], 0, 4)) || $parts[3] < date(AC_ISODATE, mktime(0, 0, 0, $month, 1, $year))) {
return FALSE;
}
$months = $element['availability_calendar']['#settings']['show_number_of_months'];
if (!checkdate(substr($parts[5], 5, 2), substr($parts[5], 8, 2), substr($parts[5], 0, 4)) || $parts[5] > date(AC_ISODATE, mktime(0, 0, 0, $month + $months + 1, 0, $year))) {
return FALSE;
}
$from = new DateTime($parts[3]);
$to = new DateTime($parts[5]);
if ($from > $to) {
return FALSE;
}
return array(
'state' => $state,
'from' => $from,
'to' => $to,
);
}
function availability_calendar_field_attach_submit_inc($entity_type, $entity, $form, &$form_state) {
if (!empty($form_state['availability_calendar_updates'])) {
foreach ($form_state['availability_calendar_updates'] as $update_info) {
list($field_name, $language_code, $delta, $cid_unique, $changes) = $update_info;
if (isset($entity->{$field_name}[$language_code][$delta]['cid_unique']) && $entity->{$field_name}[$language_code][$delta]['cid_unique'] === $cid_unique) {
$cid = availability_calendar_update_multiple_availability((int) $cid_unique, $changes);
if ($cid != $entity->{$field_name}[$language_code][$delta]['cid']) {
$entity->{$field_name}[$language_code][$delta]['cid'] = $cid;
}
}
}
}
}