/** * Wraps data from a species checklist grid: modified from original data_entry_helper * function to allow multiple rows for the same species. */ private static function wrap_species_checklist($arr, $include_if_any_data = false) { if (array_key_exists('website_id', $arr)) { $website_id = $arr['website_id']; } else { throw new Exception('Cannot find website id in POST array!'); } // Set the default method of looking for rows to include - either using data, or the checkbox (which could be hidden) $include_if_any_data = $include_if_any_data || isset($arr['rowInclusionCheck']) && $arr['rowInclusionCheck'] == 'hasData'; // Species checklist entries take the following format // sc:<taxa_taxon_list_id>:[<occurrence_id>|<sequence(negative)>]:occAttr:<occurrence_attribute_id>[:<occurrence_attribute_value_id>] // sc:<taxa_taxon_list_id>:[<occurrence_id>]:occurrence:comment // sc:<taxa_taxon_list_id>:[<occurrence_id>]:present // not doing occurrence images at this point - TBD $records = array(); $subModels = array(); foreach ($arr as $key => $value) { if (substr($key, 0, 3) == 'sc:') { // Don't explode the last element for occurrence attributes $a = explode(':', $key, 4); if ($a[2]) { $pos = strpos($a[1], '_'); $records[$a[2]]['taxa_taxon_list_id'] = $pos === false ? $a[1] : substr($a[1], 0, $pos); $records[$a[2]][$a[3]] = $value; // store any id so update existing record if (is_numeric($a[2])) { $records[$a[2]]['id'] = $a[2]; } } } } foreach ($records as $id => $record) { $present = self::wrap_species_checklist_record_present($record, $include_if_any_data); if (array_key_exists('id', $record) || $present) { // must always handle row if already present in the db if (!$present) { $record['deleted'] = 't'; } $record['website_id'] = $website_id; if (array_key_exists('occurrence:determiner_id', $arr)) { $record['determiner_id'] = $arr['occurrence:determiner_id']; } if (array_key_exists('occurrence:record_status', $arr)) { $record['record_status'] = $arr['occurrence:record_status']; } $occ = data_entry_helper::wrap($record, 'occurrence'); $subModels[] = array('fkId' => 'sample_id', 'model' => $occ); } } return $subModels; }
/** * Return the Indicia form code. * Expects there to be a sample attribute with caption 'Email' containing the email * address. * @param array $args Input parameters. * @param array $node Drupal node object * @param array $response Response from Indicia services after posting a verification. * @return HTML string */ public static function get_form($args, $node, $response) { global $user, $indicia_templates; // put each param control in a div, which makes it easier to layout with CSS $indicia_templates['prefix'] = '<div id="container-{fieldname}" class="param-container">'; $indicia_templates['suffix'] = '</div>'; $indicia_user_id = self::get_indicia_user_id($args); $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']); $r = ''; if ($_POST) { // dump out any errors that occurred on verification if (data_entry_helper::$validation_errors) { $r .= '<div class="page-notice ui-state-highlight ui-corner-all"><p>' . implode('</p></p>', array_values(data_entry_helper::$validation_errors)) . '</p></div>'; } else { if (isset($_POST['email']) && !isset($response['error'])) { // To send HTML mail, the Content-type header must be set $headers = 'MIME-Version: 1.0' . "\r\n"; $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n"; $headers .= 'From: ' . $user->mail . PHP_EOL . "\r\n"; $headers .= 'Return-Path: ' . $user->mail . "\r\n"; if (isset($_POST['photoHTML'])) { $emailBody = str_replace('[photo]', '<br/>' . $_POST['photoHTML'], $_POST['email_content']); } else { $emailBody = $_POST['email_content']; } $emailBody = str_replace("\n", "<br/>", $emailBody); // Send email. Depends upon settings in php.ini being correct $success = mail($_POST['email_to'], $_POST['email_subject'], wordwrap($emailBody, 70), $headers); if ($success) { $r .= '<div class="page-notice ui-state-highlight ui-corner-all"><p>An email was sent to ' . $_POST['email_to'] . '.</p></div>'; } else { $r .= '<div class="page-notice ui-widget-content ui-corner-all ui-state-highlight left">The webserver is not correctly configured to send emails. Please send the following email manually: <br/>' . '<div id="manual-email"><span>To:</span><div>' . $_POST['email_to'] . '</div>' . '<span>Subject:</span><div>' . $_POST['email_subject'] . '</div>' . '<span>Content:</span><div>' . $emailBody . '</div>' . '</div></div><div style="clear: both">'; } } else { if (isset($_POST['occurrence:record_status']) && isset($response['success']) && $args['emails_enabled']) { $r .= self::get_notification_email_form($args, $response, $auth); } } } if (isset($_POST['action']) && $_POST['action'] == 'send_to_verifier' && $args['log_send_to_verifier']) { $comment = str_replace(array('%email%', '%date%', '%user%'), array($_POST['email_to'], date('jS F Y'), $user->name), $args['log_send_to_verifier_comment']); } elseif (isset($_POST['action']) && ($_POST['action'] = 'general_comment')) { $comment = $_POST['comment']; } // If there is a comment to save, add it to the occurrence comments if (isset($comment)) { // get our own write tokens for this submission, as the main ones are used in the JavaScript form. $loggingAuth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']); $sub = data_entry_helper::wrap(array('comment' => $comment, 'occurrence_id' => $_POST['occurrence:id'], 'created_by_id' => $indicia_user_id), 'occurrence_comment'); $logResponse = data_entry_helper::forward_post_to('occurrence_comment', $sub, $loggingAuth['write_tokens']); if (!array_key_exists('success', $logResponse)) { $r .= data_entry_helper::dump_errors($response, false); } } } //extract fixed parameters for report grid. $params = explode(",", $args['fixed_params']); foreach ($params as $param) { $keyvals = explode("=", $param); $key = trim($keyvals[0]); $val = trim($keyvals[1]); $extraParams[$key] = $val; } // plus defaults which are not fixed $params = explode("\n", $args['param_defaults']); foreach ($params as $param) { $keyvals = explode("=", $param); $key = trim($keyvals[0]); $val = trim($keyvals[1]); $paramDefaults[$key] = $val; } $actions = array(); if ($args['send_for_verification']) { // store authorisation details as a global in js, since some of the JavaScript needs to be able to access Indicia data data_entry_helper::$javascript .= 'auth=' . json_encode($auth) . ';'; $actions[] = array('caption' => str_replace(' ', ' ', lang::get('Send to verifier')), 'class' => 'send_for_verification_btn', 'javascript' => 'indicia_send_to_verifier(\'{taxon}\', {occurrence_id}, ' . $user->uid . ', ' . $args['website_id'] . '); return false;'); $r .= self::get_send_for_verification_form(); } $actions[] = array('caption' => str_replace(' ', ' ', lang::get('Verify')), 'javascript' => 'indicia_verify(\'{taxon}\', {occurrence_id}, true, ' . $user->uid . '); return false;'); $actions[] = array('caption' => str_replace(' ', ' ', lang::get('Reject')), 'javascript' => 'indicia_verify(\'{taxon}\', {occurrence_id}, false, ' . $user->uid . '); return false;'); $actions[] = array('caption' => str_replace(' ', ' ', lang::get('Comments')), 'javascript' => 'indicia_comments(\'{taxon}\', {occurrence_id}, ' . $user->uid . ', \'' . $auth['read']['nonce'] . '\', \'' . $auth['read']['auth_token'] . '\'); return false;'); if (isset($args['path_to_record_details_page']) && $args['path_to_record_details_page']) { $actions[] = array('caption' => str_replace(' ', ' ', lang::get('View details')), 'url' => '{rootFolder}' . $args['path_to_record_details_page'], 'urlParams' => array('occurrence_id' => '{occurrence_id}')); } // default columns behaviour is to just include anything returned by the report plus add an actions column $columns = array(array('display' => 'Actions', 'actions' => $actions)); // this can be overridden if (isset($args['columns_config']) && !empty($args['columns_config'])) { $columns = array_merge(json_decode($args['columns_config'], true), $columns); } $r .= data_entry_helper::report_grid(array('id' => 'verification-grid', 'dataSource' => $args['report_name'], 'mode' => 'report', 'readAuth' => $auth['read'], 'columns' => $columns, 'rowId' => 'occurrence_id', 'itemsPerPage' => 10, 'autoParamsForm' => $args['auto_params_form'], 'extraParams' => $extraParams, 'paramDefaults' => $paramDefaults)); // Put in a blank form, which lets JavaScript set the values and post the data. $r .= ' <form id="verify" method="post" action=""> ' . $auth['write'] . ' <input type="hidden" id="occurrence:id" name="occurrence:id" value="" /> <input type="hidden" id="occurrence:record_status" name="occurrence:record_status" value="" /> <input type="hidden" id="occurrence_comment:comment" name="occurrence_comment:comment" value="" /> <input type="hidden" name="occurrence_comment:created_by_id" value="' . $indicia_user_id . '" /> <input type="hidden" id="website_id" name="website_id" value="' . $args['website_id'] . '" /> <input type="hidden" id="occurrence:verified_by_id" name="occurrence:verified_by_id" value="" /> </form> '; drupal_add_js(' var indicia_user_id = ' . $indicia_user_id . '; var url = ' . json_encode(data_entry_helper::get_reload_link_parts()) . '; var svc = "' . data_entry_helper::$base_url . 'index.php/services/data/"; var email_subject_send_to_verifier = "' . $args['email_subject_send_to_verifier'] . '"; var email_body_send_to_verifier = "' . str_replace(array("\r", "\n"), array('', '\\n'), $args['email_body_send_to_verifier']) . '"; ', 'inline'); /*.'; ');*/ return $r; }
<?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>
/** * Wraps data from a species checklist grid (generated by * data_entry_helper::species_checklist) into a suitable format for submission. This will * return an array of submodel entries which can be dropped directly into the subModel * section of the submission array. If there is a field occurrence:determiner_id or * occurrence:record_status in the main form data, then these values are applied to each * occurrence created from the grid. For example, place a hidden field in the form named * "occurrence:record_status" with a value "C" to set all occurrence records to completed * as soon as they are entered. * * @param array $arr Array of data generated by data_entry_helper::species_checklist method. * @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. */ public static function wrap_species_checklist($arr, $include_if_any_data = false) { if (array_key_exists('website_id', $arr)) { $website_id = $arr['website_id']; } else { throw new Exception('Cannot find website id in POST array!'); } // determiner and record status can be defined globally for the whole list. if (array_key_exists('occurrence:determiner_id', $arr)) { $determiner_id = $arr['occurrence:determiner_id']; } if (array_key_exists('occurrence:record_status', $arr)) { $record_status = $arr['occurrence:record_status']; } // Species checklist entries take the following format // sc:<taxa_taxon_list_id>:[<occurrence_id>]:occAttr:<occurrence_attribute_id>[:<occurrence_attribute_value_id>] // or // sc:<taxa_taxon_list_id>:[<occurrence_id>]:occurrence:comment // or // sc:<taxa_taxon_list_id>:[<occurrence_id>]:occurrence_image:fieldname:uniqueImageId $records = array(); $subModels = array(); foreach ($arr as $key => $value) { if (substr($key, 0, 3) == 'sc:') { // Don't explode the last element for occurrence attributes $a = explode(':', $key, 4); $records[$a[1]][$a[3]] = $value; // store any id so update existing record if ($a[2]) { $records[$a[1]]['id'] = $a[2]; } } } foreach ($records as $id => $record) { if (array_key_exists('present', $record) || array_key_exists('id', $record) || $include_if_any_data && implode('', $record) != '') { if (array_key_exists('id', $record) && array_key_exists('control:checkbox', $arr) && !array_key_exists('present', $record)) { // checkboxes do not appear if not checked. If uncheck, delete record. $record['deleted'] = 't'; } $record['taxa_taxon_list_id'] = $id; $record['website_id'] = $website_id; if (isset($determiner_id)) { $record['determiner_id'] = $determiner_id; } if (isset($record_status)) { $record['record_status'] = $record_status; } $occAttrs = data_entry_helper::wrap_attributes($record, 'occurrence'); $occ = data_entry_helper::wrap($record, 'occurrence'); $occ['metaFields']['occAttributes']['value'] = $occAttrs; self::attachOccurrenceImagesToModel($occ, $record); $subModels[] = array('fkId' => 'sample_id', 'model' => $occ); } } return $subModels; }
/** * Wraps data from a species checklist grid with subsamples (generated by * data_entry_helper::species_checklist) into a suitable format for submission. This will * return an array of submodel entries which can be dropped directly into the subModel * section of the submission array. If there is a field occurrence:determiner_id or * occurrence:record_status in the main form data, then these values are applied to each * occurrence created from the grid. For example, place a hidden field in the form named * "occurrence:record_status" with a value "C" to set all occurrence records to completed * as soon as they are entered. * * @param array $arr Array of data generated by data_entry_helper::species_checklist method. * @param boolean $include_if_any_data If true, then any list entry which has any data * set will be included in the submission. This defaults to false, unless the grid was * created with rowInclusionCheck=hasData in the grid options. * @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'). * @param array Array of grid ids to ignore when building sub-samples for occurrences, useful for creating * customised submissions that only need to build sub-samples for some grids. The grid id comes from the @id option given * to the species grid. */ public static function wrap_species_checklist_with_subsamples($arr, $include_if_any_data = false, $zero_attrs = true, $zero_values = array('0', 'None', 'Absent'), $gridsToExclude = array()) { if (array_key_exists('website_id', $arr)) { $website_id = $arr['website_id']; } else { throw new Exception('Cannot find website id in POST array!'); } // determiner and record status can be defined globally for the whole list. if (array_key_exists('occurrence:determiner_id', $arr)) { $determiner_id = $arr['occurrence:determiner_id']; } if (array_key_exists('occurrence:record_status', $arr)) { $record_status = $arr['occurrence:record_status']; } // Set the default method of looking for rows to include - either using data, or the checkbox (which could be hidden) $include_if_any_data = $include_if_any_data || isset($arr['rowInclusionCheck']) && $arr['rowInclusionCheck'] == 'hasData'; // Species checklist entries take the following format. // sc:<subsampleIndex>:[<sample_id>]:sample:deleted // sc:<subsampleIndex>:[<sample_id>]:sample:geom // sc:<subsampleIndex>:[<sample_id>]:sample:entered_sref // sc:<subsampleIndex>:[<sample_id>]:smpAttr:[<sample_attribute_id>] // sc:<rowIndex>:[<occurrence_id>]:occurrence:sampleIDX (val set to subsample index) // sc:<rowIndex>:[<occurrence_id>]:present (checkbox with val set to ttl_id // sc:<rowIndex>:[<occurrence_id>]:occAttr:<occurrence_attribute_id>[:<occurrence_attribute_value_id>] // sc:<rowIndex>:[<occurrence_id>]:occurrence:comment // sc:<rowIndex>:[<occurrence_id>]:occurrence_medium:fieldname:uniqueImageId $occurrenceRecords = array(); $sampleRecords = array(); $subModels = array(); foreach ($arr as $key => $value) { $gridExcluded = false; foreach ($gridsToExclude as $gridToExclude) { if (substr($key, 0, strlen($gridToExclude) + 3) == 'sc:' . $gridToExclude) { $gridExcluded = true; } } if ($gridExcluded === false && substr($key, 0, 3) == 'sc:' && substr($key, 2, 7) != ':-idx-:' && substr($key, 2, 3) != ':n:') { //discard the hidden cloneable rows // Don't explode the last element for occurrence attributes $a = explode(':', $key, 4); $b = explode(':', $a[3], 2); if ($b[0] == "sample" || $b[0] == "smpAttr") { $sampleRecords[$a[1]][$a[3]] = $value; if ($a[2]) { $sampleRecords[$a[1]]['id'] = $a[2]; } } else { $occurrenceRecords[$a[1]][$a[3]] = $value; if ($a[2]) { $occurrenceRecords[$a[1]]['id'] = $a[2]; } } } } foreach ($sampleRecords as $id => $sampleRecord) { $sampleRecords[$id]['occurrences'] = array(); } foreach ($occurrenceRecords as $id => $record) { $sampleIDX = $record['occurrence:sampleIDX']; unset($record['occurrence:sampleIDX']); $present = self::wrap_species_checklist_record_present($record, $include_if_any_data, $zero_attrs, $zero_values, array()); if (array_key_exists('id', $record) || $present !== null) { // must always handle row if already present in the db if ($present === null) { // checkboxes do not appear if not checked. If uncheck, delete record. $record['deleted'] = 't'; } else { $record['zero_abundance'] = $present ? 'f' : 't'; } $record['taxa_taxon_list_id'] = $record['present']; $record['website_id'] = $website_id; if (isset($determiner_id)) { $record['determiner_id'] = $determiner_id; } if (isset($record_status)) { $record['record_status'] = $record_status; } $occ = data_entry_helper::wrap($record, 'occurrence'); self::attachOccurrenceMediaToModel($occ, $record); $sampleRecords[$sampleIDX]['occurrences'][] = array('fkId' => 'sample_id', 'model' => $occ); } } foreach ($sampleRecords as $id => $sampleRecord) { $occs = $sampleRecord['occurrences']; unset($sampleRecord['occurrences']); $sampleRecord['website_id'] = $website_id; // copy essentials down to each subsample if (!empty($arr['survey_id'])) { $sampleRecord['survey_id'] = $arr['survey_id']; } if (!empty($arr['sample:date'])) { $sampleRecord['date'] = $arr['sample:date']; } if (!empty($arr['sample:entered_sref_system'])) { $sampleRecord['entered_sref_system'] = $arr['sample:entered_sref_system']; } if (!empty($arr['sample:location_name']) && empty($sampleRecord['location_name'])) { $sampleRecord['location_name'] = $arr['sample:location_name']; } if (!empty($arr['sample:input_form'])) { $sampleRecord['input_form'] = $arr['sample:input_form']; } $subSample = data_entry_helper::wrap($sampleRecord, 'sample'); // Add the subsample/soccurrences in as subModels without overwriting others such as a sample image if (array_key_exists('subModels', $subSample)) { $subSample['subModels'] = array_merge($sampleMod['subModels'], $occs); } else { $subSample['subModels'] = $occs; } $subModel = array('fkId' => 'parent_id', 'model' => $subSample); $copyFields = array(); if (!isset($sampleRecord['date'])) { $copyFields = array('date_start' => 'date_start', 'date_end' => 'date_end', 'date_type' => 'date_type'); } if (!isset($sampleRecord['survey_id'])) { $copyFields['survey_id'] = 'survey_id'; } if (count($copyFields) > 0) { $subModel['copyFields'] = $copyFields; } // from parent->to child $subModels[] = $subModel; } return $subModels; }
/** * 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) { $subsampleModels = array(); $read = array('nonce' => $values['read_nonce'], 'auth_token' => $values['read_auth_token']); if (!isset($values['page']) || $values['page'] == 'site') { // submitting the first page, with top level sample details // keep the first count date on a subsample for use later. // only create if a new sample: if existing, then this will already exist. if (isset($values['C1:sample:date']) && !isset($values['sample:id'])) { $sampleMethods = helper_base::get_termlist_terms(array('read' => $read), 'indicia:sample_methods', array('Timed Count Count')); $smp = array('fkId' => 'parent_id', 'model' => array('id' => 'sample', 'fields' => array('survey_id' => array('value' => $values['sample:survey_id']), 'website_id' => array('value' => $values['website_id']), 'date' => array('value' => $values['C1:sample:date']), 'sample_method_id' => array('value' => $sampleMethods[0]['id']))), 'copyFields' => array('entered_sref' => 'entered_sref', 'entered_sref_system' => 'entered_sref_system')); // 'copyFields' => array('date_start'=>'date_start','date_end'=>'date_end','date_type'=>'date_type')); $subsampleModels[] = $smp; } } else { if ($values['page'] == 'occurrences') { // at this point there is a parent supersample. // loop from 1 to numberOfCounts, or number of existing subsamples, whichever is bigger. $subSamples = data_entry_helper::get_population_data(array('table' => 'sample', 'extraParams' => $read + array('parent_id' => $values['sample:id']), 'nocache' => true)); for ($i = 1; $i <= max(count($subSamples), $args['numberOfCounts']); $i++) { if (isset($values['C' . $i . ':sample:id']) || isset($values['C' . $i . ':sample:date']) && $values['C' . $i . ':sample:date'] != '') { $subSample = array('website_id' => $values['website_id'], 'survey_id' => $values['sample:survey_id']); $occurrences = array(); $occModels = array(); foreach ($values as $field => $value) { $parts = explode(':', $field, 2); if ($parts[0] == 'C' . $i) { $subSample[$parts[1]] = $value; } if ($parts[0] == 'O' . $i) { $occurrences[$parts[1]] = $value; } } ksort($occurrences); foreach ($occurrences as $field => $value) { // have take off O<i> do is now <j>:<ttlid>:<occid>:<attrid>:<attrvalid> - sorted in <j> order $parts = explode(':', $field); $occurrence = array('website_id' => $values['website_id']); if ($parts[1] != '--ttlid--') { $occurrence['taxa_taxon_list_id'] = $parts[1]; } if ($parts[2] != '--occid--') { $occurrence['id'] = $parts[2]; } if ($value == '') { $occurrence['deleted'] = 't'; } else { if ($parts[4] == '--valid--') { $occurrence['occAttr:' . $parts[3]] = $value; } else { $occurrence['occAttr:' . $parts[3] . ':' . $parts[4]] = $value; } } if (array_key_exists('occurrence:determiner_id', $values)) { $occurrence['determiner_id'] = $values['occurrence:determiner_id']; } if (array_key_exists('occurrence:record_status', $values)) { $occurrence['record_status'] = $values['occurrence:record_status']; } if (isset($occurrence['id']) || !isset($occurrence['deleted'])) { $occ = data_entry_helper::wrap($occurrence, 'occurrence'); $occModels[] = array('fkId' => 'sample_id', 'model' => $occ); } } $smp = array('fkId' => 'parent_id', 'model' => data_entry_helper::wrap($subSample, 'sample'), 'copyFields' => array('entered_sref' => 'entered_sref', 'entered_sref_system' => 'entered_sref_system')); // from parent->to child if (!isset($subSample['sample:deleted']) && count($occModels) > 0) { $smp['model']['subModels'] = $occModels; } $subsampleModels[] = $smp; } } } } $sampleMod = submission_builder::build_submission($values, array('model' => 'sample')); if (count($subsampleModels) > 0) { $sampleMod['subModels'] = $subsampleModels; } return $sampleMod; }
/** * Return the generated form output. * @return Form HTML. */ public static function get_form($args, $node, $response = null) { global $user; global $custom_terms; $logged_in = $user->uid > 0; $r = ''; // Get authorisation tokens to update and read from the Warehouse. $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']); $readAuth = $auth['read']; $svcUrl = data_entry_helper::$base_url . '/index.php/services'; drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/jquery.form.js', 'module'); data_entry_helper::link_default_stylesheet(); data_entry_helper::add_resource('jquery_ui'); $language = iform_lang_iso_639_2($args['language']); if ($args['language'] != 'en') { data_entry_helper::add_resource('jquery_ui_' . $args['language']); } // If not logged in: Display an information message. // This form should only be called in POST mode when setting the location allocation. // All other posting is now done via AJAX. // When invoked by GET there are the following modes: // No additional arguments: mode 0. // Additional argument - new : mode 1. // Additional argument - sample_id=<id> : mode 2. // Additional argument - occurrence_id=<id> : mode 3. // Additional arguments - merge_sample_id1=<id>&merge_sample_id2=<id> : mode 2.1 $mode = 0; // default mode : output survey selector // mode 1: output the main Data Entry page: occurrence list or add/edit occurrence tabs hidden. "Survey" tab active // mode 2: output the main Data Entry page, display existing sample. Active tab determined by iform params. No occurence details filled in. // mode 2.1: sample 2 has all its occurrences merged into sample 1. sample 2 is then flagged as deleted. sample 1 is then viewed as in normal mode 2. // mode 3: output the main Data Entry page, display existing occurrence. "Edit Occurrence" tab active. Occurence details filled in. $surveyReadOnly = false; // On top of this, things can be flagged as readonly. RO mode 2+4 means no Add Occurrence tab. if (!$logged_in) { return lang::get('LANG_not_logged_in'); } $parentSample = array(); $parentLoadID = null; $childSample = array(); $childLoadID = null; $thisOccID = -1; // IDs have to be >0, so this is outside the valid range // Load up attribute details $sample_walk_direction_id = self::getAttrID($auth, $args, 'sample', self::ATTR_WALK); $sample_reliability_id = self::getAttrID($auth, $args, 'sample', self::ATTR_RELIABILITY); $sample_visit_number_id = self::getAttrID($auth, $args, 'sample', self::ATTR_VISIT); $sample_wind_id = self::getAttrID($auth, $args, 'sample', self::ATTR_WIND); $sample_precipitation_id = self::getAttrID($auth, $args, 'sample', self::ATTR_RAIN); $sample_temperature_id = self::getAttrID($auth, $args, 'sample', self::ATTR_TEMP); $sample_cloud_id = self::getAttrID($auth, $args, 'sample', self::ATTR_CLOUD); $sample_start_time_id = self::getAttrID($auth, $args, 'sample', self::ATTR_START_TIME); $sample_end_time_id = self::getAttrID($auth, $args, 'sample', self::ATTR_END_TIME); $sample_closure_id = self::getAttrID($auth, $args, 'sample', self::ATTR_CLOSED); $uid_attr_id = self::getAttrID($auth, $args, 'sample', self::ATTR_UID); $email_attr_id = self::getAttrID($auth, $args, 'sample', self::ATTR_EMAIL); $username_attr_id = self::getAttrID($auth, $args, 'sample', self::ATTR_USERNAME); $occurrence_confidence_id = self::getAttrID($auth, $args, 'occurrence', self::ATTR_CONFIDENCE); $occurrence_count_id = self::getAttrID($auth, $args, 'occurrence', self::ATTR_COUNT); $occurrence_approximation_id = self::getAttrID($auth, $args, 'occurrence', self::ATTR_APPROXIMATION); $occurrence_territorial_id = self::getAttrID($auth, $args, 'occurrence', self::ATTR_TERRITORIAL); $occurrence_atlas_code_id = self::getAttrID($auth, $args, 'occurrence', self::ATTR_ATLAS_CODE); $occurrence_overflying_id = self::getAttrID($auth, $args, 'occurrence', self::ATTR_OVERFLYING); if (!$sample_closure_id) { return '<p>This form must be used with a survey which has the "' . self::ATTR_CLOSED . '" sample attribute allocated to it. Survey_id = ' . $args['survey_id']; } if (!$uid_attr_id) { return '<p>This form must be used with a survey which has the "' . self::ATTR_UID . '" sample attribute allocated to it. Survey_id = ' . $args['survey_id']; } if (!$email_attr_id) { return '<p>This form must be used with a survey which has the "' . self::ATTR_EMAIL . '" sample attribute allocated to it. Survey_id = ' . $args['survey_id']; } if (!$username_attr_id) { return '<p>This form must be used with a survey which has the "' . self::ATTR_USERNAME . '" sample attribute allocated to it. Survey_id = ' . $args['survey_id']; } if (!$sample_walk_direction_id) { return '<p>This form must be used with a survey which has the "' . self::ATTR_WALK . '" sample attribute allocated to it. Survey_id = ' . $args['survey_id']; } if (!$sample_visit_number_id) { return '<p>This form must be used with a survey which has the "' . self::ATTR_VISIT . '" sample attribute allocated to it. Survey_id = ' . $args['survey_id']; } if (!$occurrence_count_id) { return '<p>This form must be used with a survey which has the "' . self::ATTR_COUNT . '" occurrence attribute allocated to it. Survey_id = ' . $args['survey_id']; } if (!$occurrence_territorial_id) { return '<p>This form must be used with a survey which has the "' . self::ATTR_TERRITORIAL . '" occurrence attribute allocated to it. Survey_id = ' . $args['survey_id']; } if (!$occurrence_atlas_code_id) { return '<p>This form must be used with a survey which has the "' . self::ATTR_ATLAS_CODE . '" occurrence attribute allocated to it. Survey_id = ' . $args['survey_id']; } if ($_POST) { if (!array_key_exists('website_id', $_POST)) { // non Indicia POST, in this case must be the location allocations. add check to ensure we don't corrept the data by accident if (iform_loctools_checkaccess($node, 'admin') && array_key_exists('mnhnlbtw', $_POST)) { iform_loctools_deletelocations($node); foreach ($_POST as $key => $value) { $parts = explode(':', $key); if ($parts[0] == 'location' && $value) { iform_loctools_insertlocation($node, $value, $parts[1]); } } } } } else { if (array_key_exists('merge_sample_id1', $_GET) && array_key_exists('merge_sample_id2', $_GET) && user_access($args['edit_permission'])) { $mode = 2; // first check can access the 2 samples given $parentLoadID = $_GET['merge_sample_id1']; $url = $svcUrl . '/data/sample/' . $parentLoadID . "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"]; $session = curl_init($url); curl_setopt($session, CURLOPT_RETURNTRANSFER, true); $entity = json_decode(curl_exec($session), true); if (count($entity) == 0 || $entity[0]["parent_id"]) { return '<p>' . lang::get('LANG_No_Access_To_Sample') . ' ' . $parentLoadID . '</p>'; } // The check for id2 is slightly different: there is the possiblity that someone will F5/refresh their browser, after the transfer and delete have taken place. // In this case we carry on, but do not do the transfer and delete. $url = $svcUrl . '/data/sample/' . $_GET['merge_sample_id2'] . "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"]; $session = curl_init($url); curl_setopt($session, CURLOPT_RETURNTRANSFER, true); $entity = json_decode(curl_exec($session), true); if (count($entity) > 0 && !$entity[0]["parent_id"]) { // now get child samples and point to new parent. $url = $svcUrl . '/data/sample?mode=json&view=detail&auth_token=' . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . '&parent_id=' . $_GET['merge_sample_id2']; $session = curl_init($url); curl_setopt($session, CURLOPT_RETURNTRANSFER, true); $entities = json_decode(curl_exec($session), true); if (count($entities) > 0) { foreach ($entities as $entity) { $Model = data_entry_helper::wrap(array('id' => $entity['id'], 'parent_id' => $_GET['merge_sample_id1']), 'sample'); $request = data_entry_helper::$base_url . "/index.php/services/data/save"; $postargs = 'submission=' . json_encode($Model) . '&auth_token=' . $auth['write_tokens']['auth_token'] . '&nonce=' . $auth['write_tokens']['nonce'] . '&persist_auth=true'; $postresponse = data_entry_helper::http_post($request, $postargs, false); // the response array will always feature an output, which is the actual response or error message. if it is not json format, assume error text, and json encode that. $response = $postresponse['output']; if (!json_decode($response, true)) { return "<p>" . lang::get('LANG_Error_When_Moving_Sample') . ": id " . $entity['id'] . " : " . $response; } } } // finally delete the no longer used sample $Model = data_entry_helper::wrap(array('id' => $_GET['merge_sample_id2'], 'deleted' => 'true'), 'sample'); $request = data_entry_helper::$base_url . "/index.php/services/data/save"; $postargs = 'submission=' . json_encode($Model) . '&auth_token=' . $auth['write_tokens']['auth_token'] . '&nonce=' . $auth['write_tokens']['nonce'] . '&persist_auth=true'; $postresponse = data_entry_helper::http_post($request, $postargs, false); // the response array will always feature an output, which is the actual response or error message. if it is not json format, assume error text, and json encode that. $response = $postresponse['output']; if (!json_decode($response, true)) { return "<p>" . lang::get('LANG_Error_When_Deleting_Sample') . ": id " . $entity['id'] . " : " . $response; } } } else { if (array_key_exists('sample_id', $_GET)) { $mode = 2; $parentLoadID = $_GET['sample_id']; } else { if (array_key_exists('occurrence_id', $_GET)) { $mode = 3; $childLoadID = $_GET['occurrence_id']; $thisOccID = $childLoadID; } else { if (array_key_exists('new', $_GET)) { $mode = 1; } } } } // else default to mode 0 } // define language strings so they can be used for validation translation. data_entry_helper::$javascript .= "var translations = [\n"; foreach ($custom_terms as $key => $value) { if (substr($key, 0, 4) != "LANG") { data_entry_helper::$javascript .= " {key: \"" . $key . "\", translated: \"" . $value . "\"},\n"; } } data_entry_helper::$javascript .= "];\n"; // define layers for all maps. // each argument is a comma separated list eg: // "Name:Lux Outline,URL:http://localhost/geoserver/wms,LAYERS:indicia:nation2,SRS:EPSG:2169,FORMAT:image/png,minScale:0,maxScale:1000000,units:m"; $optionsArray_Location = array(); $options = explode(',', $args['locationLayer']); foreach ($options as $option) { $parts = explode(':', $option); $optionName = $parts[0]; unset($parts[0]); $optionsArray_Location[$optionName] = implode(':', $parts); } // Work out list of locations this user can see. $locations = iform_loctools_listlocations($node); if ($locations != 'all') { data_entry_helper::$javascript .= "var locationList = [" . implode(',', $locations) . "];\n"; } drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/hasharray.js', 'module'); drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/jquery.datagrid.js', 'module'); if (method_exists(get_called_class(), 'getHeaderHTML')) { $r .= call_user_func(array(get_called_class(), 'getHeaderHTML'), $args); } // Work out list of locations this user can see. // $locations = iform_loctools_listlocations($node); /////////////////////////////////////////////////////////////////// // default mode 0 : display a page with tabs for survey selector, // locations allocator and reports (last two require permissions) /////////////////////////////////////////////////////////////////// if ($mode == 0) { // If the user has permissions, add tabs so can choose to see // locations allocator $tabs = array('#surveyList' => lang::get('LANG_Surveys')); if (iform_loctools_checkaccess($node, 'admin')) { $tabs['#setLocations'] = lang::get('LANG_Allocate_Locations'); } if (iform_loctools_checkaccess($node, 'superuser')) { $tabs['#downloads'] = lang::get('LANG_Download'); } if (count($tabs) > 1) { $r .= "<div id=\"controls\">" . data_entry_helper::enable_tabs(array('divId' => 'controls', 'active' => '#surveyList')) . "<div id=\"temp\"></div>"; $r .= data_entry_helper::tab_header(array('tabs' => $tabs)); } if ($locations == 'all') { $useloclist = 'NO'; $loclist = '-1'; } else { // an empty list will cause an sql error, lids must be > 0, so push a -1 to prevent the error. if (empty($locations)) { $locations[] = -1; } $useloclist = 'YES'; $loclist = implode(',', $locations); } // Create the Survey list datagrid for this user. drupal_add_js("jQuery(document).ready(function(){\n \$('div#smp_grid').indiciaDataGrid('rpt:reports_for_prebuilt_forms/MNHNL/mnhnl_btw_list_samples', {\n indiciaSvc: '" . $svcUrl . "',\n dataColumns: ['location_name', 'date', 'num_visit', 'num_occurrences', 'num_taxa'],\n reportColumnTitles: {location_name : '" . lang::get('LANG_Transect') . "', date : '" . lang::get('LANG_Date') . "', num_visit : '" . lang::get('LANG_Visit_No') . "', num_occurrences : '" . lang::get('LANG_Num_Occurrences') . "', num_taxa : '" . lang::get('LANG_Num_Species') . "'},\n actionColumns: {" . lang::get('LANG_Show') . " : \"" . url('node/' . $node->nid, array('query' => 'sample_id=£id£')) . "\"},\n auth : { nonce : '" . $readAuth['nonce'] . "', auth_token : '" . $readAuth['auth_token'] . "'},\n parameters : { survey_id : '" . $args['survey_id'] . "', visit_attr_id : '" . $sample_visit_number_id . "', closed_attr_id : '" . $sample_closure_id . "', use_location_list : '" . $useloclist . "', locations : '" . $loclist . "'},\n itemsPerPage : 12,\n condCss : {field : 'closed', value : '0', css: 'mnhnl-btw-highlight'},\n cssOdd : ''\n });\n});\n ", 'inline'); data_entry_helper::$javascript .= "\n// Create Layers.\nvar locationListLayer;\nmapInitialisationHooks.push(function (div) {\n \"use strict\";"; if ($locations == 'all' || $loclist != '-1') { data_entry_helper::$javascript .= "\n var WMSoptions = {SERVICE: 'WMS', VERSION: '1.1.0', STYLES: '',\n SRS: div.map.projection.proj.srsCode, /* Now takes it from map */\n FORMAT: '" . $optionsArray_Location['FORMAT'] . "',\n TRANSPARENT: 'true', "; if ($locations != 'all') { // when given a restricted feature list we have to use the feature id to filter in order to not go over 2000 char limit on the URL // Can only generate the feature id if we access a table directly, not through a view. Go direct to the locations table. // don't need to worry about parent_id in this case as we know exactly which features we want. // need to use btw_transects view for unrestricted so we can filter by parent_id=NULL. $locFeatures = array(); foreach ($locations as $location) { $locFeatures[] = "locations." . $location; } data_entry_helper::$javascript .= "\n LAYERS: 'indicia:locations',\n FEATUREID: '" . implode(',', $locFeatures) . "'"; } else { data_entry_helper::$javascript .= " LAYERS: '" . $optionsArray_Location['LAYERS'] . "', CQL_FILTER: 'website_id=" . $args['website_id'] . "'"; } data_entry_helper::$javascript .= "\n };\n locationListLayer = new OpenLayers.Layer.WMS('" . $optionsArray_Location['Name'] . "',\n '" . (function_exists(iform_proxy_url) ? iform_proxy_url($optionsArray_Location['URL']) : $optionsArray_Location['URL']) . "',\n WMSoptions, {\n minScale: " . $optionsArray_Location['minScale'] . ",\n maxScale: " . $optionsArray_Location['maxScale'] . ",\n units: '" . $optionsArray_Location['units'] . "',\n isBaseLayer: false,\n singleTile: true\n });\n div.map.addLayer(locationListLayer);\n});\n"; } $r .= ' <div id="surveyList" class="mnhnl-btw-datapanel"><div id="smp_grid"></div> <form><input type="button" value="' . lang::get('LANG_Add_Survey') . '" onclick="window.location.href=\'' . url('node/' . $node->nid, array('query' => 'new')) . '\'"></form></div>'; // Add the locations allocator if user has admin rights. if (iform_loctools_checkaccess($node, 'admin')) { $r .= ' <div id="setLocations" class="mnhnl-btw-datapanel"> <form method="post"> <input type="hidden" id="mnhnlbtw" name="mnhnlbtw" value="mnhnlbtw" />'; $url = $svcUrl . '/data/location?mode=json&view=detail&auth_token=' . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . "&parent_id=NULL&orderby=name&columns=id,name,parent_id"; $session = curl_init($url); curl_setopt($session, CURLOPT_RETURNTRANSFER, true); $entities = json_decode(curl_exec($session), true); $userlist = iform_loctools_listusers($node); if (!empty($entities)) { foreach ($entities as $entity) { if (!$entity["parent_id"]) { // only assign parent locations. $r .= "\n<label for=\"location:" . $entity["id"] . "\">" . $entity["name"] . ":</label><select id=\"location:" . $entity["id"] . "\" name=\"location:" . $entity["id"] . "\"><option value=\"\" ><" . lang::get('LANG_Not_Allocated') . "></option>"; $defaultuserid = iform_loctools_getuser($node, $entity["id"]); foreach ($userlist as $uid => $a_user) { $r .= "<option value=\"" . $uid . "\" " . ($uid == $defaultuserid ? 'selected="selected" ' : '') . ">" . $a_user->name . "</option>"; } $r .= "</select>"; } } } $r .= "\n <input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('Save Location Allocations') . "\" />\n </form>\n </div>"; } // Add the downloader if user has manager (superuser) rights. if (iform_loctools_checkaccess($node, 'superuser')) { $r .= ' <div id="downloads" class="mnhnl-btw-datapanel"> <form method="post" action="' . data_entry_helper::$base_url . '/index.php/services/report/requestReport?report=reports_for_prebuilt_forms/MNHNL/mnhnl_btw_transect_direction_report.xml&reportSource=local&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth['nonce'] . '&mode=csv"> <p>' . lang::get('LANG_Direction_Report') . '</p> <input type="hidden" name="params" value=\'{"survey_id":' . $args['survey_id'] . ', "direction_attr_id":' . $sample_walk_direction_id . ', "closed_attr_id":' . $sample_closure_id . '}\' /> <input type="submit" class="ui-state-default ui-corner-all" value="' . lang::get('LANG_Direction_Report_Button') . '"> </form> <form method="post" action="' . data_entry_helper::$base_url . '/index.php/services/report/requestReport?report=reports_for_prebuilt_forms/MNHNL/mnhnl_btw_verified_data_report.xml&reportSource=local&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth['nonce'] . '&mode=csv"> <p>' . lang::get('LANG_Verified_Data_Report') . '</p> <input type="hidden" name="params" value=\'{"survey_id":' . $args['survey_id'] . '}\' /> <input type="submit" class="ui-state-default ui-corner-all" value="' . lang::get('LANG_Verified_Data_Report_Button') . '"> </form> <form method="post" action="' . data_entry_helper::$base_url . '/index.php/services/report/requestReport?report=reports_for_prebuilt_forms/MNHNL/mnhnl_btw_download_report_2.xml&reportSource=local&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth['nonce'] . '&mode=csv"> <p>' . lang::get('LANG_Initial_Download') . '</p> <input type="hidden" name="params" value=\'{"survey_id":' . $args['survey_id'] . ', "closed_attr_id":' . $sample_closure_id . ', "download": "INITIAL", "quality": "!R", "occattrs": "' . $occurrence_confidence_id . ',' . $occurrence_count_id . ',' . $occurrence_approximation_id . ',' . $occurrence_territorial_id . ',' . $occurrence_atlas_code_id . ',' . $occurrence_overflying_id . '", "smpattrs" : "' . $sample_walk_direction_id . ',' . $sample_reliability_id . ',' . $sample_visit_number_id . ',' . $sample_wind_id . ',' . $sample_precipitation_id . ',' . $sample_temperature_id . ',' . $sample_cloud_id . ',' . $sample_start_time_id . ',' . $sample_end_time_id . ',' . $sample_closure_id . ',' . $uid_attr_id . ',' . $email_attr_id . ',' . $username_attr_id . '"}\' /> <input type="submit" class="ui-state-default ui-corner-all" value="' . lang::get('LANG_Initial_Download_Button') . '"> </form> <form method="post" action="' . data_entry_helper::$base_url . '/index.php/services/report/requestReport?report=reports_for_prebuilt_forms/MNHNL/mnhnl_btw_download_report_2.xml&reportSource=local&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth['nonce'] . '&mode=csv"> <p>' . lang::get('LANG_Confirm_Download') . '</p> <input type="hidden" name="params" value=\'{"survey_id":' . $args['survey_id'] . ', "closed_attr_id":' . $sample_closure_id . ', "download": "CONFIRM", "quality": "V", "occattrs": "' . $occurrence_confidence_id . ',' . $occurrence_count_id . ',' . $occurrence_approximation_id . ',' . $occurrence_territorial_id . ',' . $occurrence_atlas_code_id . ',' . $occurrence_overflying_id . '", "smpattrs" : "' . $sample_walk_direction_id . ',' . $sample_reliability_id . ',' . $sample_visit_number_id . ',' . $sample_wind_id . ',' . $sample_precipitation_id . ',' . $sample_temperature_id . ',' . $sample_cloud_id . ',' . $sample_start_time_id . ',' . $sample_end_time_id . ',' . $sample_closure_id . ',' . $uid_attr_id . ',' . $email_attr_id . ',' . $username_attr_id . '"}\' /> <input type="submit" class="ui-state-default ui-corner-all" value="' . lang::get('LANG_Confirm_Download_Button') . '"> </form> <form method="post" action="' . data_entry_helper::$base_url . '/index.php/services/report/requestReport?report=reports_for_prebuilt_forms/MNHNL/mnhnl_btw_download_report_2.xml&reportSource=local&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth['nonce'] . '&mode=csv"> <p>' . lang::get('LANG_Final_Download') . '</p> <input type="hidden" name="params" value=\'{"survey_id":' . $args['survey_id'] . ', "closed_attr_id":' . $sample_closure_id . ', "download": "FINAL", "quality": "V", "occattrs": "' . $occurrence_confidence_id . ',' . $occurrence_count_id . ',' . $occurrence_approximation_id . ',' . $occurrence_territorial_id . ',' . $occurrence_atlas_code_id . ',' . $occurrence_overflying_id . '", "smpattrs" : "' . $sample_walk_direction_id . ',' . $sample_reliability_id . ',' . $sample_visit_number_id . ',' . $sample_wind_id . ',' . $sample_precipitation_id . ',' . $sample_temperature_id . ',' . $sample_cloud_id . ',' . $sample_start_time_id . ',' . $sample_end_time_id . ',' . $sample_closure_id . ',' . $uid_attr_id . ',' . $email_attr_id . ',' . $username_attr_id . '"}\' /> <input type="submit" class="ui-state-default ui-corner-all" value="' . lang::get('LANG_Final_Download_Button') . '"> </form> <form method="post" action="' . data_entry_helper::$base_url . '/index.php/services/report/requestReport?report=reports_for_prebuilt_forms/MNHNL/mnhnl_btw_download_report_2.xml&reportSource=local&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth['nonce'] . '&mode=csv"> <p>' . lang::get('LANG_Complete_Final_Download') . '</p> <input type="hidden" name="params" value=\'{"survey_id":' . $args['survey_id'] . ', "closed_attr_id":' . $sample_closure_id . ', "download": "OFF", "quality": "NA", "occattrs": "' . $occurrence_confidence_id . ',' . $occurrence_count_id . ',' . $occurrence_approximation_id . ',' . $occurrence_territorial_id . ',' . $occurrence_atlas_code_id . ',' . $occurrence_overflying_id . '", "smpattrs" : "' . $sample_walk_direction_id . ',' . $sample_reliability_id . ',' . $sample_visit_number_id . ',' . $sample_wind_id . ',' . $sample_precipitation_id . ',' . $sample_temperature_id . ',' . $sample_cloud_id . ',' . $sample_start_time_id . ',' . $sample_end_time_id . ',' . $sample_closure_id . ',' . $uid_attr_id . ',' . $email_attr_id . ',' . $username_attr_id . '"}\' /> <input type="submit" class="ui-state-default ui-corner-all" value="' . lang::get('LANG_Complete_Final_Download_Button') . '"> </form> </div>'; } // Create Map $options = iform_map_get_map_options($args, $readAuth); $olOptions = iform_map_get_ol_options($args); // if($locations == 'all' || $loclist != '-1') // $options['layers'] = array('locationListLayer'); $options['searchLayer'] = 'false'; $options['editLayer'] = 'false'; $options['initialFeatureWkt'] = null; $options['proxy'] = ''; $options['scroll_wheel_zoom'] = false; $options['width'] = 'auto'; // TBD remove from arglist $r .= "<div class=\"mnhnl-btw-mappanel\">\n" . data_entry_helper::map_panel($options, $olOptions) . "</div>\n"; data_entry_helper::$javascript .= "\n\$('#controls').bind('tabsshow', function(event, ui) {\n var y = \$('.mnhnl-btw-datapanel:visible').outerHeight(true) + \$('.mnhnl-btw-datapanel:visible').position().top;\n if(y < \$('.mnhnl-btw-mappanel').outerHeight(true)+ \$('.mnhnl-btw-mappanel').position().top){\n y = \$('.mnhnl-btw-mappanel').outerHeight(true)+ \$('.mnhnl-btw-mappanel').position().top;\n }\n \$('#controls').height(y - \$('#controls').position().top);\n});\n"; if (count($tabs) > 1) { // close tabs div if present $r .= "</div>"; } if (method_exists(get_called_class(), 'getTrailerHTML')) { $r .= call_user_func(array(get_called_class(), 'getTrailerHTML'), $args); } return $r; } /////////////////////////////////////////////////////////////////// // At this point there are 3 modes: // Adding a new survey // editing/showing an existing survey // editing/showing an existing occurrence // First load the occurrence (and its position sample) if provided // Then load the parent sample if provided, or derived from occurrence. // $occReadOnly is set if the occurrence has been downloaded. Not even an admin user can modify it in this case. data_entry_helper::$javascript .= "\n// Create Layers.\nvar locationLayer, occListLayer, control;\nmapInitialisationHooks.push(function (div) {\n \"use strict\";\n // Create vector layers: one to display the location onto, and another for the occurrence list\n // the default edit layer is used for the occurrences themselves\n var locStyleMap = new OpenLayers.StyleMap({\n 'default': new OpenLayers.Style({\n fillColor: 'Green',\n strokeColor: 'Black',\n fillOpacity: 0.2,\n strokeWidth: 1\n })});\n locationLayer = new OpenLayers.Layer.Vector('" . lang::get("LANG_Location_Layer") . "', {styleMap: locStyleMap});\n var occStyleMap = new OpenLayers.StyleMap({\n 'default': new OpenLayers.Style({\n pointRadius: 3,\n fillColor: 'Red',\n fillOpacity: 0.3,\n strokeColor: 'Red',\n strokeWidth: 1\n })});\n occListLayer = new OpenLayers.Layer.Vector(\"" . lang::get("LANG_Occurrence_List_Layer") . "\", {styleMap: occStyleMap});\n div.map.addLayer(locationLayer);\n div.map.addLayer(occListLayer);\n var control = new OpenLayers.Control.SelectFeature(occListLayer);\n occListLayer.map.addControl(control);\n function onPopupClose(evt) {\n // 'this' is the popup.\n control.unselect(this.feature);\n }\n function onFeatureSelect(evt) {\n feature = evt.feature;\n popup = new OpenLayers.Popup.FramedCloud(\"featurePopup\",\n feature.geometry.getBounds().getCenterLonLat(),\n new OpenLayers.Size(100,100),\n feature.attributes.taxon + \" (\" + feature.attributes.count + \")\",\n null, true, onPopupClose);\n feature.popup = popup;\n popup.feature = feature;\n feature.layer.map.addPopup(popup);\n }\n function onFeatureUnselect(evt) {\n feature = evt.feature;\n if (feature.popup) {\n popup.feature = null;\n feature.layer.map.removePopup(feature.popup);\n feature.popup.destroy();\n feature.popup = null;\n }\n }\n occListLayer.events.on({\n 'featureselected': onFeatureSelect,\n 'featureunselected': onFeatureUnselect\n });\n control.activate();\n});\n"; $occReadOnly = false; $childSample = array(); if ($childLoadID) { // load the occurrence and its associated sample (which holds the position) $url = $svcUrl . '/data/occurrence/' . $childLoadID; $url .= "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"]; $session = curl_init($url); curl_setopt($session, CURLOPT_RETURNTRANSFER, true); $entity = json_decode(curl_exec($session), true); if (count($entity) == 0) { return '<p>' . lang::get('LANG_No_Access_To_Occurrence') . '</p>'; } foreach ($entity[0] as $key => $value) { $childSample['occurrence:' . $key] = $value; } if ($entity[0]['downloaded_flag'] == 'F') { // Final download complete, now readonly $occReadOnly = true; } $url = $svcUrl . '/data/sample/' . $childSample['occurrence:sample_id']; $url .= "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"]; $session = curl_init($url); curl_setopt($session, CURLOPT_RETURNTRANSFER, true); $entity = json_decode(curl_exec($session), true); if (count($entity) == 0) { return '<p>' . lang::get('LANG_No_Access_To_Occurrence') . '</p>'; } foreach ($entity[0] as $key => $value) { $childSample['sample:' . $key] = $value; } $childSample['sample:geom'] = ''; // value received from db is not WKT, which is assumed by all the code. $childSample['taxon'] = $childSample['occurrence:taxon']; $parentLoadID = $childSample['sample:parent_id']; } $parentSample = array(); if ($parentLoadID) { // load the container master sample $url = $svcUrl . '/data/sample/' . $parentLoadID; $url .= "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"]; $session = curl_init($url); curl_setopt($session, CURLOPT_RETURNTRANSFER, true); $entity = json_decode(curl_exec($session), true); if (count($entity) == 0) { return '<p>' . lang::get('LANG_No_Access_To_Sample') . '</p>'; } foreach ($entity[0] as $key => $value) { $parentSample['sample:' . $key] = $value; } if (is_array($locations) && !in_array($entity[0]["location_id"], $locations)) { return '<p>' . lang::get('LANG_No_Access_To_Location') . '</p>'; } if ($entity[0]["parent_id"]) { return '<p>' . lang::get('LANG_No_Access_To_Sample') . '</p>'; } $parentSample['sample:date'] = $parentSample['sample:date_start']; // bit of a bodge $childSample['sample:date'] = $parentSample['sample:date']; // enforce a match between child and parent sample dates // default values for attributes from DB are picked up automatically. } data_entry_helper::$entity_to_load = $parentSample; $attributes = data_entry_helper::getAttributes(array('id' => data_entry_helper::$entity_to_load['sample:id'], 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $readAuth)); $closedFieldName = $attributes[$sample_closure_id]['fieldname']; $closedFieldValue = data_entry_helper::check_default_value($closedFieldName, array_key_exists('default', $attributes[$sample_closure_id]) ? $attributes[$sample_closure_id]['default'] : '0'); // default is not closed if ($closedFieldValue == '') { $closedFieldValue = '0'; } if ($closedFieldValue == '1' && !user_access($args['edit_permission'])) { // sample has been closed, no admin perms. Everything now set to read only. $surveyReadOnly = true; $disabledText = "disabled=\"disabled\""; $defAttrOptions = array('extraParams' => $readAuth, 'disabled' => $disabledText); } else { // sample editable. Admin users can modify closed samples. $disabledText = ""; $defAttrOptions = array('extraParams' => $readAuth); } // with the AJAX code, we deal with the validation semi manually: Form name is meant be invalid as we only want code included. data_entry_helper::enable_validation(null); $r .= "<div id=\"controls\">\n"; $activeTab = 'survey'; // mode 1 = new Sample, display sample. if ($mode == 2) { // have specified a sample ID if ($args["on_edit_survey_nav"] == "survey") { $activeTab = 'survey'; } else { if ($surveyReadOnly || $args["on_edit_survey_nav"] == "list") { $activeTab = 'occurrenceList'; } else { $activeTab = 'occurrence'; } } if ($surveyReadOnly) { data_entry_helper::$javascript .= "jQuery('#occ-form').hide();"; } } else { if ($mode == 3) { // have specified an occurrence ID $activeTab = 'occurrence'; } } // Set Up form tabs. $r .= data_entry_helper::enable_tabs(array('divId' => 'controls', 'active' => $activeTab)); $r .= "<div id=\"temp\"></div>"; $r .= data_entry_helper::tab_header(array('tabs' => array('#survey' => lang::get('LANG_Survey'), '#occurrence' => lang::get($surveyReadOnly || $occReadOnly ? 'LANG_Show_Occurrence' : (isset($childSample['sample:id']) ? 'LANG_Edit_Occurrence' : 'LANG_Add_Occurrence')), '#occurrenceList' => lang::get('LANG_Occurrence_List')))); // Set up main Survey Form. $r .= "<div id=\"survey\" class=\"mnhnl-btw-datapanel\">\n <p id=\"read-only-survey\"><strong>" . lang::get('LANG_Read_Only_Survey') . "</strong></p>"; if (user_access($args['edit_permission']) && array_key_exists('sample:id', data_entry_helper::$entity_to_load)) { // check for other surveys of same date/transect: only if admin user. $url = $svcUrl . '/data/sample?mode=json&view=detail&auth_token=' . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . "&date_start=" . $parentSample['sample:date_start'] . "&location_id=" . $parentSample['sample:location_id']; $session = curl_init($url); curl_setopt($session, CURLOPT_RETURNTRANSFER, true); $entity = json_decode(curl_exec($session), true); if (count($entity) > 1) { // ignore ourselves! $r .= "<div id=\"mergeSurveys\"><p><strong>" . lang::get('LANG_Found_Mergable_Surveys') . "</strong></p>"; foreach ($entity as $survey) { if ($survey['id'] != $parentSample['sample:id']) { $r .= "<form action=\"" . url('node/' . $node->nid, array()) . "\" method=\"get\"><input type=\"submit\" value=\"" . lang::get('LANG_Merge_With_ID') . " " . $survey['id'] . "\"><input type=\"hidden\" name=\"merge_sample_id1\" value=\"" . $parentSample['sample:id'] . "\" /><input type=\"hidden\" name=\"merge_sample_id2\" value=\"" . $survey['id'] . "\" /></form>"; } } $r .= "</div>"; } } $r .= "<form id=\"SurveyForm\" action=\"" . iform_ajaxproxy_url($node, 'sample') . "\" method=\"post\">\n <input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n <input type=\"hidden\" id=\"sample:survey_id\" name=\"sample:survey_id\" value=\"" . $args['survey_id'] . "\" />"; if (array_key_exists('sample:id', data_entry_helper::$entity_to_load)) { $r .= "<input type=\"hidden\" id=\"sample:id\" name=\"sample:id\" value=\"" . data_entry_helper::$entity_to_load['sample:id'] . "\" />\n"; } else { $r .= "<input type=\"hidden\" id=\"sample:id\" name=\"sample:id\" value=\"\" disabled=\"disabled\" />\n"; // GvB 19/Nov/2012 : change to user detail defaults // logic is now much simpler, and they are only included/created if the sample is new. $fieldName = $attributes[$uid_attr_id]['fieldname']; $fieldValue = data_entry_helper::check_default_value($fieldName, $user->uid); $r .= "<input type=\"hidden\" name=\"" . $fieldName . "\" value=\"" . $fieldValue . "\" />\n"; $fieldName = $attributes[$email_attr_id]['fieldname']; $fieldValue = data_entry_helper::check_default_value($fieldName, $user->mail); $r .= "<input type=\"hidden\" name=\"" . $fieldName . "\" value=\"" . $fieldValue . "\" />\n"; $fieldName = $attributes[$username_attr_id]['fieldname']; $fieldValue = data_entry_helper::check_default_value($fieldName, $user->name); $r .= "<input type=\"hidden\" name=\"" . $fieldName . "\" value=\"" . $fieldValue . "\" />\n"; } $defAttrOptions['validation'] = array('required'); if ($locations == 'all') { $locOptions = array_merge(array('label' => lang::get('LANG_Transect')), $defAttrOptions); $locOptions['extraParams'] = array_merge(array('parent_id' => 'NULL', 'view' => 'detail', 'orderby' => 'name'), $locOptions['extraParams']); $r .= data_entry_helper::location_select($locOptions); } else { // can't use location select due to location filtering. $r .= "<label for=\"imp-location\">" . lang::get('LANG_Transect') . ":</label>\n<select id=\"imp-location\" name=\"sample:location_id\" " . $disabled_text . " class=\" \" >"; $url = $svcUrl . '/data/location?mode=json&view=detail&parent_id=NULL&orderby=name&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth["nonce"]; $session = curl_init($url); curl_setopt($session, CURLOPT_RETURNTRANSFER, true); $entities = json_decode(curl_exec($session), true); if (!empty($entities)) { foreach ($entities as $entity) { if (in_array($entity["id"], $locations)) { if ($entity["id"] == data_entry_helper::$entity_to_load['sample:location_id']) { $selected = 'selected="selected"'; } else { $selected = ''; } $r .= "<option value=\"" . $entity["id"] . "\" " . $selected . ">" . $entity["name"] . "</option>"; } } } $r .= "</select><span class=\"deh-required\">*</span><br />"; } $languageFilteredAttrOptions = $defAttrOptions + array('language' => iform_lang_iso_639_2($args['language'])); $r .= data_entry_helper::outputAttribute($attributes[$sample_walk_direction_id], $languageFilteredAttrOptions) . ($sample_reliability_id ? data_entry_helper::outputAttribute($attributes[$sample_reliability_id], $languageFilteredAttrOptions) : "<span style=\"display: none;\">Sample attribute '" . self::ATTR_RELIABILITY . "' not assigned to this survey</span>") . data_entry_helper::outputAttribute($attributes[$sample_visit_number_id], array_merge($languageFilteredAttrOptions, array('default' => 1, 'noBlankText' => true))); if (isset(data_entry_helper::$entity_to_load['sample:date']) && preg_match('/^(\\d{4})/', data_entry_helper::$entity_to_load['sample:date'])) { // Date has 4 digit year first (ISO style) - convert date to expected output format $d = new DateTime(data_entry_helper::$entity_to_load['sample:date']); data_entry_helper::$entity_to_load['sample:date'] = $d->format('d/m/Y'); } if ($args['language'] != 'en') { data_entry_helper::add_resource('jquery_ui_' . $args['language']); } // this will autoload the jquery_ui resource. The date_picker does not have access to the args. if ($surveyReadOnly) { $r .= data_entry_helper::text_input(array_merge($defAttrOptions, array('label' => lang::get('LANG_Date'), 'fieldname' => 'sample:date', 'disabled' => $disabledText))); } else { $r .= data_entry_helper::date_picker(array('label' => lang::get('LANG_Date'), 'fieldname' => 'sample:date', 'class' => 'vague-date-picker')); } $r .= ($sample_wind_id ? data_entry_helper::outputAttribute($attributes[$sample_wind_id], $languageFilteredAttrOptions) : "<span style=\"display: none;\">Sample attribute '" . self::ATTR_WIND . "' not assigned to this survey</span>") . ($sample_precipitation_id ? data_entry_helper::outputAttribute($attributes[$sample_precipitation_id], $languageFilteredAttrOptions) : "<span style=\"display: none;\">Sample attribute '" . self::ATTR_RAIN . "' not assigned to this survey</span>") . ($sample_temperature_id ? data_entry_helper::outputAttribute($attributes[$sample_temperature_id], array_merge($defAttrOptions, array('suffixTemplate' => 'nosuffix'))) . "<span class=\"attr-trailer\"> °C</span><br />" : "<span style=\"display: none;\">Sample attribute '" . self::ATTR_TEMP . "' not assigned to this survey</span>") . ($sample_cloud_id ? data_entry_helper::outputAttribute($attributes[$sample_cloud_id], $defAttrOptions) : "<span style=\"display: none;\">Sample attribute '" . self::ATTR_CLOUD . "' not assigned to this survey</span>") . ($sample_start_time_id ? data_entry_helper::outputAttribute($attributes[$sample_start_time_id], array_merge($defAttrOptions, array('suffixTemplate' => 'nosuffix'))) . "<span class=\"attr-trailer\"> hh:mm</span><br />" : "<span style=\"display: none;\">Sample attribute '" . self::ATTR_START_TIME . "' not assigned to this survey</span>") . ($sample_end_time_id ? data_entry_helper::outputAttribute($attributes[$sample_end_time_id], array_merge($defAttrOptions, array('suffixTemplate' => 'nosuffix'))) . "<span class=\"attr-trailer\"> hh:mm</span><br />" : "<span style=\"display: none;\">Sample attribute '" . self::ATTR_END_TIME . "' not assigned to this survey</span>"); data_entry_helper::$javascript .= "\njQuery('.attr-trailer').prev('br').remove();\n"; unset($defAttrOptions['suffixTemplate']); unset($defAttrOptions['validation']); if (user_access($args['edit_permission'])) { // users with admin permissions can override the closing of the // sample by unchecking the checkbox. // Because this is attached to the sample, we have to include the sample required fields in the // the post. This means they can't be disabled, so we enable all fields in this case. // Normal users can only set this to closed, and they do this using a button/hidden field. $r .= data_entry_helper::outputAttribute($attributes[$sample_closure_id], $defAttrOptions); // In addition admin users can delete a survey/sample. $r .= data_entry_helper::checkbox(array('label' => lang::get('Deleted'), 'fieldname' => 'sample:deleted', 'id' => 'main-sample-deleted')); } else { // hidden closed $r .= "<input type=\"hidden\" id=\"main-sample-closed\" name=\"" . $closedFieldName . "\" value=\"" . $closedFieldValue . "\" />\n"; } data_entry_helper::$javascript .= "\n\$.validator.messages.required = \"" . lang::get('validation_required') . "\";\n\$.validator.defaults.onsubmit = false; // override default - so that we handle all submission validation.\n"; if (!$surveyReadOnly) { // NB that we don't even include the buttons when readonly. data_entry_helper::$javascript .= "\njQuery('#read-only-survey').hide();\njQuery('#ro-sur-occ-warn').hide();\n"; $r .= "<input type=button id=\"close1\" class=\"ui-state-default ui-corner-all \" value=\"" . lang::get('LANG_Save_Survey_Details') . "\";\n onclick=\"var result = \$('#SurveyForm input').valid();\n var result2 = \$('#SurveyForm select').valid();\n if (!result || !result2) {\n return;\n }\n jQuery('#close1').addClass('loading-button');\n jQuery('#SurveyForm').submit();\">\n"; if (!user_access($args['edit_permission'])) { if ($mode == 1) { data_entry_helper::$javascript .= "jQuery('#close2').hide();\n"; } $r .= "<input type=button id=\"close2\" class=\"ui-state-default ui-corner-all \" value=\"" . lang::get('LANG_Save_Survey_And_Close') . "\"\n onclick=\"if(confirm('" . lang::get('LANG_Close_Survey_Confirm') . "')){\n var result = \$('#SurveyForm input').valid();\n var result2 = \$('#SurveyForm select').valid();\n if (!result || !result2) {\n return;\n }\n jQuery('#main-sample-closed').val('1');\n jQuery('#close2').addClass('loading-button');\n jQuery('#SurveyForm').submit();\n };\">\n"; } } $r .= "</form></div>\n"; data_entry_helper::$javascript .= "\nalertIndiciaError = function(data){\n\tvar errorString = \"" . lang::get('LANG_Indicia_Warehouse_Error') . "\";\n\tif(data.error){\terrorString = errorString + ' : ' + data.error;\t}\n\tif(data.errors){\n\t\tfor (var i in data.errors){\n\t\t\terrorString = errorString + ' : ' + data.errors[i];\n\t\t}\n\t}\n\talert(errorString);\n\t// the most likely cause is authentication failure - eg the read authentication has timed out.\n\t// prevent further use of the form:\n\t\$('.loading-panel').remove();\n\t\$('.loading-hide').removeClass('loading-hide');\n};\nerrorPos = null;\nclearErrors = function(formSel) {\n\tjQuery(formSel).find('.inline-error').remove();\n\terrorPos = null;\n};\nmyScrollTo = function(selector){\n\tjQuery(selector).filter(':visible').each(function(){\n\t\tif(errorPos == null || jQuery(this).offset().top < errorPos){\n\t\t\terrorPos = jQuery(this).offset().top;\n\t\t\twindow.scroll(0,errorPos);\n\t\t}\n\t});\n};\nmyScrollToError = function(){\n\tjQuery('.inline-error,.error').filter(':visible').prev().each(function(){\n\t\tif(errorPos == null || jQuery(this).offset().top < errorPos){\n\t\t\terrorPos = jQuery(this).offset().top;\n\t\t\twindow.scroll(0,errorPos);\n\t\t}\n\t});\n};\njQuery('#SurveyForm').ajaxForm({\n\tasync: false,\n\tdataType: 'json',\n beforeSubmit: function(data, obj, options){\n \tvar valid = true;\n \tclearErrors('form#SurveyForm');\n \tif (!jQuery('form#SurveyForm > input').valid()) {\n\t\t\tmyScrollToError();\n \t\t\tjQuery('.loading-button').removeClass('loading-button');\n\t\t\treturn false;\n \t\t};\n \t\tSurveyFormRetVal = true;\n \t\tif(jQuery('#main-sample-deleted:checked').length == 0){ // only do check if not deleting\n jQuery.ajax({ // now check if there are any other samples with this combination of date and location\n type: 'GET',\n url: \"" . $svcUrl . "/data/sample?mode=json&view=detail\" +\n \"&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n \"&orderby=id&callback=?&location_id=\"+jQuery('#imp-location').val()+\"&date_start=\"+jQuery('#SurveyForm [name=sample\\:date]').val(),\n data: {},\n success: function(detData) {\n for(i=0, j=0; i< detData.length; i++){\n if(detData[i].id != jQuery('#SurveyForm [name=sample\\:id]').val()) j++;\n }\n if(j) {\n \tSurveyFormRetVal = confirm(\"" . lang::get('LANG_Survey_Already_Exists') . "\");\n }\n },\n dataType: 'json',\n async: false\n });\n }\n\t\treturn SurveyFormRetVal;\n\t},\n success: function(data){\n // this will leave all the fields populated.\n \tif(data.success == 'multiple records' && data.outer_table == 'sample'){\n jQuery('#occ-form').show();\n jQuery('#na-occ-warn,#mergeSurveys').hide();"; if (!user_access($args['edit_permission'])) { // don't need to worry about record_status value for non admins as they can't modify when closed. data_entry_helper::$javascript .= "\n if(jQuery('#main-sample-closed').val() == '1'){\n jQuery('#read-only-survey,#ro-sur-occ-warn').show();\n jQuery('#close1,#close2,#occ-form').hide(); //can't enter any more occurrences\n jQuery('#SurveyForm').children().attr('disabled','disabled');\n };\n"; } else { data_entry_helper::$javascript .= "\n jQuery('#occurrence\\\\:record_status').val(jQuery('#smpAttr\\\\:" . $attributes[$sample_closure_id]['attributeId'] . ":checked').length > 0 ? 'C' : 'I');\n if(jQuery('#main-sample-deleted:checked').length > 0){\n jQuery('#return-to-main').click();\n return;\n };\n"; } data_entry_helper::$javascript .= "// If sample_id filled in -> we have a previously saved collection, so possibly have subsamples.\nif(jQuery('#SurveyForm > input[name=sample\\:id]').val() != ''){\n // Put up warning dialogue that we are checking the subsamples: include a progress bar: set to zero%.\n var dialog = \$('<span id=\"subsample-progress-span\"><p>'+\"" . lang::get('Please wait whilst some data integrity checks are carried out.') . "\"+'</p><div id=\"subsample-progress\"></div></span>').dialog({ title: \"" . lang::get('Checks') . "\", zIndex: 4000 });\n jQuery('#subsample-progress').progressbar({value: 0});\n jQuery.ajax({ // get all subsamples/occurrences to check if the dates match\n type: 'GET',\n url: \"" . $svcUrl . "/report/requestReport?report=library/occurrences/occurrences_list_for_parent_sample.xml&reportSource=local&mode=json&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n \"&callback=?&sample_id=\"+data.outer_id+\"&survey_id=&date_from=&date_to=&taxon_group_id=&smpattrs=&occattrs=\",\n data: {},\n success: function(subData) {\n jQuery('#subsample-progress').data('max',subData.length+1);\n var mainDate = \$.datepicker.formatDate('yy-mm-dd', jQuery('#SurveyForm > input[name=sample\\:date]').datepicker(\"getDate\"));\n for(i=0; i< subData.length; i++){ // loop through all subsamples\n jQuery('#subsample-progress').progressbar('option','value',(i+1)*100/jQuery('#subsample-progress').data('max'));\n var values = {};\n var url = '';\n // Check if date on subsamples matches supersample date: if not set up a post array for the sample, with correct date.\n if(subData[i].date_start != mainDate){\n values['sample:id']=subData[i].sample_id;\n values['sample:date']=mainDate;\n url=\"" . iform_ajaxproxy_url($node, 'sample') . "\";\n }\n"; // Send AJAX request to set occurrence to 'C' if closed : use sync if (!user_access($args['edit_permission'])) { data_entry_helper::$javascript .= " if(jQuery('#main-sample-closed').val() == '1'){\n"; } else { data_entry_helper::$javascript .= " if(jQuery('#smpAttr\\\\:" . $attributes[$sample_closure_id]['attributeId'] . ":checked').length > 0){\n"; } // If records are already verified, they are left verified, as if the records themselves are saved // they will flagged as no longer verified: But have to force a re verification if date is changed. data_entry_helper::$javascript .= "\n if(subData[i].record_status == 'I' || typeof values['sample:id'] != 'undefined'){\n values['occurrence:id']=subData[i].occurrence_id;\n values['occurrence:record_status']='C';\n url=(url == '' ? \"" . iform_ajaxproxy_url($node, 'occurrence') . "\" : \"" . iform_ajaxproxy_url($node, 'smp-occ') . "\");\n }\n } else { // any occurrences on unclosed collections must be flagged as 'I' - reopening unverifies.\n if(subData[i].record_status != 'I'){\n values['occurrence:id']=subData[i].occurrence_id;\n values['occurrence:record_status']='I';\n url=(url == '' ? \"" . iform_ajaxproxy_url($node, 'occurrence') . "\" : \"" . iform_ajaxproxy_url($node, 'smp-occ') . "\");\n }\n }\n if(url!=''){\n values['website_id']=" . $args['website_id'] . ";\n jQuery.ajax({ type: 'POST', url: url, data: values, dataType: 'json', async: false});\n }\n }\n },\n dataType: 'json',\n async: false\n });\n dialog.dialog('close');\n dialog.dialog('destroy');\n jQuery('#subsample-progress-span').remove();\n}\n\n\t\t\twindow.scroll(0,0);\n jQuery('#SurveyForm > input[name=sample\\:id]').removeAttr('disabled').val(data.outer_id);\n jQuery('#occ-form > input[name=sample\\:parent_id]').val(data.outer_id);\n jQuery('#occ-form > input[name=sample\\:date]').val(jQuery('#SurveyForm > input[name=sample\\:date]').val());\n loadAttributes('sample_attribute_value', 'sample_attribute_id', 'sample_id', data.outer_id, 'smpAttr');\n switch(\"" . $args["on_save_survey_nav"] . "\"){\n\t\t\t\tcase \"list\":\n\t\t\t\t\tvar a = \$('ul.ui-tabs-nav a')[2];\n\t\t\t\t\t\$(a).click();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"survey\":\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:"; if (!user_access($args['edit_permission'])) { data_entry_helper::$javascript .= "\n\t\t\t\t\tif(jQuery('#main-sample-closed').val() == 0){\n\t\t\t\t\t\tvar a = \$('ul.ui-tabs-nav a')[1];\n\t\t\t\t\t\t\$(a).click();\n\t\t\t\t\t};"; } else { data_entry_helper::$javascript .= "\n\t\t\t\t\tvar a = \$('ul.ui-tabs-nav a')[1];\n\t\t\t\t\t\$(a).click();"; } data_entry_helper::$javascript .= "\n\t\t\t\t\tbreak;\n\t\t\t}\n } else {\n\t\t\tif(data.error){\n\t\t\t\tvar lastIndex = data.error.lastIndexOf('Validation error');\n \t\t\tif (lastIndex != -1 && lastIndex == (data.error.length - 16)){\n\t\t\t\t\tif(data.errors){\n\t\t\t\t\t\t// TODO translation\n\t\t\t\t\t\tfor (i in data.errors){\n\t\t\t\t\t\t\tvar label = \$('<p/>').addClass('inline-error').html(data.errors[i]);\n\t\t\t\t\t\t\tlabel.insertAfter('[name='+i+']');\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmyScrollToError();\n\t\t\t\t\t\treturn;\n \t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\talertIndiciaError(data);\n }\n\t},\n complete: function (){\n \t\tjQuery('.loading-button').removeClass('loading-button');\n \t}\n});\n// In this case, all the samples attributes are on the survey tab, and all the occurrence attributes are on the occurrence tab. No need to worry about getting the correct form.\nloadAttributes = function(attributeTable, attributeKey, key, keyValue, prefix){\n jQuery.ajax({\n type: \"GET\",\n url: \"" . $svcUrl . "/data/\" + attributeTable + \"?mode=json&view=list\" +\n \t\"&reset_timeout=true&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n \t\t\t\"&\" + key + \"=\" + keyValue + \"&callback=?\",\n data: {},\n success: (function(attrPrefix, attrKey) {\n var retVal = function(attrdata) {\n if(!(attrdata instanceof Array)){\n alertIndiciaError(attrdata);\n } else if (attrdata.length>0) {\n for (var i=0;i<attrdata.length;i++){\n // in all cases if the attribute already has the <prefix>:<X>:<Y> format name we leave. Other wise we update <prefix>:<X> to <prefix>:<X>:<Y>\n // We leave all values unchanged.\n // need to be careful about Cloud: this is a drop down, but it is not language specific: the termlist is\n // always in english, so the iso won't match.\n if (attrdata[i].id){\n if (attrdata[i].iso == null || attrdata[i].iso == '') // no iso - not a look up.\n jQuery('[name='+attrPrefix+'\\:'+attrdata[i][attrKey]+']').attr('name', attrPrefix+':'+attrdata[i][attrKey]+':'+attrdata[i].id);\n else {\n if (attrdata[i].iso == '" . $language . "') // this is our actual language so OK\n jQuery('[name='+attrPrefix+'\\:'+attrdata[i][attrKey]+']').attr('name', attrPrefix+':'+attrdata[i][attrKey]+':'+attrdata[i].id);\n else {// not our language: look up all the other attrs, and if we don't find one of this id for our language, use this one.\n var found = false;\n for (var j=0;j<attrdata.length;j++)\n found = found || (i!=j && attrdata[i][attrKey] == attrdata[j][attrKey] && attrdata[j].iso == '" . $language . "');\n if(!found)\n jQuery('[name='+attrPrefix+'\\:'+attrdata[i][attrKey]+']').attr('name', attrPrefix+':'+attrdata[i][attrKey]+':'+attrdata[i].id);\n }\n }\n }\n }\n }};\n return retVal;\n })(prefix, attributeKey),\n\t\tdataType: 'json',\n\t async: false\n\t});\n}"; // Set up Occurrence List tab: don't include when creating a new sample as it will have no occurrences // Grid populated at a later point $r .= "<div id=\"occurrenceList\" class=\"mnhnl-btw-datapanel\"><div id=\"occ_grid\"></div>\n <form method=\"post\" action=\"" . data_entry_helper::$base_url . "/index.php/services/report/requestReport?report=reports_for_prebuilt_forms/MNHNL/mnhnl_btw_occurrences_report.xml&reportSource=local&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth['nonce'] . "&mode=csv\">\n <input type=\"hidden\" id=\"params\" name=\"params\" value='{\"survey_id\":" . $args['survey_id'] . ", \"sample_id\":" . data_entry_helper::$entity_to_load['sample:id'] . "}' />\n <input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Download_Occurrences') . "\">\n </form></div>"; if ($occReadOnly) { // NB that we don't even include the buttons when readonly. data_entry_helper::$javascript .= "\njQuery('#ro-occ-occ-warn').show();\njQuery('#ro-sur-occ-warn').hide();\n"; } else { data_entry_helper::$javascript .= "\njQuery('#ro-occ-occ-warn').hide();\n"; } if ($mode == 1) { data_entry_helper::$javascript .= "jQuery('#occ-form').hide();"; } else { data_entry_helper::$javascript .= "jQuery('#na-occ-warn').hide();"; } // Set up Occurrence tab: don't allow entry of a new occurrence until after top level sample is saved. data_entry_helper::$entity_to_load = $childSample; $attributes = data_entry_helper::getAttributes(array('id' => data_entry_helper::$entity_to_load['occurrence:id'], 'valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => 'occAttr', 'extraParams' => $readAuth)); $extraParams = $readAuth + array('taxon_list_id' => $args['list_id'], 'view' => 'detail', 'query' => urlencode(json_encode(array('in' => array('language_iso', array('lat', iform_lang_iso_639_2($args['language']))))))); if ($occReadOnly) { // if the occurrence has been downloaded, no one can modify it. $disabledText = "disabled=\"disabled\""; $defAttrOptions['disabled'] = $disabledText; } $species_ctrl_args = array('label' => lang::get('LANG_Species'), 'fieldname' => 'occurrence:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 2, 'extraParams' => $extraParams, 'disabled' => $disabledText, 'defaultCaption' => data_entry_helper::$entity_to_load['occurrence:taxon']); $r .= " <div id=\"occurrence\" class=\"mnhnl-btw-datapanel\">\n <p id=\"ro-occ-occ-warn\"><strong>" . lang::get('LANG_Read_Only_Occurrence') . "</strong></p>\n <p id=\"ro-sur-occ-warn\"><strong>" . lang::get('LANG_Read_Only_Survey') . "</strong></p>\n <p id=\"na-occ-warn\"><strong>" . lang::get('LANG_Page_Not_Available') . "</strong></p>\n <form method=\"post\" id=\"occ-form\" action=\"" . iform_ajaxproxy_url($node, 'smp-occ') . "\" >\n <input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n <input type=\"hidden\" id=\"sample:survey_id\" name=\"sample:survey_id\" value=\"" . $args['survey_id'] . "\" />\n <input type=\"hidden\" id=\"sample:parent_id\" name=\"sample:parent_id\" value=\"" . $parentSample['sample:id'] . "\" />\n <input type=\"hidden\" id=\"sample:date\" name=\"sample:date\" value=\"" . data_entry_helper::$entity_to_load['sample:date'] . "\" />\n <input type=\"hidden\" id=\"sample:id\" name=\"sample:id\" value=\"" . data_entry_helper::$entity_to_load['sample:id'] . "\" />\n <input type=\"hidden\" id=\"occurrence:id\" name=\"occurrence:id\" value=\"" . data_entry_helper::$entity_to_load['occurrence:id'] . "\" />\n <input type=\"hidden\" id=\"occurrence:record_status\" name=\"occurrence:record_status\" value=\"" . ($closedFieldValue == '0' ? 'I' : 'C') . "\" />\n <input type=\"hidden\" id=\"occurrence:downloaded_flag\" name=\"occurrence:downloaded_flag\" value=\"N\" />\n " . data_entry_helper::autocomplete($species_ctrl_args) . "\n " . ($occurrence_confidence_id ? data_entry_helper::outputAttribute($attributes[$occurrence_confidence_id], array_merge($languageFilteredAttrOptions, array('noBlankText' => ''))) : "<span style=\"display: none;\">Occurrence attribute '" . self::ATTR_CONFIDENCE . "' not assigned to this survey</span>") . "\n " . data_entry_helper::sref_and_system(array('label' => lang::get('LANG_Spatial_ref'), 'systems' => array('2169' => 'Luref (Gauss Luxembourg)'))) . "\n <p>" . lang::get('LANG_Click_on_map') . "</p>\n " . data_entry_helper::outputAttribute($attributes[$occurrence_count_id], array_merge($defAttrOptions, array('default' => 1))) . "\n " . ($occurrence_approximation_id ? data_entry_helper::outputAttribute($attributes[$occurrence_approximation_id], $defAttrOptions) : "<span style=\"display: none;\">Occurrence attribute '" . self::ATTR_APPROXIMATION . "' not assigned to this survey</span>") . "\n " . data_entry_helper::outputAttribute($attributes[$occurrence_territorial_id], array_merge($defAttrOptions, array('default' => 1, 'id' => 'occ-territorial'))) . "\n " . data_entry_helper::outputAttribute($attributes[$occurrence_atlas_code_id], $languageFilteredAttrOptions) . "\n " . ($occurrence_overflying_id ? data_entry_helper::outputAttribute($attributes[$occurrence_overflying_id], $defAttrOptions) : "<span style=\"display: none;\">Occurrence attribute '" . self::ATTR_OVERFLYING . "' not assigned to this survey</span>") . "\n " . data_entry_helper::textarea(array('label' => lang::get('LANG_Comment'), 'fieldname' => 'occurrence:comment', 'disabled' => $disabledText)); if (!$surveyReadOnly && !$occReadOnly) { if ($mode == 3) { $r .= data_entry_helper::checkbox(array('label' => lang::get('Delete'), 'fieldname' => 'sample:deleted', 'id' => 'occ-sample-deleted')); } $r .= "<input type=\"submit\" id=\"occ-submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Save_Occurrence_Details') . "\" />"; } $r .= " </form>\n"; data_entry_helper::$javascript .= "\n// because of ID tracking it is easier to rebuild entire list etc.\nretriggerGrid = function(){\n \$('div#occ_grid').empty();\n occListLayer.destroyFeatures();\n activateAddList = 1;\n thisOccID = -1;\n \$('div#occ_grid').indiciaDataGrid('rpt:reports_for_prebuilt_forms/MNHNL/mnhnl_btw_list_occurrences', {\n indiciaSvc: '" . $svcUrl . "',\n dataColumns: ['taxon', 'territorial', 'count'],\n reportColumnTitles: {taxon : '" . lang::get('LANG_Species') . "', territorial : '" . lang::get('LANG_Territorial') . "', count : '" . lang::get('LANG_Count') . "'},\n actionColumns: {'" . lang::get('LANG_Show') . "' : \"" . url('node/' . $node->nid, array('query' => 'occurrence_id=£id£')) . "\",\n '" . lang::get('LANG_Highlight') . "' : \"script:highlight(£id£);\"},\n auth : { nonce : '" . $readAuth['nonce'] . "', auth_token : '" . $readAuth['auth_token'] . "'},\n parameters : { survey_id : '" . $args['survey_id'] . "',\n parent_id : jQuery('#SurveyForm [name=sample\\:id]').val(),\n territorial_attr_id : '" . $occurrence_territorial_id . "',\n count_attr_id : '" . $occurrence_count_id . "'},\n itemsPerPage : 12,\n callback : addListFeature ,\n cssOdd : ''\n });\n}\n\njQuery('#occ-form').ajaxForm({\n\tasync: false,\n\tdataType: 'json',\n beforeSubmit: function(data, obj, options){\n \tvar valid = true;\n \tclearErrors('form#occ-form');\n \tif (!jQuery('form#occ-form > input').valid()) { valid = false; }\n \tif (!jQuery('form#occ-form > select').valid()) { valid = false; }\n \tif(!valid) {\n\t\t\tmyScrollToError();\n\t\t\treturn false;\n\t\t};\n\t\tjQuery('#occ-submit').addClass('loading-button');\n\t\treturn true;\n\t},\n success: function(data){\n // this will leave all the fields populated.\n \tif(data.success == 'multiple records' && data.outer_table == 'sample'){\n\t\t\twindow.scroll(0,0);\n\t\t\t// cant use reset form, as returns it to original values: if this was called with occurrence_id =<x> then it would repopulate with original occurrence's values\n\t\t\t// website_id, survey_id, record_status, downloaded_flag, sample:entered_sref_system are constants and are left alone. parent_id, date are only set referring to parent sample.\n\t\t\tjQuery('form#occ-form').find('[name^=occAttr\\:]').each(function(){\n\t\t\t\tvar name = jQuery(this).attr('name').split(':');\n\t\t\t\tjQuery(this).attr('name', name[0]+':'+name[1]);\n\t\t\t});\n\t\t\tjQuery('form#occ-form').find('[name=occurrence\\:id],[name=sample\\:id]').val('').attr('disabled', 'disabled');\n\t\t\tjQuery('form#occ-form').find('[name=occurrence\\:taxa_taxon_list_id],[name=occurrence\\:taxa_taxon_list_id\\:taxon],[name=sample\\:entered_sref],[name=sample\\:geom],[name=occurrence\\:comment]').val('');\n\t\t\tjQuery('form#occ-form').find('[name=occAttr\\:" . $occurrence_confidence_id . "]').find('option').removeAttr('selected');\n\t\t\tjQuery('form#occ-form').find('[name=occAttr\\:" . $occurrence_count_id . "]').val('1');\n\t\t\tjQuery('form#occ-form').find('input[name=occAttr\\:" . $occurrence_approximation_id . "],input[name=occAttr\\:" . $occurrence_overflying_id . "]').removeAttr('checked','checked');\n\t\t\tjQuery('form#occ-form').find('#occ-territorial').attr('checked','checked');\n\t\t\tjQuery('label[for=occ-sample-deleted]').remove(); // sample deleted only applicable when editing an existing occurrence. After saving reverts to Add Occurreence: no delete. Remove label then actual checkbox\n\t\t\tjQuery('form#occ-form').find('[name=sample\\:deleted]').remove(); // This removes both parts of the checkbox.\n\t\t\tsetAtlasStatus();\n\t\t\tretriggerGrid();\n\t\t\tlocationLayer.map.editLayer.destroyFeatures();\n\t\t\tvar a = \$('ul.ui-tabs-nav a')[1];\n\t\t\t\$(a).empty().html('<span>" . lang::get('LANG_Add_Occurrence') . "</span>');\n\t\t\tswitch(\"" . $args["on_save_occurrence_nav"] . "\"){\n\t\t\t\tcase \"list\":\n\t\t\t\t\ta = \$('ul.ui-tabs-nav a')[2];\n\t\t\t\t\t\$(a).click();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"survey\":\n\t\t\t\t\ta = \$('ul.ui-tabs-nav a')[0];\n\t\t\t\t\t\$(a).click();\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n } else {\n\t\t\tif(data.error){\n\t\t\t\tvar lastIndex = data.error.lastIndexOf('Validation error');\n \t\t\tif (lastIndex != -1 && lastIndex == (data.error.length - 16)){\n\t\t\t\t\tif(data.errors){\n\t\t\t\t\t\t// TODO translation\n\t\t\t\t\t\tfor (i in data.errors){\n\t\t\t\t\t\t\tvar label = \$('<p/>').addClass('inline-error').html(data.errors[i]);\n\t\t\t\t\t\t\tlabel.insertAfter('[name='+i+']');\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmyScrollToError();\n\t\t\t\t\t\treturn;\n \t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\talertIndiciaError(data);\n }\n\t},\n complete: function (){\n \t\tjQuery('.loading-button').removeClass('loading-button');\n \t}\n});\nsetAtlasStatus = function() {\n if (jQuery(\"#occ-territorial:checked\").length == 0) {\n jQuery(\"select[name=occAttr\\:" . $occurrence_atlas_code_id . "],select[name^=occAttr\\:" . $occurrence_atlas_code_id . "\\:]\").val('');\n } else {\n if(jQuery(\"select[name=occAttr\\:" . $occurrence_atlas_code_id . "],select[name^=occAttr\\:" . $occurrence_atlas_code_id . "\\:]\").val() == '') {\n // Find the BB02 option (depends on the language what val it has)\n var bb02;\n jQuery.each(jQuery(\"select[name=occAttr\\:" . $occurrence_atlas_code_id . "],select[name^=occAttr\\:" . $occurrence_atlas_code_id . "\\:]\").find('option'), function(index, option) {\n if (option.text.substr(0,4)=='BB02') {\n bb02 = option.value;\n return; // just from the each loop\n }\n });\n jQuery(\"select[name=occAttr\\:" . $occurrence_atlas_code_id . "],select[name^=occAttr\\:" . $occurrence_atlas_code_id . "\\:]\").val(bb02);\n }\n }\n};\njQuery(\"#occ-territorial\").change(setAtlasStatus);\nif(\$.browser.msie) {\n jQuery(\"#occ-territorial\").click(function() {\n \$(this).change();\n });\n}\n\n"; if ($mode != 3) { data_entry_helper::$javascript .= "setAtlasStatus();\n"; } // reset the atlas when not looking at a old occurrence. $r .= '</div>'; // add map panel. $options = iform_map_get_map_options($args, $readAuth); $olOptions = iform_map_get_ol_options($args); // $options['layers'] = array('locationLayer', 'occListLayer'); $options['searchLayer'] = 'false'; $options['initialFeatureWkt'] = null; $options['proxy'] = ''; $options['scroll_wheel_zoom'] = false; $options['width'] = 'auto'; // TBD remove from arglist $r .= "<div class=\"mnhnl-btw-mappanel\">\n"; $r .= data_entry_helper::map_panel($options, $olOptions); // for timing reasons, all the following has to be done after the map is loaded. // 1) feature selector for occurrence list must have the map present to attach the control // 2) location placer must have the location layer populated and the map present in // order to zoom the map into the location. // 3) occurrence list feature adder must have map present in order to zoom into any // current selection. data_entry_helper::$onload_javascript .= "\n\n\nlocationChange = function(obj){\n locationLayer.destroyFeatures();\n if(obj.value != ''){\n jQuery.getJSON(\"" . $svcUrl . "\" + \"/data/location/\"+obj.value +\n \"?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . "\" +\n \"&callback=?\", function(data) {\n if (data.length>0) {\n var parser = new OpenLayers.Format.WKT();\n for (var i=0;i<data.length;i++)\n {\n if(data[i].centroid_geom){\n " . self::readBoundaryJs('data[i].centroid_geom', $args['map_projection']) . "\n feature.style = {label: data[i].name,\n\t\t\t\t\t\t strokeColor: \"Green\",\n strokeWidth: 2,\n fillOpacity: 0};\n centre = feature.geometry.getCentroid();\n centrefeature = new OpenLayers.Feature.Vector(centre, {}, {label: data[i].name});\n locationLayer.addFeatures([feature, centrefeature]);\n }\n if(data[i].boundary_geom){\n " . self::readBoundaryJs('data[i].boundary_geom', $args['map_projection']) . "\n feature.style = {strokeColor: \"Blue\", strokeWidth: 2};\n locationLayer.addFeatures([feature]);\n }\n locationLayer.map.zoomToExtent(locationLayer.getDataExtent());\n }\n }\n });\n jQuery.getJSON(\"" . $svcUrl . "\" + \"/data/location\" +\n \"?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . "&callback=?&parent_id=\"+obj.value, function(data) {\n if (data.length>0) {\n var parser = new OpenLayers.Format.WKT();\n for (var i=0;i<data.length;i++)\n {\n if(data[i].centroid_geom){\n " . self::readBoundaryJs('data[i].centroid_geom', $args['map_projection']) . "\n locationLayer.addFeatures([feature]);\n }\n if(data[i].boundary_geom){\n " . self::readBoundaryJs('data[i].boundary_geom', $args['map_projection']) . "\n feature.style = {label: data[i].name,\n labelAlign: \"cb\",\n strokeColor: \"Blue\",\n strokeWidth: 2};\n locationLayer.addFeatures([feature]);\n }\n }\n }\n });\n }\n};\n// upload location initial value into map.\njQuery('#imp-location').each(function(){\n locationChange(this);\n});\njQuery('#imp-location').unbind('change');\njQuery('#imp-location').change(function(){\n locationChange(this);\n});\nvar selected = \$('#controls').tabs('option', 'selected');\n\n// Only leave the click control activated for edit/add occurrence tab.\nif(selected != 1){\n locationLayer.map.editLayer.clickControl.deactivate();\n}\n\$('#controls').bind('tabsshow', function(event, ui) {\n if(ui.index == 1)\n {\n locationLayer.map.editLayer.clickControl.activate();\n }\n else\n {\n locationLayer.map.editLayer.clickControl.deactivate();\n }\n }\n);\nactivateAddList = 1;\nthisOccID = " . $thisOccID . ";\naddListFeature = function(div, r, record, count) {\n if(activateAddList == 0)\n return;\n if(r == count)\n activateAddList = 0;\n var parser = new OpenLayers.Format.WKT();\n " . self::readBoundaryJs('record.geom', $args['map_projection']) . "\n if(record.id != thisOccID || 1==" . ($surveyReadOnly ? 1 : 0) . " || 1==" . ($occReadOnly ? 1 : 0) . "){\n feature.attributes.id = record.id;\n feature.attributes.taxon = record.taxon;\n feature.attributes.count = record.count;\n occListLayer.addFeatures([feature]);\n if(record.id == " . $thisOccID . "){\n var bounds=feature.geometry.getBounds();\n locationLayer.map.setCenter(bounds.getCenterLonLat());\n }\n } else {\n locationLayer.map.editLayer.destroyFeatures();\n locationLayer.map.editLayer.addFeatures([feature]);\n var bounds=feature.geometry.getBounds()\n var centre=bounds.getCenterLonLat();\n locationLayer.map.setCenter(centre);\n }\n};\nhighlight = function(id){\n if(id == " . $thisOccID . "){\n if(occListLayer.map.editLayer.features.length > 0){\n var bounds=occListLayer.map.editLayer.features[0].geometry.getBounds()\n var centre=bounds.getCenterLonLat();\n occListLayer.map.setCenter(centre);\n return;\n }\n }\n for(var i = 0; i < occListLayer.features.length; i++){\n if(occListLayer.features[i].attributes.id == id){\n control.unselectAll();\n var bounds=occListLayer.features[i].geometry.getBounds()\n var centre=bounds.getCenterLonLat();\n occListLayer.map.setCenter(centre);\n control.select(occListLayer.features[i]);\n return;\n }\n }\n}\n"; if ($mode != 1) { data_entry_helper::$onload_javascript .= "\n\$('div#occ_grid').indiciaDataGrid('rpt:reports_for_prebuilt_forms/MNHNL/mnhnl_btw_list_occurrences', {\n indiciaSvc: '" . $svcUrl . "',\n dataColumns: ['taxon', 'territorial', 'count'],\n reportColumnTitles: {taxon : '" . lang::get('LANG_Species') . "', territorial : '" . lang::get('LANG_Territorial') . "', count : '" . lang::get('LANG_Count') . "'},\n actionColumns: {'" . lang::get('LANG_Show') . "' : \"" . url('node/' . $node->nid, array('query' => 'occurrence_id=£id£')) . "\",\n '" . lang::get('LANG_Highlight') . "' : \"script:highlight(£id£);\"},\n auth : { nonce : '" . $readAuth['nonce'] . "', auth_token : '" . $readAuth['auth_token'] . "'},\n parameters : { survey_id : '" . $args['survey_id'] . "',\n parent_id : '" . $parentSample['sample:id'] . "',\n territorial_attr_id : '" . $occurrence_territorial_id . "',\n count_attr_id : '" . $occurrence_count_id . "'},\n itemsPerPage : 12,\n callback : addListFeature ,\n cssOdd : ''\n });\n\n// activateAddList = 0;\n\n"; } $r .= "</div><div><form><input id=\"return-to-main\" type=\"button\" value=\"" . lang::get('LANG_Return') . "\" onclick=\"window.location.href='" . url('node/' . $node->nid, array('query' => 'Main')) . "'\"></form></div></div>\n"; if (method_exists(get_called_class(), 'getTrailerHTML')) { $r .= call_user_func(array(get_called_class(), 'getTrailerHTML'), $args); } return $r; }
public static function wrap_species_checklist_with_subsamples($arr, $section_id_attribute, $subsites, $subSampleIds, $include_if_any_data = false, $zero_attrs = true, $zero_values = array('0', 'None', 'Absent')) { if (array_key_exists('website_id', $arr)) { $website_id = $arr['website_id']; } else { throw new Exception('Cannot find website id in POST array!'); } // determiner and record status can be defined globally for the whole list. if (array_key_exists('occurrence:determiner_id', $arr)) { $determiner_id = $arr['occurrence:determiner_id']; } if (array_key_exists('occurrence:record_status', $arr)) { $record_status = $arr['occurrence:record_status']; } // Set the default method of looking for rows to include - either using data, or the checkbox (which could be hidden) $include_if_any_data = $include_if_any_data || isset($arr['rowInclusionCheck']) && $arr['rowInclusionCheck'] == 'hasData'; // Species checklist entries take the following format. // sc:<subsampleIndex>:[<sample_id>]:sample:deleted // sc:<subsampleIndex>:[<sample_id>]:sample:geom // sc:<subsampleIndex>:[<sample_id>]:sample:entered_sref // sc:<subsampleIndex>:[<sample_id>]:smpAttr:[<sample_attribute_id>] // sc:<rowIndex>:[<occurrence_id>]:occurrence:sampleIDX (val set to subsample index) // sc:<rowIndex>:[<occurrence_id>]:present (checkbox with val set to ttl_id // sc:<rowIndex>:[<occurrence_id>]:occAttr:<occurrence_attribute_id>[:<occurrence_attribute_value_id>] // sc:<rowIndex>:[<occurrence_id>]:occurrence:comment // sc:<rowIndex>:[<occurrence_id>]:occurrence_medium:fieldname:uniqueImageId $occurrenceRecords = array(); $sampleRecords = array(); $subModels = array(); foreach ($arr as $key => $value) { if (substr($key, 0, 3) == 'sc:' && substr($key, 2, 7) != ':-idx-:' && substr($key, 2, 3) != ':n:') { //discard the hidden cloneable rows // Don't explode the last element for occurrence attributes $a = explode(':', $key, 4); $b = explode(':', $a[3], 3); if ($value && count($b) >= 2) { if ($b[0] == "occAttr" && $b[1] == $section_id_attribute) { if (!isset($sampleRecords['smp' . $value])) { $sampleRecords['smp' . $value] = array(); } $occurrenceRecords[$a[1]]['sectionIdVal'] = $value; } } $occurrenceRecords[$a[1]][$a[3]] = $value; if ($a[2]) { $occurrenceRecords[$a[1]]['id'] = $a[2]; } } } foreach ($occurrenceRecords as $record) { $present = !empty($record['present']); if (array_key_exists('id', $record) || $present) { // must always handle row if already present in the db if (!$present) { // checkboxes do not appear if not checked. If uncheck, delete record. $record['deleted'] = 't'; } $record['zero_abundance'] = self::recordZeroAbundance($record, $section_id_attribute); $record['taxa_taxon_list_id'] = $record['present']; $record['website_id'] = $website_id; if (isset($determiner_id)) { $record['determiner_id'] = $determiner_id; } if (isset($record_status)) { $record['record_status'] = $record_status; } $occ = data_entry_helper::wrap($record, 'occurrence'); // At this point, a deleted record only has present=0 and an id. No link to the sample since our section ID field has been // disabled. So we need to use the subSampleIds data to work out the original site ID and link via that. if (isset($record['sectionIdVal'])) { $sectionId = $record['sectionIdVal']; } else { $orderedSubSites = array_keys($subSampleIds); $sectionId = $orderedSubSites[$record['occurrence:sampleIDX']]; } $sampleRecords["smp{$sectionId}"]['occurrences'][] = array('fkId' => 'sample_id', 'model' => $occ); } } // convert subsites to a keyed array, for easier lookup $keyedSS = array(); foreach ($subsites as $ss) { $keyedSS["ss{$ss['id']}"] = $ss; } foreach ($sampleRecords as $id => $sampleRecord) { $idx = preg_replace('/^smp/', '', $id); $subsite = $keyedSS["ss{$idx}"]; $occs = $sampleRecord['occurrences']; unset($sampleRecord['occurrences']); $sampleRecord['website_id'] = $website_id; // copy essentials down to each subsample if (!empty($arr['survey_id'])) { $sampleRecord['survey_id'] = $arr['survey_id']; } if (!empty($arr['sample:date'])) { $sampleRecord['date'] = $arr['sample:date']; } if (!empty($arr['subsample:sample_method_id'])) { $sampleRecord['sample_method_id'] = $arr['subsample:sample_method_id']; } $sampleRecord['entered_sref'] = $subsite['centroid_sref']; $sampleRecord['entered_sref_system'] = $subsite['centroid_sref_system']; $sampleRecord['geom'] = $subsite['boundary_geom']; $sampleRecord['location_id'] = $subsite['id']; if (!empty($subSampleIds[$sampleRecord['location_id']])) { $sampleRecord['id'] = $subSampleIds[$sampleRecord['location_id']]; } if (!empty($arr['sample:entered_sref_system'])) { $sampleRecord['entered_sref_system'] = $arr['sample:entered_sref_system']; } if (!empty($arr['sample:location_name']) && empty($sampleRecord['location_name'])) { $sampleRecord['location_name'] = $arr['sample:location_name']; } if (!empty($arr['sample:input_form'])) { $sampleRecord['input_form'] = $arr['sample:input_form']; } $subSample = data_entry_helper::wrap($sampleRecord, 'sample'); // Add the subsample/soccurrences in as subModels without overwriting others such as a sample image if (array_key_exists('subModels', $subSample)) { $subSample['subModels'] = array_merge($sampleMod['subModels'], $occs); } else { $subSample['subModels'] = $occs; } $subModel = array('fkId' => 'parent_id', 'model' => $subSample); $copyFields = array(); if (!isset($sampleRecord['date'])) { $copyFields = array('date_start' => 'date_start', 'date_end' => 'date_end', 'date_type' => 'date_type'); } if (!isset($sampleRecord['survey_id'])) { $copyFields['survey_id'] = 'survey_id'; } if (count($copyFields) > 0) { $subModel['copyFields'] = $copyFields; } // from parent->to child $subModels[] = $subModel; } return $subModels; }
/** * Wraps data from a species checklist grid: modified from original data_entry_helper * function to allow multiple rows for the same species, plus linking to survey method */ private static function wrap_species_checklist($arr, $method) { if (array_key_exists('website_id', $arr)) { $website_id = $arr['website_id']; } else { throw new Exception('Cannot find website id in POST array!'); } // occurrences are included dependant on the present field... If present is // Species checklist entries take the following format // sc:<method-meaning-id>:<taxa_taxon_list_id>:[<occurrence_id>|<sequence(negative)>]:occAttr:<occurrence_attribute_id>[:<occurrence_attribute_value_id>] // sc:<method-meaning-id>:<taxa_taxon_list_id>:[<occurrence_id>|<sequence(negative)>]:present // not doing occurrence images at this point - TBD $records = array(); $subModels = array(); foreach ($arr as $key => $value) { if (substr($key, 0, 3) == 'sc:') { // Don't explode the last element for occurrence attributes $a = explode(':', $key, 5); if ($a[3] && $a[1] == $method) { if (!array_key_exists($a[3], $records)) { $records[$a[3]]['taxa_taxon_list_id'] = $a[2]; if (is_numeric($a[3]) && $a[3] > 0) { $records[$a[3]]['id'] = $a[3]; } } $records[$a[3]][$a[4]] = $value; // does attrs and present field } } } foreach ($records as $id => $record) { $present = self::wrap_species_checklist_record_present($record); if (array_key_exists('id', $record) || $present) { // must always handle row if already present in the db if (!$present) { $record['deleted'] = 't'; } $record['website_id'] = $website_id; if (array_key_exists('occurrence:determiner_id', $arr)) { $record['determiner_id'] = $arr['occurrence:determiner_id']; } if (array_key_exists('occurrence:record_status', $arr)) { $record['record_status'] = $arr['occurrence:record_status']; } $occ = data_entry_helper::wrap($record, 'occurrence'); $subModels[] = array('fkId' => 'sample_id', 'model' => $occ); } } return $subModels; }
/** * Based on wrap_species_checklist_with_third_level_samples in data_entry_helper. * Altered for Seasearch as it needs to understand there is a third level of samples. There is one third level sample for each occurrence to hold its spatial reference. */ private static function wrap_species_checklist_with_third_level_samples($arr, $include_if_any_data = false, $zero_attrs = true, $zero_values = array('0', 'None', 'Absent'), $gridsToExclude = array()) { if (array_key_exists('website_id', $arr)) { $website_id = $arr['website_id']; } else { throw new Exception('Cannot find website id in POST array!'); } // determiner and record status can be defined globally for the whole list. if (array_key_exists('occurrence:determiner_id', $arr)) { $determiner_id = $arr['occurrence:determiner_id']; } if (array_key_exists('occurrence:record_status', $arr)) { $record_status = $arr['occurrence:record_status']; } // Set the default method of looking for rows to include - either using data, or the checkbox (which could be hidden) $include_if_any_data = $include_if_any_data || isset($arr['rowInclusionCheck']) && $arr['rowInclusionCheck'] == 'hasData'; $occurrenceRecords = array(); $sampleRecord = array(); $sampleRecords = array(); $subModels = array(); foreach ($arr as $key => $value) { $gridExcluded = false; foreach ($gridsToExclude as $gridToExclude) { if (substr($key, 0, strlen($gridToExclude) + 3) == 'sc:' . $gridToExclude) { $gridExcluded = true; } } //Only look at rows on occurrences grid excluding the clonable row if ($gridExcluded === false && strpos($key, 'sc:') !== false && strpos($key, '-idx-') === false) { //discard the hidden cloneable rows // Don't explode the last element for occurrence attributes $a = explode(':', $key, 4); $b = explode(':', $a[3], 2); //At this stage we just collected all the information to create a general sample which //can be duplicated for each occurrence. This sample is then altered later in submission to set things like entered_sref. if ($b[0] == "sample" || $b[0] == "smpAttr") { $sampleRecord[$a[1]][$a[3]] = $value; } else { //Make a list of occurrences $occurrenceRecords[$a[1]][$a[3]] = $value; } } } $sampleRecords = array(); foreach ($occurrenceRecords as $id => $record) { $present = data_entry_helper::wrap_species_checklist_record_present($record, $include_if_any_data, $zero_attrs, $zero_values, array()); if (array_key_exists('id', $record) || $present !== null) { // must always handle row if already present in the db if ($present === null) { // checkboxes do not appear if not checked. If uncheck, delete record. $record['deleted'] = 't'; } else { $record['zero_abundance'] = $present ? 'f' : 't'; } $record['taxa_taxon_list_id'] = $record['present']; $record['website_id'] = $website_id; if (isset($determiner_id)) { $record['determiner_id'] = $determiner_id; } if (isset($record_status)) { $record['record_status'] = $record_status; } $occ = data_entry_helper::wrap($record, 'occurrence'); data_entry_helper::attachOccurrenceMediaToModel($occ, $record); //Duplicate the general sample record for each occurrence, these are then altered later in submission specifically for the occurrence $sampleRecords[] = $sampleRecord; //Added the occurrence to the sample $sampleRecords[count($sampleRecords) - 1]['occurrences'] = array(); $sampleRecords[count($sampleRecords) - 1]['occurrences'][] = array('fkId' => 'sample_id', 'model' => $occ); } } foreach ($sampleRecords as $id => $sampleRecord) { $occs = $sampleRecord['occurrences']; unset($sampleRecord['occurrences']); $sampleRecord['website_id'] = $website_id; // copy essentials down to each subsample if (!empty($arr['survey_id'])) { $sampleRecord['survey_id'] = $arr['survey_id']; } if (!empty($arr['sample:date'])) { $sampleRecord['date'] = $arr['sample:date']; } if (!empty($arr['sample:entered_sref_system'])) { $sampleRecord['entered_sref_system'] = $arr['sample:entered_sref_system']; } if (!empty($arr['sample:location_name']) && empty($sampleRecord['location_name'])) { $sampleRecord['location_name'] = $arr['sample:location_name']; } if (!empty($arr['sample:input_form'])) { $sampleRecord['input_form'] = $arr['sample:input_form']; } $subSample = data_entry_helper::wrap($sampleRecord, 'sample'); // Add the subsample/soccurrences in as subModels without overwriting others such as a sample image if (array_key_exists('subModels', $subSample)) { $subSample['subModels'] = array_merge($sampleMod['subModels'], $occs); } else { $subSample['subModels'] = $occs; } $subModel = array('fkId' => 'parent_id', 'model' => $subSample); $copyFields = array(); if (!isset($sampleRecord['date'])) { $copyFields = array('date_start' => 'date_start', 'date_end' => 'date_end', 'date_type' => 'date_type'); } if (!isset($sampleRecord['survey_id'])) { $copyFields['survey_id'] = 'survey_id'; } if (count($copyFields) > 0) { $subModel['copyFields'] = $copyFields; } // from parent->to child $subModels[] = $subModel; } return $subModels; }
/** * Wraps data from a species checklist grid: modified from original data_entry_helper * function to allow multiple rows for the same species. */ private static function wrap_species_checklist($arr) { if (!array_key_exists('website_id', $arr)) { throw new Exception('Cannot find website id in POST array!'); } // not doing occurrence images at this point - TBD $samples = array(); $occurrences = array(); foreach ($arr as $key => $value) { // Don't explode the last element for attributes $a = explode(':', $key, 6); // sc:--GroupID--:--SampleID--:--TTLID--:--OccurrenceID-- if ($a[0] == 'sc' && $a[1] != '' && $a[1] != '--GroupID--') { $b = explode(':', $a[5]); if ($a[1]) { // key on the Group ID $occurrences[$a[1]]['taxa_taxon_list_id'] = $a[3]; if ($b[0] == 'sample' || $b[0] == 'smpAttr') { $samples[$a[1]][$a[5]] = $value; } else { // for a multiple entry checkbox group, need to remove the sc:--GroupID--:--SampleID--:--TTLID--:--OccurrenceID-- to give value:occAttr:value[:value] $newvalue = $value; if (is_array($value)) { $newvalue = array(); foreach ($value as $X) { $tokens = explode(':', $X, 7); $newvalue[] = count($tokens) == 7 ? $tokens[0] . ':' . $tokens[6] : $X; } } $occurrences[$a[1]][$a[5]] = $newvalue; } // store any id so update existing record prefix if (is_numeric($a[2]) && $a[2] > 0) { $samples[$a[1]]['id'] = $a[2]; } if (is_numeric($a[4]) && $a[4] > 0) { $occurrences[$a[1]]['id'] = $a[4]; } } } } $subModels = array(); foreach ($occurrences as $id => $occurrence) { $present = self::wrap_species_checklist_record_present($occurrence); if (array_key_exists('id', $occurrence) || $present) { // must always handle row if already present in the db if (!$present) { $occurrence['deleted'] = 't'; } $occurrence['website_id'] = $arr['website_id']; if (array_key_exists('occurrence:determiner_id', $arr)) { $occurrence['determiner_id'] = $arr['occurrence:determiner_id']; } if (array_key_exists('occurrence:record_status', $arr)) { $occurrence['record_status'] = $arr['occurrence:record_status']; } $occ = data_entry_helper::wrap($occurrence, 'occurrence'); if (isset($arr['includeSubSample'])) { if (!$present) { $samples[$id]['deleted'] = 't'; } $samples[$id]['website_id'] = $arr['website_id']; $samples[$id]['entered_sref_system'] = '2169'; // TBD $samples[$id]['survey_id'] = $arr['survey_id']; $smp = data_entry_helper::wrap($samples[$id], 'sample'); $smp['subModels'] = array(array('fkId' => 'sample_id', 'model' => $occ)); $smp = array('fkId' => 'parent_id', 'model' => $smp); if (!isset($samples[$id]['date'])) { $smp['copyFields'] = array('date_start' => 'date_start', 'date_end' => 'date_end', 'date_type' => 'date_type'); } // from parent->to child $subModels[] = $smp; } else { $subModels[] = array('fkId' => 'sample_id', 'model' => $occ); } } } return $subModels; }
/** * Wraps data from a species checklist grid (generated by * data_entry_helper::species_checklist) into a suitable format for submission. This will * return an array of submodel entries which can be dropped directly into the subModel * section of the submission array. If there is a field occurrence:determiner_id or * occurrence:record_status in the main form data, then these values are applied to each * occurrence created from the grid. For example, place a hidden field in the form named * "occurrence:record_status" with a value "C" to set all occurrence records to completed * as soon as they are entered. * * @param array $arr Array of data generated by data_entry_helper::species_checklist method. * @param boolean $include_if_any_data If true, then any list entry which has any data * set will be included in the submission. This defaults to false, unless the grid was * created with rowInclusionCheck=hasData. * in the grid. */ public static function wrap_species_checklist($arr, $include_if_any_data = false) { if (array_key_exists('website_id', $arr)) { $website_id = $arr['website_id']; } else { throw new Exception('Cannot find website id in POST array!'); } // determiner and record status can be defined globally for the whole list. if (array_key_exists('occurrence:determiner_id', $arr)) { $determiner_id = $arr['occurrence:determiner_id']; } if (array_key_exists('occurrence:record_status', $arr)) { $record_status = $arr['occurrence:record_status']; } // Set the default method of looking for rows to include - either using data, or the checkbox (which could be hidden) $include_if_any_data = $include_if_any_data || isset($arr['rowInclusionCheck']) && $arr['rowInclusionCheck'] == 'hasData'; // Species checklist entries take the following format // sc:<taxa_taxon_list_id>:[<occurrence_id>]:occAttr:<occurrence_attribute_id>[:<occurrence_attribute_value_id>] // or // sc:<taxa_taxon_list_id>:[<occurrence_id>]:occurrence:comment // or // sc:<taxa_taxon_list_id>:[<occurrence_id>]:occurrence_image:fieldname:uniqueImageId $records = array(); $subModels = array(); foreach ($arr as $key => $value) { if (substr($key, 0, 3) == 'sc:') { // Don't explode the last element for occurrence attributes $a = explode(':', $key, 4); $records[$a[1]][$a[3]] = $value; // store any id so update existing record if ($a[2]) { $records[$a[1]]['id'] = $a[2]; } } } foreach ($records as $id => $record) { $present = self::wrap_species_checklist_record_present($record, $include_if_any_data); if (array_key_exists('id', $record) || $present) { // must always handle row if already present in the db if (!$present) { // checkboxes do not appear if not checked. If uncheck, delete record. $record['deleted'] = 't'; } $record['taxa_taxon_list_id'] = $id; $record['website_id'] = $website_id; if (isset($determiner_id)) { $record['determiner_id'] = $determiner_id; } if (isset($record_status)) { $record['record_status'] = $record_status; } $occ = data_entry_helper::wrap($record, 'occurrence'); self::attachOccurrenceImagesToModel($occ, $record); $subModels[] = array('fkId' => 'sample_id', 'model' => $occ); } } return $subModels; }