Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- // $Id$
- /*
- * @file allocated_seating.module
- * Provides form elements to enable other modules to define allocated seating
- * and collect user input
- * @copyright Copyright(c) 2010 Lee Rowlands
- * @license GPL v2 http://www.fsf.org/licensing/licenses/gpl.html
- * @author Lee Rowlands leerowlands at rowlands-bcs dot com
- *
- */
- /**
- * Implementation of hook_menu().
- */
- function allocated_seating_menu() {
- //generic Call handler, append args to return specific form elements
- $items['allocated_seating/ajax'] = array(
- 'title' => 'Generic Call handler',
- 'delivery callback' => 'drupal_json_output',
- 'page callback' => 'allocated_seating_ajax',
- 'access arguments' => array('create seating plans'),
- 'type' => MENU_CALLBACK
- );
- return $items;
- }
- /**
- * Implements hook_permission
- */
- function allocated_seating_permission() {
- return array(
- 'create seating plans' => array(
- 'title' => t('Create seating plans'),
- )
- );
- }
- /**
- * Implementation of hook_elements_info().
- */
- function allocated_seating_element_info() {
- $type['allocated_seating_seat_design'] = array(
- '#input' => TRUE,
- '#tree' => TRUE,
- '#default_value' => array(
- 'seats' => 40,
- 'row_count' => 2,
- 'floor_count' => 1,
- 'floors' => array(),
- ),
- '#process' => array('allocated_seating_seat_design_process'),
- '#theme' => array('allocated_seating_seat_design'),
- );
- $type['allocated_seating_seat_select'] = array(
- '#input' => TRUE,
- '#tree' => TRUE,
- '#process' => array('allocated_seating_seat_select_process'),
- '#element_validate' => array('allocated_seating_seat_select_validate'),
- '#required_seats' => NULL,
- );
- return $type;
- }
- /**
- * Implementation of hook_theme().
- */
- function allocated_seating_theme($existing, $type, $theme, $path) {
- return array(
- 'allocated_seating_seat_design' => array(
- 'arguments' => array('element' => NULL),
- ),
- 'allocated_seating_seat_select' => array(
- 'arguments' => array('element' => NULL),
- ),
- 'allocated_seating_seat_available' => array(
- 'arguments' => array('plan' => array(),
- 'not_available' => array()
- ),
- ),
- );
- }
- /**
- * Provides processing to expand the form element
- */
- function allocated_seating_seat_select_process($element, $form_state, $complete_form) {
- if (empty($element['#plan'])) {
- //no floor plan!
- return;
- }
- $plan = $element['#plan'];
- if (!$element['#not_available']) {
- $element['#not_available'] = array();
- }
- $blank = 1;
- $parents = $element['#parents'];
- $element['floors'] = array(
- '#tree' => FALSE, //we structure the data in a nest for theming but only want seat# => 1/0
- '#parents' => array_merge($parents, array('floors'))
- );
- foreach ($plan['floors'] as $f => $floor) {
- $element['floors'][$f] = array(
- '#tree' => FALSE,
- '#col_count' => $floor['col_count'],
- 'title' => array(
- '#value' => $floor['title']
- ),
- 'rows' => array(
- '#tree' => FALSE,
- )
- );
- foreach ($floor['rows'] as $r => $row) {
- $element['floors'][$f]['rows'][$r] = array(
- '#tree' => FALSE,
- 'columns' => array(
- '#tree' => FALSE,
- '#parents' => array_merge($parents, array('floors', $f, 'rows', $r, 'columns')),
- )
- );
- foreach ($row['columns'] as $c => $column) {
- if ($column['seat'] &&
- is_numeric($column['seat']) &&
- !in_array($column['seat'], $element['#not_available'])) {
- //add the seat checkbox
- $element['floors'][$f]['rows'][$r]['columns'][$column['seat']] = array(
- '#attributes' => array('class' => 'allocated-seating-seat'),
- '#type' => 'checkbox',
- '#parents' => array('seats', $column['seat']),
- '#title' => $column['seat']
- );
- }
- else {
- //add the blank
- $element['floors'][$f]['rows'][$r]['columns']['b_'. $blank] = array(
- '#value' => ' '
- );
- $blank++;
- }
- }
- }
- }
- return $element;
- }
- /**
- * Provides processing to expand the form element
- */
- function allocated_seating_seat_design_process($element, $form_state, $complete_form) {
- static $plan,$post_static;
- // Cache the submitted $_POST data.
- if (!empty($element['#post']) || $post_static === NULL) {
- if (count($element['#array_parents']) == 1) {
- $post = &$element['#post'][$element['#array_parents'][0]];
- $post_static = $element['#post'][$element['#array_parents'][0]];
- }
- elseif (count($element['#array_parents']) == 2) {
- $post = &$element['#post'][$element['#array_parents'][0]][$element['#array_parents'][1]];
- $post_static = $element['#post'][$element['#array_parents'][0]][$element['#array_parents'][1]];
- }
- elseif (count($element['#array_parents']) == 3) {
- $post = &$element['#post'][$element['#array_parents'][0]][$element['#array_parents'][1]][$element['#array_parents'][2]];
- $post_static = $element['#post'][$element['#array_parents'][0]][$element['#array_parents'][1]][$element['#array_parents'][2]];
- }
- else {
- $post = array();
- $post_static = array();
- }
- }
- $all_defaults = array();
- $all_defaults['allocated_seating_seat_design'] = element_info('allocated_seating_seat_design');
- $defaults = $all_defaults['allocated_seating_seat_design']['#default_value'];
- // Ensure there are correct defaults.
- foreach ($all_defaults['allocated_seating_seat_design']['#default_value'] as $var => $default) {
- if (empty($element['#value'][$var])) {
- $element['#value'][$var] = $default;
- }
- }
- if (empty($element['#seats'])) {
- //must know the # of seats!
- return array(
- '#value' => t('Did not receive number of seats for the design, cannot proceed. Please set the #seats element attribute.')
- );
- }
- if (empty($plan)) {
- if (empty($element['#value']['floors'])) {
- $default = array(
- 'floors' => array(
- array(
- 'title' => t('Floor 1'),
- 'rows' => array()
- )
- )
- );//the default
- $cols = ceil($element['#seats'] / 4); //default 4 rows
- $row = 0;
- $s = 1;
- while ($row < 4) {
- $col = 0;
- $default['floors'][0]['rows'][$row] = array('columns' => array()); //add the rows
- while ($col < $cols) {
- if ($s <= $element['#seats']) {
- $seat = $s;
- $s++;
- }
- else {
- $seat = FALSE;
- }
- $default['floors'][0]['rows'][$row]['columns'][] = array('seat' => $seat); //add the seat
- $col++;
- }
- $row++;
- }
- $element['#value'] = $default;
- }
- else {
- // Check if a new floor needs to be added.
- if (!empty($form_state['post']['_triggering_element_name']) && $form_state['post']['_triggering_element_value'] == t('Add floor')) {
- $element['#value'] = $_POST['ticket_plan'];
- allocated_seating_plan_add_floor($element, $post);
- }
- //make sure our seats matches the number in the plan
- $real_seats = allocated_seating_real_seats($element['#value']);
- $needed_seats = $element['#seats'];
- //do we have enough?
- $total_seats = allocated_seating_plan_seats($element['#value']);
- while ($total_seats < $needed_seats) {
- allocated_seating_plan_floor_add_row($element['#value'], 0);
- $total_seats = allocated_seating_plan_seats($element['#value']);
- }
- if ($needed_seats != $real_seats) {
- //we have an issue here
- $seat_map = allocated_seating_get_map($element['#value']);
- $blanks = $seat_map['blanks'];
- if ($needed_seats < $real_seats) {
- //we need to remove some seats
- while ($needed_seats < $real_seats) {
- $remove = $seat_map['seats'][$real_seats];
- if ($remove) {
- $element['#value']['floors'][$remove['floor']]['rows'][$remove['row']]['columns'][$remove['column']]['seat'] = FALSE;
- }
- $real_seats--;
- }
- }
- else {
- //we need to add some
- while ($needed_seats > $real_seats) {
- $real_seats++;
- $blank = array_shift($blanks);
- $element['#value']['floors'][$blank['floor']]['rows'][$blank['row']]['columns'][$blank['column']]['seat'] = $real_seats;
- }
- }
- }
- }
- $plan = $element['#value'];
- }
- $parents = $element['#parents'];
- $element['floors'] = array(
- '#prefix' => '<div id="as-wrap-'. $element['#id'] .'">',
- '#suffix' => '</div>'
- );
- if ($form_state['storage']['type']) {
- $total_seats = allocated_seating_total_seats($plan);
- if ($total_seats < $element['#seats']) {
- form_set_error(implode('][', $element['#parents']), t('The entered row and column combination is not sufficient to meet the required number of seats, please try again'));
- }
- switch ($form_state['storage']['type']) {
- case 'row':
- $floor = $form_state['storage']['floor'];
- $current_rows = $original_rows = count($plan['floors'][$floor]['rows']);
- $row_count = $plan['floors'][$floor]['row_count'];
- while ($current_rows < $row_count) {
- allocated_seating_plan_floor_add_row($plan, $floor);
- $current_rows++;
- }
- while ($current_rows > $row_count) {
- allocated_seating_plan_remove_row($plan, $floor);
- $current_rows--;
- }
- break;
- case 'column':
- $floor = $form_state['storage']['floor'];
- $current_cols = $original_cols = count($plan['floors'][$floor]['rows'][0]['columns']);
- $col_count = $plan['floors'][$floor]['col_count'];
- if ($col_count > 23) {
- form_set_error('', t('The seating designer does not support more than 23 columns.'));
- $col_count = 23;
- }
- while ($current_cols < $col_count) {
- allocated_seating_plan_floor_add_column($plan, $floor);
- $current_cols++;
- }
- while ($current_cols > $col_count) {
- allocated_seating_plan_remove_column($plan, $floor);
- $current_cols--;
- }
- break;
- }
- unset($form_state['storage']['type'], $form_state['storage']['floor']);
- }
- foreach ($plan['floors'] as $f => $floor) {
- $element['floors'][$f] = array(
- '#tree' => TRUE,
- '#parents' => array_merge($parents, array('floors', $f)),
- 'title' => array(
- '#type' => 'textfield',
- '#title' => t('Floor title'),
- '#parents' => array_merge($parents, array('floors', $f, 'title')),
- '#default_value' => t('Floor !floor', array('!floor' => $f + 1)),
- '#size' => 10,
- '#maxlength' => 50,
- '#required' => TRUE,
- ),
- 'row_count' => array(
- '#type' => 'textfield',
- '#title' => t('Rows'),
- '#parents' => array_merge($parents, array('floors', $f, 'row_count')),
- '#default_value' => count($floor['rows']),
- '#size' => 10,
- '#maxlength' => 10,
- '#required' => TRUE,
- '#ajax' => array(
- 'path' => 'allocated_seating/ajax/row/'. $f + 1 .'/'. $element['#ajax_extra'] . implode('/', $parents),
- 'wrapper' => 'as-wrap-'. $element['#id'],
- 'event' => 'change',
- 'method' => 'replace',
- 'effect' => 'fade',
- ),
- ),
- 'col_count' => array(
- '#type' => 'textfield',
- '#title' => t('Columns'),
- '#parents' => array_merge($parents, array('floors', $f, 'col_count')),
- '#default_value' => count($floor['rows'][0]['columns']),
- '#size' => 10,
- '#maxlength' => 10,
- '#required' => TRUE,
- '#ajax' => array(
- 'event' => 'change',
- 'path' => 'allocated_seating/ajax/column/'. $f + 1 .'/'. $element['#ajax_extra'] . implode('/', $parents),
- 'wrapper' => 'as-wrap-'. $element['#id'],
- 'method' => 'replace',
- 'effect' => 'fade',
- ),
- ),
- 'remove_floor' => array(
- '#type' => 'submit',
- '#value' => t('Remove floor '). ($f + 1),
- '#submit' => array('allocated_seating_design_remove_floor'),
- '#ajax' => array(
- 'path' => 'allocated_seating/ajax/floor/'. $element['#ajax_extra'] . implode('/', $parents),
- 'wrapper' => 'as-wrap-'. $element['#id'],
- 'method' => 'replace',
- 'effect' => 'fade',
- )
- ),
- 'rows' => array(
- '#tree' => TRUE,
- '#parents' => array_merge($parents, array('floors', $f, 'rows')),
- )
- );
- foreach ($floor['rows'] as $r => $row) {
- $element['floors'][$f]['rows'][$r] = array(
- '#tree' => TRUE,
- '#parents' => array_merge($parents, array('floors', $f, 'rows', $r)),
- 'columns' => array(
- '#tree' => TRUE,
- '#parents' => array_merge($parents, array('floors', $f, 'rows', $r, 'columns')),
- )
- );
- foreach ($row['columns'] as $c => $column) {
- //add the seat string and value
- $element['floors'][$f]['rows'][$r]['columns'][$c]['drag'] = array(
- '#parents' => array_merge($parents, array('floors', $f, 'rows', $r, 'columns', $c, 'drag')),
- '#attributes' => array('class' => 'allocated-seating-seat'),
- '#type' => '#markup',
- '#value' => $column['seat'] ? $column['seat'] : ' '
- );
- $element['floors'][$f]['rows'][$r]['columns'][$c]['seat'] = array(
- '#parents' => array_merge($parents, array('floors', $f, 'rows', $r, 'columns', $c, 'seat')),
- '#type' => 'hidden',
- '#value' => $column['seat']
- );
- }
- }
- }
- $element['add_floor_row_count'] = array(
- '#type' => 'textfield',
- '#title' => t('Rows'),
- '#default_value' => isset($form_state['post']['add_floor_row_count']) ? $form_state['post']['add_floor_row_count'] : 4,
- '#size' => 10,
- '#maxlength' => 10
- );
- $element['add_floor_col_count'] = array(
- '#type' => 'textfield',
- '#title' => t('Cols'),
- '#default_value' => isset($form_state['post']['add_floor_col_count']) ? $form_state['post']['add_floor_col_count'] : 10,
- '#size' => 10,
- '#maxlength' => 10
- );
- $element['add_floor_ticket_count'] = array(
- '#type' => 'textfield',
- '#title' => t('Tickets'),
- '#default_value' => 0,
- '#size' => 10,
- '#maxlength' => 10,
- '#description' => t('Start with this many tickets on the floor')
- );
- $element['add_floor'] = array(
- '#type' => 'submit',
- '#value' => t('Add floor'),
- '#submit' => array('allocated_seating_design_add_floor'),
- '#executes_submit_callback' => true,
- '#ajax' => array(
- 'path' => 'allocated_seating/ajax/floor/'. $element['#ajax_extra'] . implode('/', $parents),
- 'callback' => 'allocated_seating_design_add_floor',
- 'wrapper' => 'as-wrap-'. $element['#id'],
- 'method' => 'replace',
- 'effect' => 'fade',
- )
- );
- return $element;
- }
- /**
- * Removes a floor from the design
- */
- function allocated_seating_design_remove_floor($form, &$form_state) {
- $button = $form_state['clicked_button'];
- $field_parents = $button['#parents'];
- $floor = $field_parents[count($field_parents) - 2];
- $depth = count($field_parents) - 4;
- $field_name = $field_parents[$depth];
- if ($depth > 0) {
- //we have a tree arrangement here
- switch ($depth) {
- case 1:
- allocated_seating_plan_remove_floor($form_state['values'][$field_parents[0]][$field_name], $floor);
- break;
- case 2:
- allocated_seating_plan_remove_floor($form_state['values'][$field_parents[0]][$field_parents[1]][$field_name], $floor);
- break;
- case 3:
- allocated_seating_plan_remove_floor($form_state['values'][$field_parents[0]][$field_parents[1]][$field_parents[2]][$field_name], $floor);
- break;
- //that ought to be enough
- }
- }
- else {
- allocated_seating_plan_remove_floor($form_state['values'][$field_name], $floor);
- }
- unset($form_state['submit_handlers']);
- form_execute_handlers('submit', $form, $form_state);
- $form_state['rebuild'] = TRUE;
- }
- /**
- * Adds a floor to a design
- */
- function allocated_seating_design_add_floor($form, &$form_state) {
- $button = $form_state['clicked_button'];
- $parents = $button['#array_parents'];
- $button_name = array_pop($parents);
- $field_name = array_pop($parents);
- $field_parents = $button['#parents'];
- $new_rows = $form_state['values']['add_floor_row_count'];
- $new_cols = $form_state['values']['add_floor_col_count'];
- $new_tickets = $form_state['values']['add_floor_ticket_count'];
- if (count($field_parents) > 1) {
- //we have a tree arrangement here
- switch (count($field_parents)) {
- case 2:
- //allocated_seating_plan_add_floor($form_state['values'][$field_parents[0]][$field_name], $new_rows, $new_cols, $new_tickets);
- break;
- case 3:
- // allocated_seating_plan_add_floor($form_state['values'][$field_parents[0]][$field_parents[1]][$field_name], $new_rows, $new_cols, $new_tickets);
- break;
- case 4:
- // allocated_seating_plan_add_floor($form_state['values'][$field_parents[0]][$field_parents[1]][$field_parents[2]][$field_name], $new_rows, $new_cols, $new_tickets);
- break;
- //that ought to be enough
- }
- }
- else {
- //allocated_seating_plan_add_floor($form_state['values'][$field_name], $new_rows, $new_cols, $new_tickets);
- }
- unset($form_state['submit_handlers']);
- form_execute_handlers('submit', $form, $form_state);
- $form_state['rebuild'] = TRUE;
- }
- /**
- * Default implementation of theme_allocated_seating_seat_select
- */
- function theme_allocated_seating_seat_select($element) {
- jquery_ui_add(array('ui.sortable', 'ui.droppable', 'ui.tabs'));
- drupal_add_js(drupal_get_path('module', 'allocated_seating') .'/allocated_seating.js');
- drupal_add_css(drupal_get_path('module', 'allocated_seating') .'/allocated_seating.css');
- drupal_add_css(drupal_get_path('module', 'jquery_ui') . '/jquery.ui/themes/default/ui.all.css');
- $output = '<div id="allocated-seating-tabs" class="allocated-seating-seat-select"><ul>';
- $tabs = '';
- foreach (element_children($element['floors']) as $key) {
- $title = $element['floors'][$key]['title']['#value'];
- $output .= '<li><a href="#allocated-seating-tabs-'. $key .'">'. check_plain($title) .'</a></li>';
- $tabs .= '<div id="allocated-seating-tabs-'. $key .'">'.
- $element['floors'][$key]['title']['#value']
- . '<div class="floor-front cols-'. $element['floors'][$key]['#col_count'] .'">'. t('Front') .'</div>'
- .'<ul class="allocated-seating-seats no-drag cols-'. $element['floors'][$key]['#col_count'] .'">';
- foreach (element_children($element['floors'][$key]['rows']) as $row) {
- foreach (element_children($element['floors'][$key]['rows'][$row]['columns']) as $column) {
- $tabs .= '<li class="ui-state-highlight';
- if ($element['floors'][$key]['rows'][$row]['columns'][$column]['#type'] == 'checkbox') {
- $tabs .= '">'. theme('checkbox', $element['floors'][$key]['rows'][$row]['columns'][$column]);
- }
- else {
- $tabs .= ' not-available"> ';
- }
- $tabs .= '</li>';
- }
- }
- $tabs .= '</ul>'. $values .'<div class="clear"></div></div>';
- }
- $output .= '</ul>';
- $output .= $tabs;
- $output .= '</div>';
- return $output;
- }
- /**
- * Default implementation of theme_allocated_seating_seat_available
- */
- function theme_allocated_seating_seat_available($plan, $not_available) {
- $blank = 1;
- $element['floors'] = array(
- '#tree' => FALSE, //we structure the data in a nest for theming but only want seat# => 1/0
- '#parents' => array('floors')
- );
- foreach ($plan['floors'] as $f => $floor) {
- $element['floors'][$f] = array(
- '#tree' => FALSE,
- '#col_count' => $floor['col_count'],
- 'title' => array(
- '#value' => $floor['title']
- ),
- 'rows' => array(
- '#tree' => FALSE,
- )
- );
- foreach ($floor['rows'] as $r => $row) {
- $element['floors'][$f]['rows'][$r] = array(
- '#tree' => FALSE,
- 'columns' => array(
- '#tree' => FALSE,
- '#parents' => array('floors', $f, 'rows', $r, 'columns'),
- )
- );
- foreach ($row['columns'] as $c => $column) {
- $state = 'available';
- if ($column['seat'] &&
- is_numeric($column['seat']) &&
- in_array($column['seat'], $not_available)) {
- $state = 'unavailable';
- }
- //add the seat field
- $element['floors'][$f]['rows'][$r]['columns'][$column['seat']] = array(
- '#value' => '<div class="allocated-seating-seat '. $state .'">'. $column['seat'] .'</div>',
- '#parents' => array('seats', $column['seat']),
- );
- }
- }
- }
- drupal_add_library('system', 'ui.sortable');
- drupal_add_library('system', 'ui.tabs');
- drupal_add_library('system', 'ui.droppable');
- //jquery_ui_add(array('ui.sortable', 'ui.droppable', 'ui.tabs'));
- drupal_add_js(drupal_get_path('module', 'allocated_seating') .'/allocated_seating.js');
- drupal_add_css(drupal_get_path('module', 'allocated_seating') .'/allocated_seating.css');
- drupal_add_css(drupal_get_path('module', 'jquery_ui') . '/jquery.ui/themes/default/ui.all.css');
- $output = '<div id="allocated-seating-tabs" class="allocated-seating-seat-select"><ul>';
- $tabs = '';
- foreach (element_children($element['floors']) as $key) {
- $title = $element['floors'][$key]['title']['#value'];
- $output .= '<li><a href="#allocated-seating-tabs-'. $key .'">'. check_plain($title) .'</a></li>';
- $tabs .= '<div id="allocated-seating-tabs-'. $key .'">'.
- $element['floors'][$key]['title']['#value']
- . '<div class="floor-front cols-'. $element['floors'][$key]['#col_count'] .'">'. t('Front') .'</div>'
- .'<ul class="allocated-seating-seats no-drag cols-'. $element['floors'][$key]['#col_count'] .'">';
- foreach (element_children($element['floors'][$key]['rows']) as $row) {
- foreach (element_children($element['floors'][$key]['rows'][$row]['columns']) as $column) {
- $tabs .= '<li class="ui-state-highlight">'.
- drupal_render($element['floors'][$key]['rows'][$row]['columns'][$column])
- .'</li>';
- }
- }
- $tabs .= '</ul>'. $values .'<div class="clear"></div></div>';
- }
- $output .= '</ul>';
- $output .= $tabs;
- $output .= '</div>';
- return $output;
- }
- /**
- * Default implementation of theme_allocated_seating_seat_design
- */
- function theme_allocated_seating_seat_design($variable) {
- drupal_add_library('system', 'ui.sortable');
- drupal_add_library('system', 'ui.tabs');
- drupal_add_library('system', 'ui.droppable');
- $element = array_shift($variable);
- //jquery_ui_add(array('ui.sortable', 'ui.tabs', 'ui.droppable'));
- drupal_add_js(drupal_get_path('module', 'allocated_seating') .'/allocated_seating.js');
- drupal_add_css(drupal_get_path('module', 'allocated_seating') .'/allocated_seating.css');
- drupal_add_css(drupal_get_path('module', 'jquery_ui') . '/jquery.ui/themes/default/ui.all.css');
- $output = '<div id="as-wrap-'. $element['#id'] .'" class="as-wrap"><div id="allocated-seating-tabs" class="allocated-seating-seat-design"><ul>';
- $tabs = '';
- foreach (element_children($element['floors']) as $key) {
- $inputs = '';
- $title = $element['floors'][$key]['title']['#value'];
- $output .= '<li><a href="#allocated-seating-tabs-'. $key .'">'. check_plain($title) .'</a></li>';
- $tabs .= '<div id="allocated-seating-tabs-'. $key .'" class="floor-details">'.
- '<div class="floor-item">'.
- theme('form_element_label', $element['floors'][$key]['title']).
- theme('textfield', $element['floors'][$key]['title']) .
- '</div><div class="floor-item">'.
- theme('form_element_label', $element['floors'][$key]['row_count']).
- theme('textfield', $element['floors'][$key]['row_count']) .
- '</div><div class="floor-item">'.
- theme('form_element_label', $element['floors'][$key]['col_count']).
- theme('textfield', $element['floors'][$key]['col_count']).
- '</div>'
- . '<div class="floor-front cols-'. $element['floors'][$key]['col_count']['#value'] .'">'. t('Front') .'</div>'
- .'<ul class="allocated-seating-seats connectedSortable ui-helper-reset cols-'. $element['floors'][$key]['col_count']['#value'] .'">';
- foreach (element_children($element['floors'][$key]['rows']) as $row) {
- foreach (element_children($element['floors'][$key]['rows'][$row]['columns']) as $column) {
- $tabs .= '<li class="ui-state-highlight" rel="'. $element['floors'][$key]['rows'][$row]['columns'][$column]['seat']['#value'] .'">'.
- $element['floors'][$key]['rows'][$row]['columns'][$column]['drag']['#value']
- .'</li>';
- $inputs .= theme('hidden', $element['floors'][$key]['rows'][$row]['columns'][$column]['seat']);
- }
- }
- $tabs .= $inputs .'</ul>'. $values .'<div class="clear"></div>'.
- drupal_render($element['floors'][$key]['remove_floor'])
- .'</div>';
- }
- $output .= '</ul>';
- $output .= $tabs;
- $output .= '</div><div class="allocated-seating-design-add-floor"><fieldset><legend>'. t('Add a floor') .'</legend>'.
- t('Add a new floor with this many rows/columns').
- drupal_render($element['add_floor_row_count']).
- drupal_render($element['add_floor_col_count']).
- drupal_render($element['add_floor_ticket_count']).
- drupal_render($element['add_floor'])
- .'</fieldset></div>';
- if (!empty($element['#description'])) {
- $output .= ' <div class="description as-description">'. $element['#description'] ."</div>\n";
- }
- $output .= '</div><div class="clear"></div>';
- return $output;
- }
- /**
- * Validation handler for seat selection
- */
- function allocated_seating_seat_select_validate($element, &$form_state) {
- $seats = array_sum($form_state['values']['seats']);
- if ($element['#required_seats'] &&
- $element['#required_seats'] != $seats) {
- form_error($element, format_plural($element['#required_seats'],
- 'Please choose 1 seat',
- 'Please choose @count seats'));
- }
- }
- /**
- * Call callback handler.
- *
- */
- function allocated_seating_ajax() {
- module_load_include('inc', 'node', 'node.pages');
- //get args
- $elements = func_get_args();
- $type = array_shift($elements);
- if ($type == 'row' || $type == 'column') {
- $floor = array_shift($elements);
- }
- //we set submitted as TRUE so prevent _form_builder_ie_cleanup() from triggering
- //submit on ajax that does not involve a button
- $form_state = array('storage' => NULL, 'submitted' => TRUE);
- $form_build_id = $_POST['form_build_id'];
- $form = form_get_cache($form_build_id, $form_state);
- if (isset($_POST['_triggering_element_name'])) {
- if($_POST['_triggering_element_name'] == 'op' && $_POST['_triggering_element_value'] == 'Add floor') {
- $form_state['submit_handlers'] = array('allocated_seating_design_add_floor');
- }
- }
- unset($form_state['storage']['type']); //don't redo the cached action
- //remove validation (thanks ajax_helper!)
- if (!isset($_POST['op'])) {
- // For the defaults
- $form['#validate'] = NULL;
- $form['#submit'] = NULL;
- // For customly set #validate and #submit handlers.
- $form_state['submit_handlers'] = array();
- $form_state['validate_handlers'] = array();
- }
- $form_id = $form['#form_id'];
- $form['#post'] = $_POST;
- $form['#redirect'] = FALSE;
- $form['#programmed'] = FALSE;
- $form_state['post'] = $_POST;
- drupal_process_form($form_id, $form, $form_state);
- $form_state['storage']['type'] = $type;
- $form_state['storage']['floor'] = $floor;
- if ($type == 'floor') {
- $form_state['storage']['add_floor_row_count'] = $form_state['values']['add_floor_row_count'];
- $form_state['storage']['add_floor_col_count'] = $form_state['values']['add_floor_col_count'];
- }
- $form = drupal_rebuild_form($form_id, $form_state, $form );
- foreach ($elements as $element) {
- $form = $form[$element];
- }
- if (!$form) {
- watchdog('allocated seating', 'Call method was called with elements not found in resultant form', array(), WATCHDOG_ERROR);
- $form = array(
- 'error' => array(
- '#value' => t('An error occured while processing your request, please try again. If the problem persists, please contact the site administrator')
- )
- );
- }
- unset($form['#prefix'], $form['#suffix']); // Prevent duplicate wrappers.
- $javascript = drupal_add_js(NULL, NULL, 'header');
- // Loop through the JS settings and find the settings needed for our buttons.
- $new_ajax_settings = array();
- if (isset($javascript['settings'])) {
- foreach ($javascript['settings'] as $settings) {
- if (isset($settings['ajax'])) {
- foreach ($settings['ajax'] as $id => $ajax_settings) {
- $new_ajax_settings[$id] = $ajax_settings;
- }
- }
- }
- }
- // Add the Call settings needed for our new elements.
- if (!empty($new_ajax_settings)) {
- $output = '<script type="text/javascript">jQuery.extend(Drupal.settings.Ajax, '. drupal_to_js($new_ajax_settings) .');</script>';
- }
- return array(array(
- 'status' => TRUE,
- 'data' => theme('status_messages') . $output . drupal_render($form),
- 'settings' => call_user_func_array('array_merge_recursive', $javascript['setting']),
- 'command' => 'syncSeating'
- ));
- }
- /**
- * Utility to remove a floor from the plan
- * @param $plan array the plan
- */
- function allocated_seating_plan_remove_floor(&$plan, $floor) {
- if (!isset($plan['floors'][$floor])) {
- return;
- }
- foreach ($plan['floors'][$floor]['rows'] as $row) {
- foreach ($row['columns'] as $col) {
- if ((int)$col['seat'] > 0) {
- form_set_error('', t('You cannot remove this floor, it still contains seats, please move them to another floor first.'));
- return;
- }
- }
- }
- unset($plan['floors'][$floor]);
- }
- /**
- * Utility to remove a col from the plan
- * @param $plan array the plan
- */
- function allocated_seating_plan_remove_column(&$plan, $floor) {
- if (!isset($plan['floors'][$floor])) {
- return;
- }
- $remove_col = count($plan['floors'][$floor]['rows'][0]['columns']) - 1;
- foreach ($plan['floors'][$floor]['rows'] as $row) {
- $col = $row['columns'][$remove_col];
- if ((int)$col['seat'] > 0) {
- form_set_error('', t('You cannot remove the last column from this floor, it still contains seats, please move them to another floor or column first.'));
- return;
- }
- }
- foreach ($plan['floors'][$floor]['rows'] as $key => $row) {
- unset($plan['floors'][$floor]['rows'][$key]['columns'][$remove_col]);
- }
- }
- /**
- * Utility to remove a row from the plan
- * @param $plan array the plan
- */
- function allocated_seating_plan_remove_row(&$plan, $floor) {
- if (!isset($plan['floors'][$floor])) {
- return;
- }
- $remove_row = count($plan['floors'][$floor]['rows']) - 1;
- foreach ($plan['floors'][$floor]['rows'][$remove_row]['columns'] as $col) {
- if ((int)$col['seat'] > 0) {
- form_set_error('', t('You cannot remove the last row from this floor, it still contains seats, please move them to another floor or row first.'));
- return;
- }
- }
- unset($plan['floors'][$floor]['rows'][$remove_row]);
- }
- /**
- * Utility to add a floor to a plan
- * @param $plan array the plan
- */
- function allocated_seating_plan_add_floor(&$element, &$post) {
- $plan = &$element['#value'];
- $rows = $plan['add_floor_row_count'];
- $cols = $plan['add_floor_col_count'];
- $tickets = $plan['add_floor_ticket_count'];
- $available_tickets = array();
- if ($tickets) {
- if ($tickets > ($rows * $cols)) {
- $tickets = $rows * $cols;
- drupal_set_message(t('You cannot move more than !tix seats to the new floor', array('!tix' => ($rows * $cols))));
- }
- $map = allocated_seating_get_map($plan);
- $seat = count($available_tickets);
- $seats = $map['seats'];
- $seat_numbers = array_keys($seats);
- asort($seat_numbers);
- while ($seat < $tickets) {
- $seat++;
- $new_seat = array_pop($seat_numbers);
- $remove = $seats[$new_seat];
- $available_tickets[] = $new_seat;
- $plan['floors'][$remove['floor']]['rows'][$remove['row']]['columns'][$remove['column']]['seat'] = FALSE;
- }
- }
- $floor = array(
- 'title' => t('Floor !floor', array('!floor' => count($plan['floors']) + 1)),
- 'rows' => array()
- );
- $row = 0;
- $s = 1;
- while ($row < $rows) {
- $col = 0;
- $floor['rows'][$row] = array('columns' => array()); //add the rows
- while ($col < $cols) {
- if (count($available_tickets) > 0) {
- $seat = array_pop($available_tickets);
- }
- else {
- $seat = FALSE;
- }
- $floor['rows'][$row]['columns'][] = array('seat' => $seat); //add the seat as a blank or a number
- $col++;
- }
- $row++;
- }
- $plan['floors'][] = $floor;
- }
- /**
- * Utility to add row to a floor of a plan
- * @param $plan array the plan
- * @param $floor int the floor delta
- */
- function allocated_seating_plan_floor_add_row(&$plan, $floor) {
- $cols = count($plan['floors'][$floor]['rows'][0]['columns']);
- $rows = count($plan['floors'][$floor]['rows']);
- $col = 0;
- $row = array('columns' => array()); //create the row
- while ($col < $cols) {
- $row['columns'][] = array('seat' => FALSE); //add the seat as a blank
- $col++;
- }
- $plan['floors'][$floor]['rows'][] = $row;
- }
- /**
- * Utility to add column to a floor of a plan
- * @param $plan array the plan
- * @param $floor int the floor delta
- */
- function allocated_seating_plan_floor_add_column(&$plan, $floor) {
- $rows = count($plan['floors'][$floor]['rows']);
- $row = 0;
- while ($row < $rows) {
- $plan['floors'][$floor]['rows'][$row]['columns'][] = array('seat' => FALSE);
- $row++;
- }
- }
- /**
- * Utility to setup required js files etc
- */
- function allocated_seating_setup() {
- drupal_add_library('system', 'ui.sortable');
- drupal_add_library('system', 'ui.tabs');
- drupal_add_library('system', 'ui.droppable');
- //jquery_ui_add(array('ui.sortable', 'ui.tabs', 'ui.droppable'));
- drupal_add_js(drupal_get_path('module', 'allocated_seating') .'/allocated_seating.js');
- drupal_add_css(drupal_get_path('module', 'allocated_seating') .'/allocated_seating.css');
- }
- /**
- * Util to fetch number of rows and columns (seats) submitted in the plan
- * @param $plan array seating plan as submitted in $element['#value']
- */
- function allocated_seating_total_seats($plan) {
- $seats = 0;
- foreach ($plan['floors'] as $floor) {
- $rows = $floor['row_count'];
- $cols = $floor['col_count'];
- $seats += ($rows * $cols);
- }
- return $seats;
- }
- /**
- * Util to fetch number of rows and columns (seats) submitted in the plan
- * @param $plan array seating plan as submitted in $element['#value']
- */
- function allocated_seating_plan_seats($plan) {
- $seats = 0;
- foreach ($plan['floors'] as $floor) {
- $rows = count($floor['rows']);
- $cols = count($floor['rows'][0]['columns']);
- $seats += ($rows * $cols);
- }
- return $seats;
- }
- /**
- * Util to fetch number of real seats (non blank) in the plan
- * @param $plan array seating plan as submitted in $element['#value']
- */
- function allocated_seating_real_seats($plan) {
- $seats = 0;
- foreach ($plan['floors'] as $floor) {
- foreach ($floor['rows'] as $row) {
- foreach ($row['columns'] as $column) {
- if ((int)$column['seat'] > 0) {
- $seats++;
- }
- }
- }
- }
- return $seats;
- }
- /**
- * Util to fetch reveresed map keyed by seat
- * @param $plan array seating plan
- * @return array with two members as follows
- * seats => array keyed by seat # with array or floor, row and column members
- * blanks => same but for blanks
- */
- function allocated_seating_get_map($plan) {
- $map = $blanks = array();
- foreach ($plan['floors'] as $fid => $floor) {
- foreach ($floor['rows'] as $rid => $row) {
- foreach ($row['columns'] as $cid => $column) {
- if ((int)$column['seat'] > 0) {
- $map[$column['seat']] = array('row' => $rid, 'column' => $cid, 'floor' => $fid);
- }
- else {
- $blanks[] = array('row' => $rid, 'column' => $cid, 'floor' => $fid);
- }
- }
- }
- }
- return array('seats' => $map, 'blanks' => $blanks);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement