/**
  * Return the generated output for the main sample tab.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  *                    This array always contains a value for language.
  * @param integer $nid The Drupal node object's ID.
  * @param object $auth The full read-write authorisation.
  * @return HTML.
  */
 private static function get_sample_tab($args, $nid, $auth, $attributes, &$packageAttr)
 {
     global $user;
     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
         // @todo The date format should be a global configurable option. It should also be applied to reloading of custom date attributes.
         $d = new DateTime(data_entry_helper::$entity_to_load['sample:date']);
         data_entry_helper::$entity_to_load['sample:date'] = $d->format('d/m/Y');
     }
     // are there any option overrides for the custom attributes?
     if (isset($args['custom_attribute_options']) && $args['custom_attribute_options']) {
         $blockOptions = get_attr_options_array_with_user_data($args['custom_attribute_options']);
     } else {
         $blockOptions = array();
     }
     $systems = array();
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get("sref:{$system}");
     }
     $options = iform_map_get_map_options($args, $auth['read']);
     $olOptions = iform_map_get_ol_options($args);
     if (!empty(data_entry_helper::$entity_to_load['sample:wkt'])) {
         $options['initialFeatureWkt'] = data_entry_helper::$entity_to_load['sample:wkt'];
     }
     if (!isset($options['standardControls'])) {
         $options['standardControls'] = array('layerSwitcher', 'panZoomBar');
     }
     $options['tabDiv'] = 'sample';
     // we pass through the read auth. This makes it possible for the get_submission method to authorise against the warehouse
     // without an additional (expensive) warehouse call, so it can get subsample details.
     $r = '<div id="sample">' . '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>' . get_user_profile_hidden_inputs($attributes, $args, isset(data_entry_helper::$entity_to_load['sample:id']), $auth['read']) . data_entry_helper::text_input(array('label' => lang::get('Location Name'), 'fieldname' => 'sample:location_name', 'class' => 'control-width-5', 'validation' => array('required'))) . data_entry_helper::date_picker(array('label' => lang::get('Date'), 'fieldname' => 'sample:date')) . self::_build_package_control($args, $packageAttr) . get_attribute_html($attributes, $args, array('extraParams' => $auth['read']), null, $blockOptions) . data_entry_helper::textarea(array('fieldname' => 'sample:comment', 'label' => lang::get('Overall comment'))) . data_entry_helper::sref_and_system(array('label' => lang::get('Grid Reference'), 'systems' => $systems)) . '<p class="ui-state-highlight page-notice ui-corner-all">' . t('Use the search box to find a nearby town or village, then drag the map to pan and click on the map to set the centre grid reference of the transect. ' . 'Alternatively if you know the grid reference you can enter it in the Grid Ref box above: this will then be drawn automatically on the map.') . '</p>' . (isset(data_entry_helper::$entity_to_load['sample:id']) ? '' : data_entry_helper::georeference_lookup(array('label' => lang::get('Search for place'), 'driver' => $args['georefDriver'], 'georefPreferredArea' => $args['georefPreferredArea'], 'georefCountry' => $args['georefCountry'], 'georefLang' => $args['language'], 'readAuth' => $auth['read']))) . map_helper::map_panel($options, $olOptions) . (self::$readOnly ? '' : '<br/><input type="submit" value="' . lang::get('Save') . '" title="' . lang::get('Saves any data entered across all the tabs.') . '" />') . '</div>';
     return $r;
 }
