mirror of
https://github.com/farmOS/farmOS.git
synced 2024-02-23 11:37:38 +01:00
586 lines
17 KiB
Plaintext
586 lines
17 KiB
Plaintext
<?php
|
|
|
|
/**
|
|
* @file
|
|
* Farm plan consideration module.
|
|
*/
|
|
|
|
/**
|
|
* Implements hook_menu().
|
|
*/
|
|
function farm_plan_consideration_menu() {
|
|
|
|
// List planning considerations.
|
|
$items['farm/plan/%farm_plan/considerations'] = array(
|
|
'title' => 'Considerations',
|
|
'description' => 'Identify considerations that will affect the planning process.',
|
|
'page callback' => 'farm_plan_consideration_list',
|
|
'page arguments' => array(2),
|
|
'access callback' => 'farm_plan_access',
|
|
'access arguments' => array('update', 2),
|
|
'type' => MENU_LOCAL_TASK,
|
|
);
|
|
|
|
// Add a new consideration.
|
|
$items['farm/plan/%farm_plan/considerations/add'] = array(
|
|
'title' => 'Add a consideration',
|
|
'description' => 'Add a new planning consideration.',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('farm_plan_consideration_form', 2),
|
|
'access callback' => 'farm_plan_access',
|
|
'access arguments' => array('update', 2),
|
|
'type' => MENU_LOCAL_ACTION,
|
|
);
|
|
|
|
// Edit an existing consideration.
|
|
$items['farm/plan/%farm_plan/considerations/%/edit'] = array(
|
|
'title' => 'Edit consideration',
|
|
'description' => 'Edit an existing consideration.',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('farm_plan_consideration_form', 2, 4),
|
|
'access callback' => 'farm_plan_access',
|
|
'access arguments' => array('update', 2),
|
|
);
|
|
|
|
// Delete a consideration.
|
|
$items['farm/plan/%farm_plan/considerations/%/delete'] = array(
|
|
'title' => 'Delete consideration',
|
|
'description' => 'Delete a consideration.',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('farm_plan_consideration_delete_form', 2, 4),
|
|
'access callback' => 'farm_plan_access',
|
|
'access arguments' => array('update', 2),
|
|
);
|
|
|
|
return $items;
|
|
}
|
|
|
|
/**
|
|
* Get available consideration types provided by modules.
|
|
*
|
|
* @return array
|
|
* Returns an array of consideration type information.
|
|
*/
|
|
function farm_plan_consideration_types() {
|
|
|
|
// Ask modules for consideration types. Use static caching.
|
|
$consideration_types = &drupal_static(__FUNCTION__);
|
|
if (!isset($consideration_types)) {
|
|
$consideration_types = module_invoke_all('farm_plan_consideration_types');
|
|
}
|
|
|
|
// Return consideration types.
|
|
return $consideration_types;
|
|
}
|
|
|
|
/**
|
|
* Implements hook_farm_plan_consideration_types().
|
|
*/
|
|
function farm_plan_farm_plan_consideration_types() {
|
|
|
|
// Provide two basic consideration types: "Management concern" and "Urgent".
|
|
return array(
|
|
'concern' => array(
|
|
'label' => t('Management concern'),
|
|
'color' => 'purple',
|
|
),
|
|
'urgent' => array(
|
|
'label' => t('Urgent'),
|
|
'color' => 'red',
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Create a new consideration.
|
|
*
|
|
* @param string $type
|
|
* The consideration type machine name.
|
|
* @param string $name
|
|
* The consideration name.
|
|
* @param int $start_time
|
|
* The start timestamp of the consideration.
|
|
* @param int $end_time
|
|
* The end timestamp of the consideration.
|
|
* @param int $plan_id
|
|
* The ID of the plan this consideration is linked to (optional).
|
|
*
|
|
* @return object
|
|
* Returns an empty consideration object.
|
|
*/
|
|
function farm_plan_consideration_create($type = 'concern', $name = '', $start_time = 0, $end_time = 0, $plan_id = NULL) {
|
|
$consideration = new stdClass();
|
|
$consideration->id = NULL;
|
|
$consideration->type = $type;
|
|
$consideration->name = $name;
|
|
$consideration->plan_id = $plan_id;
|
|
$consideration->start_time = $start_time;
|
|
$consideration->end_time = $end_time;
|
|
$consideration->entities = array();
|
|
return $consideration;
|
|
}
|
|
|
|
/**
|
|
* Save a consideration to the database.
|
|
*
|
|
* @param object $consideration
|
|
* The consideration object.
|
|
*/
|
|
function farm_plan_consideration_save(&$consideration) {
|
|
|
|
// Build the primary keys parameter for drupal_write_record() depending on
|
|
// whether or not the consideration has an ID (insert vs update).
|
|
$keys = array();
|
|
if (!empty($consideration->id)) {
|
|
$keys[] = 'id';
|
|
}
|
|
|
|
// Save the consideration to the database.
|
|
drupal_write_record('farm_plan_consideration', $consideration, $keys);
|
|
|
|
// Save all entity links to the consideration.
|
|
if (!empty($consideration->id)) {
|
|
|
|
// First delete all existing links.
|
|
db_query('DELETE FROM {farm_plan_consideration_entity} WHERE consideration_id = :id', array(':id' => $consideration->id));
|
|
|
|
// If there are links to save, iterate through them.
|
|
if (!empty($consideration->entities)) {
|
|
foreach ($consideration->entities as $entity_type => $entity_ids) {
|
|
if (!empty($entity_ids)) {
|
|
foreach ($entity_ids as $entity_id) {
|
|
|
|
// Save the entity+consideration link.
|
|
$record = array(
|
|
'consideration_id' => $consideration->id,
|
|
'entity_type' => $entity_type,
|
|
'entity_id' => $entity_id,
|
|
);
|
|
drupal_write_record('farm_plan_consideration_entity', $record);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Load a consideration from the database.
|
|
*
|
|
* @param int $id
|
|
* The consideration ID.
|
|
*
|
|
* @return object|bool
|
|
* Returns the consideration object, or FALSE if one doesn't exist.
|
|
*/
|
|
function farm_plan_consideration_load($id) {
|
|
|
|
// Load the consideration record from the database.
|
|
$consideration = db_query('SELECT * FROM {farm_plan_consideration} WHERE id = :id', array(':id' => $id))->fetch();
|
|
|
|
// If a consideration couldn't be loaded, bail.
|
|
if (empty($consideration)) {
|
|
return FALSE;
|
|
}
|
|
|
|
// Load entity associations with this consideration.
|
|
$result = db_query('SELECT * FROM {farm_plan_consideration_entity} WHERE consideration_id = :id', array(':id' => $id));
|
|
foreach ($result as $record) {
|
|
$consideration->entities[$record->entity_type][] = $record->entity_id;
|
|
}
|
|
|
|
// Return the consideration.
|
|
return $consideration;
|
|
}
|
|
|
|
/**
|
|
* Delete a consideration from the database.
|
|
*
|
|
* @param int $id
|
|
* The consideration ID.
|
|
*/
|
|
function farm_plan_consideration_delete($id) {
|
|
|
|
// If the ID is empty, bail.
|
|
if (empty($id)) {
|
|
return;
|
|
}
|
|
|
|
// Delete the consideration.
|
|
db_query('DELETE FROM {farm_plan_consideration} WHERE id = :id', array(':id' => $id));
|
|
|
|
// Delete any entity associations to that consideration.
|
|
db_query('DELETE FROM {farm_plan_consideration_entity} WHERE consideration_id = :id', array(':id' => $id));
|
|
}
|
|
|
|
/**
|
|
* Page callback for considerations list, filtered for a plan.
|
|
*
|
|
* @param $plan
|
|
* The plan object to filter considerations for..
|
|
*
|
|
* @return string
|
|
* Return the content of the page.
|
|
*/
|
|
function farm_plan_consideration_list($plan) {
|
|
|
|
// Set the page title.
|
|
drupal_set_title(t('Considerations'));
|
|
|
|
// Create a fieldset for the considerations.
|
|
$build['considerations'] = array(
|
|
'#type' => 'fieldset',
|
|
'#title' => t('Planning considerations'),
|
|
'#description' => t('Use this to define any planning considerations you want to remember. Considerations can be specific to a single plan, or they can apply to all plans.'),
|
|
);
|
|
|
|
// Define the considerations table header.
|
|
$header = array(
|
|
t('Consideration'),
|
|
t('Type'),
|
|
t('Start'),
|
|
t('End'),
|
|
t('Associations'),
|
|
t('Plan'),
|
|
t('Actions'),
|
|
);
|
|
|
|
// Load information about all consideration types.
|
|
$consideration_types = farm_plan_consideration_types();
|
|
|
|
// Query all considerations from the database that either apply to all plans,
|
|
// or are associated with this plan specifically, and build a set of rows for
|
|
// the table.
|
|
$rows = array();
|
|
$result = db_query('SELECT id FROM {farm_plan_consideration} WHERE plan_id IS NULL OR plan_id = :plan_id', array(':plan_id' => $plan->id));
|
|
foreach ($result as $record) {
|
|
|
|
// Load the consideration.
|
|
$consideration = farm_plan_consideration_load($record->id);
|
|
|
|
// If the consideration didn't load, skip it.
|
|
if (empty($consideration)) {
|
|
continue;
|
|
}
|
|
|
|
// Sanitize the name.
|
|
$name = check_plain($consideration->name);
|
|
|
|
// Get the consideration type label.
|
|
$type = $consideration->type;
|
|
if (!empty($consideration_types[$type]['label'])) {
|
|
$type = $consideration_types[$type]['label'];
|
|
}
|
|
|
|
// Format the start and end dates.
|
|
$date_format = 'M j Y';
|
|
$start_time = date($date_format, $consideration->start_time);
|
|
$end_time = date($date_format, $consideration->end_time);
|
|
|
|
// If there are entity associations, build a list.
|
|
$associations = '';
|
|
$entity_links = array();
|
|
if (!empty($consideration->entities)) {
|
|
foreach ($consideration->entities as $entity_type => $ids) {
|
|
foreach ($ids as $id) {
|
|
$entities = entity_load($entity_type, array($id));
|
|
if (empty($entities)) {
|
|
continue;
|
|
}
|
|
$entity = reset($entities);
|
|
$label = entity_label($entity_type, $entity);
|
|
$uri = entity_uri($entity_type, $entity);
|
|
$entity_links[] = l($label, $uri['path']);
|
|
}
|
|
}
|
|
}
|
|
if (!empty($entity_links)) {
|
|
$associations = theme('item_list', array('items' => $entity_links));
|
|
}
|
|
|
|
// If the consideration is linked to a plan, show a link to it. Otherwise,
|
|
// just say "all".
|
|
$plan_link = 'all';
|
|
if (!empty($consideration->plan_id)) {
|
|
$consideration_plan = farm_plan_load($consideration->plan_id);
|
|
if (!empty($plan)) {
|
|
$plan_label = entity_label('farm_plan', $consideration_plan);
|
|
$plan_uri = entity_uri('farm_plan', $consideration_plan);
|
|
$plan_link = l($plan_label, $plan_uri['path']);
|
|
}
|
|
}
|
|
|
|
// Build the actions.
|
|
$actions = array();
|
|
$actions[] = l(t('Edit'), 'farm/plan/' . $plan->id . '/considerations/' . $consideration->id . '/edit');
|
|
$actions[] = l(t('Delete'), 'farm/plan/' . $plan->id . '/considerations/' . $consideration->id . '/delete');
|
|
$actions = implode(' | ', $actions);
|
|
|
|
// Assemble the row.
|
|
$row = array(
|
|
$name,
|
|
$type,
|
|
$start_time,
|
|
$end_time,
|
|
$associations,
|
|
$plan_link,
|
|
$actions,
|
|
);
|
|
|
|
// Add it to the rows array.
|
|
$rows[] = $row;
|
|
}
|
|
|
|
// Build the table render array.
|
|
$build['considerations']['table'] = array(
|
|
'#theme' => 'table',
|
|
'#header' => $header,
|
|
'#rows' => $rows,
|
|
'#empty' => t('No considerations found.'),
|
|
);
|
|
|
|
return $build;
|
|
}
|
|
|
|
/**
|
|
* Build the farm plan considerations form.
|
|
*/
|
|
function farm_plan_consideration_form($form, &$form_state, $plan, $consideration_id = NULL) {
|
|
|
|
// Set the page title.
|
|
if (empty($consideration_id)) {
|
|
$title = t('Add a consideration');
|
|
}
|
|
else {
|
|
$title = t('Edit consideration');
|
|
}
|
|
drupal_set_title($title);
|
|
|
|
// Store the plan in the form for future use.
|
|
$form['plan'] = array(
|
|
'#type' => 'value',
|
|
'#value' => $plan,
|
|
);
|
|
|
|
// Load the consideration record, if one is specified.
|
|
if (!empty($consideration_id)) {
|
|
$consideration = farm_plan_consideration_load($consideration_id);
|
|
}
|
|
|
|
// Otherwise, start a new one.
|
|
else {
|
|
$consideration = farm_plan_consideration_create();
|
|
}
|
|
|
|
// Store the consideration in the form for future use.
|
|
$form['consideration'] = array(
|
|
'#type' => 'value',
|
|
'#value' => $consideration,
|
|
);
|
|
|
|
// Build an array of consideration type options.
|
|
$consideration_types = farm_plan_consideration_types();
|
|
$consideration_type_options = array();
|
|
foreach ($consideration_types as $type => $info) {
|
|
if (!empty($info['label'])) {
|
|
$consideration_type_options[$type] = $info['label'];
|
|
}
|
|
}
|
|
|
|
// Consideration type.
|
|
$form['type'] = array(
|
|
'#type' => 'select',
|
|
'#title' => t('Consideration type'),
|
|
'#description' => t('Specify what type of consideration this is.'),
|
|
'#options' => $consideration_type_options,
|
|
'#default_value' => !empty($consideration->type) ? $consideration->type : 'concern',
|
|
'#required' => TRUE,
|
|
'#ajax' => array(
|
|
'callback' => 'farm_plan_consideration_form_ajax',
|
|
'wrapper' => 'consideration-extra',
|
|
),
|
|
);
|
|
|
|
// Name.
|
|
$form['name'] = array(
|
|
'#type' => 'textfield',
|
|
'#title' => t('Name'),
|
|
'#description' => t('Provide a brief name for this consideration to describe it.'),
|
|
'#default_value' => !empty($consideration->name) ? $consideration->name : '',
|
|
'#required' => TRUE,
|
|
);
|
|
|
|
// Define date format.
|
|
$date_format = 'Y-m-d';
|
|
|
|
// Start date.
|
|
$default_start_time = !empty($consideration->start_time) ? date($date_format, $consideration->start_time) : '';
|
|
$form['start_time'] = array(
|
|
'#type' => 'date_select',
|
|
'#title' => t('Start date'),
|
|
'#date_label_position' => 'within',
|
|
'#date_format' => $date_format,
|
|
'#date_year_range' => '-3:+10',
|
|
'#default_value' => $default_start_time,
|
|
'#required' => TRUE,
|
|
);
|
|
|
|
// End date.
|
|
$default_end_time = !empty($consideration->end_time) ? date($date_format, $consideration->end_time) : '';
|
|
$form['end'] = array(
|
|
'#type' => 'date_select',
|
|
'#title' => t('End date'),
|
|
'#date_label_position' => 'within',
|
|
'#date_format' => $date_format,
|
|
'#date_year_range' => '-3:+10',
|
|
'#default_value' => $default_end_time,
|
|
'#required' => TRUE,
|
|
);
|
|
|
|
// Is this consideration specific to a plan?
|
|
$plan_label = entity_label('farm_plan', $plan);
|
|
if (!empty($consideration_id)) {
|
|
if (!empty($consideration->plan_id)) {
|
|
$form['plan_id'] = array(
|
|
'#type' => 'markup',
|
|
'#markup' => '<p><strong>' . t('This consideration is specific to plan %plan_label.', array('%plan_label' => $plan_label)) . '</strong></p>',
|
|
);
|
|
}
|
|
else {
|
|
$form['plan_id'] = array(
|
|
'#type' => 'markup',
|
|
'#markup' => '<p><strong>' . t('This consideration applies to all plans.') . '</p></strong>',
|
|
);
|
|
}
|
|
}
|
|
else {
|
|
$form['plan_id'] = array(
|
|
'#type' => 'checkbox',
|
|
'#title' => t('Is this consideration specific to plan %plan_label?', array('%plan_label' => $plan_label)),
|
|
'#description' => t('If this is checked, the consideration will only be visible in the context of this plan. Otherwise, it will be visible to all plans.'),
|
|
'#default_value' => FALSE,
|
|
);
|
|
}
|
|
|
|
// Add an area for extra fields. Modules can use this to add type-specific
|
|
// configuration for their consideration types. For example: linking them
|
|
// to entities.
|
|
$form['extra'] = array(
|
|
'#prefix' => '<div id="consideration-extra">',
|
|
'#suffix' => '</div>',
|
|
);
|
|
|
|
// Submit button.
|
|
$form['submit'] = array(
|
|
'#type' => 'submit',
|
|
'#value' => t('Save consideration'),
|
|
);
|
|
|
|
return $form;
|
|
}
|
|
|
|
/**
|
|
* Consideration form ajax callback.
|
|
*/
|
|
function farm_plan_consideration_form_ajax($form, &$form_state) {
|
|
return $form['extra'];
|
|
}
|
|
|
|
/**
|
|
* Consideration form submit function.
|
|
*/
|
|
function farm_plan_consideration_form_submit($form, &$form_state) {
|
|
|
|
// Load the consideration from the form.
|
|
$consideration = $form_state['values']['consideration'];
|
|
|
|
// Format, sanitize, and set information from the submitted values.
|
|
$consideration->type = $form_state['values']['type'];
|
|
$consideration->name = check_plain($form_state['values']['name']);
|
|
|
|
// Convert dates to timestamps.
|
|
$consideration->start_time = strtotime($form_state['values']['start_time']);
|
|
$consideration->end_time = strtotime($form_state['values']['end_time']);
|
|
|
|
// If this is a new consideration, and it is specific to the plan, save the
|
|
// plan ID.
|
|
if (empty($consideration->id) && !empty($form_state['values']['plan']->id)) {
|
|
$consideration->plan_id = $form_state['values']['plan']->id;
|
|
}
|
|
|
|
// Save the consideration.
|
|
farm_plan_consideration_save($consideration);
|
|
|
|
// Set a message.
|
|
drupal_set_message(t('Consideration saved.'));
|
|
|
|
// Redirect to the considerations list.
|
|
$form_state['redirect'] = 'farm/plan/' . $form_state['values']['plan']->id . '/considerations';
|
|
}
|
|
|
|
/**
|
|
* Delete confirmation form.
|
|
*
|
|
* @param array $form
|
|
* The form array.
|
|
* @param array $form_state
|
|
* The form state array.
|
|
* @param $plan
|
|
* The farm plan entity.
|
|
* @param $consideration_id
|
|
* The ID of the consideration record.
|
|
*
|
|
* @return array
|
|
* Returns a form array.
|
|
*/
|
|
function farm_plan_consideration_delete_form(array $form, array &$form_state, $plan, $consideration_id) {
|
|
|
|
// Store the plan in the form.
|
|
$form['plan'] = array(
|
|
'#type' => 'value',
|
|
'#value' => $plan,
|
|
);
|
|
|
|
// Load the consideration.
|
|
$consideration = farm_plan_consideration_load($consideration_id);
|
|
|
|
// Store the consideration in the form.
|
|
$form['consideration'] = array(
|
|
'#type' => 'value',
|
|
'#value' => $consideration,
|
|
);
|
|
|
|
// Build a confirmation form.
|
|
return confirm_form($form,
|
|
t('Are you sure you want to delete %name?', array('%name' => $consideration->name)),
|
|
'farm/plan/' . $plan->id . '/considerations',
|
|
t('This action cannot be undone.'),
|
|
t('Delete'),
|
|
t('Cancel')
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Delete form submit handler.
|
|
*
|
|
* @param array $form
|
|
* The form array.
|
|
* @param array $form_state
|
|
* The form state array.
|
|
*/
|
|
function farm_plan_consideration_delete_form_submit(array $form, array &$form_state) {
|
|
|
|
// Pull the plan and consideration out of the form.
|
|
$plan = $form_state['values']['plan'];
|
|
$consideration = $form_state['values']['consideration'];
|
|
|
|
// Delete the consideration.
|
|
farm_plan_consideration_delete($consideration->id);
|
|
|
|
// Set a message.
|
|
drupal_set_message(t('The consideration was deleted.'));
|
|
|
|
// Redirect to the considerations list.
|
|
$form_state['redirect'] = 'farm/plan/' . $plan->id . '/considerations';
|
|
}
|