'fieldset', '#title' => t('Record an animal birth'), '#description' => t('Use this form to record the birth of one or more animals. A new birth log will be created, along with the new child animal records.'), '#tree' => TRUE, ); // Date select (default to now). $form['birth']['timestamp'] = array( '#type' => 'date_select', '#title' => t('Date'), '#date_format' => 'M j Y H:i', '#date_type' => DATE_FORMAT_UNIX, '#date_year_range' => '-10:+3', '#default_value' => REQUEST_TIME, '#required' => TRUE, ); // Mother animal reference. Required because we need to be able to get the // species/breed from at least on of the parents. $form['birth']['mother'] = array( '#type' => 'textfield', '#title' => t('Mother'), '#description' => t('Select the mother animal. As you type, a dropdown of matching animal names will appear. Click on the one you want, and the field will be filled in with the name and asset ID (example: "Betsy [id: 123]"). The "[id: X]" portion is required.'), '#autocomplete_path' => 'farm_asset/autocomplete/animal', '#required' => TRUE, ); // Father animal reference. $form['birth']['father'] = array( '#type' => 'textfield', '#title' => t('Father'), '#description' => t('Select the father animal (optional). See the mother field above for instructions.'), '#autocomplete_path' => 'farm_asset/autocomplete/animal', ); // Number of children. $form['birth']['children'] = array( '#type' => 'select', '#title' => t('How many children were born?'), '#options' => drupal_map_assoc(range(1, 15)), '#default_value' => 1, '#ajax' => array( 'callback' => 'farm_livestock_birth_form_children_ajax', 'wrapper' => 'farm-livestock-birth-children', ), ); // Create a wrapper around all child fields, for AJAX replacement. $form['birth']['child'] = array( '#prefix' => '
', '#suffix' => '
', ); // Add fields for each child. $children = 1; if (!empty($form_state['values']['birth']['children'])) { $children = $form_state['values']['birth']['children']; } for ($i = 0; $i < $children; $i++) { // Fieldset for the child. $form['birth']['child'][$i] = array( '#type' => 'fieldset', '#title' => t('Child @number', array('@number' => $i + 1)), '#collapsible' => TRUE, '#collapsed' => FALSE, ); // Animal name. $form['birth']['child'][$i]['name'] = array( '#type' => 'textfield', '#title' => t('Name'), '#description' => t('Give the animal a name (and/or tag ID below). If the name is left blank, then it will be copied from the tag ID.'), '#weight' => 0, ); // Tag ID. $form['birth']['child'][$i]['tag_id'] = array( '#type' => 'textfield', '#title' => t('Tag ID'), '#weight' => 0, ); // Male or female. $form['birth']['child'][$i]['sex'] = array( '#type' => 'radios', '#title' => t('Sex'), '#options' => array( 'F' => t('Female'), 'M' => t('Male'), ), '#weight' => 10, ); // Animal description. $form['birth']['child'][$i]['description'] = array( '#type' => 'text_format', '#title' => t('Description'), '#format' => 'farm_format', '#weight' => 30, ); // Survived. $form['birth']['child'][$i]['survived'] = array( '#type' => 'checkbox', '#title' => t('Survived birth'), '#description' => t('Uncheck this if the child did not survive. The child animal record will still be created, but will be immediately archived.'), '#default_value' => TRUE, '#weight' => 40, ); } // Group assignment choice $form['birth']['assign_group'] = array( '#type' => 'checkbox', '#title' => t('Assign group(s)'), '#description' => t('By default, assign the mother\'s groups to the children. Check this to manually assign groups.'), '#default_value' => FALSE, '#required' => FALSE, '#ajax' => array( 'callback' => 'farm_livestock_birth_form_group_ajax', 'wrapper' => 'farm-livestock-birth-group', ), ); // Create a wrapper around the group field, for AJAX replacement. $form['birth']['group'] = array( '#prefix' => '
', '#suffix' => '
', ); // Group if (!empty($form_state['values']['birth']['assign_group'])) { $form['birth']['group']['group'] = array( '#type' => 'select', '#title' => t('Group'), '#multiple' => TRUE, '#options' => farm_group_options(), '#required' => FALSE, ); } // Birth notes. $form['birth']['notes'] = array( '#type' => 'text_format', '#title' => t('Birth notes'), '#format' => 'farm_format', ); // Submit button. $form['birth']['submit'] = array( '#type' => 'submit', '#value' => t('Save birth records'), ); // Return the form. return $form; } /** * Form ajax function for children / birth quick form */ function farm_livestock_birth_form_children_ajax($form, &$form_state) { return $form['birth']['child']; } /** * Form ajax function for groups / birth quick form */ function farm_livestock_birth_form_group_ajax($form, &$form_state) { return $form['birth']['group']; } /** * Validate callback for birth quick form. */ function farm_livestock_birth_form_validate($form, &$form_state) { // Validate mother and father. $parents = array( 'mother', 'father', ); foreach ($parents as $parent) { if (!empty($form_state['values']['birth'][$parent])) { // Extract asset ID. $id = 0; $matches = array(); $result = preg_match('/\\[id: ([0-9]+)\\]/', $form_state['values']['birth'][$parent], $matches); if (!empty($matches[$result])) { $id = $matches[$result]; } // If an ID couldn't be extracted, throw an error. if (empty($id)) { form_set_error('birth][' . $parent, t('Could not load the @parent animal record. Make sure the animal asset ID is included. For example: "My animal [id: 123]"', array('@parent' => $parent))); continue; } // Load the asset. $asset = farm_asset_load($id); // If the asset didn't load, throw an error. if (empty($asset)) { form_set_error('birth][' . $parent, t('Could not load the @parent animal record. Make sure the animal name and ID are correct.', array('@parent' => $parent))); continue; } // Save the asset to the form state. $form_state['storage'][$parent] = $asset; } } // If both a mother and a father are specified, make sure they're different. if (!empty($form_state['storage']['mother']) && !empty($form_state['storage']['father'])) { if ($form_state['storage']['mother']->id == $form_state['storage']['father']->id) { unset($form_state['storage']['father']); form_set_error('birth][father', t('The mother and father cannot be the same animal.')); } } // Iterate through the children. foreach ($form_state['values']['birth']['child'] as $i => $child) { // Make sure that either the name or tag ID is filled in. if (empty($child['name']) && empty($child['tag_id'])) { form_set_error('birth][child][' . $i . '][name', t('The child must have a name or tag ID.')); } } } /** * Submit callback for birth quick form. */ function farm_livestock_birth_form_submit($form, &$form_state) { // Get the birth timestamp. $timestamp = strtotime($form_state['values']['birth']['timestamp']); // Get the mother and father animals, if they exists. $parents = array( 'mother' => FALSE, 'father' => FALSE, ); if (!empty($form_state['storage']['mother'])) { $parents['mother'] = $form_state['storage']['mother']; } if (!empty($form_state['storage']['father'])) { $parents['father'] = $form_state['storage']['father']; } // Iterate through the children, and build an array of their asset records. $children = array(); foreach ($form_state['values']['birth']['child'] as $child) { // If the name is not set, but tag ID is, copy the tag ID to the name. if (empty($child['name']) && !empty($child['tag_id'])) { $child['name'] = $child['tag_id']; } // Create a new animal asset. $values = array( 'type' => 'animal', 'name' => $child['name'], 'created' => $timestamp, ); $child_asset = entity_create('farm_asset', $values); $child_wrapper = entity_metadata_wrapper('farm_asset', $child_asset); // Set the animal's birthdate to the date of the log. $child_wrapper->field_farm_date->set($timestamp); // Set the animal's tag ID, if available. Create a new ID tag // field_collection entity attached to the animal. if (!empty($child['tag_id'])) { $animal_tag = entity_create('field_collection_item', array('field_name' => 'field_farm_animal_tag')); $animal_tag->setHostEntity('farm_asset', $child_asset); $animal_tag_wrapper = entity_metadata_wrapper('field_collection_item', $animal_tag); $animal_tag_wrapper->field_farm_animal_tag_id->set($child['tag_id']); $animal_tag_wrapper->save(); } // Set the animal's sex, if available. if (!empty($child['sex'])) { $child_wrapper->field_farm_animal_sex->set($child['sex']); } // Set the animal's description, if available. if (!empty($child['description']['value'])) { $child_wrapper->field_farm_description->set($child['description']); } // Iterate through the parents. foreach ($parents as $name => $parent) { // If an asset is not loaded, skip it. if (empty($parent)) { continue; } // Add them to the child's parents. $child_wrapper->field_farm_parent[] = $parent->id; // Load metadata wrapper. $parent_wrapper = entity_metadata_wrapper('farm_asset', $parent); // If this is the mother... if ($name == 'mother') { // Copy the species/breed to the child. $animal_type = $parent_wrapper->field_farm_animal_type->value(); $child_wrapper->field_farm_animal_type->set($animal_type); } } // If the child did not survive, then archive them. if (empty($child['survived'])) { $child_wrapper->archived->set($timestamp); } // Save the animal asset. $child_wrapper->save(); // Add it to the array. $children[] = $child_asset; // Link the asset to this quick form. if (function_exists('farm_quick_entity_link')) { farm_quick_entity_link('farm_livestock_birth_form', 'farm_asset', $child_asset); } // Set a message. $label = entity_label('farm_asset', $child_asset); $uri = entity_uri('farm_asset', $child_asset); drupal_set_message(t('Child animal created') . ': ' . l($label, $uri['path'])); } // Create a birth log. Leave the name blank so that it is auto-generated. $log_type = 'farm_birth'; $log_name = ''; $log = farm_log_create($log_type, $log_name, $timestamp, TRUE, $children); // Create an entity metadata wrapper for the log. $log_wrapper = entity_metadata_wrapper('log', $log); // Set the birth mother. $log_wrapper->field_farm_mother->set($parents['mother']->id); // Set the location (from the mother, if available). $movement_log = farm_movement_asset_latest_movement($parents['mother']); if (!empty($movement_log)) { $movement_log_wrapper = entity_metadata_wrapper('log', $movement_log); $movement_field = entity_create('field_collection_item', array('field_name' => 'field_farm_movement')); $movement_field->setHostEntity('log', $log); $movement_field_wrapper = entity_metadata_wrapper('field_collection_item', $movement_field); $movement_field_wrapper->field_farm_move_to->set($movement_log_wrapper->field_farm_movement->field_farm_move_to->value()); $movement_field_wrapper->field_farm_geofield->set($movement_log_wrapper->field_farm_movement->field_farm_geofield->value()); $movement_field_wrapper->save(); } // Get group membership - by default from the mother (if available), or user selected (if any) $groups = array(); if (empty($form_state['values']['birth']['assign_group'])) { $membership_log = farm_group_asset_latest_membership($parents['mother']); if (!empty($membership_log)) { $membership_log_wrapper = entity_metadata_wrapper('log', $membership_log); $groups = $membership_log_wrapper->field_farm_membership->field_farm_group->value(); } } else { // Load the selected groups; only proceed if the group multiselect has a value if (!empty($form_state['values']['birth']['group']['group'])) { $groups = farm_asset_load_multiple($form_state['values']['birth']['group']['group']); } } // Set group membership if (!empty($groups)) { $membership_field = entity_create('field_collection_item', array('field_name' => 'field_farm_membership')); $membership_field->setHostEntity('log', $log); $membership_field_wrapper = entity_metadata_wrapper('field_collection_item', $membership_field); $membership_field_wrapper->field_farm_group->set($groups); $membership_field_wrapper->save(); } // Set the birth log notes, if available. if (!empty($form_state['values']['birth']['notes']['value'])) { $log_wrapper->field_farm_notes->set($form_state['values']['birth']['notes']); } // Save the log. $log_wrapper->save(); // Link the log to the quick form. if (function_exists('farm_quick_entity_link')) { farm_quick_entity_link('farm_livestock_birth_form', 'log', $log); } // Set a message linking to the mother animal. $label = entity_label('farm_asset', $parents['mother']); $uri = entity_uri('farm_asset', $parents['mother']); drupal_set_message(t("View the mother's animal record") . ': ' . l($label, $uri['path'])); // Add the children to $form_state['storage'] so that other submit functions // can work with them. $form_state['storage']['children'] = $children; }