Пример #2
0
 public static function get_occurrences_form($args, $node, $response)
 {
     global $user;
     data_entry_helper::add_resource('jquery_form');
     data_entry_helper::add_resource('jquery_ui');
     data_entry_helper::add_resource('json');
     data_entry_helper::add_resource('autocomplete');
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     // did the parent sample previously exist? Default is no.
     $parentSampleId = null;
     $existing = false;
     if (isset($_POST['sample:id'])) {
         // have just posted an edit to the existing parent sample, so can use it to get the parent location id.
         $parentSampleId = $_POST['sample:id'];
         $existing = true;
     } else {
         if (isset($response['outer_id'])) {
             // have just posted a new parent sample, so can use it to get the parent location id.
             $parentSampleId = $response['outer_id'];
         } else {
             $parentSampleId = $_GET['sample_id'];
             $existing = true;
         }
     }
     if (!$parentSampleId || $parentSampleId == '') {
         return 'Could not determine the parent sample.';
     }
     // find any attributes that apply to Timed Count Count samples.
     $sampleMethods = helper_base::get_termlist_terms($auth, 'indicia:sample_methods', array('Timed Count Count'));
     if (count($sampleMethods) == 0) {
         return 'The sample method "Timed Count Count" must be defined in the termlist in order to use this form.';
     }
     $attributes = data_entry_helper::getAttributes(array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'sample_method_id' => $sampleMethods[0]['id'], 'multiValue' => false));
     if (!isset(data_entry_helper::$validation_errors)) {
         // the parent sample and at least one sub-sample have already been created: can't cache in case a new subsample (Count) added.
         data_entry_helper::load_existing_record($auth['read'], 'sample', $parentSampleId);
         $d = new DateTime(data_entry_helper::$entity_to_load['sample:date']);
         data_entry_helper::$entity_to_load['sample:date'] = $d->format('Y');
         // using the report returns the attributes as well.
         $subSamples = data_entry_helper::get_population_data(array('report' => 'library/samples/samples_list_for_parent_sample', 'extraParams' => $auth['read'] + array('sample_id' => $parentSampleId, 'date_from' => '', 'date_to' => '', 'sample_method_id' => '', 'smpattrs' => implode(',', array_keys($attributes))), 'nocache' => true));
         // subssamples ordered by id desc, so reorder by date asc.
         usort($subSamples, "iform_timed_count_subsample_cmp");
         for ($i = 0; $i < count($subSamples); $i++) {
             data_entry_helper::$entity_to_load['C' . ($i + 1) . ':sample:id'] = $subSamples[$i]['sample_id'];
             data_entry_helper::$entity_to_load['C' . ($i + 1) . ':sample:date'] = $subSamples[$i]['date'];
             // this is in correct format
             foreach ($subSamples[$i] as $field => $value) {
                 if (preg_match('/^attr_sample_/', $field)) {
                     $parts = explode('_', $field);
                     if ($subSamples[$i]['attr_id_sample_' . $parts[2]] != null) {
                         data_entry_helper::$entity_to_load['C' . ($i + 1) . ':smpAttr:' + $parts[2] + ':' + $subSamples[$i]['attr_id_sample_' . $parts[2]]] = $value;
                     }
                 }
             }
         }
     }
     data_entry_helper::$javascript .= "indiciaData.speciesList = " . $args['taxon_list_id'] . ";\n";
     if (!empty($args['taxon_filter_field']) && !empty($args['taxon_filter'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesListFilterField = '" . $args['taxon_filter_field'] . "';\n";
         $filterLines = helper_base::explode_lines($args['taxon_filter']);
         data_entry_helper::$javascript .= "indiciaData.speciesListFilterValues = '" . json_encode($filterLines) . "';\n";
     }
     data_entry_helper::$javascript .= "\r\nindiciaData.indiciaSvc = '" . data_entry_helper::$base_url . "';\n";
     data_entry_helper::$javascript .= "indiciaData.readAuth = {nonce: '" . $auth['read']['nonce'] . "', auth_token: '" . $auth['read']['auth_token'] . "'};\n";
     data_entry_helper::$javascript .= "indiciaData.parentSample = " . $parentSampleId . ";\n";
     data_entry_helper::$javascript .= "indiciaData.occAttrId = " . $args['occurrence_attribute_id'] . ";\n";
     if ($existing) {
         // Only need to load the occurrences for a pre-existing sample
         $o = data_entry_helper::get_population_data(array('report' => 'library/occurrences/occurrences_list_for_parent_sample', 'extraParams' => $auth['read'] + array('view' => 'detail', 'sample_id' => $parentSampleId, 'survey_id' => '', 'date_from' => '', 'date_to' => '', 'taxon_group_id' => '', 'smpattrs' => '', 'occattrs' => $args['occurrence_attribute_id']), 'nocache' => true));
         // the report is ordered id desc. REverse it
         $o = array_reverse($o);
     } else {
         $o = array();
     }
     // empty array of occurrences when no creating a new sample.
     // we pass through the read auth. This makes it possible for the get_submission method to authorise against the warehouse
     // without an additional (expensive) warehouse call.
     // pass a param that sets the next page to display
     $r = "<form method='post' id='subsamples'>" . $auth['write'] . "\r\n<input type='hidden' name='page' value='occurrences'/>\r\n<input type='hidden' name='read_nonce' value='" . $auth['read']['nonce'] . "'/>\r\n<input type='hidden' name='read_auth_token' value='" . $auth['read']['auth_token'] . "'/>\r\n<input type='hidden' name='website_id' value='" . $args['website_id'] . "'/>\r\n<input type='hidden' name='sample:id' value='" . data_entry_helper::$entity_to_load['sample:id'] . "'/>\r\n<input type='hidden' name='sample:survey_id' value='" . $args['survey_id'] . "'/>\r\n<input type='hidden' name='sample:date' value='" . data_entry_helper::$entity_to_load['sample:date'] . "'/>\r\n<input type='hidden' name='sample:entered_sref' value='" . data_entry_helper::$entity_to_load['sample:entered_sref'] . "'/>\r\n<input type='hidden' name='sample:entered_sref_system' value='" . data_entry_helper::$entity_to_load['sample:entered_sref_system'] . "'/>\r\n<input type='hidden' name='sample:geom' value='" . data_entry_helper::$entity_to_load['sample:geom'] . "'/>\r\n";
     if (isset($args['custom_attribute_options']) && $args['custom_attribute_options']) {
         $blockOptions = get_attr_options_array_with_user_data($args['custom_attribute_options']);
     } else {
         $blockOptions = array();
     }
     for ($i = 0; $i < $args['numberOfCounts']; $i++) {
         $subSampleId = isset($subSamples[$i]) ? $subSamples[$i]['sample_id'] : null;
         $r .= "<fieldset id=\"count-{$i}\"><legend>" . lang::get('Count ') . ($i + 1) . "</legend>";
         if ($subSampleId) {
             $r .= "<input type='hidden' name='C" . ($i + 1) . ":sample:id' value='" . $subSampleId . "'/>";
         }
         $r .= '<input type="hidden" name="C' . ($i + 1) . ':sample:sample_method_id" value="' . $sampleMethods[0]['id'] . '" />';
         if ($subSampleId || isset(data_entry_helper::$entity_to_load['C' . ($i + 1) . ':sample:date']) && data_entry_helper::$entity_to_load['C' . ($i + 1) . ':sample:date'] != '') {
             $dateValidation = array('required', 'date');
         } else {
             $dateValidation = array('date');
         }
         $r .= data_entry_helper::date_picker(array('label' => lang::get('Date'), 'fieldname' => 'C' . ($i + 1) . ':sample:date', 'validation' => $dateValidation));
         data_entry_helper::$javascript .= "\$('#C" . ($i + 1) . "\\\\:sample\\\\:date' ).datepicker( 'option', 'minDate', new Date(" . data_entry_helper::$entity_to_load['sample:date'] . ", 1 - 1, 1) );\r\n\$('#C" . ($i + 1) . "\\\\:sample\\\\:date' ).datepicker( 'option', 'maxDate', new Date(" . data_entry_helper::$entity_to_load['sample:date'] . ", 12 - 1, 31) );\n";
         if (!$subSampleId && $i) {
             $r .= "<p>" . lang::get('You must enter the date before you can enter any further information.') . '</p>';
             data_entry_helper::$javascript .= "\$('#C" . ($i + 1) . "\\\\:sample\\\\:date' ).change(function(){\r\n  myFieldset = \$(this).addClass('required').closest('fieldset');\r\n  myFieldset.find('.smp-input,[name=taxonLookupControl]').removeAttr('disabled'); // leave the count fields as are.\r\n});\n";
         }
         if ($subSampleId && $i) {
             $r .= "<label for='C" . ($i + 1) . ":sample:deleted'>Delete this count:</label>\r\n<input id='C" . ($i + 1) . ":sample:deleted' type='checkbox' value='t' name='C" . ($i + 1) . ":sample:deleted'><br />\r\n<p>" . lang::get('Setting this will delete this count when the page is saved.') . '</p>';
         }
         foreach ($attributes as $attr) {
             if (strcasecmp($attr['untranslatedCaption'], 'Unconfirmed Individuals') == 0) {
                 continue;
             }
             // output the attribute - tag it with a class & id to make it easy to find from JS.
             $attrOpts = array_merge(isset($blockOptions[$attr['fieldname']]) ? $blockOptions[$attr['fieldname']] : array(), array('class' => 'smp-input smpAttr-' . ($i + 1), 'id' => 'C' . ($i + 1) . ':' . $attr['fieldname'], 'fieldname' => 'C' . ($i + 1) . ':' . $attr['fieldname'], 'extraParams' => $auth['read']));
             // we need process validation specially: deh expects an array, we have a string...
             if (isset($attrOpts['validation']) && is_string($attrOpts['validation'])) {
                 $attrOpts['validation'] = explode(';', $attrOpts['validation']);
             }
             // if there is an existing value, set it and also ensure the attribute name reflects the attribute value id.
             if (isset($subSampleId)) {
                 // but have to take into account possibility that this field has been blanked out, so deleting the attribute.
                 if (isset($subSamples[$i]['attr_id_sample_' . $attr['attributeId']]) && $subSamples[$i]['attr_id_sample_' . $attr['attributeId']] != '') {
                     $attrOpts['fieldname'] = 'C' . ($i + 1) . ':' . $attr['fieldname'] . ':' . $subSamples[$i]['attr_id_sample_' . $attr['attributeId']];
                     $attr['default'] = $subSamples[$i]['attr_sample_' . $attr['attributeId']];
                 }
             } else {
                 if ($i) {
                     $attrOpts['disabled'] = "disabled=\"disabled\"";
                 }
             }
             $r .= data_entry_helper::outputAttribute($attr, $attrOpts);
         }
         $r .= '<table id="timed-counts-input-' . $i . '" class="ui-widget">';
         $r .= '<thead><tr><th class="ui-widget-header">' . lang::get('Species') . '</th><th class="ui-widget-header">' . lang::get('Count') . '</th><th class="ui-widget-header"></th></tr></thead>';
         $r .= '<tbody class="ui-widget-content">';
         $occs = array();
         // not very many occurrences so no need to optimise.
         if (isset($subSampleId) && $existing && count($o) > 0) {
             foreach ($o as $oc) {
                 if ($oc['sample_id'] == $subSampleId) {
                     $occs[] = $oc;
                 }
             }
         }
         for ($j = 0; $j < $args['numberOfSpecies']; $j++) {
             $rowClass = '';
             // O<i>:<j>:<ttlid>:<occid>:<attrid>:<attrvalid>
             if (isset($occs[$j])) {
                 $taxon = $occs[$j]['common'] . ' (' . $occs[$j]['taxon'] . ')';
                 $fieldname = 'O' . ($i + 1) . ':' . ($j + 1) . ':' . $occs[$j]['taxa_taxon_list_id'] . ':' . $occs[$j]['occurrence_id'] . ':' . $args['occurrence_attribute_id'] . ':' . $occs[$j]['attr_id_occurrence_' . $args['occurrence_attribute_id']];
                 $value = $occs[$j]['attr_occurrence_' . $args['occurrence_attribute_id']];
             } else {
                 $taxon = '';
                 $fieldname = 'O' . ($i + 1) . ':' . ($j + 1) . ':--ttlid--:--occid--:' . $args['occurrence_attribute_id'] . ':--valid--';
                 $value = '';
             }
             $r .= '<tr ' . $rowClass . '>' . '<td><input id="TLC-' . ($i + 1) . '-' . ($j + 1) . '" name="taxonLookupControl" value="' . $taxon . '" ' . (!$j && (!$i || $subSampleId) || $taxon ? 'class="required"' : '') . ' ' . (!$subSampleId && $i ? 'disabled="disabled"' : '') . '>' . (!$j && (!$i || $subSampleId) || $taxon ? '<span class="deh-required">*</span>' : '') . '</td>' . '<td><input name="' . $fieldname . '" id="occ-' . ($i + 1) . '-' . ($j + 1) . '" value="' . $value . '" class="occValField integer ' . (!$j && (!$i || $subSampleId) || $taxon ? 'required' : '') . '" ' . (!$subSampleId && $i || $taxon == '' && ($i || $j) ? 'disabled="disabled"' : '') . ' min=0 >' . (!$j && (!$i || $subSampleId) || $taxon ? '<span class="deh-required">*</span>' : '') . '</td>' . '<td>' . (!$j ? '' : '<div class="ui-state-default remove-button">' . lang::get('Remove this Species entry') . '</div>') . '</td>' . '</tr>';
             $rowClass = $rowClass == '' ? 'class="alt-row"' : '';
             data_entry_helper::$javascript .= "bindSpeciesAutocomplete(\"TLC-" . ($i + 1) . "-" . ($j + 1) . "\",\"occ-" . ($i + 1) . "-" . ($j + 1) . "\",\"" . data_entry_helper::$base_url . "index.php/services/data\", \"" . $args['taxon_list_id'] . "\",\r\n  indiciaData.speciesListFilterField, indiciaData.speciesListFilterValues, {\"auth_token\" : \"" . $auth['read']['auth_token'] . "\", \"nonce\" : \"" . $auth['read']['nonce'] . "\"}, 25);\n";
         }
         foreach ($attributes as $attr) {
             if (strcasecmp($attr['untranslatedCaption'], 'Unconfirmed Individuals')) {
                 continue;
             }
             // output the attribute - tag it with a class & id to make it easy to find from JS.
             $attrOpts = array('class' => 'smp-input smpAttr-' . ($i + 1), 'id' => 'C' . ($i + 1) . ':' . $attr['fieldname'], 'fieldname' => 'C' . ($i + 1) . ':' . $attr['fieldname'], 'extraParams' => $auth['read']);
             // if there is an existing value, set it and also ensure the attribute name reflects the attribute value id.
             if (isset($subSampleId)) {
                 // but have to take into account possibility that this field has been blanked out, so deleting the attribute.
                 if (isset($subSamples[$i]['attr_id_sample_' . $attr['attributeId']]) && $subSamples[$i]['attr_id_sample_' . $attr['attributeId']] != '') {
                     $attrOpts['fieldname'] = 'C' . ($i + 1) . ':' . $attr['fieldname'] . ':' . $subSamples[$i]['attr_id_sample_' . $attr['attributeId']];
                     $attr['default'] = $subSamples[$i]['attr_sample_' . $attr['attributeId']];
                 }
             } else {
                 if ($i) {
                     $attrOpts['disabled'] = "disabled=\"disabled\"";
                 }
             }
             $r .= '<tr ' . $rowClass . '>' . '<td>' . $attr['caption'] . '</td>';
             unset($attr['caption']);
             $r .= '<td>' . data_entry_helper::outputAttribute($attr, $attrOpts) . '</td>' . '<td></td>' . '</tr>';
         }
         $r .= '</tbody></table>';
         if ($i && !$subSampleId) {
             $r .= '<button type="button" class="clear-button ui-state-default ui-corner-all smp-input" disabled="disabled" />' . lang::get('Clear this count') . '</button>';
         }
         $r .= '</fieldset>';
     }
     $r .= '<input type="submit" value="' . lang::get('Save') . '" />';
     $r .= '<a href="' . $args['summary_page'] . '"><button type="button" class="ui-state-default ui-corner-all" />' . lang::get('Cancel') . '</button></a></form>';
     data_entry_helper::enable_validation('subsamples');
     data_entry_helper::$javascript .= "initButtons();\n";
     return $r;
 }
 public static function get_sample_form($args, $node, $response)
 {
     global $user;
     if (!module_exists('iform_ajaxproxy')) {
         return 'This form must be used in Drupal with the Indicia AJAX Proxy module enabled.';
     }
     iform_load_helpers(array('map_helper'));
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $sampleId = isset($_GET['sample_id']) ? $_GET['sample_id'] : null;
     $locationId = null;
     if ($sampleId) {
         data_entry_helper::load_existing_record($auth['read'], 'sample', $sampleId, 'detail', false, true);
         $locationId = data_entry_helper::$entity_to_load['sample:location_id'];
     } else {
         // location ID also might be in the $_POST data after a validation save of a new record
         if (isset($_POST['sample:location_id'])) {
             $locationId = $_POST['sample:location_id'];
         }
     }
     $url = explode('?', $args['my_obs_page'], 2);
     $params = NULL;
     $fragment = NULL;
     // fragment is always at the end.
     if (count($url) > 1) {
         $params = explode('#', $url[1], 2);
         if (count($params) > 1) {
             $fragment = $params[1];
         }
         $params = $params[0];
     } else {
         $url = explode('#', $url[0], 2);
         if (count($url) > 1) {
             $fragment = $url[1];
         }
     }
     $args['my_obs_page'] = url($url[0], array('query' => $params, 'fragment' => $fragment, 'absolute' => TRUE));
     $r = '<form method="post" id="sample">';
     $r .= $auth['write'];
     $r .= '<input type="hidden" name="page" value="mainSample"/>';
     $r .= '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>';
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         $r .= '<input type="hidden" name="sample:id" value="' . data_entry_helper::$entity_to_load['sample:id'] . '"/>';
     }
     $r .= '<input type="hidden" name="sample:survey_id" value="' . $args['survey_id'] . '"/>';
     $r .= '<div id="cols" class="ui-helper-clearfix"><div class="left" style="width: ' . (98 - (isset($args['percent_width']) ? $args['percent_width'] : 50)) . '%">';
     // Output only the locations for this website and location type.
     $availableSites = data_entry_helper::get_population_data(array('report' => 'library/locations/locations_list', 'extraParams' => $auth['read'] + array('website_id' => $args['website_id'], 'location_type_id' => $args['locationType'], 'locattrs' => 'CMS User ID', 'attr_location_cms_user_id' => $user->uid), 'nocache' => true));
     // convert the report data to an array for the lookup, plus one to pass to the JS so it can keep the map updated
     $sitesLookup = array();
     $sitesIds = array();
     $sitesJs = array();
     foreach ($availableSites as $site) {
         $sitesLookup[$site['location_id']] = $site['name'];
         $sitesIds[] = $site['location_id'];
     }
     $sites = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('website_id' => $args['website_id'], 'id' => $sitesIds, 'view' => 'detail')));
     foreach ($sites as $site) {
         $sitesJs[$site['id']] = $site;
     }
     data_entry_helper::$javascript .= "indiciaData.sites = " . json_encode($sitesJs) . ";\n";
     if ($locationId) {
         $r .= '<input type="hidden" name="sample:location_id" id="sample_location_id" value="' . $locationId . '"/>';
         // for reload of existing, don't let the user switch the square as that could mess everything up.
         $r .= '<label>' . lang::get('1km square') . ':</label><span>' . $sitesJs[$locationId]['name'] . '</span><br/>' . lang::get('<p class="ui-state-highlight page-notice ui-corner-all">Please use the map to select a more precise location for your timed observation.</p>');
     } else {
         $options = array('label' => lang::get('Select 1km square'), 'validation' => array('required'), 'blankText' => lang::get('Please select'), 'lookupValues' => $sitesLookup, 'id' => "sample_location_id");
         // if ($locationId) $options['default'] = $locationId;
         $r .= data_entry_helper::location_select($options) . lang::get('<p class="ui-state-highlight page-notice ui-corner-all">After selecting the 1km square, use the map to select a more precise location for your timed observation.</p>');
     }
     // [spatial reference]
     $systems = array();
     foreach (explode(',', str_replace(' ', '', $args['spatial_systems'])) as $system) {
         $systems[$system] = lang::get("sref:{$system}");
     }
     $r .= data_entry_helper::sref_and_system(array('label' => lang::get('Grid Ref'), 'systems' => $systems));
     $r .= data_entry_helper::file_box(array('table' => 'sample_image', 'readAuth' => $auth['read'], 'caption' => lang::get('Upload photo(s) of timed search area')));
     $sampleMethods = helper_base::get_termlist_terms($auth, 'indicia:sample_methods', array('Field Observation'));
     $attributes = data_entry_helper::getAttributes(array('id' => $sampleId, 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'sample_method_id' => $sampleMethods[0]['id']));
     $r .= get_user_profile_hidden_inputs($attributes, $args, '', $auth['read']);
     if (isset($_GET['date'])) {
         $r .= '<input type="hidden" name="sample:date" value="' . $_GET['date'] . '"/>';
         $r .= '<label>' . lang::get('Date') . ':</label> <span class="value-label">' . $_GET['date'] . '</span><br/>';
     } else {
         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
             // @todo The date format should be a global configurable option. It should also be applied to reloading of custom date attributes.
             $d = new DateTime(data_entry_helper::$entity_to_load['sample:date']);
             data_entry_helper::$entity_to_load['sample:date'] = $d->format('d/m/Y');
         }
         $r .= data_entry_helper::date_picker(array('label' => lang::get('Date'), 'fieldname' => 'sample:date'));
     }
     // are there any option overrides for the custom attributes?
     if (isset($args['custom_attribute_options']) && $args['custom_attribute_options']) {
         $blockOptions = get_attr_options_array_with_user_data($args['custom_attribute_options']);
     } else {
         $blockOptions = array();
     }
     $r .= get_attribute_html($attributes, $args, array('extraParams' => $auth['read']), null, $blockOptions);
     $r .= '<input type="hidden" name="sample:sample_method_id" value="' . $sampleMethods[0]['id'] . '" />';
     $r .= '<input type="submit" value="' . lang::get('Next') . '" />';
     $r .= '<a href="' . $args['my_obs_page'] . '" class="button">' . lang::get('Cancel') . '</a>';
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         $r .= '<button id="delete-button" type="button" class="ui-state-default ui-corner-all" />' . lang::get('Delete') . '</button>';
     }
     $r .= "</div>";
     // left
     $r .= '<div class="right" style="width: ' . (isset($args['percent_width']) ? $args['percent_width'] : 50) . '%">';
     // [place search]
     $georefOpts = iform_map_get_georef_options($args, $auth['read']);
     $georefOpts['label'] = lang::get('Search for Place on Map');
     // can't use place search without the driver API key
     if ($georefOpts['driver'] == 'geoplanet' && empty(helper_config::$geoplanet_api_key)) {
         $r .= '<span style="display: none;">The form structure includes a place search but needs a geoplanet api key.</span>';
     } else {
         $r .= data_entry_helper::georeference_lookup($georefOpts);
     }
     // [map]
     $options = iform_map_get_map_options($args, $auth['read']);
     if (!empty(data_entry_helper::$entity_to_load['sample:wkt'])) {
         $options['initialFeatureWkt'] = data_entry_helper::$entity_to_load['sample:wkt'];
     }
     $olOptions = iform_map_get_ol_options($args);
     if (!isset($options['standardControls'])) {
         $options['standardControls'] = array('layerSwitcher', 'panZoomBar');
     }
     $r .= map_helper::map_panel($options, $olOptions);
     data_entry_helper::$javascript .= "\nmapInitialisationHooks.push(function(mapdiv) {\n  var defaultStyle = new OpenLayers.Style({pointRadius: 6,fillOpacity: 0,strokeColor: \"Red\",strokeWidth: 1});\n  var SiteStyleMap = new OpenLayers.StyleMap({\"default\": defaultStyle});\n  indiciaData.SiteLayer = new OpenLayers.Layer.Vector('1km square',{styleMap: SiteStyleMap, displayInLayerSwitcher: true});\n  mapdiv.map.addLayer(indiciaData.SiteLayer);\n  if(jQuery('#sample_location_id').length > 0) {\n    if(jQuery('#sample_location_id').val() != ''){\n      var parser = new OpenLayers.Format.WKT();\n      var feature = parser.read(indiciaData.sites[jQuery('#sample_location_id').val()].geom);\n      indiciaData.SiteLayer.addFeatures([feature]);\n      // for existing data we zoom on the site, not this parent location\n    } \n    jQuery('#sample_location_id').change(function(){\n      indiciaData.SiteLayer.destroyFeatures();\n      if(jQuery('#sample_location_id').val() != ''){\n        var parser = new OpenLayers.Format.WKT();\n        var feature = parser.read(indiciaData.sites[jQuery('#sample_location_id').val()].geom);\n        indiciaData.SiteLayer.addFeatures([feature]);\n        var layerBounds = indiciaData.SiteLayer.getDataExtent().clone(); // use a clone\n        indiciaData.SiteLayer.map.zoomToExtent(layerBounds);\n      }\n    });\n  }\n});\n";
     $r .= "</div>";
     // right
     $r .= '</form>';
     // Recorder Name - assume Easy Login uid
     if (function_exists('module_exists') && module_exists('easy_login')) {
         $userId = hostsite_get_user_field('indicia_user_id');
         // For non easy login test only     $userId = 1;
         foreach ($attributes as $attrID => $attr) {
             if (strcasecmp('Recorder Name', $attr["untranslatedCaption"]) == 0 && !empty($userId)) {
                 // determining which you have used is difficult from a services based autocomplete, esp when the created_by_id is not available on the data.
                 data_entry_helper::add_resource('autocomplete');
                 data_entry_helper::$javascript .= "bindRecorderNameAutocomplete(" . $attrID . ", '" . $userId . "', '" . data_entry_helper::$base_url . "', '" . $args['survey_id'] . "', '" . $auth['read']['auth_token'] . "', '" . $auth['read']['nonce'] . "');\n";
             }
         }
     }
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         // allow deletes if sample id is present.
         data_entry_helper::$javascript .= "jQuery('#delete-button').click(function(){\n  if(confirm(\"" . lang::get('Are you sure you want to delete this walk?') . "\")){\n    jQuery('#delete-form').submit();\n  } // else do nothing.\n});\n";
         // note we only require bare minimum in order to flag a sample as deleted.
         $r .= '<form method="post" id="delete-form" style="display: none;">';
         $r .= $auth['write'];
         $r .= '<input type="hidden" name="page" value="delete"/>';
         $r .= '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>';
         $r .= '<input type="hidden" name="sample:id" value="' . data_entry_helper::$entity_to_load['sample:id'] . '"/>';
         $r .= '<input type="hidden" name="sample:deleted" value="t"/>';
         $r .= '</form>';
     }
     data_entry_helper::enable_validation('sample');
     return $r;
 }
 public static function get_sample_form($args, $node, $response)
 {
     global $user;
     if (!module_exists('iform_ajaxproxy')) {
         return 'This form must be used in Drupal with the Indicia AJAX Proxy module enabled.';
     }
     iform_load_helpers(array('map_helper'));
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $sampleId = isset($_GET['sample_id']) ? $_GET['sample_id'] : null;
     if ($sampleId) {
         data_entry_helper::load_existing_record($auth['read'], 'sample', $sampleId);
         $locationId = data_entry_helper::$entity_to_load['sample:location_id'];
     } else {
         $locationId = isset($_GET['site']) ? $_GET['site'] : null;
         // location ID also might be in the $_POST data after a validation save of a new record
         if (!$locationId && isset($_POST['sample:location_id'])) {
             $locationId = $_POST['sample:location_id'];
         }
     }
     $url = explode('?', $args['my_walks_page'], 2);
     $params = NULL;
     $fragment = NULL;
     // fragment is always at the end.
     if (count($url) > 1) {
         $params = explode('#', $url[1], 2);
         if (count($params) > 1) {
             $fragment = $params[1];
         }
         $params = $params[0];
     } else {
         $url = explode('#', $url[0], 2);
         if (count($url) > 1) {
             $fragment = $url[1];
         }
     }
     $args['my_walks_page'] = url($url[0], array('query' => $params, 'fragment' => $fragment, 'absolute' => TRUE));
     $r = '<form method="post" id="sample">';
     $r .= $auth['write'];
     // we pass through the read auth. This makes it possible for the get_submission method to authorise against the warehouse
     // without an additional (expensive) warehouse call, so it can get location details.
     $r .= '<input type="hidden" name="page" value="mainSample"/>';
     $r .= '<input type="hidden" name="read_nonce" value="' . $auth['read']['nonce'] . '"/>';
     $r .= '<input type="hidden" name="read_auth_token" value="' . $auth['read']['auth_token'] . '"/>';
     $r .= '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>';
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         $r .= '<input type="hidden" name="sample:id" value="' . data_entry_helper::$entity_to_load['sample:id'] . '"/>';
     }
     $r .= '<input type="hidden" name="sample:survey_id" value="' . $args['survey_id'] . '"/>';
     if (isset($args['include_map_samples_form']) && $args['include_map_samples_form']) {
         $r .= '<div id="cols" class="ui-helper-clearfix"><div class="left" style="width: ' . (98 - (isset($args['percent_width']) ? $args['percent_width'] : 50)) . '%">';
     }
     if ($locationId) {
         $site = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('view' => 'detail', 'id' => $locationId, 'deleted' => 'f')));
         $site = $site[0];
         $r .= '<input type="hidden" name="sample:location_id" value="' . $locationId . '"/>';
         $r .= '<input type="hidden" name="sample:entered_sref" value="' . $site['centroid_sref'] . '"/>';
         $r .= '<input type="hidden" name="sample:entered_sref_system" value="' . $site['centroid_sref_system'] . '"/>';
     }
     if ($locationId && (isset(data_entry_helper::$entity_to_load['sample:id']) || isset($_GET['site']))) {
         // for reload of existing or the the site is specified in the URL, don't let the user switch the transect as that would mess everything up.
         $r .= '<label>' . lang::get('Transect') . ':</label> <span class="value-label">' . $site['name'] . '</span><br/>';
     } else {
         // Output only the locations for this website and transect type. Note we load both transects and sections, just so that
         // we always use the same warehouse call and therefore it uses the cache.
         $typeTerms = array(empty($args['transect_type_term']) ? 'Transect' : $args['transect_type_term'], empty($args['section_type_term']) ? 'Section' : $args['section_type_term']);
         $locationTypes = helper_base::get_termlist_terms($auth, 'indicia:location_types', $typeTerms);
         $siteParams = $auth['read'] + array('website_id' => $args['website_id'], 'location_type_id' => $locationTypes[0]['id']);
         if ((!isset($args['user_locations_filter']) || $args['user_locations_filter']) && (!isset($args['managerPermission']) || !user_access($args['managerPermission']))) {
             $siteParams += array('locattrs' => 'CMS User ID', 'attr_location_cms_user_id' => $user->uid);
         } else {
             $siteParams += array('locattrs' => '');
         }
         $availableSites = data_entry_helper::get_population_data(array('report' => 'library/locations/locations_list', 'extraParams' => $siteParams, 'nocache' => true));
         // convert the report data to an array for the lookup, plus one to pass to the JS so it can keep the hidden sref fields updated
         $sitesLookup = array();
         $sitesJs = array();
         foreach ($availableSites as $site) {
             $sitesLookup[$site['location_id']] = $site['name'];
             $sitesJs[$site['location_id']] = $site;
         }
         // bolt in branch locations. Don't assume that branch list is superset of normal sites list.
         // Only need to do if not a manager - they have already fetched the full list anyway.
         if (isset($args['branch_assignment_permission']) && user_access($args['branch_assignment_permission']) && $siteParams['locattrs'] != '') {
             $siteParams['locattrs'] = 'Branch CMS User ID';
             $siteParams['attr_location_branch_cms_user_id'] = $user->uid;
             unset($siteParams['attr_location_cms_user_id']);
             $availableSites = data_entry_helper::get_population_data(array('report' => 'library/locations/locations_list', 'extraParams' => $siteParams, 'nocache' => true));
             foreach ($availableSites as $site) {
                 $sitesLookup[$site['location_id']] = $site['name'];
                 $sitesJs[$site['location_id']] = $site;
             }
             natcasesort($sitesLookup);
             // merge into original list in alphabetic order.
         }
         data_entry_helper::$javascript .= "indiciaData.sites = " . json_encode($sitesJs) . ";\n";
         $options = array('label' => lang::get('Select Transect'), 'validation' => array('required'), 'blankText' => lang::get('please select'), 'lookupValues' => $sitesLookup);
         if ($locationId) {
             $options['default'] = $locationId;
         }
         $r .= data_entry_helper::location_select($options);
     }
     if (!$locationId) {
         $r .= '<input type="hidden" name="sample:entered_sref" value="" id="entered_sref"/>';
         $r .= '<input type="hidden" name="sample:entered_sref_system" value="" id="entered_sref_system"/>';
         // sref values for the sample will be populated automatically when the submission is built.
     }
     $sampleMethods = helper_base::get_termlist_terms($auth, 'indicia:sample_methods', array('Transect'));
     $attributes = data_entry_helper::getAttributes(array('id' => $sampleId, 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'sample_method_id' => $sampleMethods[0]['id']));
     $r .= get_user_profile_hidden_inputs($attributes, $args, '', $auth['read']);
     if (isset($_GET['date'])) {
         $r .= '<input type="hidden" name="sample:date" value="' . $_GET['date'] . '"/>';
         $r .= '<label>' . lang::get('Date') . ':</label> <span class="value-label">' . $_GET['date'] . '</span><br/>';
     } else {
         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
             // @todo The date format should be a global configurable option. It should also be applied to reloading of custom date attributes.
             $d = new DateTime(data_entry_helper::$entity_to_load['sample:date']);
             data_entry_helper::$entity_to_load['sample:date'] = $d->format('d/m/Y');
         }
         $r .= data_entry_helper::date_picker(array('label' => lang::get('Date'), 'fieldname' => 'sample:date'));
     }
     // are there any option overrides for the custom attributes?
     if (isset($args['custom_attribute_options']) && $args['custom_attribute_options']) {
         $blockOptions = get_attr_options_array_with_user_data($args['custom_attribute_options']);
     } else {
         $blockOptions = array();
     }
     $r .= get_attribute_html($attributes, $args, array('extraParams' => $auth['read']), null, $blockOptions);
     $r .= '<input type="hidden" name="sample:sample_method_id" value="' . $sampleMethods[0]['id'] . '" />';
     $r .= '<input type="submit" value="' . lang::get('Next') . '" />';
     $r .= '<a href="' . $args['my_walks_page'] . '" class="button">' . lang::get('Cancel') . '</a>';
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         $r .= '<button id="delete-button" type="button" class="ui-state-default ui-corner-all" />' . lang::get('Delete') . '</button>';
     }
     if (isset($args['include_map_samples_form']) && $args['include_map_samples_form']) {
         $r .= "</div>" . '<div class="right" style="width: ' . (isset($args['percent_width']) ? $args['percent_width'] : 50) . '%">';
         // no place search: [map]
         $options = iform_map_get_map_options($args, $auth['read']);
         if (!empty(data_entry_helper::$entity_to_load['sample:wkt'])) {
             $options['initialFeatureWkt'] = data_entry_helper::$entity_to_load['sample:wkt'];
         }
         $olOptions = iform_map_get_ol_options($args);
         if (!isset($options['standardControls'])) {
             $options['standardControls'] = array('layerSwitcher', 'panZoomBar');
         }
         $r .= map_helper::map_panel($options, $olOptions);
         $r .= "</div>";
         // right
     }
     $r .= '</form>';
     // Recorder Name - assume Easy Login uid
     if (function_exists('module_exists') && module_exists('easy_login')) {
         $userId = hostsite_get_user_field('indicia_user_id');
         // For non easy login test only     $userId = 1;
         foreach ($attributes as $attrID => $attr) {
             if (strcasecmp('Recorder Name', $attr["untranslatedCaption"]) == 0 && !empty($userId)) {
                 // determining which you have used is difficult from a services based autocomplete, esp when the created_by_id is not available on the data.
                 data_entry_helper::add_resource('autocomplete');
                 data_entry_helper::$javascript .= "bindRecorderNameAutocomplete(" . $attrID . ", '" . $userId . "', '" . data_entry_helper::$base_url . "', '" . $args['survey_id'] . "', '" . $auth['read']['auth_token'] . "', '" . $auth['read']['nonce'] . "');\n";
             }
         }
     }
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         // allow deletes if sample id is present.
         data_entry_helper::$javascript .= "jQuery('#delete-button').click(function(){\n  if(confirm(\"" . lang::get('Are you sure you want to delete this walk?') . "\")){\n    jQuery('#delete-form').submit();\n  } // else do nothing.\n});\n";
         // note we only require bare minimum in order to flag a sample as deleted.
         $r .= '<form method="post" id="delete-form" style="display: none;">';
         $r .= $auth['write'];
         $r .= '<input type="hidden" name="page" value="delete"/>';
         $r .= '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>';
         $r .= '<input type="hidden" name="sample:id" value="' . data_entry_helper::$entity_to_load['sample:id'] . '"/>';
         $r .= '<input type="hidden" name="sample:deleted" value="t"/>';
         $r .= '</form>';
     }
     data_entry_helper::enable_validation('sample');
     return $r;
 }