bat.module in Booking and Availability Management Tools for Drupal 7
Same filename and directory in other branches
Provides basic underlying functionality and configuration options used by all BAT modules.
File
bat.moduleView source
<?php
/**
* @file
* Provides basic underlying functionality and configuration options used
* by all BAT modules.
*/
/**
* Implements hook_permission().
*/
function bat_permission() {
$permissions = array(
'configure bat settings' => array(
'title' => t('Configure BAT'),
'description' => t('Allows users to manage site-wide BAT configuration settings.'),
'restrict access' => TRUE,
),
);
return $permissions;
}
/**
* Implements hook_menu().
*/
function bat_menu() {
$items = array();
// Top level "BAT" container.
$items['admin/bat'] = array(
'title' => 'BAT',
'description' => 'Administer BAT.',
'page callback' => 'system_admin_menu_block_page',
'access arguments' => array(
'access administration pages',
),
'file path' => drupal_get_path('module', 'system'),
'file' => 'system.admin.inc',
'weight' => -7,
);
$items['admin/bat/config'] = array(
'title' => 'Configuration',
'description' => 'Configure settings and business rules for BAT management.',
'page callback' => 'system_admin_menu_block_page',
'access arguments' => array(
'configure bat settings',
),
'type' => MENU_NORMAL_ITEM,
'weight' => 10,
'file path' => drupal_get_path('module', 'system'),
'file' => 'system.admin.inc',
);
$items['admin/bat/config/date-format'] = array(
'title' => 'Date format',
'description' => 'Configure date format.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'bat_date_format_form',
),
'access arguments' => array(
'configure bat settings',
),
'type' => MENU_NORMAL_ITEM,
'weight' => 30,
);
return $items;
}
/**
* Main booking settings form.
*/
function bat_date_format_form($form, &$form_state) {
$form['bat_date_format'] = array(
'#type' => 'item',
'#title' => t('BAT PHP Date Format'),
'#description' => t("A custom date format for events, search summary and calendar pop-ups. Define a php date format string like 'Y-m-d H:i' (see <a href=\"@link\">http://php.net/date</a> for more details).", array(
'@link' => 'http://php.net/date',
)),
);
$form['bat_date_format']['bat_date_format'] = array(
'#type' => 'textfield',
'#size' => 12,
'#prefix' => '<div class="container-inline form-item">' . t('Date format') . ': ',
'#suffix' => '</div>',
'#default_value' => variable_get('bat_date_format', 'Y-m-d H:i'),
);
$form['bat_date_format']['bat_daily_date_format'] = array(
'#type' => 'textfield',
'#size' => 12,
'#prefix' => '<div class="container-inline form-item">' . t('Daily date format') . ': ',
'#suffix' => '</div>',
'#default_value' => variable_get('bat_daily_date_format', 'Y-m-d'),
);
$form['bat_hourly_format'] = array(
'#type' => 'item',
'#title' => 'Hourly PHP Date Format',
'#description' => t("Define a php date format string like 'H:i' (see <a href=\"@link\">http://php.net/date</a> for more details).", array(
'@link' => 'http://php.net/date',
)),
);
$form['bat_hourly_format']['bat_hourly_date_format'] = array(
'#type' => 'textfield',
'#size' => 12,
'#prefix' => '<div class="container-inline form-item">' . t('Time format') . ': ',
'#suffix' => '</div>',
'#default_value' => variable_get('bat_hourly_date_format', 'H:i'),
);
return system_settings_form($form);
}
/**
* Implements hook_date_format_types().
*/
function bat_date_format_types() {
return array(
'bat_daily' => t('BAT Daily Date format'),
'bat' => t('BAT Date format'),
);
}
/**
* Implements hook_date_formats().
*/
function bat_date_formats() {
$formats = array();
$formats[] = array(
'type' => 'bat_daily',
'format' => variable_get('bat_daily_date_format', 'Y-m-d'),
'locales' => array(),
);
$formats[] = array(
'type' => 'bat',
'format' => variable_get('bat_date_format', 'Y-m-d H:i'),
'locales' => array(),
);
foreach ($formats as $format) {
variable_set('date_format_' . $format['type'], $format['format']);
}
return $formats;
}
/**
* Generic access control for entities that BAT defines.
*
* @param string $op
* The operation being performed. One of 'view', 'update', 'create' or
* 'delete'.
* @param object $entity
* Optionally an entity to check access for. If no entity is given, it will be
* determined whether access is allowed for all entities of the given type.
* @param object $account
* The user to check for. Leave it to NULL to check for the global user.
* @param string $entity_type
* The entity type of the entity to check for.
*
* @return bool
* Boolean indicating whether the user is granted or not.
*
* @see entity_access()
*/
function bat_entity_access($op, $entity, $account, $entity_type) {
$rights =& drupal_static(__FUNCTION__, array());
global $user;
$account = isset($account) ? $account : $user;
$entity_info = entity_get_info($entity_type);
// $entity may be either an object or a entity type. Since entity types cannot
// be an integer, use either nid or type as the static cache id.
$cid = is_object($entity) ? $entity->{$entity_info['entity keys']['id']} : $entity;
// If we are creating a new entity make sure we set the type so permissions get
// applied.
if ($op == 'create' && $cid == '') {
$cid = $entity->type;
}
// If we've already checked access for this node, user and op, return the
// cached result.
if (isset($rights[$account->uid][$cid][$op])) {
return $rights[$account->uid][$cid][$op];
}
// Grant generic administrator level access.
if (user_access('bypass ' . $entity_type . ' entities access', $account)) {
$rights[$account->uid][$cid][$op] = TRUE;
return TRUE;
}
if ($op == 'view') {
if (isset($entity)) {
// When trying to figure out access to an entity, query the base table
// using our access control tag.
if (!empty($entity_info['access arguments']['access tag']) && module_implements('query_' . $entity_info['access arguments']['access tag'] . '_alter')) {
$query = db_select($entity_info['base table']);
$query
->addExpression('1');
$result = (bool) $query
->addTag($entity_info['access arguments']['access tag'])
->addMetaData('account', $account)
->condition($entity_info['entity keys']['id'], $entity->{$entity_info['entity keys']['id']})
->range(0, 1)
->execute()
->fetchField();
$rights[$account->uid][$cid][$op] = $result;
return $result;
}
else {
$rights[$account->uid][$cid][$op] = TRUE;
return TRUE;
}
}
else {
$access = user_access('view any ' . $entity_type . ' entity', $account);
$rights[$account->uid][$cid][$op] = $access;
return $access;
}
}
else {
// Non-view operations.
// First grant access to the entity for the specified operation if no other
// module denies it and at least one other module says to grant access.
$access_results = module_invoke_all('bat_entity_access', $op, $entity, $account, $entity_type);
if (in_array(FALSE, $access_results, TRUE)) {
$rights[$account->uid][$cid][$op] = FALSE;
return FALSE;
}
elseif (in_array(TRUE, $access_results, TRUE)) {
$rights[$account->uid][$cid][$op] = TRUE;
return TRUE;
}
// Grant access based on entity type and bundle specific permissions with
// special handling for the create operation since the entity passed in will
// be initialized without ownership.
if ($op == 'create') {
// Assuming an entity was passed in and we know its bundle key, perform
// the entity type and bundle-level access checks.
if (isset($entity) && !empty($entity_info['entity keys']['bundle'])) {
$access = user_access('create ' . $entity_type . ' entities', $account) || user_access('create ' . $entity_type . ' entities of bundle ' . $entity->{$entity_info['entity keys']['bundle']}, $account);
$rights[$account->uid][$cid][$op] = $access;
return $access;
}
else {
// Otherwise perform an entity type-level access check.
$access = user_access('create ' . $entity_type . ' entities', $account);
$rights[$account->uid][$cid][$op] = $access;
return $access;
}
}
else {
// Finally perform checks for the rest of operations. Begin by
// extracting the bundle name from the entity if available.
$bundle_name = '';
if (isset($entity) && !empty($entity_info['entity keys']['bundle'])) {
$bundle_name = $entity->{$entity_info['entity keys']['bundle']};
}
// For the delete and delete operations, first perform the entity type and
// bundle-level access check for any entity.
if (user_access($op . ' any ' . $entity_type . ' entity', $account) || user_access($op . ' any ' . $entity_type . ' entity of bundle ' . $bundle_name, $account)) {
$rights[$account->uid][$cid][$op] = TRUE;
return TRUE;
}
// Check an authenticated user's access to delete own entities.
if ($account->uid && !empty($entity_info['access arguments']['user key']) && isset($entity->{$entity_info['access arguments']['user key']}) && $entity->{$entity_info['access arguments']['user key']} == $account->uid) {
if (user_access($op . ' own ' . $entity_type . ' entities', $account) || user_access($op . ' own ' . $entity_type . ' entities of bundle ' . $bundle_name, $account)) {
$rights[$account->uid][$cid][$op] = TRUE;
return TRUE;
}
}
}
}
return FALSE;
}
/**
* Return permission names for a given entity type.
*/
function bat_entity_access_permissions($entity_type) {
$entity_info = entity_get_info($entity_type);
$labels = $entity_info['permission labels'];
$permissions = array();
// General 'bypass' permission.
$permissions['bypass ' . $entity_type . ' entities access'] = array(
'title' => t('Bypass access to @entity_type', array(
'@entity_type' => $labels['plural'],
)),
'description' => t('Allows users to perform any action on @entity_type.', array(
'@entity_type' => $labels['plural'],
)),
'restrict access' => TRUE,
);
// Generic create and edit permissions.
$permissions['create ' . $entity_type . ' entities'] = array(
'title' => t('Create @entity_type of any type', array(
'@entity_type' => $labels['plural'],
)),
);
if (!empty($entity_info['access arguments']['user key'])) {
$permissions['view own ' . $entity_type . ' entities'] = array(
'title' => t('View own @entity_type of any type', array(
'@entity_type' => $labels['plural'],
)),
);
}
$permissions['view any ' . $entity_type . ' entity'] = array(
'title' => t('View any @entity_type of any type', array(
'@entity_type' => $labels['singular'],
)),
'restrict access' => TRUE,
);
if (!empty($entity_info['access arguments']['user key'])) {
$permissions['update own ' . $entity_type . ' entities'] = array(
'title' => t('Edit own @entity_type of any type', array(
'@entity_type' => $labels['plural'],
)),
);
}
$permissions['update any ' . $entity_type . ' entity'] = array(
'title' => t('Edit any @entity_type of any type', array(
'@entity_type' => $labels['singular'],
)),
'restrict access' => TRUE,
);
if (!empty($entity_info['access arguments']['user key'])) {
$permissions['delete own ' . $entity_type . ' entities'] = array(
'title' => t('Delete own @entity_type of any type', array(
'@entity_type' => $labels['plural'],
)),
);
}
$permissions['delete any ' . $entity_type . ' entity'] = array(
'title' => t('Delete any @entity_type of any type', array(
'@entity_type' => $labels['singular'],
)),
'restrict access' => TRUE,
);
// Per-bundle create and edit permissions.
if (!empty($entity_info['entity keys']['bundle'])) {
foreach ($entity_info['bundles'] as $bundle_name => $bundle_info) {
$permissions['create ' . $entity_type . ' entities of bundle ' . $bundle_name] = array(
'title' => t('Create %bundle @entity_type', array(
'@entity_type' => $labels['plural'],
'%bundle' => $bundle_info['label'],
)),
);
if (!empty($entity_info['access arguments']['user key'])) {
$permissions['view own ' . $entity_type . ' entities of bundle ' . $bundle_name] = array(
'title' => t('View own %bundle @entity_type', array(
'@entity_type' => $labels['plural'],
'%bundle' => $bundle_info['label'],
)),
);
}
$permissions['view any ' . $entity_type . ' entity of bundle ' . $bundle_name] = array(
'title' => t('View any %bundle @entity_type', array(
'@entity_type' => $labels['singular'],
'%bundle' => $bundle_info['label'],
)),
'restrict access' => TRUE,
);
if (!empty($entity_info['access arguments']['user key'])) {
$permissions['update own ' . $entity_type . ' entities of bundle ' . $bundle_name] = array(
'title' => t('Edit own %bundle @entity_type', array(
'@entity_type' => $labels['plural'],
'%bundle' => $bundle_info['label'],
)),
);
}
$permissions['update any ' . $entity_type . ' entity of bundle ' . $bundle_name] = array(
'title' => t('Edit any %bundle @entity_type', array(
'@entity_type' => $labels['singular'],
'%bundle' => $bundle_info['label'],
)),
'restrict access' => TRUE,
);
if (!empty($entity_info['access arguments']['user key'])) {
$permissions['delete own ' . $entity_type . ' entities of bundle ' . $bundle_name] = array(
'title' => t('Delete own %bundle @entity_type', array(
'@entity_type' => $labels['plural'],
'%bundle' => $bundle_info['label'],
)),
);
}
$permissions['delete any ' . $entity_type . ' entity of bundle ' . $bundle_name] = array(
'title' => t('Delete any %bundle @entity_type', array(
'@entity_type' => $labels['singular'],
'%bundle' => $bundle_info['label'],
)),
'restrict access' => TRUE,
);
}
}
return $permissions;
}
/**
* Implements hook_query_alter().
*
* Enforces access control for bat units during database queries.
*/
function bat_entity_access_query_alter($query, $entity_type, $base_table = NULL, $account = NULL, $op = 'view') {
global $user;
// Get the Drupal user account from the query if available, or
// default to the logged in user if not.
if (!isset($account) && !($account = $query
->getMetaData('account'))) {
$account = $user;
}
// Do not apply any conditions for users with administrative view permissions.
if (user_access('bypass ' . $entity_type . ' access', $account) || user_access($op . ' any ' . $entity_type . ' entity', $account)) {
return;
}
// Get the entity type info array for the current access check and prepare a
// conditions object.
$entity_info = entity_get_info($entity_type);
// If a base table wasn't specified, attempt to read it from the query if
// available, look for a table in the query's tables array that matches the
// base table of the given entity type, or just default to the first table.
if (!isset($base_table) && !($base_table = $query
->getMetaData('base_table'))) {
// Initialize the base table to the first table in the array. If a table can
// not be found that matches the entity type's base table, this will result
// in an invalid query if the first table is not the table we expect,
// forcing the caller to actually properly pass a base table in that case.
$tables = $query
->getTables();
reset($tables);
$base_table = key($tables);
foreach ($tables as $table_info) {
if (!$table_info instanceof SelectQueryInterface) {
// If this table matches the entity type's base table, use its table
// alias as the base table for the purposes of bundle and ownership
// access checks.
if ($table_info['table'] == $entity_info['base table']) {
$base_table = $table_info['alias'];
}
}
}
}
// Prepare an OR container for conditions. Conditions will be added that seek
// to grant access, meaning any particular type of permission check may grant
// access even if none of the others apply. At the end of this function, if no
// conditions have been added to the array, a condition will be added that
// always returns FALSE (1 = 0).
$conditions = db_or();
// Loop over every possible bundle for the given entity type.
foreach ($entity_info['bundles'] as $bundle_name => $bundle_info) {
// If the user has access to operation entities of the current bundle...
if (user_access($op . ' any ' . $entity_type . ' entity of bundle ' . $bundle_name, $account)) {
// Add a condition granting access if the entity specified by the view
// query is of the same bundle.
$conditions
->condition($base_table . '.' . $entity_info['entity keys']['bundle'], $bundle_name);
}
elseif ($account->uid && !empty($entity_info['access arguments']['user key']) && user_access($op . ' own ' . $entity_type . ' entities of bundle ' . $bundle_name, $account)) {
// Add an AND condition group that grants access if the entity specified
// by the view query matches the same bundle and belongs to the user.
$conditions
->condition(db_and()
->condition($base_table . '.' . $entity_info['entity keys']['bundle'], $bundle_name)
->condition($base_table . '.' . $entity_info['access arguments']['user key'], $account->uid));
}
}
// If the given entity type has a user ownership key...
if (!empty($entity_info['access arguments']['user key'])) {
// Perform 'operation own' access control for the entity in the query if the
// user is authenticated.
if ($account->uid && user_access($op . ' own ' . $entity_type . ' entities', $account)) {
$conditions
->condition($base_table . '.' . $entity_info['access arguments']['user key'], $account->uid);
}
}
// Prepare an array of condition alter hooks to invoke and an array of context
// data for the current query.
$hooks = array(
'bat_entity_access_' . $op . '_condition_' . $entity_type,
'bat_entity_access_' . $op . '_condition',
);
$context = array(
'account' => $account,
'entity_type' => $entity_type,
'base_table' => $base_table,
);
// Allow other modules to add conditions to the array as necessary.
drupal_alter($hooks, $conditions, $context);
// If we have more than one condition based on the entity access permissions
// and any hook implementations...
if (count($conditions)) {
// Add the conditions to the query.
$query
->condition($conditions);
}
else {
// Otherwise, since we don't have any possible conditions to match against,
// we falsify this query. View checks are access grants, not access denials.
$query
->where('1 = 0');
}
}
/**
* Utility function to create two related datepickers.
*
* We have a few forms that need a start and end date field
* and we need to apply the same javascript to these forms in order to enforce
* specific consistent behaviours and group the form elements and javascript
* injection in one place.
*
* @param int $year
* @param int $month
*
* @return array
* The array holding the field definitions
*/
function bat_date_range_fields($year = NULL, $month = NULL, $granularity = 'bat_hourly') {
$date_range_fields = array();
// Create unique ids and selectors for each datepicker.
$start_date_id = drupal_html_id('datepicker-start-date');
$start_date_selector = '#' . $start_date_id . ' .form-text';
$end_date_id = drupal_html_id('datepicker-end-date');
$end_date_selector = '#' . $start_date_id . ' .form-text';
// Specify the default datepicker parameters (see date_popup_element_info())
$datepicker_options = array(
'dateFormat' => date_popup_format_to_popup(variable_get('bat_daily_date_format', 'Y-m-d')),
// Limit bookings to X days in advance according to the
// chosen configuration in your BAT installation.
// Defaults to the current day.
'minDate' => '+' . variable_get('bat_event_start_date', 0) . 'd',
);
if ($year && $month) {
// Calculate min and max dates of the specified year/month.
$date = new DateTime();
$date
->setDate($year, $month, 01);
$min_date = $date
->format(variable_get('bat_daily_date_format', 'Y-m-d'));
$date
->modify('last day of this month');
$max_date = $date
->format(variable_get('bat_daily_date_format', 'Y-m-d'));
$datepicker_options += array(
'minDate' => $min_date,
'maxDate' => $max_date,
'defaultDate' => $min_date,
'numberOfMonths' => 1,
);
}
else {
$datepicker_options += array(
'minDate' => '+' . variable_get('bat_event_start_date', 0) . 'd',
);
}
$date_range_fields['bat_start_date'] = array(
'#prefix' => '<div class="form-wrapper bat-date-range"><div class="start-date" id="' . $start_date_id . '">',
'#suffix' => '</div>',
'#type' => 'date_popup',
'#title' => t('Event Start'),
'#date_type' => DATE_DATETIME,
'#date_format' => variable_get('bat_daily_date_format', 'Y-m-d'),
'#date_increment' => 1,
'#date_year_range' => '-1:+3',
// Default parameters defined above, with an additional parameter
// linking to the jQuery selector for the end datepicker.
'#datepicker_options' => array_merge($datepicker_options, array(
'endDateSelector' => $end_date_selector,
)),
'#required' => TRUE,
);
$date_range_fields['bat_end_date'] = array(
'#prefix' => '<div class="end-date" id="' . $end_date_id . '">',
'#suffix' => '</div></div>',
'#type' => 'date_popup',
'#title' => t('Event End'),
'#date_type' => DATE_DATETIME,
'#date_format' => variable_get('bat_daily_date_format', 'Y-m-d'),
'#date_increment' => 1,
'#date_year_range' => '-1:+3',
// Default parameters defined above, with an additional parameter
// parameter linking to the jQuery selector for the start datepicker.
'#datepicker_options' => array_merge($datepicker_options, array(
'startDateSelector' => $start_date_selector,
)),
'#required' => TRUE,
'#attached' => array(
'css' => array(
drupal_get_path('module', 'bat') . '/css/bat_date_range_fields.css',
),
'js' => array(
drupal_get_path('module', 'bat') . '/js/bat_date_popup.js',
array(
'data' => array(
'bat' => array(
'batStartYear' => $year,
'batStartMonth' => $month,
'batBookingStartDay' => variable_get('bat_event_start_date', 0),
'batDateFormat' => 'dd/mm/yy',
'batDateGranularity' => $granularity,
// Here we create a listing of all datepickers registered on the
// current page. This is available for use in your own custom
// jQuery scripts as Drupal.settings.bat.datepickers.
'datepickers' => array(
$start_date_selector => array(
'endDateSelector' => $end_date_selector,
),
),
),
),
'type' => 'setting',
),
),
),
);
return $date_range_fields;
}
/**
* Given a form state array, locate the start/end dates in the input array
* and instantiate and return DateTime objects.
*/
function bat_form_input_get_start_end_dates($form_state) {
// If form_state['values']['bat_X_date'] is not set, it is an empty array.
// In this case, we need to check and set values so that
// _constructor below will not fail.
if (is_array($form_state['values']['bat_start_date'])) {
if ($form_state['values']['bat_start_date']['date'] == '') {
$start = new DateTime();
}
else {
$start = new DateTime($form_state['values']['bat_start_date']['date'] . ' ' . $form_state['values']['bat_start_date']['time']);
}
}
else {
$start = new DateTime($form_state['values']['bat_start_date']);
}
if (is_array($form_state['values']['bat_end_date'])) {
if ($form_state['values']['bat_end_date']['date'] == '') {
$end = new DateTime();
}
else {
$end = new DateTime($form_state['values']['bat_end_date']['date'] . ' ' . $form_state['values']['bat_end_date']['time']);
}
}
else {
$end = new DateTime($form_state['values']['bat_end_date']);
}
return array(
$start,
$end,
);
}
/**
* Given a form state array, locate the start/end dates in the
* values array and instantiate and return DateTime objects.
*/
function bat_form_values_get_start_end_dates($form_state) {
// Date values have a format of year-month-day.
// This is one of the default expected formats, so there
// is no need to explicitly define the format.
// (see http://www.php.net/manual/en/datetime.formats.date.php)
$start_date = $form_state['values']['bat_start_date'];
$end_date = $form_state['values']['bat_end_date'];
// If the input format is numeric we assume that is a Unix timestamp.
if (is_numeric($start_date) && is_numeric($end_date)) {
// The @ lets the DateTime class know that the date is
// formatted as a Unix timestamp.
$start_date = '@' . $start_date;
$end_date = '@' . $end_date;
}
$start = new DateTime($start_date);
$end = new DateTime($end_date);
return array(
$start,
$end,
);
}
/**
* Validation callback that can be reused in all forms that need to
* validate dates.
*
* The end date must be greater than start date.
*/
function bat_form_start_end_dates_validate($form, &$form_state) {
list($start_date, $end_date) = bat_form_input_get_start_end_dates($form_state);
// Fail validation if no dates are provided.
if (empty($start_date) || empty($end_date)) {
form_set_error('date_range', t('Please choose dates.'));
return;
}
// Check date validity.
$errors = bat_check_dates_validity($start_date, $end_date);
// For some forms we need to ensure that the selected date matches with current values.
if (isset($form_state['values']['curr_month']) && isset($form_state['values']['curr_year'])) {
$curr_month = $form_state['values']['curr_month'];
$curr_year = $form_state['values']['curr_year'];
if ($start_date
->format('n') != $curr_month || $end_date
->format('n') != $curr_month || $start_date
->format('Y') != $curr_year || $end_date
->format('Y') != $curr_year) {
$errors[] = t('Both the start and end date must be within the current month.');
}
}
// When there are multiple errors for the same form element, Drupal only
// displays the first. Here we concatenate all errors so that they will all
// be displayed.
if ($errors) {
$error_msg = implode(' ', $errors);
form_set_error('date_range', $error_msg);
}
}
/**
* Checks the logical validity of date values.
*
* @param DateTime $start_date
* The start date.
* @param DateTime $end_date
* The end date.
*
* @return array
* An array with error messages.
*/
function bat_check_dates_validity(DateTime $start_date, DateTime $end_date) {
$errors = array();
// The end date must be greater or equal than start date.
if ($end_date < $start_date) {
$errors[] = t('End date must be on or after the start date.');
}
return $errors;
}
/**
* Loads a DateTime object from a string.
*
* @param string $date_string
* Expects to see a date in the form Y-m-d H:i:s.
*
* @return DateTime
* Object or null if invalid
*/
function bat_date_load($date_string) {
$date_string = check_plain($date_string);
try {
$date = new DateTime($date_string);
} catch (Exception $e) {
$date = 0;
}
return $date;
}
/**
* Get the default database prefix.
*/
function bat_get_db_prefix() {
global $databases;
$prefix = '';
if (!empty($databases['default']['default']['prefix'])) {
if (is_array($databases['default']['default']['prefix'])) {
$prefix = $databases['default']['default']['prefix']['default'];
}
else {
$prefix = $databases['default']['default']['prefix'];
}
}
return $prefix;
}
Functions
Name | Description |
---|---|
bat_check_dates_validity | Checks the logical validity of date values. |
bat_date_formats | Implements hook_date_formats(). |
bat_date_format_form | Main booking settings form. |
bat_date_format_types | Implements hook_date_format_types(). |
bat_date_load | Loads a DateTime object from a string. |
bat_date_range_fields | Utility function to create two related datepickers. |
bat_entity_access | Generic access control for entities that BAT defines. |
bat_entity_access_permissions | Return permission names for a given entity type. |
bat_entity_access_query_alter | Implements hook_query_alter(). |
bat_form_input_get_start_end_dates | Given a form state array, locate the start/end dates in the input array and instantiate and return DateTime objects. |
bat_form_start_end_dates_validate | Validation callback that can be reused in all forms that need to validate dates. |
bat_form_values_get_start_end_dates | Given a form state array, locate the start/end dates in the values array and instantiate and return DateTime objects. |
bat_get_db_prefix | Get the default database prefix. |
bat_menu | Implements hook_menu(). |
bat_permission | Implements hook_permission(). |