public static function get_submission($values, $args) { $values['habitat-count'] = 2; $habitatSamples = array(); for ($i = 1; $i <= $values['habitat-count']; $i++) { $habitatSamples["habitat{$i}"] = array(); } foreach ($values as $key => $value) { if (substr_count($key, ':') === 3) { $parts = explode(':', $key, 4); if ($parts[0] === 'smpAttr') { // If the last part of a habitat field is not a number, this is just a dummy field used // when cloning habitat controls. We also skip empty new attribute values. if (preg_match('/^\\d+$/', $parts[3]) && (!empty($parts[2]) || !empty($value))) { // habitat number is the last part of the attribute field name $id = array_pop($parts); // remove empty stuff from the attribute name (e.g. an unused space for the existing value ID, if a new attribute value). while (empty($parts[count($parts) - 1])) { array_pop($parts); } $fieldname = implode(':', $parts); $habitatSamples["habitat{$id}"][$fieldname] = $value; } unset($values[$key]); } } $parts = explode(':', $key); // For the group_name, the autocomplete functionality needs to be removed from the submission. // So copy the edit box into the underlying field which gets posted. if (array_pop($parts) === 'group_name') { $values[implode(':', $parts)] = $value; } } $buddyPairSubmission = submission_builder::wrap_with_images($values, 'sample'); unset($buddyPairSubmission['fields']['habitat-count']); // Get the list of records implied by the SACFOR data for each habitat. At this point we'll create 1 big list and split // it across the habitats later. $occurrences = data_entry_helper::wrap_species_checklist($values, true, array(), array()); // now work out which habitat contains which occurrence $habitatOccurrences = array(); foreach (array_keys($habitatSamples) as $habitatId) { $habitatOccurrences[$habitatId] = array(); } foreach ($occurrences as $occurrence) { // take a copy of the fields with all habitat data $fields = array_merge($occurrence['model']['fields']); // @todo Remove hard coded field ID. $habitatFields = preg_grep('/occAttr:243(:\\d+)?/', array_keys($fields)); if (count($habitatFields)) { $habitatId = $fields[array_pop($habitatFields)]['value']; } else { // this case occurs when deleting an occurrence, as the habitat ID input field is disabled. Therefore // we need to revert to the original hidden sampleIdx field for the loaded record. $habitatId = $fields['sampleIDX']['value'] + 1; } // zero indexed $habitatOccurrences["habitat{$habitatId}"][] = $occurrence; } // now create the submodel data for each habitat. $buddyPairSubmission['subModels'] = array(); // copy the basic sample data into each set of habitat subsample values foreach ($habitatSamples as $habitatId => &$habitatSample) { $habitatIdx = str_replace('habitat', '', $habitatId); $habitatSample['website_id'] = $values['website_id']; $habitatSample['survey_id'] = $values['survey_id']; if (isset($_POST["habitat_sample_id:{$habitatIdx}"])) { $habitatSample['sample:id'] = $_POST["habitat_sample_id:{$habitatIdx}"]; } $habitatSample['sample:date'] = $values['sample:date']; $habitatSample['sample:entered_sref'] = $values['sample:entered_sref']; $habitatSample['sample:entered_sref_system'] = $values['sample:entered_sref_system']; $habitatSample['sample:input_form'] = $values['sample:input_form']; if (isset($_POST["sample:comment:{$habitatIdx}"])) { $habitatSample['sample:comment'] = $_POST["sample:comment:{$habitatIdx}"]; unset($buddyPairSubmission['fields']["comment:{$habitatIdx}"]); } $habitatSubmission = submission_builder::wrap($habitatSample, 'sample'); $habitatSubmission['subModels'] = $habitatOccurrences[$habitatId]; $buddyPairSubmission['subModels'][] = array('fkId' => 'parent_id', 'model' => $habitatSubmission); } return $buddyPairSubmission; }
/** * Helper function to simplify building of a submission that contains a single sample * and multiple occurrences records generated by a species_checklist control. * * @param array $values List of the posted values to create the submission from. * @param boolean $include_if_any_data If true, then any list entry which has any data * set will be included in the submission. Set this to true when hiding the select checkbox * in the grid. * @param array $zero_attrs Set to an array of abundance attribute field IDs that can be * treated as abundances. Alternatively set to true to treat all occurrence custom attributes * as possible zero abundance indicators. * @param array $zero_values Set to an array of values which are considered to indicate a * zero abundance record if found for one of the zero_attrs. Values are case-insensitive. Defaults to * array('0','None','Absent'). * of values that can be treated as meaning a zero abundance record. E.g. * array(' * @return array Sample submission array */ public static function build_sample_occurrences_list_submission($values, $include_if_any_data = false, $zero_attrs = true, $zero_values = array('0', 'None', 'Absent')) { // We're mainly submitting to the sample model $sampleMod = submission_builder::wrap_with_images($values, 'sample'); $occurrences = data_entry_helper::wrap_species_checklist($values, $include_if_any_data, $zero_attrs, $zero_values); // Add the occurrences in as subModels without overwriting others such as a sample image if (array_key_exists('subModels', $sampleMod)) { $sampleMod['subModels'] = array_merge($sampleMod['subModels'], $occurrences); } else { $sampleMod['subModels'] = $occurrences; } return $sampleMod; }
<?php session_start(); require '../../../client_helpers/data_entry_helper.php'; require '../data_entry_config.php'; $base_url = helper_config::$base_url; $readAuth = data_entry_helper::get_read_auth($config['website_id'], $config['password']); // Store data from the previous page into the session data_entry_helper::add_post_to_session(); // To post our data, we need to get the whole lot from the session $data = data_entry_helper::extract_session_array(); // Collect up the sample, sample attributes and grid data $sampleMod = data_entry_helper::wrap($data, 'sample'); $smpAttrs = data_entry_helper::wrap_attributes($data, 'sample'); $occurrences = data_entry_helper::wrap_species_checklist($data); // Add the occurrences in as submodels $sampleMod['subModels'] = $occurrences; // and link in the attributes of the sample $sampleMod['metaFields']['smpAttributes']['value'] = $smpAttrs; // Wrap submission and submit $submission = array('submission' => array('entries' => array(array('model' => $sampleMod)))); $response = data_entry_helper::forward_post_to('save', $submission); if (array_key_exists('success', $response)) { // on success, redirect to the thank you page header('Location:success.php'); die; } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head>
/** * Helper function to simplify building of a submission that contains a single sample * and multiple occurrences records generated by a species_checklist control. * * @param array $values List of the posted values to create the submission from. * @param boolean $include_if_any_data If true, then any list entry which has any data * set will be included in the submission. Set this to true when hiding the select checkbox * in the grid. * @return array Sample submission array */ public static function build_sample_occurrences_list_submission($values, $include_if_any_data = false) { // We're mainly submitting to the sample model $sampleMod = data_entry_helper::wrap_with_attrs($values, 'sample'); $occurrences = data_entry_helper::wrap_species_checklist($values, $include_if_any_data); // Add the occurrences in as subModels $sampleMod['subModels'] = $occurrences; return $sampleMod; }
public static function build_three_level_sample_with_occ_submission($values, $website_id, $password, $gpxDataAttrId, $diveStartTimeAttrId, $exifDateTimeAttrId) { $standardGridValues = array(); //Create two different $values arrays. //The $standardGridValues array contains all the values you would expect from a normal species grid entry form. This contains the species grid we don't have images for. //The $values array contains the values from the form and only includes the other three level sample species grid foreach ($values as $key => $value) { if (strpos($key, 'sc:') === false || strpos($key, 'sc:') !== false && strpos($key, 'first-level-smp-occ-grid') !== false) { $standardGridValues[$key] = $values[$key]; } if (strpos($key, 'first-level-smp-occ-grid') !== false) { unset($values[$key]); } } //Identify any occurrences which don't have images and will therefore be attached to the top level sample. $standardOccurrences = data_entry_helper::wrap_species_checklist($standardGridValues); $modelName = 'sample'; //Wrap up the main parent sample $modelWrapped = data_entry_helper::wrap($values, $modelName, null); //2nd level samples are prefixed with the word new_sample_sub_sample:<num>: or existing_sample_sub_sample:<id>: in the name. //This function returns an array of possible sub-samples (habitats) which have been extracted from the values on the page by looking //for this text on the front of the keys in the values array. $possibleSubSampleModels = self::extract_sub_sample_data($values, $website_id, $password, $gpxDataAttrId); //Cycle through the sub-samples and then set them up as sub-samples of the main sample if (!empty($possibleSubSampleModels)) { foreach ($possibleSubSampleModels as $subSample) { $modelWrapped['subModels'][] = array('fkId' => 'sample_id', 'model' => $subSample); } } // Build sub-models for the sample media files. Also extract the image exif data $media = data_entry_helper::extract_media_data($values, $modelName . '_medium', true, true); if (function_exists('exif_read_data')) { $uploadpath = './sites/all/modules/iform/client_helpers/upload/'; foreach ($media as $idx => $mediaItem) { if (file_exists($uploadpath . $mediaItem['path'])) { $exif = exif_read_data($uploadpath . $mediaItem['path'], 0, true); $media[$idx]['exif'] = json_encode($exif); $strToTime = strtotime($exif['EXIF']['DateTimeOriginal']); $time = explode(' ', $exif['EXIF']['DateTimeOriginal']); //On the first tab (when we don't have a date field) then collect the date from the exif from the earliest photo //and also set a default on the time field in the same way //Cycle round the media items and only set the date/time if it is the smallest one so far. if ((empty($smallestStrToTime) || $smallestStrToTime > $strToTime) && !empty($exif['EXIF']['DateTimeOriginal']) && empty($modelWrapped['fields']['sample:date']['value'])) { $smallestStrToTime = $strToTime; $gpsFromFirstExif = $exif['GPS']; $modelWrapped['fields']['date']['value'] = date('d/m/Y', $smallestStrToTime); $values['sample:date'] = date('d/m/Y', $smallestStrToTime); $modelWrapped['fields']['smpAttr:' . $diveStartTimeAttrId]['value'] = $time[1]; $values['smpAttr:' . $diveStartTimeAttrid] = $time[1]; } //Save the dates and times from the photos into an attribute for easy access by javascript, so contruct a string to save first. //Note I didn't use json as that dates include colons. So the format is date,time;date,time;date,time;date,time;date,time; if (!empty($mediaDates)) { $mediaDates = $mediaDates . ';' . date('d/m/Y', $strToTime) . ',' . $time[1]; } else { $mediaDates = date('d/m/Y', $strToTime) . ',' . $time[1]; } } } //When the images are first loaded, we don't have a spatial reference to create the main sample with, so try to read one from the earliest picture exif data if (!empty($gpsFromFirstExif['GPSLatitude']) && !empty($gpsFromFirstExif['GPSLongitude']) && !empty($gpsFromFirstExif['GPSLatitudeRef']) && !empty($gpsFromFirstExif['GPSLongitudeRef'])) { //Read from exif, concert from degrees, minutes, seconds to decimal degrees $gpsLat0 = explode('/', $gpsFromFirstExif['GPSLatitude'][0]); $gpsLat0 = doubleval($gpsLat0[0]) / doubleval($gpsLat0[1]); $gpsLat1 = explode('/', $gpsFromFirstExif['GPSLatitude'][1]); $gpsLat1 = doubleval($gpsLat1[0]) / doubleval($gpsLat1[1]) / 60; $gpsLat2 = explode('/', $gpsFromFirstExif['GPSLatitude'][2]); $gpsLat2 = doubleval($gpsLat2[0]) / doubleval($gpsLat2[1]) / 3600; $gpsLon0 = explode('/', $gpsFromFirstExif['GPSLongitude'][0]); $gpsLon0 = doubleval($gpsLon0[0]) / doubleval($gpsLon0[1]); $gpsLon1 = explode('/', $gpsFromFirstExif['GPSLongitude'][1]); $gpsLon1 = doubleval($gpsLon1[0]) / doubleval($gpsLon1[1]) / 60; $gpsLon2 = explode('/', $gpsFromFirstExif['GPSLongitude'][2]); $gpsLon2 = doubleval($gpsLon2[0]) / doubleval($gpsLon2[1]) / 3600; $lat = (string) floatval($gpsLat0 + $gpsLat1 + $gpsLat2); $lon = (string) floatval($gpsLon0 + $gpsLon1 + $gpsLon2); //Convert back into format that is acceptable to the seasearch on screen spatial reference extension which is again in degrees, minutes $latArray = explode('.', $lat); $lat = $latArray[0] . ':' . round(floatval('0.' . $latArray[1]) * 60, 4); $lonArray = explode('.', $lon); $lon = $lonArray[0] . ':' . round(floatval('0.' . $lonArray[1]) * 60, 4); $gpsFromFirstExif = $lat . $gpsFromFirstExif['GPSLatitudeRef'] . ' ' . $lon . $gpsFromFirstExif['GPSLongitudeRef']; $modelWrapped['fields']['entered_sref']['value'] = $gpsFromFirstExif; $values['sample:entered_sref'] = $gpsFromFirstExif; $modelWrapped['fields']['entered_sref_system']['value'] = '4277'; $values['sample:entered_sref_system'] = '4277'; } } if (!empty($mediaDates)) { //Need to find the attribute that starts with smpAttr:<exifDateTimeAttrId> as in edit mode it will also have the sample_attribute_value on the end so in that //case we need to overwrite existing value instead of creating new one. foreach ($values as $theKey => $theValue) { if (substr($theKey, 0, strlen('smpAttr:' . $exifDateTimeAttrId)) === 'smpAttr:' . $exifDateTimeAttrId) { $modelWrapped['fields'][$theKey]['value'] = $mediaDates; $values[$theKey] = $mediaDates; } } } foreach ($media as $item) { //Only add media to the main sample if it isn't already contained in any sub-sample if (empty($values['sample_medium:' . $item['id'] . ':sample_id']) || $values['sample_medium:' . $item['id'] . ':sample_id'] == $modelWrapped['fields']['id']['value']) { $wrapped = data_entry_helper::wrap($item, $modelName . '_medium'); $modelWrapped['subModels'][] = array('fkId' => $modelName . '_id', 'model' => $wrapped); } } // Put any extra occurrences (without images) // the user has identified onto the end of the main sample model. if (array_key_exists('subModels', $modelWrapped)) { $modelWrapped['subModels'] = array_merge($modelWrapped['subModels'], $standardOccurrences); } else { $modelWrapped['subModels'] = $standardOccurrences; } //Create the third level samples with occurrences $modelWrapped = self::create_third_level_sample_model($modelWrapped, $values, $website_id, $password, $gpxDataAttrId); //The user is can rearrange which third level sample points to which second level sample. When the user does this we just need to attach the //change to the parent_id to the end of the submission model $thirdLevelSampleShiftModel = array(); foreach ($values as $key => $value) { //TODO I think this name is misleading, as it isn't the sample_id for the occurrence, it is the sample_id for the occurrence sample's parent sample. //Maybe change name at some point. if (strpos($key, 'occurrence_medium') !== false && strpos($key, ':sample_id') !== false) { $splitKey = explode(':', $key); $thirdLevelSampleShiftModel['id'] = 'sample'; $thirdLevelSampleShiftModel['fields']['id']['value'] = $splitKey[3]; $thirdLevelSampleShiftModel['fields']['parent_id']['value'] = $value; if (!empty($modelWrapped['submission_list']['entries'])) { $modelWrapped['submission_list']['entries'][] = $thirdLevelSampleShiftModel; } else { $multiSubmission['id'] = 'sample'; $multiSubmission['submission_list']['entries'][0] = $modelWrapped; $multiSubmission['submission_list']['entries'][1] = $thirdLevelSampleShiftModel; $modelWrapped = $multiSubmission; } } } return $modelWrapped; }
/** * Handles the construction of a submission array from a set of form values. * @param array $values Associative array of form data values. * @param array $args iform parameters. * @return array Submission structure. */ public static function get_submission($values, $args) { if (isset($values['sample:recorder_names'])) { if (is_array($values['sample:recorder_names'])) { $values['sample:recorder_names'] = implode("\r\n", $values['sample:recorder_names']); } } // else just load the string if (isset($values['gridmode'])) { $occurrences = data_entry_helper::wrap_species_checklist($values); } else { $occurrences = submission_builder::wrap_with_images($values, 'occurrence'); } // when a non admin selects an existing location they can not modify it or its attributes and the location record does not form part of the submission if (isset($values['location:name'])) { $sampleMod = submission_builder::wrap_with_images($values, 'sample'); if (count($occurrences) > 0) { $sampleMod['subModels'] = $occurrences; } $locationMod = submission_builder::wrap_with_images($values, 'location'); $locationMod['subModels'] = array(array('fkId' => 'location_id', 'model' => $sampleMod)); if (array_key_exists('locations_website:website_id', $_POST)) { $lw = submission_builder::wrap_with_images($values, 'locations_website'); $locationMod['subModels'][] = array('fkId' => 'location_id', 'model' => $lw); } return $locationMod; } $values['sample:location_id'] = $values['location:id']; $sampleMod = submission_builder::wrap_with_images($values, 'sample'); if (count($occurrences) > 0) { $sampleMod['subModels'] = $occurrences; } return $sampleMod; }
/** * Handles the construction of a submission array from a set of form values. * @param array $values Associative array of form data values. * @param array $args iform parameters. * @return array Submission structure. */ public static function get_submission($values, $args) { if (isset($values['source'])) { // comes from main Sites tab, Admins may create so need to check for locations_website entry $locModel = submission_builder::wrap_with_images($values, 'location'); if (isset($values['locations_website:website_id'])) { // assume no other submodels $locModel['subModels'] = array(array('fkId' => 'location_id', 'model' => array('id' => 'locations_website', 'fields' => array('website_id' => array('value' => $values['locations_website:website_id']))))); } return $locModel; } if (isset($values['sample:recorder_names'])) { if (is_array($values['sample:recorder_names'])) { $values['sample:recorder_names'] = implode("\r\n", $values['sample:recorder_names']); } } // else just load the string $sampleMod = submission_builder::wrap_with_images($values, 'sample'); if (!isset($values['sample:deleted'])) { if (isset($values['gridmode'])) { $occurrences = data_entry_helper::wrap_species_checklist($values); } else { $occurrences = submission_builder::wrap_with_images($values, 'occurrence'); } // when a non admin selects an existing location they can not modify it or its attributes and the location record does not form part of the submission if (isset($values['location:location_type_id'])) { if (count($occurrences) > 0) { $sampleMod['subModels'] = $occurrences; } $locationMod = submission_builder::wrap_with_images($values, 'location'); $locationMod['subModels'] = array(array('fkId' => 'location_id', 'model' => $sampleMod)); if (array_key_exists('locations_website:website_id', $_POST)) { $lw = submission_builder::wrap_with_images($values, 'locations_website'); $locationMod['subModels'][] = array('fkId' => 'location_id', 'model' => $lw); } return $locationMod; } // $values['sample:location_id'] = $values['location:id']; if (count($occurrences) > 0) { $sampleMod['subModels'] = $occurrences; } } return $sampleMod; }
/** * Builds the special submission format required for seasearch data * @param array $values * @param array $args * @return array * @throws \Exception */ public static function get_submission($values, $args) { // First, build an array of the field values for each habitat sample. $habitatSamples = array(); foreach ($values as $key => $value) { if (substr_count($key, ':') === 3) { $parts = explode(':', $key, 4); if ($parts[0] === 'smpAttr') { // If the last part of a habitat field is not a number, this is just a dummy field used // when cloning habitat controls. if (preg_match('/^\\d+$/', $parts[3])) { // habitat number is the last part of the attribute field name $id = array_pop($parts); if (!isset($habitatSamples["habitat{$id}"])) { $habitatSamples["habitat{$id}"] = array(); } // Skip empty new attribute values. if (!empty($parts[2]) || !empty($value)) { // remove empty stuff from the attribute name (e.g. an unused space for the existing value ID, if a new attribute value). while (empty($parts[count($parts) - 1])) { array_pop($parts); } $fieldname = implode(':', $parts); $habitatSamples["habitat{$id}"][$fieldname] = $value; } } unset($values[$key]); } } // Also check for habitat photos, attached to a fake table name indicating the habitat index if (preg_match('/^sample_medium(?P<id>\\d)/', $key, $matches)) { $parts = explode(':', $key); if (!isset($habitatSamples["habitat{$matches['id']}"])) { $habitatSamples["habitat{$matches['id']}"] = array(); } $parts[0] = 'sample_medium'; $habitatSamples["habitat{$matches['id']}"][implode(':', $parts)] = $value; } $parts = explode(':', $key); // For the group_name, the autocomplete functionality needs to be removed from the submission. // So copy the edit box into the underlying field which gets posted. if (array_pop($parts) === 'group_name') { $values[implode(':', $parts)] = $value; } } // Find the attribute which contains SACFORP habitat data. $readAuth = data_entry_helper::get_read_auth(variable_get('indicia_website_id'), variable_get('indicia_password')); $attributeOpts = array('valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => 'occAttr', 'extraParams' => $readAuth + array('caption' => 'SACFOR/P'), 'survey_id' => $args['survey_id']); $attributes = data_entry_helper::getAttributes($attributeOpts, false); $values['habitat-count'] = count($habitatSamples); $buddyPairSubmission = submission_builder::wrap_with_images($values, 'sample'); unset($buddyPairSubmission['fields']['habitat-count']); // Get the list of records implied by the SACFOR data for each habitat. At this point we'll create 1 big list and split // it across the habitats later. $occurrences = data_entry_helper::wrap_species_checklist($values, true, array(), array()); // now work out which habitat contains which occurrence $habitatOccurrences = array(); foreach (array_keys($habitatSamples) as $habitatId) { $habitatOccurrences[$habitatId] = array(); } foreach ($occurrences as $uniqueId => $occurrence) { // for existing occurrences, they are already linked to a sample via the SampleIDX field. if (!empty($occurrence['model']['fields']['sampleIDX'])) { $habitatOccurrences['habitat' . ($occurrence['model']['fields']['sampleIDX']['value'] + 1)][] = $occurrence; } else { // search the posted data for a habitat SACFOR value for the occurrence row foreach (array_keys($habitatSamples) as $habitatId) { $habitatIdx = str_replace('habitat', '', $habitatId); if (!empty($values["{$uniqueId}:habitat-{$habitatIdx}"])) { $thisOccurrence = array_merge($occurrence); $thisOccurrence['model']['fields'][$attributes[0]['fieldname']] = array('value' => $values["{$uniqueId}:habitat-{$habitatIdx}"]); $habitatOccurrences[$habitatId][] = $thisOccurrence; } } } } // now create the submodel data for each habitat. $buddyPairSubmission['subModels'] = array(); // copy the basic sample data into each set of habitat subsample values foreach ($habitatSamples as $habitatId => &$habitatSample) { $habitatIdx = str_replace('habitat', '', $habitatId); $habitatSample['website_id'] = $values['website_id']; $habitatSample['survey_id'] = $values['survey_id']; if (isset($_POST["habitat_sample_id:{$habitatIdx}"])) { $habitatSample['sample:id'] = $_POST["habitat_sample_id:{$habitatIdx}"]; } $habitatSample['sample:date'] = $values['sample:date']; $habitatSample['sample:entered_sref'] = $values['sample:entered_sref']; $habitatSample['sample:entered_sref_system'] = $values['sample:entered_sref_system']; $habitatSample['sample:input_form'] = $values['sample:input_form']; if (isset($_POST["sample:comment:{$habitatIdx}"])) { $habitatSample['sample:comment'] = $_POST["sample:comment:{$habitatIdx}"]; unset($buddyPairSubmission['fields']["comment:{$habitatIdx}"]); } $habitatSubmission = submission_builder::wrap_with_images($habitatSample, 'sample'); if (!isset($habitatSubmission['subModels'])) { $habitatSubmission['subModels'] = array(); } $habitatSubmission['subModels'] += $habitatOccurrences[$habitatId]; $buddyPairSubmission['subModels'][] = array('fkId' => 'parent_id', 'model' => $habitatSubmission); } return $buddyPairSubmission; }