class AvailabilityCalendarsNodeEditCalendarFormHandler in Availability Calendars 7.2
Hierarchy
Expanded class hierarchy of AvailabilityCalendarsNodeEditCalendarFormHandler
File
- ./
availability_calendars.node.inc, line 328
View source
class AvailabilityCalendarsNodeEditCalendarFormHandler {
private static $instance = NULL;
/** @var $node object */
protected $node;
/** @var $settings object */
protected $settings;
/** @var $states array */
protected $states;
/** @var $states array */
protected $commands;
/**
* @param object $node
* @return AvailabilityCalendarsNodeEditCalendarFormHandler
*/
public static function instance($node = NULL) {
if (self::$instance === NULL) {
self::$instance = new AvailabilityCalendarsNodeEditCalendarFormHandler($node);
}
return self::$instance;
}
protected function __construct($node) {
$this->node = $node;
$this->settings = availability_calendars_get_settings($this->node);
// Show the editor month count.
$this->settings->monthcount = $this->settings->editormonthcount;
// Do not show the key. We show our own key here with radio buttons and no special states.
$this->settings->showkey = false;
}
/**
* Builds the node/%node/availability-calendars page form.
*
* @param array $form
* @return array
* The modified form.
*/
public function build($form) {
// Add js or the edit functionality.
availability_calendars_add_js($this->node, NULL, 'edit');
// Add form fields.
$year = (int) date('Y');
$month = (int) date('m');
$form['availability_calendar'] = array(
'#type' => 'markup',
'#theme' => 'availability_calendars_node',
'#markup' => '',
'#prefix' => '<div class="description">' . t('To update the calendar: select a state (below the calendar) and click on a begin and end date. Repeat if needed. When finished, click on <em>@button</em>.', array(
'@button' => t('Update'),
)) . '</div>',
'#node' => $this->node,
'#year' => $year,
'#month' => $month,
'#settings' => $this->settings,
);
$options = array();
foreach ($this->settings->states as $class => $state) {
$options[$class] = t($state['label']);
}
$form['availability_states'] = array(
'#type' => 'radios',
'#title' => t('States'),
'#default_value' => $this->settings->defaultstatus,
'#options' => $options,
);
$form['availability_changes'] = array(
'#type' => 'hidden',
'#title' => t('Changes in availability'),
'#default_value' => '',
'#attributes' => array(
'id' => 'edit-availability-changes',
),
);
// Add form button.
$form['actions'] = array(
'#type' => 'actions',
);
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => t('Update'),
);
return $form;
}
/**
* Callback to validate the form for the styles form.
*/
public function validate($form, &$form_state) {
$op = isset($form_state['values']['op']) ? $form_state['values']['op'] : '';
if ($op == t('Update')) {
$this->commands = array();
$changes = $form_state['values']['availability_changes'];
// Silently ignore empty updates.
if (!empty($changes)) {
$changes = explode("\n", $changes);
foreach ($changes as $change) {
// Ignore empty lines (e.g. the last line).
if (!empty($change)) {
$command = $this
->validateCommand($change);
if ($command === FALSE) {
form_set_error('availability_changes', t('The requested calendar changes contain an invalid request.'));
break;
}
$this->commands[] = $command;
}
}
}
}
}
/**
* Validates a single command line.
*
* @param string $change
* Command line: state: <string> from: yyyy-mm-dd[(pm)] to: yyyy-mm-dd[(am)]
* @return boolean|array
* An array with key 'from', 'to' and 'state' representing the parsed and
* validated command line or FALSE on validation errors.
*/
public function validateCommand($change) {
// Basic syntax checking.
$parts = explode(' ', trim($change));
if (count($parts) !== 6 || $parts[0] !== 'state:' || !array_key_exists($parts[1], $this->settings->states) || $parts[2] !== 'from:' || preg_match('/^[1-2][0-9]{3}-[0-1][0-9]-[0-3][0-9](\\(pm\\))?$/', $parts[3]) !== 1 || $parts[4] !== 'to:' || preg_match('/^[1-2][0-9]{3}-[0-1][0-9]-[0-3][0-9](\\(am\\))?$/', $parts[5]) !== 1) {
return FALSE;
}
// Check dates: valid date, in between ranges of the calendar, no am/pm when no split days
// allowed, and from <= to (including the pm/am modifier: this prevents the "same day from
// pm to am" situation.
$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;
}
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 + $this->settings->monthcount + 1, 0, $year))) {
return FALSE;
}
if ($this->settings->splitday == '0' && (strlen($parts[3]) > 10 || strlen($parts[5]) > 10)) {
return FALSE;
}
if ($parts[3] > $parts[5]) {
return FALSE;
}
return array(
'from' => $parts[3],
'to' => $parts[5],
'state' => $parts[1],
);
}
/**
* Callback to process form submission for the styles form.
*/
public function submit($form, &$form_state) {
$op = isset($form_state['values']['op']) ? $form_state['values']['op'] : '';
if ($op == t('Update')) {
foreach ($this->commands as $command) {
availability_calendars_update_node_states_range($this->settings->calendar_id, $command['from'], $command['to'], $command['state']);
}
// Redirect to node view (as is also done on the node edit form).
$form_state['redirect'] = 'node/' . $this->node->nid;
// Clear the page and block caches (don't regress #747992).
entity_get_controller('node')
->resetCache(array(
$this->settings->calendar_id,
));
cache_clear_all();
drupal_set_message(t('Availability information saved.'));
}
}
}