/**
  * Preparing to display an existing sample with occurrences.
  * When displaying a grid of occurrences, just load the sample and data_entry_helper::species_checklist
  * will load the occurrences.
  * When displaying just one occurrence we must load the sample and the occurrence
  */
 protected static function getEntity($args, $auth)
 {
     data_entry_helper::$entity_to_load = array();
     // If we know the occurrence ID but not the sample, we must look it up
     if (self::$loadedOccurrenceId && !self::$loadedSampleId) {
         $response = data_entry_helper::get_population_data(array('table' => 'occurrence', 'extraParams' => $auth['read'] + array('id' => self::$loadedOccurrenceId, 'view' => 'detail')));
         if (count($response) != 0) {
             //we found an occurrence
             self::$loadedSampleId = $response[0]['sample_id'];
         }
     }
     // Load the sample record
     if (self::$loadedSampleId) {
         data_entry_helper::load_existing_record($auth['read'], 'sample', self::$loadedSampleId, 'detail', false, true);
     }
     // Ensure that if we are used to load a different survey's data, then we get the correct survey attributes. We can change args
     // because the caller passes by reference.
     if ($args['survey_id'] != data_entry_helper::$entity_to_load['sample:survey_id']) {
         throw new exception(lang::get('Attempt to access a record on a different survey.'));
     }
     if ($args['sample_method_id'] != data_entry_helper::$entity_to_load['sample:sample_method_id']) {
         throw new exception(lang::get('Attempt to access a record with the wrong sample_method_id.'));
     }
     // enforce that people only access their own data, unless explicitly have permissions
     $editor = !empty($args['edit_permission']) && function_exists('user_access') && user_access($args['edit_permission']);
     if (!$editor && function_exists('hostsite_get_user_field') && data_entry_helper::$entity_to_load['sample:created_by_id'] != 1 && data_entry_helper::$entity_to_load['sample:created_by_id'] !== hostsite_get_user_field('indicia_user_id')) {
         throw new exception(lang::get('Attempt to access a record you did not create.'));
     }
 }
Ejemplo n.º 2
0
 /**
  * Return the generated form output.
  * @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 object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  */
 public static function get_form($args, $node, $response = null)
 {
     $reloadPath = self::get_reload_path();
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $r = "<form method=\"post\" id=\"entry_form\" action=\"{$reloadPath}\">\n";
     $r .= $auth['write'];
     data_entry_helper::$entity_to_load = array();
     if (!empty($_GET['termlists_term_id'])) {
         data_entry_helper::load_existing_record($auth['read'], 'termlists_term', $_GET['termlists_term_id']);
         // map fields to their appropriate supermodels
         data_entry_helper::$entity_to_load['term:term'] = data_entry_helper::$entity_to_load['termlists_term:term'];
         data_entry_helper::$entity_to_load['term:id'] = data_entry_helper::$entity_to_load['termlists_term:term_id'];
         data_entry_helper::$entity_to_load['meaning:id'] = data_entry_helper::$entity_to_load['termlists_term:meaning_id'];
         if (function_exists('hostsite_set_page_title')) {
             hostsite_set_page_title(lang::get('Edit {1}', data_entry_helper::$entity_to_load['term:term']));
         }
     }
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'website_id', 'default' => $args['website_id']));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'termlists_term:id'));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'termlists_term:termlist_id', 'default' => $args['termlist_id']));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'termlists_term:preferred', 'default' => 't'));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'term:id'));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'term:language_id', 'default' => $args['language_id']));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'meaning:id'));
     // request automatic JS validation
     data_entry_helper::enable_validation('entry_form');
     $r .= data_entry_helper::text_input(array('label' => lang::get('Term'), 'fieldname' => 'term:term', 'helpText' => lang::get('Please provide the term'), 'validation' => array('required'), 'class' => 'control-width-5'));
     $r .= "<input type=\"submit\" name=\"form-submit\" id=\"delete\" value=\"Delete\" />\n";
     $r .= "<input type=\"submit\" name=\"form-submit\" value=\"Save\" />\n";
     $r .= '<form>';
     self::set_breadcrumb($args);
     return $r;
 }
Ejemplo n.º 3
0
 /**
  * Return the generated form output.
  * @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 object $node The Drupal node object.
  * @param array $errors When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  */
 public static function get_form($args, $node, $errors = null)
 {
     $r = '';
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     // variables to tracks which parts of the plots grid are not completed, so we can display a correct message
     $someGridRefsMissing = false;
     $someHabitatsMissing = false;
     $someSqTypesMissing = false;
     data_entry_helper::$validation_mode = array('colour', 'hint', 'message');
     if (isset($_GET['sample_id'])) {
         data_entry_helper::load_existing_record($auth['read'], 'sample', $_GET['sample_id']);
         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');
         }
         $topSampleAttrs = self::load_top_sample_attrs($auth, $args, $_GET['sample_id']);
     } else {
         $topSampleAttrs = self::load_top_sample_attrs($auth, $args);
     }
     global $indicia_templates;
     $indicia_templates['starredSuffix'] = "*<br/>\n";
     $indicia_templates['validation_message'] = "<span class=\"ui-state-error-text\">{error}</span>\n";
     data_entry_helper::enable_validation('entry-form');
     $r .= '<form method="post" action="" id="entry-form">';
     $r .= '<div id="tabs">';
     data_entry_helper::enable_tabs(array('divId' => 'tabs', 'navButtons' => true));
     $r .= data_entry_helper::tab_header(array('tabs' => array('#your-square' => 'Find Place', '#your-plots' => 'Your Plots', '#species_1' => 'Species Page 1', '#species_2' => 'Species Page 2', '#species_3' => 'Species Page 3', '#species_other' => 'Other Species')));
     $r .= '<div id="your-square">';
     $r .= self::get_hiddens($args, $auth);
     $r .= self::tab_your_square($args, $auth['read'], $topSampleAttrs);
     $r .= '</div>';
     // your-square
     $r .= '<div id="your-plots">';
     $r .= self::tab_your_plots($args, $auth['read']);
     $r .= '</div>';
     // your-plots
     $r .= '<div id="species_1">';
     $r .= self::tab_species($args, $auth, 0, 34);
     $r .= '</div>';
     // species-1
     $r .= '<div id="species_2">';
     $r .= self::tab_species($args, $auth, 34, 34);
     $r .= '</div>';
     // species-2
     $r .= '<div id="species_3">';
     $r .= self::tab_species($args, $auth, 68, 34);
     $r .= '</div>';
     // species-3
     $r .= '<div id="species_other">';
     $r .= self::tab_other_species($args, $auth);
     $r .= '</div>';
     // species-3
     $r .= '</div>';
     // tabs
     $r .= '</form>';
     return $r;
 }
 /**
  * Return the generated form output.
  * @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 object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  * @todo: Implement this method 
  */
 public static function get_form($args, $node, $response = null)
 {
     require_once drupal_get_path('module', 'iform') . '/client_helpers/map_helper.php';
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $settings = array('locationTypes' => helper_base::get_termlist_terms($auth, 'indicia:location_types', array('Transect Section')), 'locationId' => isset($_GET['section_id']) ? $_GET['section_id'] : null, 'parentId' => isset($_GET['transect_id']) ? $_GET['transect_id'] : null);
     if ($settings['parentId']) {
         $parent = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('view' => 'detail', 'id' => $settings['parentId'], 'deleted' => 'f'), 'nocache' => true));
         $settings['parent'] = $parent[0];
     } else {
         return 'This form must be called with a parent transect_id parameter.';
     }
     $settings['sections'] = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('view' => 'detail', 'parent_id' => $settings['parentId'], 'deleted' => 'f'), 'nocache' => true));
     if ($settings['locationId']) {
         data_entry_helper::load_existing_record($auth['read'], 'location', $settings['locationId']);
     } else {
         data_entry_helper::$entity_to_load['location:code'] = 'S' . (count($settings['sections']) + 1);
     }
     $settings['attributes'] = data_entry_helper::getAttributes(array('id' => $settings['locationId'], 'valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'location_type_id' => $settings['locationTypes'][0]['id']));
     if (data_entry_helper::$entity_to_load['location:code']) {
         $r = '<form method="post" id="input-form">';
     }
     $r .= $auth['write'];
     $r .= '<div id="controls">';
     $customAttributeTabs = array_merge(array('Section' => array('[*]')), get_attribute_tabs($settings['attributes']));
     if (count($customAttributeTabs) > 1) {
         $headerOptions = array('tabs' => array());
         foreach ($customAttributeTabs as $tab => $content) {
             $alias = preg_replace('/[^a-zA-Z0-9]/', '', strtolower($tab));
             $headerOptions['tabs']['#' . $alias] = lang::get($tab);
         }
         $r .= data_entry_helper::tab_header($headerOptions);
         data_entry_helper::enable_tabs(array('divId' => 'controls', 'style' => $args['interface'], 'progressBar' => isset($args['tabProgress']) && $args['tabProgress'] == true));
     }
     foreach ($customAttributeTabs as $tab => $content) {
         if ($tab == 'Section') {
             $r .= self::get_section_tab($auth, $args, $settings);
         } else {
             $alias = preg_replace('/[^a-zA-Z0-9]/', '', strtolower($tab));
             $r .= "\n<div id=\"{$alias}\">\n";
             $r .= get_attribute_html($settings['attributes'], $args, array('extraParams' => $auth['read']), $tab);
             $r .= "</div>\n";
         }
     }
     $r .= '</div>';
     // controls
     $r .= '</form>';
     data_entry_helper::link_default_stylesheet();
     if (function_exists('drupal_set_breadcrumb')) {
         $breadcrumb = array();
         $breadcrumb[] = l('Home', '<front>');
         $breadcrumb[] = l('Sites', $args['sites_list_path']);
         $breadcrumb[] = l($settings['parent']['name'], $args['transect_edit_path'], array('query' => array('id' => $settings['parentId'])));
         $breadcrumb[] = $settings['locationId'] ? data_entry_helper::$entity_to_load['location:name'] : lang::get('new section');
         drupal_set_breadcrumb($breadcrumb);
     }
     return $r;
 }
Ejemplo n.º 5
0
 /**
  * Return the generated form output.
  * @return Form HTML.
  */
 public static function get_form($args)
 {
     require_once drupal_get_path('module', 'iform') . '/client_helpers/map_helper.php';
     $hidden = str_replace("\r\n", "\n", $args['hide_fields']);
     $hidden = explode("\n", $hidden);
     if (empty($_GET['occurrence_id'])) {
         return 'This form requires an occurrence_id parameter in the URL.';
     }
     // Get authorisation tokens to update and read from the Warehouse.
     $auth = data_entry_helper::get_read_auth($args['website_id'], $args['password']);
     data_entry_helper::load_existing_record($auth, 'occurrence', $_GET['occurrence_id']);
     data_entry_helper::load_existing_record($auth, 'sample', data_entry_helper::$entity_to_load['occurrence:sample_id']);
     $r .= "<div id=\"controls\">\n";
     $r .= "<table>\n";
     if (!in_array('Species', $hidden)) {
         $r .= "<tr><td><strong>" . lang::get('Species') . "</strong></td><td>" . data_entry_helper::$entity_to_load['occurrence:taxon'] . "</td></tr>\n";
     }
     if (!in_array('Date', $hidden)) {
         $r .= "<tr><td><strong>Date</strong></td><td>" . data_entry_helper::$entity_to_load['sample:date'] . "</td></tr>\n";
     }
     if (!in_array('Grid Reference', $hidden)) {
         $r .= "<tr><td><strong>Grid Reference</strong></td><td>" . data_entry_helper::$entity_to_load['sample:entered_sref'] . "</td></tr>\n";
     }
     $siteLabels = array();
     if (!empty(data_entry_helper::$entity_to_load['sample:location'])) {
         $siteLabels[] = data_entry_helper::$entity_to_load['sample:location'];
     }
     if (!empty(data_entry_helper::$entity_to_load['sample:location_name'])) {
         $siteLabels[] = data_entry_helper::$entity_to_load['sample:location_name'];
     }
     if (!in_array('Site', $hidden) && !empty($siteLabels)) {
         $r .= "<tr><td><strong>Site</strong></td><td>" . implode(' | ', $siteLabels) . "</td></tr>\n";
     }
     $smpAttrs = data_entry_helper::getAttributes(array('id' => data_entry_helper::$entity_to_load['sample:id'], 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'extraParams' => $auth, 'survey_id' => data_entry_helper::$entity_to_load['occurrence:survey_id']));
     $occAttrs = data_entry_helper::getAttributes(array('id' => $_GET['occurrence_id'], 'valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'extraParams' => $auth, 'survey_id' => data_entry_helper::$entity_to_load['occurrence:survey_id']));
     $attributes = array_merge($smpAttrs, $occAttrs);
     foreach ($attributes as $attr) {
         if (!in_array($attr['caption'], $hidden)) {
             $r .= "<tr><td><strong>" . lang::get($attr['caption']) . "</strong></td><td>" . $attr['displayValue'] . "</td></tr>\n";
         }
     }
     $r .= "</table>\n";
     $r .= "</div>\n";
     $options = iform_map_get_map_options($args, $readAuth);
     $olOptions = iform_map_get_ol_options($args);
     $options['initialFeatureWkt'] = data_entry_helper::$entity_to_load['occurrence:wkt'];
     $r .= map_helper::map_panel($options, $olOptions);
     return $r;
 }
 /**
  * Return the generated form output.
  * @return Form HTML.
  */
 public static function get_form($args)
 {
     if (empty($_GET['occurrence_id'])) {
         return 'This form requires an occurrence_id parameter in the URL.';
     }
     $r = "<form method=\"post\">\n";
     // Get authorisation tokens to update and read from the Warehouse.
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     data_entry_helper::load_existing_record($auth['read'], 'occurrence', $_GET['occurrence_id']);
     data_entry_helper::load_existing_record($auth['read'], 'sample', data_entry_helper::$entity_to_load['occurrence:sample_id']);
     $r .= $auth['write'];
     $r .= "<input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" id=\"occurrence:id\" name=\"occurrence:id\" value=\"" . $_GET['occurrence_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" id=\"occurrence:sample_id\" name=\"occurrence:sample_id\" value=\"" . data_entry_helper::$entity_to_load['sample:id'] . "\" />\n";
     $r .= "<div id=\"controls\">\n";
     $r .= "<table>\n";
     $r .= "<tr><td><strong>Date</strong></td><td>" . data_entry_helper::$entity_to_load['sample:date'] . "</td></tr>\n";
     $r .= "<tr><td><strong>Spatial Reference</strong></td><td>" . data_entry_helper::$entity_to_load['sample:entered_sref'] . "</td></tr>\n";
     $siteLabels = array();
     if (!empty(data_entry_helper::$entity_to_load['sample:location'])) {
         $siteLabels[] = data_entry_helper::$entity_to_load['sample:location'];
     }
     if (!empty(data_entry_helper::$entity_to_load['sample:location_name'])) {
         $siteLabels[] = data_entry_helper::$entity_to_load['sample:location_name'];
     }
     $r .= "<tr><td><strong>Site</strong></td><td>" . implode(' | ', $siteLabels) . "</td></tr>\n";
     $smpAttrs = data_entry_helper::getAttributes(array('id' => data_entry_helper::$entity_to_load['sample:id'], 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'extraParams' => $auth['read'], 'survey_id' => data_entry_helper::$entity_to_load['occurrence:survey_id']));
     $occAttrs = data_entry_helper::getAttributes(array('id' => $_GET['occurrence_id'], 'valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'extraParams' => $auth['read'], 'survey_id' => data_entry_helper::$entity_to_load['occurrence:survey_id']));
     $attributes = array_merge($smpAttrs, $occAttrs);
     foreach ($attributes as $attr) {
         $r .= "<tr><td><strong>" . $attr['caption'] . "</strong></td><td>" . $attr['displayValue'] . "</td></tr>\n";
     }
     $extraParams = $auth['read'] + array('taxon_list_id' => $args['list_id']);
     if ($args['preferred']) {
         $extraParams += array('preferred' => 't');
     }
     $species_list_args = array('itemTemplate' => 'select_species', 'fieldname' => 'occurrence:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 2, 'extraParams' => $extraParams);
     // Dynamically generate the species selection control required.
     $r .= '<tr/><td><strong>Species</strong></td><td>' . call_user_func(array('data_entry_helper', $args['species_ctrl']), $species_list_args) . "</td></tr>\n";
     $r .= "</table>\n";
     $r .= "</div>\n";
     $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"Save\" />\n";
     $r .= "</form>";
     return $r;
 }
Ejemplo n.º 7
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;
 }
Ejemplo n.º 8
0
<div id="wrap">
  <h1>Record details</h1>
<?php 
if ($_POST) {
    $response = data_entry_helper::forward_post_to('occurrence_comment');
    echo data_entry_helper::dump_errors($response);
}
if (empty($_GET['id'])) {
    echo 'This form requires an occurrence_id parameter in the URL.';
    return;
}
data_entry_helper::link_default_stylesheet();
// Get authorisation tokens to update and read from the Warehouse.
$auth = data_entry_helper::get_read_write_auth($config['website_id'], $config['password']);
data_entry_helper::load_existing_record($auth['read'], 'occurrence', $_GET['id']);
data_entry_helper::load_existing_record($auth['read'], 'sample', data_entry_helper::$entity_to_load['occurrence:sample_id']);
$r .= "<div id=\"controls\">\n";
$r .= "<table>\n";
$r .= "<tr><td><strong>" . lang::get('Species') . "</strong></td><td>" . data_entry_helper::$entity_to_load['occurrence:taxon'] . "</td></tr>\n";
$r .= "<tr><td><strong>Date</strong></td><td>" . data_entry_helper::$entity_to_load['sample:date'] . "</td></tr>\n";
$r .= "<tr><td><strong>Grid Reference</strong></td><td>" . data_entry_helper::$entity_to_load['sample:entered_sref'] . "</td></tr>\n";
$siteLabels = array();
if (!empty(data_entry_helper::$entity_to_load['sample:location'])) {
    $siteLabels[] = data_entry_helper::$entity_to_load['sample:location'];
}
if (!empty(data_entry_helper::$entity_to_load['sample:location_name'])) {
    $siteLabels[] = data_entry_helper::$entity_to_load['sample:location_name'];
}
$r .= "<tr><td><strong>Site</strong></td><td>" . implode(' | ', $siteLabels) . "</td></tr>\n";
$smpAttrs = data_entry_helper::getAttributes(array('id' => data_entry_helper::$entity_to_load['sample:id'], 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'extraParams' => $auth['read'], 'survey_id' => data_entry_helper::$entity_to_load['occurrence:survey_id']));
$occAttrs = data_entry_helper::getAttributes(array('id' => $_GET['occurrence_id'], 'valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'extraParams' => $auth['read'], 'survey_id' => data_entry_helper::$entity_to_load['occurrence:survey_id']));
 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.';
     }
     require_once dirname(dirname(__FILE__)) . '/map_helper.php';
     $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'];
         }
     }
     $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="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'] . '"/>';
     // pass a param that sets the next page to display
     $r .= '<input type="hidden" name="page" value="grid"/>';
     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'])) {
         // for reload of existing, don't let the user switch the transect as that would mess everything up.
         $r .= '<label>' . lang::get('Transect') . ':</label><span>' . $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.
         $locationTypes = helper_base::get_termlist_terms($auth, 'indicia:location_types', array('Transect', 'Transect Section'));
         $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' => $locationTypes[0]['id'], '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 hidden sref fields updated
         $sitesLookup = array();
         $sitesJs = array();
         foreach ($availableSites as $site) {
             $sitesLookup[$site['location_id']] = $site['name'];
             $sitesJs[$site['location_id']] = $site;
         }
         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.
     }
     $r .= data_entry_helper::date_picker(array('label' => lang::get('Date'), 'fieldname' => 'sample:date'));
     $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_attribute_html($attributes, $args, array('extraParams' => $auth['read']));
     $r .= '<input type="hidden" name="sample:sample_method_id" value="' . $sampleMethods[0]['id'] . '" />';
     $r .= '<input type="submit" value="' . lang::get('Next') . '" class="ui-state-default ui-corner-all" />';
     $r .= '</form>';
     data_entry_helper::enable_validation('sample');
     return $r;
 }
 /**
  * Return the generated form output.
  * @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 object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  * @todo: Implement this method 
  */
 public static function get_form($args, $node, $response = null)
 {
     global $user;
     $checks = self::check_prerequisites();
     $args = self::getArgDefaults($args);
     if ($checks !== true) {
         return $checks;
     }
     iform_load_helpers(array('map_helper'));
     data_entry_helper::add_resource('jquery_form');
     self::$ajaxFormUrl = iform_ajaxproxy_url($node, 'location');
     self::$ajaxFormSampleUrl = iform_ajaxproxy_url($node, 'sample');
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $typeTerms = array(empty($args['transect_type_term']) ? 'Transect' : $args['transect_type_term'], empty($args['section_type_term']) ? 'Section' : $args['section_type_term']);
     $settings = array('locationTypes' => helper_base::get_termlist_terms($auth, 'indicia:location_types', $typeTerms), 'locationId' => isset($_GET['id']) ? $_GET['id'] : null, 'canEditBody' => true, 'canEditSections' => true, 'canAllocBranch' => $args['managerPermission'] == "" || user_access($args['managerPermission']), 'canAllocUser' => $args['managerPermission'] == "" || user_access($args['managerPermission']));
     $settings['attributes'] = data_entry_helper::getAttributes(array('id' => $settings['locationId'], 'valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'location_type_id' => $settings['locationTypes'][0]['id'], 'multiValue' => true));
     $settings['section_attributes'] = data_entry_helper::getAttributes(array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'location_type_id' => $settings['locationTypes'][1]['id'], 'multiValue' => true));
     if ($args['allow_user_assignment']) {
         if (false == ($settings['cmsUserAttr'] = extract_cms_user_attr($settings['attributes']))) {
             return 'This form is designed to be used with the CMS User ID attribute setup for locations in the survey, or the "Allow users to be assigned to transects" option unticked.';
         }
         // keep a copy of the cms user ID attribute so we can use it later.
         self::$cmsUserAttrId = $settings['cmsUserAttr']['attributeId'];
     }
     // need to check if branch allocation is active.
     if ($args['branch_assignment_permission'] != '') {
         if (false == ($settings['branchCmsUserAttr'] = self::extract_attr($settings['attributes'], "Branch CMS User ID"))) {
             return '<br />This form is designed to be used with either<br />1) the Branch CMS User ID attribute setup for locations in the survey, or<br />2) the "Permission name for Branch Manager" option left blank.<br />';
         }
         // keep a copy of the branch cms user ID attribute so we can use it later.
         self::$branchCmsUserAttrId = $settings['branchCmsUserAttr']['attributeId'];
     }
     data_entry_helper::$javascript .= "indiciaData.sections = {};\n";
     $settings['sections'] = array();
     $settings['numSectionsAttr'] = "";
     $settings['maxSectionCount'] = $args['maxSectionCount'];
     $settings['autocalcSectionLengthAttrId'] = empty($args['autocalc_section_length_attr_id']) ? 0 : $args['autocalc_section_length_attr_id'];
     $settings['defaultSectionGridRef'] = empty($args['default_section_grid_ref']) ? 'parent' : $args['default_section_grid_ref'];
     if ($settings['locationId']) {
         data_entry_helper::load_existing_record($auth['read'], 'location', $settings['locationId']);
         $settings['walks'] = data_entry_helper::get_population_data(array('table' => 'sample', 'extraParams' => $auth['read'] + array('view' => 'detail', 'location_id' => $settings['locationId'], 'deleted' => 'f'), 'nocache' => true));
         // Work out permissions for this user: note that canAllocBranch setting effectively shows if a manager.
         if (!$settings['canAllocBranch']) {
             // Check whether I am a normal user and it is allocated to me, and also if I am a branch manager and it is allocated to me.
             $settings['canEditBody'] = false;
             $settings['canEditSections'] = false;
             if ($args['allow_user_assignment'] && count($settings['walks']) == 0 && isset($settings['cmsUserAttr']['default']) && !empty($settings['cmsUserAttr']['default'])) {
                 foreach ($settings['cmsUserAttr']['default'] as $value) {
                     // multi value
                     if ($value['default'] == $user->uid) {
                         // comparing string against int so no triple equals
                         $settings['canEditBody'] = true;
                         $settings['canEditSections'] = true;
                         break;
                     }
                 }
             }
             // If a Branch Manager and not a main manager, then can't edit the number of sections
             if ($args['branch_assignment_permission'] != '' && user_access($args['branch_assignment_permission']) && isset($settings['branchCmsUserAttr']['default']) && !empty($settings['branchCmsUserAttr']['default'])) {
                 foreach ($settings['branchCmsUserAttr']['default'] as $value) {
                     // now multi value
                     if ($value['default'] == $user->uid) {
                         // comparing string against int so no triple equals
                         $settings['canEditBody'] = true;
                         $settings['canAllocUser'] = true;
                         break;
                     }
                 }
             }
         }
         // for an admin user the defaults apply, which will be can do everything.
         // find the number of sections attribute.
         foreach ($settings['attributes'] as $attr) {
             if ($attr['caption'] === 'No. of sections') {
                 $settings['numSectionsAttr'] = $attr['fieldname'];
                 for ($i = 1; $i <= $attr['displayValue']; $i++) {
                     $settings['sections']["S{$i}"] = null;
                 }
                 $existingSectionCount = empty($attr['displayValue']) ? 1 : $attr['displayValue'];
                 data_entry_helper::$javascript .= "\$('#" . str_replace(':', '\\\\:', $attr['id']) . "').attr('min',{$existingSectionCount}).attr('max'," . $args['maxSectionCount'] . ");\n";
                 if (!$settings['canEditSections']) {
                     data_entry_helper::$javascript .= "\$('#" . str_replace(':', '\\\\:', $attr['id']) . "').attr('readonly','readonly').css('color','graytext');\n";
                 }
             }
         }
         $sections = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('view' => 'detail', 'parent_id' => $settings['locationId'], 'deleted' => 'f', 'orderby' => 'id'), 'nocache' => true));
         foreach ($sections as $section) {
             $code = $section['code'];
             data_entry_helper::$javascript .= "indiciaData.sections.{$code} = {'geom':'" . $section['boundary_geom'] . "','id':'" . $section['id'] . "','sref':'" . $section['centroid_sref'] . "','system':'" . $section['centroid_sref_system'] . "'};\n";
             $settings['sections'][$code] = $section;
         }
     } else {
         // not an existing site therefore no walks. On initial save, no section data is created.
         foreach ($settings['attributes'] as $attr) {
             if ($attr['caption'] === 'No. of sections') {
                 $settings['numSectionsAttr'] = $attr['fieldname'];
                 data_entry_helper::$javascript .= "\$('#" . str_replace(':', '\\\\:', $attr['id']) . "').attr('min',1).attr('max'," . $args['maxSectionCount'] . ");\n";
             }
         }
         $settings['walks'] = array();
     }
     if ($settings['numSectionsAttr'] === '') {
         for ($i = 1; $i <= $settings['maxSectionCount']; $i++) {
             $settings['sections']["S{$i}"] = null;
         }
     }
     $r = '<div id="controls">';
     $headerOptions = array('tabs' => array('#site-details' => lang::get('Site Details')));
     if ($settings['locationId']) {
         $headerOptions['tabs']['#your-route'] = lang::get('Your Route');
         if ($args['always_show_section_details'] || count($settings['section_attributes']) > 0) {
             $headerOptions['tabs']['#section-details'] = lang::get('Section Details');
         }
     }
     if (count($headerOptions['tabs'])) {
         $r .= data_entry_helper::tab_header($headerOptions);
         data_entry_helper::enable_tabs(array('divId' => 'controls', 'style' => 'Tabs', 'progressBar' => isset($args['tabProgress']) && $args['tabProgress'] == true));
     }
     $r .= self::get_site_tab($auth, $args, $settings);
     if ($settings['locationId']) {
         $r .= self::get_your_route_tab($auth, $args, $settings);
         if ($args['always_show_section_details'] || count($settings['section_attributes']) > 0) {
             $r .= self::get_section_details_tab($auth, $args, $settings);
         }
     }
     $r .= '</div>';
     // controls
     data_entry_helper::enable_validation('input-form');
     if (function_exists('drupal_set_breadcrumb')) {
         $breadcrumb = array();
         $breadcrumb[] = l(lang::get('Home'), '<front>');
         $breadcrumb[] = l(lang::get('Sites'), $args['sites_list_path']);
         if ($settings['locationId']) {
             $breadcrumb[] = data_entry_helper::$entity_to_load['location:name'];
         } else {
             $breadcrumb[] = lang::get('New Site');
         }
         drupal_set_breadcrumb($breadcrumb);
     }
     // Inform JS where to post data to for AJAX form saving
     data_entry_helper::$javascript .= 'indiciaData.ajaxFormPostUrl="' . self::$ajaxFormUrl . "\";\n";
     data_entry_helper::$javascript .= 'indiciaData.ajaxFormPostSampleUrl="' . self::$ajaxFormSampleUrl . "\";\n";
     data_entry_helper::$javascript .= 'indiciaData.website_id="' . $args['website_id'] . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.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.currentSection = '';\n";
     data_entry_helper::$javascript .= "indiciaData.sectionTypeId = '" . $settings['locationTypes'][1]['id'] . "';\n";
     data_entry_helper::$javascript .= "indiciaData.sectionDeleteConfirm = \"" . lang::get('Are you sure you wish to delete section') . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.sectionInsertConfirm = \"" . lang::get('Are you sure you wish to insert a new section after section') . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.sectionChangeConfirm = \"" . lang::get('Do you wish to save the currently unsaved changes you have made to the Section Details?') . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.numSectionsAttrName = \"" . $settings['numSectionsAttr'] . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.maxSectionCount = \"" . $settings['maxSectionCount'] . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.autocalcSectionLengthAttrId = " . $settings['autocalcSectionLengthAttrId'] . ";\n";
     data_entry_helper::$javascript .= "indiciaData.defaultSectionGridRef = '" . $settings['defaultSectionGridRef'] . "';\n";
     if ($settings['locationId']) {
         data_entry_helper::$javascript .= "selectSection('S1', true);\n";
     }
     return $r;
 }
 /**
  * Return the generated form output.
  * @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 object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  */
 public static function get_form($args, $node, $response = null)
 {
     $form = '<form action="#" method="POST" id="entry_form">';
     if ($_POST) {
         $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
         self::subscribe($args, $auth);
     } else {
         // don't bother with write auth for initial form load, as read auth is cached and faster
         $auth = array('read' => data_entry_helper::get_read_auth($args['website_id'], $args['password']));
     }
     if (!empty($_GET['id'])) {
         data_entry_helper::load_existing_record($auth['read'], 'species_alert', $_GET['id']);
         // enforce permissions
         if (data_entry_helper::$entity_to_load['species_alert:user_id'] != hostsite_get_user_field('indicia_user_id')) {
             return lang::get('You cannot modify a species alert subscription created by someone else');
         }
         $form .= data_entry_helper::hidden_text(array('fieldname' => 'species_alert:id', 'default' => $_GET['id']));
     }
     // if not logged in, then ask for details to register against
     global $user;
     if (!hostsite_get_user_field('id') || !isset($user) || empty($user->mail) || !hostsite_get_user_field('last_name')) {
         $form .= "<fieldset><legend>" . lang::get('Your details') . ":</legend>\n";
         $default = empty($_POST['first_name']) ? hostsite_get_user_field('first_name', '') : $_POST['first_name'];
         $form .= data_entry_helper::text_input(array('label' => lang::get('First name'), 'fieldname' => 'first_name', 'validation' => array('required'), 'default' => $default, 'class' => 'control-width-4'));
         $default = empty($_POST['surname']) ? hostsite_get_user_field('last_name', '') : $_POST['surname'];
         $form .= data_entry_helper::text_input(array('label' => lang::get('Last name'), 'fieldname' => 'surname', 'validation' => array('required'), 'default' => $default, 'class' => 'control-width-4'));
         $default = empty($_POST['email']) ? empty($user->mail) ? '' : $user->mail : $_POST['email'];
         $form .= data_entry_helper::text_input(array('label' => lang::get('Email'), 'fieldname' => 'email', 'validation' => array('required', 'email'), 'default' => $default, 'class' => 'control-width-4'));
         $form .= "</fieldset>\n";
     } else {
         $form .= data_entry_helper::hidden_text(array('fieldname' => 'first_name', 'default' => hostsite_get_user_field('first_name')));
         $form .= data_entry_helper::hidden_text(array('fieldname' => 'surname', 'default' => hostsite_get_user_field('last_name')));
         $form .= data_entry_helper::hidden_text(array('fieldname' => 'email', 'default' => $user->mail));
         $form .= data_entry_helper::hidden_text(array('fieldname' => 'user_id', 'default' => hostsite_get_user_field('indicia_user_id')));
     }
     $form .= "<fieldset><legend>" . lang::get('Alert criteria') . ":</legend>\n";
     // Output the species selection control
     // Default after saving with a validation failure can be pulled direct from the post, but
     // when reloading we don't need a default taxa taxon list ID since we already know the meaning
     // ID or external key.
     $default = empty($_POST['taxa_taxon_list_id']) ? '' : $_POST['taxa_taxon_list_id'];
     if (empty($_POST['taxa_taxon_list_id:taxon'])) {
         $defaultCaption = empty(data_entry_helper::$entity_to_load['species_alert:preferred_taxon']) ? '' : data_entry_helper::$entity_to_load['species_alert:preferred_taxon'];
     } else {
         $defaultCaption = $_POST['taxa_taxon_list_id:taxon'];
     }
     $form .= data_entry_helper::species_autocomplete(array('label' => lang::get('Alert species'), 'helpText' => lang::get('Select the species you are interested in receiving alerts in ' . 'relation to if you want to receive alerts on a single species.'), 'fieldname' => 'taxa_taxon_list_id', 'cacheLookup' => true, 'extraParams' => $auth['read'] + array('taxon_list_id' => $args['list_id']), 'class' => 'control-width-4', 'default' => $default, 'defaultCaption' => $defaultCaption));
     if (empty($default)) {
         // Unless we've searched for the species name then posted (and failed), then the
         // default will be empty. We might therefore be reloading existing data which has
         // a meaning ID or external key.
         if (!empty(data_entry_helper::$entity_to_load['species_alert:external_key'])) {
             $form .= data_entry_helper::hidden_text(array('fieldname' => 'species_alert:external_key', 'default' => data_entry_helper::$entity_to_load['species_alert:external_key']));
         } elseif (!empty(data_entry_helper::$entity_to_load['species_alert:taxon_meaning_id'])) {
             $form .= data_entry_helper::hidden_text(array('fieldname' => 'species_alert:taxon_meaning_id', 'default' => data_entry_helper::$entity_to_load['species_alert:taxon_meaning_id']));
         }
     }
     if (!empty($args['full_lists'])) {
         $form .= data_entry_helper::select(array('label' => lang::get('Select full species lists'), 'helpText' => lang::get('If you want to restrict the alerts to records of any ' . 'species within a species list, then select the list here.'), 'fieldname' => 'species_alert:taxon_list_id', 'blankText' => lang::get('<Select a species list>'), 'table' => 'taxon_list', 'valueField' => 'id', 'captionField' => 'title', 'extraParams' => $auth['read'] + array('id' => $args['full_lists'], 'orderby' => 'title'), 'class' => 'control-width-4'));
     }
     $form .= data_entry_helper::location_select(array('label' => lang::get('Select location'), 'helpText' => lang::get('If you want to restrict the alerts to records within a certain boundary, select it here.'), 'fieldname' => 'species_alert:location_id', 'id' => 'imp-location', 'blankText' => lang::get('<Select boundary>'), 'extraParams' => $auth['read'] + array('location_type_id' => $args['location_type_id'], 'orderby' => 'name'), 'class' => 'control-width-4'));
     $form .= data_entry_helper::checkbox(array('label' => lang::get('Alert on initial entry'), 'helpText' => lang::get('Tick this box if you want to receive a notification when the record is first input into the system.'), 'fieldname' => 'species_alert:alert_on_entry'));
     $form .= data_entry_helper::checkbox(array('label' => lang::get('Alert on verification as correct'), 'helpText' => lang::get('Tick this box if you want to receive a notification when the record has been verified as correct.'), 'fieldname' => 'species_alert:alert_on_verify'));
     $form .= "</fieldset>\n";
     $form .= '<input type="Submit" value="Subscribe" />';
     $form .= '</form>';
     data_entry_helper::enable_validation('entry_form');
     iform_load_helpers(array('map_helper'));
     $mapOptions = iform_map_get_map_options($args, $auth['read']);
     $map = map_helper::map_panel($mapOptions);
     global $indicia_templates;
     return str_replace(array('{col-1}', '{col-2}'), array($form, $map), $indicia_templates['two-col-50']);
 }
Ejemplo n.º 12
0
 /**
  * Return the generated form output.
  * @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 object $node The Drupal node object.
  * @param array $errors When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  */
 public static function get_form($args, $node, $errors = null)
 {
     $r = '';
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     // Determine how the form was requested and therefore what to output
     self::$mode = self::getMode($args, $node);
     if (self::$mode === self::MODE_GRID) {
         //Displayed the grid when the page opens initially
         $r .= self::getGrid($args, $node, $auth);
     } else {
         // variables to tracks which parts of the plots grid are not completed, so we can display a correct message
         $someGridRefsMissing = false;
         $someHabitatsMissing = false;
         $someSqTypesMissing = false;
         data_entry_helper::$validation_mode = array('colour', 'hint', 'message');
         if (self::$mode === self::MODE_EXISTING || self::$mode === self::MODE_CLONE) {
             data_entry_helper::load_existing_record($auth['read'], 'sample', $_GET['sample_id']);
             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');
             }
             $topSampleAttrs = self::load_top_sample_attrs($auth, $args, $_GET['sample_id']);
         } else {
             $topSampleAttrs = self::load_top_sample_attrs($auth, $args);
         }
         //If in mode clone, we want to load existing data but as a new sample. So strip out all the existing attribute value ids from the form
         //html so the data is loaded but it creates a new sample.
         if (self::$mode === self::MODE_CLONE) {
             self::cloneEntity($args, $auth, $topSampleAttrs);
         }
         global $indicia_templates;
         $indicia_templates['starredSuffix'] = "*<br/>\n";
         $indicia_templates['validation_message'] = "<span class=\"ui-state-error-text\">{error}</span>\n";
         data_entry_helper::enable_validation('entry-form');
         $r .= '<form method="post" action="" id="entry-form">';
         $r .= '<div id="tabs">';
         data_entry_helper::enable_tabs(array('divId' => 'tabs', 'navButtons' => true));
         //User needs to set configuration options for the number of species tabs they want and the
         //number of species to appear on each tab. The user needs to make sure this will result in enough
         //space to display all the required species from the species list.
         if (!empty($args['num_species_tabs'])) {
             $numSpeciesTabs = $args['num_species_tabs'];
         } else {
             $numSpeciesTabs = 3;
         }
         if (!empty($args['num_species_per_tab'])) {
             $numSpeciesPerTab = $args['num_species_per_tab'];
         } else {
             $numSpeciesPerTab = 34;
         }
         $tabsArray = array('#your-square' => 'Find Place', '#your-plots' => 'Your Path');
         //Tell the system that it needs to display the number of tabs specified by the user
         for ($i = 0; $i < $numSpeciesTabs; $i++) {
             $tabNum = $i + 1;
             $tabsArray = array_merge($tabsArray, array('#species_' . $tabNum => 'Species Page ' . $tabNum));
         }
         $r .= data_entry_helper::tab_header(array('tabs' => $tabsArray));
         $r .= '<div id="your-square">';
         $r .= self::get_hiddens($args, $auth);
         $r .= self::getFirstTabAdditionalContent($args, $auth);
         $r .= self::tab_your_square($args, $auth['read'], $topSampleAttrs);
         $r .= '</div>';
         // your-square
         $r .= '<div id="your-plots">';
         $r .= self::tab_your_plots($args, $auth['read']);
         $r .= '</div>';
         // your-plots (now called Your Paths, the old Wildflower form was Your Plots)
         //Create the html for each species tab.
         for ($i = 0; $i < $numSpeciesTabs; $i++) {
             $tabNum = $i + 1;
             $speciesStartIndex = $numSpeciesPerTab * $i;
             $r .= '<div id="species_' . $tabNum . '">';
             $r .= self::tab_species_npms_paths($args, $auth, $speciesStartIndex, $numSpeciesPerTab, $tabNum, $numSpeciesTabs);
             $r .= '</div>';
             // species-1
         }
         $r .= '</div>';
         // tabs
         $r .= '</form>';
     }
     return $r;
 }
Ejemplo n.º 13
0
 /**
  * Ajax handler to provide the content for the details of a single record.
  */
 public static function ajax_details($website_id, $password)
 {
     iform_load_helpers(array('data_entry_helper'));
     $auth = data_entry_helper::get_read_auth($website_id, $password);
     data_entry_helper::load_existing_record($auth, 'occurrence', $_GET['occurrence_id']);
     data_entry_helper::load_existing_record($auth, 'sample', data_entry_helper::$entity_to_load['occurrence:sample_id']);
     $siteLabels = array();
     if (!empty(data_entry_helper::$entity_to_load['sample:location'])) {
         $siteLabels[] = data_entry_helper::$entity_to_load['sample:location'];
     }
     if (!empty(data_entry_helper::$entity_to_load['sample:location_name'])) {
         $siteLabels[] = data_entry_helper::$entity_to_load['sample:location_name'];
     }
     // build an array of all the data. This allows the JS to insert the data into emails etc. Note we
     // use an array rather than an assoc array to build the JSON, so that order is guaranteed.
     $data = array(array('caption' => lang::get('Species'), 'value' => data_entry_helper::$entity_to_load['occurrence:taxon']), array('caption' => lang::get('Date'), 'value' => data_entry_helper::$entity_to_load['sample:date']), array('caption' => lang::get('Grid Ref.'), 'value' => data_entry_helper::$entity_to_load['sample:entered_sref']), array('caption' => lang::get('Site'), 'value' => implode(' | ', $siteLabels)));
     $smpAttrs = data_entry_helper::getAttributes(array('id' => data_entry_helper::$entity_to_load['sample:id'], 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'extraParams' => $auth, 'survey_id' => data_entry_helper::$entity_to_load['occurrence:survey_id']));
     $occAttrs = data_entry_helper::getAttributes(array('id' => $_GET['occurrence_id'], 'valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'extraParams' => $auth, 'survey_id' => data_entry_helper::$entity_to_load['occurrence:survey_id']));
     $attributes = array_merge($smpAttrs, $occAttrs);
     foreach ($attributes as $attr) {
         $data[] = array('caption' => lang::get($attr['caption']), 'value' => $attr['displayValue']);
     }
     $r = "<table>\n";
     $status = data_entry_helper::$entity_to_load['occurrence:record_status'];
     $r .= '<tr><td><strong>' . lang::get('Status') . '</strong></td><td class="status status-' . $status . '">';
     $r .= self::statusLabel($status);
     if (data_entry_helper::$entity_to_load['occurrence:zero_abundance'] === 't') {
         $r .= '<br/>' . lang::get('This is a record indicating absence.');
     }
     $r .= "</td></tr>\n";
     foreach ($data as $item) {
         if (!empty($item['value'])) {
             $r .= "<tr><td><strong>" . $item['caption'] . "</strong></td><td>" . $item['value'] . "</td></tr>\n";
         }
     }
     $r .= "</table>\n";
     $additional = array();
     $additional['wkt'] = data_entry_helper::$entity_to_load['occurrence:wkt'];
     $additional['taxon'] = data_entry_helper::$entity_to_load['occurrence:taxon'];
     header('Content-type: application/json');
     echo json_encode(array('content' => $r, 'data' => $data, 'additional' => $additional));
 }
Ejemplo n.º 14
0
 protected static function get_form_mode_7($args, $node)
 {
     // MODE_POST_OCCURRENCE
     if (!is_null(data_entry_helper::$entity_to_load)) {
         // errors with new sample+occurrence combination, entity poulated with post, so display this data.
         return call_user_func(array(get_called_class(), 'get_form_sampleoccurrence'), $args, $node);
     }
     // else valid save
     if (array_key_exists('navigate:newoccurrence', $_POST)) {
         // display a new sample/occurrence combination, with the same parent & date
         data_entry_helper::$entity_to_load = array('sample:parent_id' => $_POST['sample:parent_id'], 'sample:date' => $_POST['sample:date']);
         return call_user_func(array(get_called_class(), 'get_form_sampleoccurrence'), $args, $node);
     }
     $loadedSampleId = $_POST['sample:parent_id'];
     data_entry_helper::load_existing_record(self::$auth['read'], 'sample', $loadedSampleId);
     return call_user_func(array(get_called_class(), 'get_form_supersample'), $args, $node);
 }
Ejemplo n.º 15
0
 /**
  * Return the generated form output.
  * @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 object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  */
 public static function get_form($args, $node, $response = null)
 {
     global $user;
     data_entry_helper::$helpTextPos = 'before';
     $checks = self::check_prerequisites();
     $args = self::getArgDefaults($args);
     if ($checks !== true) {
         return $checks;
     }
     iform_load_helpers(array('map_helper'));
     data_entry_helper::add_resource('jquery_form');
     self::$ajaxFormUrl = iform_ajaxproxy_url($node, 'loc-smp-occ');
     self::$ajaxFormLocationUrl = iform_ajaxproxy_url($node, 'location');
     self::$ajaxFormSampleUrl = iform_ajaxproxy_url($node, 'sample');
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $settings = array('SiteLocationType' => helper_base::get_termlist_terms($auth, 'indicia:location_types', array(empty($args['location_type_term']) ? 'TreeSite' : $args['location_type_term'])), 'TreeLocationType' => helper_base::get_termlist_terms($auth, 'indicia:location_types', array(empty($args['tree_type_term']) ? 'Tree' : $args['tree_type_term'])), 'locationId' => isset($_GET['id']) ? $_GET['id'] : null, 'canAllocUser' => $args['manager_permission'] == "" || user_access($args['manager_permission']));
     $settings['attributes'] = data_entry_helper::getAttributes(array('id' => $settings['locationId'], 'valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'location_type_id' => $settings['SiteLocationType'][0]['id'], 'multiValue' => true));
     $settings['tree_attributes'] = data_entry_helper::getAttributes(array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'location_type_id' => $settings['TreeLocationType'][0]['id'], 'multiValue' => true));
     if ($args['allow_user_assignment']) {
         if (false == ($settings['cmsUserAttr'] = extract_cms_user_attr($settings['attributes']))) {
             return 'This form is designed to be used with the "CMS User ID" attribute setup for Site locations in the survey, or the "Allow users to be assigned to locations" option unticked.';
         }
         // keep a copy of the cms user ID attribute so we can use it later.
         self::$cmsUserAttrId = $settings['cmsUserAttr']['attributeId'];
         $found = false;
         foreach ($settings['tree_attributes'] as $idx => $attr) {
             if (strcasecmp($attr['caption'], 'Recorder Name') === 0) {
                 data_entry_helper::$javascript .= "indiciaData.assignedRecorderID = " . $attr['attributeId'] . ";\n";
                 $found = true;
                 break;
             }
         }
         if (!$found) {
             return 'This form is designed to be used with the "Recorder Name" attribute setup for Tree locations in the survey, or the "Allow users to be assigned to locations" option unticked.';
         }
     }
     // TBD data drive
     $definitions = array(array("attr" => "111", "term" => "WD", "target" => "112", "required" => true, "title" => "You must pick the dominant species from this drop down list when the WD (Dominant Species) checkbox is set."), array("attr" => "111", "term" => "WP", "target" => "113", "required" => false, "title" => "If known, you may enter the year that the woodland was planted in when the WP (Planted Date) checkbox is set."));
     $common = "var check_attrs = function(){\n";
     data_entry_helper::$javascript .= "var checkbox_changed_base = function(changedSelector, targetSelector, required){\n  \$(changedSelector).closest('span').find('label.inline-error').remove();\n  \$(changedSelector).closest('span').find('.ui-state-error').removeClass('ui-state-error');\n  \$(changedSelector).closest('span').find('label.error').remove();\n  \$(changedSelector).closest('span').find('.error').removeClass('error');\n  if(\$(changedSelector).attr('checked'))\n    \$(targetSelector).addClass(required ? 'required' : 'notrequired').closest('span').show();\n  else {\n    \$(targetSelector).removeClass('required').val('').closest('span').hide();\n  }\n};\nvar check_attr_def = [];\ncheck_attrs = function(){\n  for(var i=0; i<check_attr_def.length; i++){\n    checkbox_changed_base(check_attr_def[i][0], check_attr_def[i][1], check_attr_def[i][2]);\n  }\n}\n";
     foreach ($definitions as $defn) {
         data_entry_helper::$javascript .= "\$('[id^=locAttr\\\\:" . $defn["attr"] . "\\\\:]:checkbox').each(function(idx,elem){\n  if(\$('label[for='+\$(elem).attr('id').replace(/:/g,'\\\\:')+']').html() == '" . $defn["term"] . "'){\n    var tgt = \$('#locAttr\\\\:" . $defn["target"] . "');\n    tgt.prev('label').remove();\n    tgt.next('br').remove();\n    var span = \$('<span/>');\n    \$(elem).closest('span').append(span);\n    span.append(tgt);" . ($defn["required"] ? "\n    span.append('<span class=\"deh-required\">*</span>');" : "") . "\n    tgt.attr('title','" . $defn["title"] . "');\n    \$(elem).change(function(e){checkbox_changed_base(e.target, '#locAttr\\\\:" . $defn["target"] . "', " . ($defn["required"] ? "true" : "false") . ");});\n    check_attr_def.push([elem, '#locAttr\\\\:" . $defn["target"] . "', " . ($defn["required"] ? "true" : "false") . "]);\n  }\n});\n";
     }
     data_entry_helper::$javascript .= "check_attrs();\nindiciaData.trees = {};\n";
     $settings['trees'] = array();
     if ($settings['locationId']) {
         data_entry_helper::load_existing_record($auth['read'], 'location', $settings['locationId']);
         // Work out permissions for this user
         $canEdit = $args['manager_permission'] == "" || user_access($args['manager_permission']);
         if ($args['allow_user_assignment'] && isset($settings['cmsUserAttr']['default']) && !empty($settings['cmsUserAttr']['default'])) {
             foreach ($settings['cmsUserAttr']['default'] as $value) {
                 // multi value
                 if ($value['default'] == $user->uid) {
                     // comparing string against int so no triple equals
                     $canEdit = true;
                     break;
                 }
             }
         }
         if (!$canEdit) {
             return 'You do not have access to this site.';
         }
         $trees = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('view' => 'detail', 'parent_id' => $settings['locationId'], 'deleted' => 'f', 'orderby' => 'name'), 'nocache' => true));
         foreach ($trees as $tree) {
             $id = $tree['id'];
             data_entry_helper::$javascript .= "indiciaData.trees[{$id}] = {'id':'" . $tree['id'] . "','name':'" . str_replace("'", "\\'", $tree['name']) . "','geom':'" . $tree['centroid_geom'] . "','sref':'" . $tree['centroid_sref'] . "','system':'" . $tree['centroid_sref_system'] . "'};\n";
             $settings['trees'][$id] = $tree;
         }
     }
     $r = '<div id="controls">';
     $headerOptions = array('tabs' => array('#site-details' => lang::get('Site Details')));
     $tabOptions = array('divId' => 'controls', 'style' => 'Tabs');
     if ($settings['locationId']) {
         $headerOptions['tabs']['#site-trees'] = lang::get('Tree Details');
         $tabOptions['active'] = '#site-trees';
     }
     $r .= data_entry_helper::tab_header($headerOptions);
     data_entry_helper::enable_tabs($tabOptions);
     $settings['treeSampleMethod'] = helper_base::get_termlist_terms($auth, 'indicia:sample_methods', array('TreeInitialRegistration'));
     // TODO put in error check, add in $arg driving of text value
     $settings['treeSampleMethod'] = $settings['treeSampleMethod'][0];
     $r .= self::get_site_tab($auth, $args, $settings);
     if ($settings['locationId']) {
         $r .= self::get_site_trees_tab($auth, $args, $settings);
         data_entry_helper::enable_validation('tree-form');
         data_entry_helper::setup_jquery_validation_js();
     }
     $r .= '</div>';
     // controls
     data_entry_helper::enable_validation('input-form');
     if (function_exists('drupal_set_breadcrumb')) {
         $breadcrumb = array();
         $breadcrumb[] = l(lang::get('Home'), '<front>');
         $breadcrumb[] = l(lang::get('Sites'), $args['sites_list_path']);
         if ($settings['locationId']) {
             $breadcrumb[] = data_entry_helper::$entity_to_load['location:name'];
         } else {
             $breadcrumb[] = lang::get('New Site');
         }
         drupal_set_breadcrumb($breadcrumb);
     }
     // Inform JS where to post data to for AJAX form saving
     data_entry_helper::$javascript .= 'indiciaData.ajaxFormPostUrl="' . self::$ajaxFormUrl . "\";\n";
     data_entry_helper::$javascript .= 'indiciaData.ajaxFormPostLocationUrl="' . self::$ajaxFormLocationUrl . "\";\n";
     data_entry_helper::$javascript .= 'indiciaData.ajaxFormPostSampleUrl="' . self::$ajaxFormSampleUrl . "\";\n";
     data_entry_helper::$javascript .= 'indiciaData.website_id="' . $args['website_id'] . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.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.currentTree = '';\n";
     data_entry_helper::$javascript .= "indiciaData.treeTypeId = '" . $settings['TreeLocationType'][0]['id'] . "';\n";
     data_entry_helper::$javascript .= "indiciaData.treeDeleteConfirm = \"" . lang::get('Are you sure you wish to delete tree') . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.treeInsertConfirm = \"" . lang::get('Are you sure you wish to create a new tree (make sure you have saved any data)') . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.treeChangeConfirm = \"" . lang::get('Do you wish to save the currently unsaved changes you have made to the Tree Details?') . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.treeSampleMethodID = \"" . $settings['treeSampleMethod']['id'] . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.newVisitDialog = \"" . lang::get('You have just created a new tree. You can now create the first phenology observation data, or you can leave it until later. Do you wish to create the phenology observation data now? (This will open in a new window.)') . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.existingVisitDialog = \"" . lang::get('You have just modified an existing tree. Do you wish to create phenology observation data now? (This will open in a new window.)') . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.visitURL = \"" . ($args['visit_path'] . (strpos($args['visit_path'], '?') === false ? '?' : '&') . "new=1&location_id=") . "\";\n";
     $r .= '<a id="visit_link" style="display:none;" href="" target="_blank" />';
     if ($settings['locationId']) {
         data_entry_helper::$onload_javascript .= "var first=true;\njQuery.each(indiciaData.trees, function(idx, tree) {\n  if(first) selectTree(tree.id, true);  \nfirst=false\n});\nif(first) insertTree();\n";
     }
     return $r;
 }
Ejemplo n.º 16
0
   /**
    * Return the generated form output.
    * @return Form HTML.
    */
   public static function get_form($args, $node)
   {
       define("MODE_GRID", 0);
       define("MODE_NEW_SAMPLE", 1);
       define("MODE_EXISTING", 2);
       self::parse_defaults($args);
       self::getArgDefaults($args);
       global $user;
       $logged_in = $user->uid > 0;
       self::$node = $node;
       // Get authorisation tokens to update and read from the Warehouse.
       $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
       $svcUrl = data_entry_helper::$base_url . '/index.php/services';
       self::$auth = $auth;
       $mode = isset($args['no_grid']) && $args['no_grid'] ? MODE_NEW_SAMPLE : MODE_GRID;
       // default mode when no grid set to false - display grid of existing data
       // mode MODE_EXISTING: display existing sample
       $loadedSampleId = null;
       $loadedOccurrenceId = null;
       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 (function_exists('iform_loctools_checkaccess') && iform_loctools_checkaccess($node, 'admin') && array_key_exists('mnhnld1', $_POST)) {
                   iform_loctools_deletelocations($node);
                   foreach ($_POST as $key => $value) {
                       $parts = explode(':', $key);
                       iform_loctools_insertlocation($node, $parts[2], $parts[1]);
                   }
               }
           } else {
               if (!is_null(data_entry_helper::$entity_to_load)) {
                   $mode = MODE_EXISTING;
                   // errors with new sample, entity populated with post, so display this data.
               }
           }
           // else valid save, so go back to gridview: default mode 0
       }
       if (array_key_exists('sample_id', $_GET) && $_GET['sample_id'] != '{sample_id}') {
           $mode = MODE_EXISTING;
           $loadedSampleId = $_GET['sample_id'];
       }
       if (array_key_exists('occurrence_id', $_GET) && $_GET['occurrence_id'] != '{occurrence_id}') {
           $mode = MODE_EXISTING;
           $loadedOccurrenceId = $_GET['occurrence_id'];
           self::$occurrenceIds = array($loadedOccurrenceId);
       }
       if ($mode != MODE_EXISTING && array_key_exists('newSample', $_GET)) {
           $mode = MODE_NEW_SAMPLE;
           data_entry_helper::$entity_to_load = array();
       }
       // else default to mode MODE_GRID or MODE_NEW_SAMPLE depending on no_grid parameter
       self::$mode = $mode;
       // default mode  MODE_GRID : display grid of the samples to add a new one
       // or edit an existing one.
       if ($mode == MODE_GRID) {
           $r = '';
           $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']), false);
           $tabs = array('#sampleList' => lang::get('LANG_Main_Samples_Tab'));
           if ($args['includeLocTools'] && function_exists('iform_loctools_checkaccess') && iform_loctools_checkaccess($node, 'admin')) {
               $tabs['#setLocations'] = lang::get('LANG_Allocate_Locations');
           }
           if (method_exists(get_called_class(), 'getExtraGridModeTabs')) {
               $extraTabs = call_user_func(array(get_called_class(), 'getExtraGridModeTabs'), false, $auth['read'], $args, $attributes);
               if (is_array($extraTabs)) {
                   $tabs = $tabs + $extraTabs;
               }
           }
           if (count($tabs) > 1) {
               $r .= "<div id=\"controls\">" . data_entry_helper::enable_tabs(array('divId' => 'controls', 'active' => '#sampleList')) . "<div id=\"temp\"></div>";
               $r .= data_entry_helper::tab_header(array('tabs' => $tabs));
           }
           $r .= "<div id=\"sampleList\">" . call_user_func(array(get_called_class(), 'getSampleListGrid'), $args, $node, $auth, $attributes) . "</div>";
           if ($args['includeLocTools'] && function_exists('iform_loctools_checkaccess') && iform_loctools_checkaccess($node, 'admin')) {
               $r .= '
 <div id="setLocations">
   <form method="post">
     <input type="hidden" id="mnhnld1" name="mnhnld1" value="mnhnld1" /><table border="1"><tr><td></td>';
               $url = $svcUrl . '/data/location?mode=json&view=detail&auth_token=' . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&parent_id=NULL&orderby=name";
               $session = curl_init($url);
               curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
               $entities = json_decode(curl_exec($session), true);
               $userlist = iform_loctools_listusers($node);
               foreach ($userlist as $uid => $a_user) {
                   $r .= '<td>' . $a_user->name . '</td>';
               }
               $r .= "</tr>";
               if (!empty($entities)) {
                   foreach ($entities as $entity) {
                       if (!$entity["parent_id"]) {
                           // only assign parent locations.
                           $r .= "<tr><td>" . $entity["name"] . "</td>";
                           $defaultuserids = iform_loctools_getusers($node, $entity["id"]);
                           foreach ($userlist as $uid => $a_user) {
                               $r .= '<td><input type="checkbox" name="location:' . $entity["id"] . ':' . $uid . (in_array($uid, $defaultuserids) ? '" checked="checked"' : '"') . '></td>';
                           }
                           $r .= "</tr>";
                       }
                   }
               }
               $r .= "</table>\n      <input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Save_Location_Allocations') . "\" />\n    </form>\n  </div>";
           }
           if (method_exists(get_called_class(), 'getExtraGridModeTabs')) {
               $r .= call_user_func(array(get_called_class(), 'getExtraGridModeTabs'), true, $auth['read'], $args, $attributes);
           }
           if (count($tabs) > 1) {
               // close tabs div if present
               $r .= "</div>";
           }
           return $r;
       }
       if ($mode == MODE_EXISTING && is_null(data_entry_helper::$entity_to_load)) {
           // only load if not in error situation
           data_entry_helper::$entity_to_load = array();
           // Displaying an existing sample. If we know the occurrence ID, and don't know the sample ID or are displaying just one occurrence
           // rather than a grid of occurrences then we must load the occurrence data to get the sample id.
           if ($loadedOccurrenceId && (!$loadedSampleId || !self::getGridMode($args))) {
               data_entry_helper::load_existing_record($auth['read'], 'occurrence', $loadedOccurrenceId);
               // Get the sample ID for the occurrence. This overwrites it if supply in GET but did not match the occurrence's sample
               $loadedSampleId = data_entry_helper::$entity_to_load['occurrence:sample_id'];
               if (self::getGridMode($args)) {
                   // in grid mode, we only needed to load the occurrence to find out the sample id.
                   data_entry_helper::$entity_to_load = array();
               }
           }
           if ($loadedSampleId) {
               data_entry_helper::load_existing_record($auth['read'], 'sample', $loadedSampleId);
           }
       }
       // attributes must be fetched after the entity to load is filled in - this is because the id gets filled in then!
       $attrOpts = array('id' => data_entry_helper::$entity_to_load['sample:id'], 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']);
       // select only the custom attributes that are for this sample method or all sample methods, if this
       // form is for a specific sample method.
       if (!empty($args['sample_method_id'])) {
           $attrOpts['sample_method_id'] = $args['sample_method_id'];
       }
       $attributes = data_entry_helper::getAttributes($attrOpts, false);
       //// Make sure the form action points back to this page
       $reload = data_entry_helper::get_reload_link_parts();
       unset($reload['params']['sample_id']);
       unset($reload['params']['occurrence_id']);
       unset($reload['params']['newSample']);
       $reloadPath = $reload['path'];
       if (count($reload['params'])) {
           $reloadPath .= '?' . http_build_query($reload['params']);
       }
       $r = "<form method=\"post\" id=\"entry_form\" action=\"{$reloadPath}\">\n";
       // Get authorisation tokens to update the Warehouse, plus any other hidden data.
       $hiddens = $auth['write'] . "<input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n" . "<input type=\"hidden\" id=\"survey_id\" name=\"survey_id\" value=\"" . $args['survey_id'] . "\" />\n";
       if (!empty($args['sample_method_id'])) {
           $hiddens .= '<input type="hidden" name="sample:sample_method_id" value="' . $args['sample_method_id'] . '"/>';
       }
       if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
           $hiddens .= "<input type=\"hidden\" id=\"sample:id\" name=\"sample:id\" value=\"" . data_entry_helper::$entity_to_load['sample:id'] . "\" />\n";
       }
       if (isset(data_entry_helper::$entity_to_load['occurrence:id'])) {
           $hiddens .= "<input type=\"hidden\" id=\"occurrence:id\" name=\"occurrence:id\" value=\"" . data_entry_helper::$entity_to_load['occurrence:id'] . "\" />\n";
       }
       // Check if Record Status is included as a control. If not, then add it as a hidden.
       $arr = explode("\r\n", $args['structure']);
       if (!in_array('[record status]', $arr)) {
           $value = isset($args['defaults']['occurrence:record_status']) ? $args['defaults']['occurrence:record_status'] : 'C';
           $hiddens .= "<input type=\"hidden\" id=\"occurrence:record_status\" name=\"occurrence:record_status\" value=\"{$value}\" />\n";
       }
       // request automatic JS validation
       if (!isset($args['clientSideValidation']) || $args['clientSideValidation']) {
           data_entry_helper::enable_validation('entry_form');
       }
       // If logged in, output some hidden data about the user
       if (isset($args['copyFromProfile']) && $args['copyFromProfile'] == true) {
           self::profile_load_all_profile($user);
       }
       foreach ($attributes as &$attribute) {
           $attrPropName = 'profile_' . strtolower(str_replace(' ', '_', $attribute['caption']));
           if (isset($args['copyFromProfile']) && $args['copyFromProfile'] == true && isset($user->{$attrPropName})) {
               if ($args['nameShow'] == true) {
                   $attribute['default'] = $user->{$attrPropName};
               } else {
                   // profile attributes are not displayed as the user is logged in
                   $attribute['handled'] = true;
                   $attribute['value'] = $user->{$attrPropName};
               }
           } elseif (strcasecmp($attribute['caption'], 'cms user id') == 0) {
               if ($logged_in) {
                   $attribute['value'] = $user->uid;
               }
               $attribute['handled'] = true;
               // user id attribute is never displayed
           } elseif (strcasecmp($attribute['caption'], 'cms username') == 0) {
               if ($logged_in) {
                   $attribute['value'] = $user->name;
               }
               $attribute['handled'] = true;
               // username attribute is never displayed
           } elseif (strcasecmp($attribute['caption'], 'email') == 0) {
               if ($logged_in) {
                   if ($args['emailShow'] != true) {
                       // email attribute is not displayed
                       $attribute['value'] = $user->mail;
                       $attribute['handled'] = true;
                   } else {
                       $attribute['default'] = $user->mail;
                   }
               }
           } elseif ((strcasecmp($attribute['caption'], 'first name') == 0 || strcasecmp($attribute['caption'], 'last name') == 0 || strcasecmp($attribute['caption'], 'surname') == 0) && $logged_in) {
               if ($args['nameShow'] != true) {
                   // name attributes are not displayed because we have the users login
                   $attribute['handled'] = true;
               }
           }
           // If we have a value for one of the user login attributes then we need to output this value. BUT, for existing data
           // we must not overwrite the user who created the record.
           if (isset($attribute['value']) && $mode != MODE_EXISTING) {
               $hiddens .= '<input type="hidden" name="' . $attribute['fieldname'] . '" value="' . $attribute['value'] . '" />' . "\n";
           }
       }
       $customAttributeTabs = get_attribute_tabs($attributes);
       $tabs = self::get_all_tabs($args['structure'], $customAttributeTabs);
       $r .= "<div id=\"controls\">\n";
       // Build a list of the tabs that actually have content
       $tabHtml = self::get_tab_html($tabs, $auth, $args, $attributes, $hiddens);
       // Output the dynamic tab headers
       if ($args['interface'] != 'one_page') {
           $headerOptions = array('tabs' => array());
           foreach ($tabHtml as $tab => $tabContent) {
               $alias = preg_replace('/[^a-zA-Z0-9]/', '', strtolower($tab));
               $tabtitle = lang::get("LANG_Tab_{$alias}");
               if ($tabtitle == "LANG_Tab_{$alias}") {
                   // if no translation provided, we'll just use the standard heading
                   $tabtitle = $tab;
               }
               $headerOptions['tabs']['#' . $alias] = $tabtitle;
           }
           $r .= data_entry_helper::tab_header($headerOptions);
           data_entry_helper::enable_tabs(array('divId' => 'controls', 'style' => $args['interface'], 'progressBar' => isset($args['tabProgress']) && $args['tabProgress'] == true));
       }
       // Output the dynamic tab content
       $pageIdx = 0;
       foreach ($tabHtml as $tab => $tabContent) {
           // get a machine readable alias for the heading
           $tabalias = preg_replace('/[^a-zA-Z0-9]/', '', strtolower($tab));
           $r .= '<div id="' . $tabalias . '">' . "\n";
           // For wizard include the tab title as a header.
           if ($args['interface'] == 'wizard') {
               $r .= '<h1>' . $headerOptions['tabs']['#' . $tabalias] . '</h1>';
           }
           $r .= $tabContent;
           // Add any buttons required at the bottom of the tab
           if ($args['interface'] == 'wizard') {
               $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => $pageIdx === 0 ? 'first' : ($pageIdx == count($tabHtml) - 1 ? 'last' : 'middle')));
           } elseif ($pageIdx == count($tabHtml) - 1 && !($args['interface'] == 'tabs' && $args['save_button_below_all_pages'])) {
               // last part of a non wizard interface must insert a save button, unless it is tabbed interface with save button beneath all pages
               $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" id=\"save-button\" value=\"" . lang::get('LANG_Save') . "\" />\n";
           }
           $pageIdx++;
           $r .= "</div>\n";
       }
       $r .= "</div>\n";
       if ($args['interface'] == 'tabs' && $args['save_button_below_all_pages']) {
           $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" id=\"save-button\" value=\"" . lang::get('LANG_Save') . "\" />\n";
       }
       if (!empty(data_entry_helper::$validation_errors)) {
           $r .= data_entry_helper::dump_remaining_errors();
       }
       $r .= "</form>";
       $r .= self::link_species_popups($args);
       return $r;
   }
Ejemplo n.º 17
0
function iform_mnhnl_lux5kgridControl($auth, $args, $node, $options)
{
    global $indicia_templates, $user;
    $options = array_merge(array('initLoadArgs' => '{}', 'Instructions1' => lang::get('LANG_CommonInstructions1'), 'Instructions2' => lang::get('LANG_DE_Instructions2'), 'MainFieldLabel' => lang::get('LANG_DE_LocationIDLabel'), 'ChooseParentLabel' => lang::get('LANG_CommonParentLabel'), 'ParentLabel' => lang::get('LANG_CommonParentLabel'), 'NameLabel' => lang::get('LANG_CommonLocationNameLabel'), 'FilterNameLabel' => lang::get('LANG_CommonFilterNameLabel'), 'CodeLabel' => lang::get('LANG_CommonLocationCodeLabel'), 'AdminMode' => false, 'disabled' => false), $options);
    switch ($args['locationMode']) {
        case 'multi':
            $options = array_merge(array('ChooseParentFieldID' => 'sample-location-id', 'ChooseParentFieldName' => 'sample:location_id', 'MainFieldID' => 'dummy-location-id', 'MainFieldName' => 'dummy:location_id'), $options);
            break;
        default:
            // parent, single, filtered
            $options = array_merge(array('ChooseParentFieldID' => 'dummy-parent-id', 'ChooseParentFieldName' => 'dummy:parent_id', 'ParentFieldID' => 'location-parent-id', 'ParentFieldName' => 'location:parent_id', 'MainFieldID' => 'location-id', 'MainFieldName' => 'location:id'), $options);
            break;
    }
    // we are using meaning_ids: for the location attributes we need to convert the id to the term for the templates. Can't just output value - convert raw value
    $attrArgs = array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']);
    $locationAttributes = data_entry_helper::getAttributes($attrArgs, false);
    // this does not get values
    $termlists = array();
    $requiresConv = array();
    foreach ($locationAttributes as $locAttr) {
        if (!is_null($locAttr["termlist_id"])) {
            $termlists[] = $locAttr["termlist_id"];
            $requiresConv[] = $locAttr["attributeId"];
        }
    }
    data_entry_helper::$javascript .= "\nvar requiresConv = " . json_encode($requiresConv) . ";\n";
    if (count($termlists) > 0) {
        data_entry_helper::$javascript .= "var terms = {";
        $extraParams = $auth['read'] + array('view' => 'detail', 'preferred' => 't', 'orderby' => 'meaning_id', 'termlist_id' => $termlists);
        $terms_data_def = array('table' => 'termlists_term', 'extraParams' => $extraParams);
        $terms = data_entry_helper::get_population_data($terms_data_def);
        $first = true;
        foreach ($terms as $term) {
            data_entry_helper::$javascript .= ($first ? '' : ',') . $term['meaning_id'] . ": \"" . htmlSpecialChars($term['term']) . "\"\n";
            $first = false;
        }
        data_entry_helper::$javascript .= "};\nconvertTerm=function(id){\n\tif(typeof terms[id] == 'undefined') return id;\n\treturn terms[id];\n}\n";
    }
    $precisionAttrID = iform_mnhnl_getAttrID($auth, $args, 'location', 'Precision');
    if ($precisionAttrID && isset($args['movePrecision']) && $args['movePrecision']) {
        data_entry_helper::$javascript .= "\nvar precisionAttr = jQuery('[name=locAttr\\:" . $precisionAttrID . "],[name^=locAttr\\:" . $precisionAttrID . "\\:]');\nvar precisionLabel = precisionAttr.prev();\nprecisionAttr.next().filter('br').remove();\nprecisionLabel.addClass('auto-width prepad').insertAfter('#imp-srefY');\nprecisionAttr.insertAfter(precisionLabel).addClass('precision');\n";
    }
    $creatorAttr = iform_mnhnl_getAttrID($auth, $args, 'location', 'Creator');
    if (isset(data_entry_helper::$entity_to_load["sample:updated_by_id"])) {
        // only set if data loaded from db, not error condition
        data_entry_helper::load_existing_record($auth['read'], 'location', data_entry_helper::$entity_to_load["sample:location_id"]);
    }
    $retVal = '<div id="clickableLayersOutputDiv" style="display:none;"></div>';
    if ($args['LocationTypeTerm'] == '' && isset($args['loctoolsLocTypeID'])) {
        $args['LocationTypeTerm'] = $args['loctoolsLocTypeID'];
    }
    $primary = iform_mnhnl_getTermID($auth, 'indicia:location_types', $args['LocationTypeTerm']);
    if ($args['SecondaryLocationTypeTerm'] != '') {
        $secondary = iform_mnhnl_getTermID($auth, 'indicia:location_types', $args['SecondaryLocationTypeTerm']);
        $loctypequery = "\"&query=\"+escape(JSON.stringify({'in': ['location_type_id', [{$primary}, {$secondary}]]}))";
        $loctypeParam = array($primary, $secondary);
    } else {
        $loctypequery = "\"&location_type_id=" . $primary . "\"";
        $loctypeParam = $primary;
    }
    // $retVal .= "<p>".print_r($options,true)."</p>";
    data_entry_helper::$javascript .= "\n// Create vector layers: one to display the Parent Square onto, and another for the site locations list\n// the default edit layer is used for this sample\nParentLocStyleMap = new OpenLayers.StyleMap({\"default\": new OpenLayers.Style({strokeColor: \"Yellow\",fillOpacity: 0,strokeWidth: 4})});\nParentLocationLayer = new OpenLayers.Layer.Vector('Parents',{styleMap: ParentLocStyleMap,displayInLayerSwitcher: false});\n\ndefaultPointStyle = new OpenLayers.Style({pointRadius: 6,fillColor: \"Red\",fillOpacity: 0.3,strokeColor: \"Yellow\",strokeWidth: 1});\nselectPointStyle = new OpenLayers.Style({pointRadius: 6,fillColor: \"Blue\",fillOpacity: 0.3,strokeColor: \"Yellow\",strokeWidth: 2});\ndefaultStyle = new OpenLayers.Style({pointRadius: 6, fillColor: \"Red\",fillOpacity: 0.3,strokeColor: \"Red\",strokeWidth: 1});\nselectStyle = new OpenLayers.Style({fillColor: \"Blue\",fillOpacity: 0.3,strokeColor: \"Blue\",strokeWidth: 2});\n//defaultLabelStyle = new OpenLayers.Style({fontColor: \"Yellow\", labelAlign: \"" . $args['labelAlign'] . "\", labelXOffset: " . $args['labelXOffset'] . ", labelSelect: true});\ndragPointStyleHash={pointRadius: 6,fillColor: \"Fuchsia\",fillOpacity: 0.3,strokeColor: \"Fuchsia\",strokeWidth: 1};\n// Interesting behaviour of the Points: when any mod control is active it creates a set of vertices which can be \n// dragged, allowing the existing geometry to be modified. All fine for Lines and polygons, but for points\n// the vertices are generated in the default style, and appear over the top of our existing geometry, so\n// effectively making it appear unselected! \n// We want consistent colouring, so\n// 1) normal=red, yellow surrounds points\n// 2) highlighted=blue, yellow surrounds points\n// 3) Drag points=purple.\n\nSitePointStyleMap = new OpenLayers.StyleMap({\"default\": defaultPointStyle, \"select\": selectPointStyle});\nSiteStyleMap = new OpenLayers.StyleMap({\"default\": defaultStyle, \"select\": selectStyle});\n//SiteLabelStyleMap = new OpenLayers.StyleMap({\"default\": defaultLabelStyle});\n\n" . ($args['SecondaryLocationTypeTerm'] != '' && $options['AdminMode'] ? "SiteListPrimaryLabelStyleHash={fontColor: \"Red\", labelAlign: \"" . $args['labelAlign'] . "\", labelXOffset: " . $args['labelXOffset'] . ", labelSelect: true, fontSize: \"1.2em\", fontWeight: \"bold\"};\nSiteListSecondaryLabelStyleHash" : "\nSiteListPrimaryLabelStyleHash") . "={fontColor: \"Yellow\", labelAlign: \"" . $args['labelAlign'] . "\", labelXOffset: " . $args['labelXOffset'] . ", labelSelect: true};\n\nSitePointLayer = new OpenLayers.Layer.Vector('Site Points',{styleMap: SitePointStyleMap, displayInLayerSwitcher: false});\n//SitePointLayer = new OpenLayers.Layer.Vector('Site Points',{styleMap: SitePointStyleMap});\nSitePathLayer = new OpenLayers.Layer.Vector('Site Paths',{styleMap: SiteStyleMap, displayInLayerSwitcher: false});\nSiteAreaLayer = new OpenLayers.Layer.Vector('Site Areas',{styleMap: SiteStyleMap, displayInLayerSwitcher: false});\nSiteLabelLayer = new OpenLayers.Layer.Vector('Site Labels',{//styleMap: SiteLabelStyleMap, \ndisplayInLayerSwitcher: false});\nvar SiteNum = 0;\n";
    if (isset($args['locationLayerWMS']) && $args['locationLayerWMS'] != '') {
        // define Parent WMS Layer
        $WMSoptions = explode(',', $args['locationLayerWMS']);
        if ($args['includeLocTools'] && function_exists('iform_loctools_listlocations')) {
            $squares = iform_loctools_listlocations($node);
            if (is_array($squares) && count($squares) == 0) {
                $squares = array("-1");
            }
            // put in dummy value (all ids are > 0) to allow CQL filter to work on a blank list.
        } else {
            $squares = 'all';
        }
        // can't use the column name id in the cql_filter as this has a special (fid) meaning.
        data_entry_helper::$javascript .= "\nWMSoptions = {SERVICE: 'WMS', VERSION: '1.1.0', STYLES: '', SRS: '" . $WMSoptions[2] . "', FORMAT: 'image/png', TRANSPARENT: 'true', LAYERS: '" . $WMSoptions[1] . "',\n  CQL_FILTER: \"location_type_id=" . $args['loctoolsLocTypeID'] . " AND website_id=" . $args['website_id'] . ($squares != 'all' ? " AND location_id IN (" . implode(',', $squares) . ")" : '') . "\"\n    };\nParentWMSLayer = new OpenLayers.Layer.WMS('Parent Grid',\n  '" . (function_exists(iform_proxy_url) ? iform_proxy_url($WMSoptions[0]) : $WMSoptions[0]) . "',\n  WMSoptions, {\n    minScale: " . $WMSoptions[3] . ",\n    maxScale: " . $WMSoptions[4] . ",\n    units: '" . $WMSoptions[5] . "',\n    isBaseLayer: false,\n    singleTile: true\n  });\n";
        if ($args['locationMode'] == 'multi' && isset(data_entry_helper::$entity_to_load["sample:location_id"])) {
            data_entry_helper::$javascript .= "setClickedParent = function(features, div){ return ''; };\n";
        } else {
            data_entry_helper::$javascript .= "setClickedParent = function(features, div){\n  jQuery('[name=" . str_replace(':', '\\:', $options['ChooseParentFieldName']) . "]').val(features[0].data.id).change();\n  return '';\n};\n";
        }
    }
    data_entry_helper::$javascript .= "\n// not happy about centroid calculations: lines and multipoints seem to take first vertex\n_getCentroid = function(geometry){\n  var retVal;\n  retVal = {sumx: 0, sumy: 0, count: 0};\n  switch(geometry.CLASS_NAME){\n    case \"OpenLayers.Geometry.Point\":\n      retVal = {sumx: geometry.x, sumy: geometry.y, count: 1};\n      break;\n    case \"OpenLayers.Geometry.MultiPoint\":\n    case \"OpenLayers.Geometry.MultiLineString\":\n    case \"OpenLayers.Geometry.LineString\":\n    case \"OpenLayers.Geometry.MultiPolygon\":\n    case \"OpenLayers.Geometry.Collection\":\n      var retVal = {sumx: 0, sumy: 0, count: 0};\n      for(var i=0; i< geometry.components.length; i++){\n        var point=_getCentroid(geometry.components[i]);\n        retVal = {sumx: retVal.sumx+point.sumx, sumy: retVal.sumy+point.sumy, count: retVal.count+point.count};\n      }\n      break;\n    case \"OpenLayers.Geometry.Polygon\": // only do outer ring\n      var point=geometry.getCentroid();\n      retVal = {sumx: point.x*geometry.components[0].components.length, sumy: point.y*geometry.components[0].components.length, count: geometry.components[0].components.length};\n      break;\n  }\n  return retVal;\n}\ngetCentroid=function(geometry){\n  var oddball=_getCentroid(geometry);\n  return new OpenLayers.Geometry.Point(oddball.sumx/oddball.count, oddball.sumy/oddball.count);\n}\nrecalcNumSites = function(){\n  var sitearray = {};\n  var allFeatures = SiteAreaLayer.features.concat(SitePathLayer.features,SitePointLayer.features);\n  // don't need to consider Label layer...\n  for(var i=0; i< allFeatures.length; i++){\n    if(typeof allFeatures[i].attributes.SiteNum != 'undefined')\n      sitearray['x'+allFeatures[i].attributes.SiteNum.toString()] = true;\n  }\n  var count = 0;\n  for (x in sitearray) count++;\n  jQuery('#dummy-num-sites').val(count);\n};\nrecalcNumSites();\nclearLocation = function(hookArg, clearName){ // clears all the data in the fields.\n  if(clearName === true || (clearName == 'maybe' && jQuery('#" . $options['MainFieldID'] . "').val() != ''))\n    jQuery('" . ($args['locationMode'] != 'multi' ? "#sample-location-name" : "") . ",#location-name').val('');\n  jQuery('#" . $options['MainFieldID'] . ($args['locationMode'] != 'multi' ? ",#sample-location-id" : "") . ",#centroid_sref,#imp-srefX,#imp-srefY,#centroid_geom,#boundary_geom,[name=location\\:comment],[name=location\\:parent_id],#location-code').val('');\n  jQuery('#location-code').attr('dbCode','');\n" . ($args['locationMode'] != 'multi' && $args['siteNameTermListID'] != "" && isset($args['duplicateNameCheck']) && $args['duplicateNameCheck'] == 'enforce' ? "  jQuery('#location-name option').removeAttr('disabled');\n  var nameVal = jQuery('#location-name').val();\n  for(var i=0; i< SiteLabelLayer.features.length; i++){\n    if(typeof SiteLabelLayer.features[i].attributes.SiteNum != 'undefined'){\n      // At the moment the allowable options are integers: if the old data is dodgy it may not hold an integer\n      if(SiteLabelLayer.features[i].style.label == parseInt(SiteLabelLayer.features[i].style.label)){\n\t\tif(SiteLabelLayer.features[i].style.label == nameVal) jQuery('#location-name').val('');\n\t\tjQuery('#location-name').find('option').filter('[value='+SiteLabelLayer.features[i].style.label+']').attr('disabled','disabled');\n      }\n    }\n  }\n" : "") . "  jQuery('#location_location_type_id').val('{$primary}');\n  // first  to remove any hidden multiselect checkbox unclick fields\n  var fullAttrList=jQuery('[name^=locAttr\\:]').not('[name\$=\\:term]');\n  var attrList=jQuery('[name^=locAttr\\:]').not('[name\$=\\:term]').not('.filterFields');\n  fullAttrList.filter('.multiselect').remove();\n  fullAttrList.filter(':checkbox').removeAttr('checked').each(function(idx,elem){\n    var name = jQuery(elem).attr('name').split(':');\n    var value = jQuery(elem).val().split(':');\n    jQuery('[name^=locAttr\\:'+name[1]+'\\:]').filter(':hidden').remove();\n    jQuery(elem).val(value[0]);\n  });\n  // rename\n  fullAttrList.each(function(){\n    var name = jQuery(this).attr('name').split(':');\n    if(name[1].indexOf('[]') > 0) name[1] = name[1].substr(0, name[1].indexOf('[]'));\n    jQuery(this).attr('name', name[0]+':'+name[1]);\n  });\n  // reset values (checkboxes done above).\n  attrList.filter(':radio').removeAttr('checked');\n  attrList.filter(':text').val('');\n  attrList.filter('select').val('');\n  // rename checkboxes to add square brackets\n  attrList.filter(':checkbox').each(function(idx,elem){\n\tvar name = jQuery(elem).attr('name').split(':');\n\tvar similar = jQuery('[name=locAttr\\:'+name[1]+'],[name=locAttr\\:'+name[1]+'\\[\\]]').filter(':checkbox');\n\tif(similar.length > 1) // only do this for checkbox groups.\n\t\tjQuery(this).attr('name', name[0]+':'+name[1]+'[]');\n  });\n  if(typeof hook_set_defaults != 'undefined') hook_set_defaults(hookArg);\n}\nsetPermissions = function(enableItems, disableItems){\n  if(disableItems.length > 0) jQuery(disableItems.join(',')).attr('disabled',true);\n  if(enableItems.length > 0) jQuery(enableItems.join(',')).removeAttr('disabled');\n}\n// sets the permissions when there is nothing selected, and no parent is provided\nsetPermissionsNoParent = function(){\n  setPermissions([],\n                 ['[name=locations_website\\:website_id]',\n                  '#" . $options['MainFieldID'] . "',\n                  '[name=location\\:code]',\n                  '[name=location\\:name]',\n                  '[name=location\\:comment]',\n                  '[name=location\\:location_type_id]',\n                  '[name=location\\:deleted]',\n                  '[name=location\\:parent_id]',\n                  '[name^=locAttr\\:]',\n                  '#dummy-name',\n                  '#imp-sref',\n                  '#imp-geom',\n                  '#imp-boundary-geom']);\n}\nsetPermissionsNoSite = function(){\n  // In filter mode, if parent is in filter options, need it available. Also in that case will need to enter filter options before the main ID becomes available\n  // else when creating a new site, it is possible to select an old site from the drop down, provided there are some to select.\n  var disable = ['[name=locations_website\\:website_id]',\n                  '[name=location\\:code]',\n                  '[name=location\\:name]',\n                  '[name=location\\:comment]',\n                  '[name=location\\:location_type_id]',\n                  '[name=location\\:deleted]',\n                  '[name^=locAttr\\:]',\n                  '#dummy-name',\n                  '#imp-sref',\n                  '#imp-geom',\n                  '#imp-boundary-geom'];\n  if(typeof indiciaData.filterMode == 'undefined'){\n    var enable = ['#" . $options['MainFieldID'] . "']; // can choose site from drop down.\n    disable.push('[name=location\\:parent_id]');\n  } else {\n    disable.push('#" . $options['MainFieldID'] . "');\n    var enable = ['[name=location\\:parent_id]'];\n  }\n  setPermissions(enable,disable);\n}\nsetPermissionsOldEditableSite = function(){\n  setPermissions(['#" . $options['MainFieldID'] . "',\n                  '[name=location\\:code]',\n                  '[name=location\\:name]',\n                  '[name=location\\:comment]',\n                  '[name=location\\:location_type_id]',\n                  '[name=location\\:deleted]',\n                  '[name=location\\:parent_id]',\n                  '[name^=locAttr\\:]',\n                  '#dummy-name',\n                  '#imp-sref',\n                  '#imp-geom',\n                  '#imp-boundary-geom'],\n                 ['[name=locations_website\\:website_id]']);\n}\nsetPermissionsOldReadOnlySite = function(){\n  setPermissions(['#" . $options['MainFieldID'] . "'],\n                 ['[name=locations_website\\:website_id]',\n                  '[name=location\\:code]',\n                  '[name=location\\:name]',\n                  '[name=location\\:comment]',\n                  '[name=location\\:location_type_id]',\n                  '[name=location\\:deleted]',\n                  '[name=location\\:parent_id]',\n                  '[name^=locAttr\\:]',\n                  '#dummy-name',\n                  '#imp-sref',\n                  '#imp-geom',\n                  '#imp-boundary-geom']);\n}\nsetPermissionsNewSite = function(){\n  // when creating a new site, it is possible to select an old site from the drop down, provided there are some to select.\n  var enable = ['[name=locations_website\\:website_id]',\n                '[name=location\\:code]',\n                '[name=location\\:name]',\n                '[name=location\\:comment]',\n                '[name=location\\:location_type_id]',\n                '[name=location\\:parent_id]',\n                '[name^=locAttr\\:]',\n                '#dummy-name',\n                '#imp-sref',\n                '#imp-geom',\n                '#imp-boundary-geom'];\n  var disable = ['[name=location\\:deleted]'];\n  var allFeatures = SiteAreaLayer.features.concat(SitePathLayer.features,SitePointLayer.features);\n  var haveOld=false;\n  for(var i=0; i<allFeatures.length; i++){\n    if(allFeatures[i].attributes['new']==false){\n      haveOld=true;\n    }}\n  if(haveOld){\n    enable.push('#" . $options['MainFieldID'] . "');  // in case we want to change to an existing site.\n  } else {\n    disable.push('#" . $options['MainFieldID'] . "');\n  }\n  setPermissions(enable,disable);\n}\nloadLocation = function(feature){ // loads all the data into the location fields from a feature.\n  if(feature.attributes['new'])\n    setPermissionsNewSite();\n  else if (feature.attributes.canEdit)\n    setPermissionsOldEditableSite();\n  else\n    setPermissionsOldReadOnlySite();\n" . ($args['locationMode'] == 'multi' ? "  var mySelector = '#dummy-name';\n" : "  var mySelector = '#location-name';\n  clearLocation(false, true);\n") . "\n" . ($args['siteNameTermListID'] != "" ? "  jQuery(mySelector).find('option').removeAttr('disabled');\n" : "") . "  // the label is stored in the SiteLabelLayer. For new locations this is the only place the name is stored in the generic module.\n  for(var i=0; i< SiteLabelLayer.features.length; i++){\n    if(typeof SiteLabelLayer.features[i].attributes.SiteNum != 'undefined'){\n      if(feature.attributes.SiteNum == SiteLabelLayer.features[i].attributes.SiteNum){\n        jQuery('#dummy-name').val(SiteLabelLayer.features[i].style.label);\n      }\n" . ($args['siteNameTermListID'] != "" ? "      else {\n        // At the moment the allowable options are integers: if the old data is dodgy it may not hold an integer\n        if(SiteLabelLayer.features[i].style.label == parseInt(SiteLabelLayer.features[i].style.label))\n          jQuery(mySelector).find('option').filter('[value='+SiteLabelLayer.features[i].style.label+']').attr('disabled','disabled');\n      }\n" : "") . "    }\n  }\n" . ($args['locationMode'] == 'multi' ? "" : ";  // main field ID could be a select without an entry for me (in case of a filter) so add one if needed.\n  var amIaSelect = jQuery('#" . $options['MainFieldID'] . "').filter('select');\n  if(amIaSelect.length>0 && amIaSelect.find('[value='+feature.attributes.data.id+']').length==0){\n    amIaSelect.append('<option value=\"'+feature.attributes.data.id+'\">'+feature.attributes.data.name+'</option>');\n  }\n  jQuery(\"#" . $options['MainFieldID'] . ",#sample-location-id\").val(feature.attributes.data.id);\n  // parent_id is left as is in drop down if present. Not multi so must be an existing site.\n  jQuery('#location-name,#sample-location-name').val(feature.attributes.data.name);\n  jQuery('#location_location_type_id').val(feature.attributes.data.location_type_id);\n  if(feature.attributes.data.comment == null) feature.attributes.data.comment='';\n  jQuery('[name=location\\:comment]').val(feature.attributes.data.comment);\n  jQuery('[name=location\\:parent_id],[name=dummy\\:parent_id]').val(feature.attributes.data.parent_id);\n  jQuery('#location-code').val(feature.attributes.data.code).attr('dbCode',feature.attributes.data.code);\n  jQuery('#imp-geom').val(feature.attributes.data.centroid_geom); // this is as stored in the database i.e. 3857/900913 projection, not necessarily the map projection\n  jQuery('#imp-boundary-geom').val(feature.attributes.data.boundary_geom); // this is as stored in the database i.e. 3857/900913 projection, not necessarily the map projection\n  setSref(feature.geometry, feature.attributes.data.centroid_sref);\n  // reset attributes is done by clearLocation above. this clears the values of checkboxes.\n  jQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/data/location_attribute_value' +\n            '?mode=json&view=list&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&location_id='+feature.attributes.data.id+'&callback=?', function(data) {\n    if(data instanceof Array && data.length>0){\n      for (var i=0;i<data.length;i++){\n        if (data[i].id) {\n          // no multiselect or boolean checkboxes at the moment so don't code\n          var radiobuttons = jQuery('[name=locAttr\\:'+data[i]['location_attribute_id']+'],[name^=locAttr\\:'+data[i]['location_attribute_id']+'\\:]').filter(':radio');\n          var checkbuttons = jQuery('[name=locAttr\\:'+data[i]['location_attribute_id']+'\\[\\]],[name^=locAttr\\:'+data[i]['location_attribute_id']+'\\:]').filter(':checkbox');\n          if(radiobuttons.length > 0){ // radio buttons all share the same name, only one checked.\n            radiobuttons.attr('name', 'locAttr:'+data[i]['location_attribute_id']+':'+data[i].id)\n                  .filter('[value='+data[i].raw_value+']').attr('checked', 'checked');\n          } else if(checkbuttons.length > 0){ // checkbuttons buttons have different name if selected, any number selected.\n\t\t\tcheckbuttons = checkbuttons.filter('[value='+data[i].raw_value+']')\n\t\t\t\t.attr('name', 'locAttr:'+data[i]['location_attribute_id']+':'+data[i].id).attr('checked', 'checked');\n\t\t\tcheckbuttons.each(function(){\n\t\t\t\tjQuery('<input type=\"hidden\" value=\"\" class=\"multiselect\">').attr('name', jQuery(this).attr('name')).insertBefore(this);\n\t\t\t});\n          } else {\n            jQuery('[name=locAttr\\:'+data[i]['location_attribute_id']+']')\n                      .attr('name', 'locAttr:'+data[i]['location_attribute_id']+':'+data[i].id).val(data[i].raw_value);\n            if(jQuery('[name=locAttr\\:'+data[i]['location_attribute_id']+'\\:term]').length>0){ // autocomplete entries: force a lookup, we are using meaning_id\n              jQuery('[name=locAttr\\:'+data[i]['location_attribute_id']+'\\:term]').val('');\n              jQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/data/termlists_term' +\n                '?mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&preferred=t&meaning_id='+data[i].raw_value+'&callback=?', function(tdata) {\n                if(tdata.length>0){\n                  jQuery('[name^=locAttr]').filter('[value='+tdata[0].meaning_id+']').each(function(idx,elem){\n                    var name = jQuery(elem).attr('name').split(':');\n                    jQuery('[name=locAttr\\:'+name[1]+'\\:term]').val(tdata[0].term);\n                  });\n                }\n              });\n            }\n          }\n        }\n      }\n      if(typeof hook_loadFilters != 'undefined')\n        hook_loadFilters(); // can only be done after attributes loaded\n     }});\n") . "\n  if(typeof hook_loadLocation != 'undefined')\n    hook_loadLocation(feature);\n}\ncheckEditable = function(isNew, id){\n  if(isNew) return true; // if I have created a new Site in this session, I can edit it.\n  if(typeof canEditExistingSites != 'undefined') return canEditExistingSites;\n  return(SiteEditable[id]);\n}\nconvertFeature = function(feature, projection){\n  if(feature instanceof Array){\n    if(feature.length == 0) return geom;\n    var newfeatures = [];\n    \$.each(feature, function(idx, featureElem){\n      newfeatures.push(convertFeature(featureElem, projection));\n    });\n    return newfeatures;\n  }\n  feature.geometry = convertGeom(feature.geometry, projection);\n  return feature;\n}\nconvertGeom = function(geom, projection){\n  if (projection.projcode!='EPSG:900913' && projection.projcode!='EPSG:3857') { \n    var cloned = geom.clone();\n    return cloned.transform(new OpenLayers.Projection('EPSG:900913'), projection);\n  }\n  return geom;\n}\nreverseConvertGeom = function(geom, projection){\n  if (projection.projcode!='EPSG:900913' && projection.projcode!='EPSG:3857') {\n    var cloned = geom.clone();\n    return cloned.transform(projection, new OpenLayers.Projection('EPSG:900913'));\n  }\n  return geom;\n}\nzoomToLayerExtent = function(layer){\n  var layerBounds = layer.getDataExtent().clone(); // use a clone\n  var mapBounds = layer.map.getMaxExtent();\n  if(layerBounds.left   < mapBounds.left)   layerBounds.left = mapBounds.left;\n  if(layerBounds.right  > mapBounds.right)  layerBounds.right = mapBounds.right;\n  if(layerBounds.bottom < mapBounds.bottom) layerBounds.bottom = mapBounds.bottom;\n  if(layerBounds.top    > mapBounds.top)    layerBounds.top = mapBounds.top;\n  layer.map.zoomToExtent(layerBounds);\n}\n\nloadFeatures = function(parent_id, child_id, childArgs, loadParent, setSelectOptions, zoomParent, clearLocationFlag, setPermissionState){\n  ParentLocationLayer.destroyFeatures();\n  SiteLabelLayer.destroyFeatures();\n  SiteAreaLayer.destroyFeatures();\n  SitePathLayer.destroyFeatures();\n  SitePointLayer.destroyFeatures();\n  if(setSelectOptions)\n    jQuery('#" . $options['MainFieldID'] . "').find('option').remove();\n" . ($args['locationMode'] != 'multi' && $args['siteNameTermListID'] != "" ? "  jQuery('#location-name').find('option').removeAttr('disabled');\n" : "") . "  if(clearLocationFlag){\n    clearLocation(false, true);\n  }\n  deactivateControls();\n  recalcNumSites();\n  SiteNum=0;\n  if(parent_id != '' && loadParent){\n    jQuery.getJSON(\"" . data_entry_helper::$base_url . "/index.php/services/data/location/\"+parent_id+\"?mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&callback=?\",\n      function(data) {\n       if (data.length>0) {\n         var parser = new OpenLayers.Format.WKT();\n         if(data[0].boundary_geom){ // only one location if any\n           var feature = parser.read(data[0].boundary_geom)\n           feature=convertFeature(feature, \$('#map')[0].map.projection);\n           ParentLocationLayer.addFeatures([feature]);\n           if(zoomParent) {\n             // Parent squares may overlap the edges of the map.\n             zoomToLayerExtent(ParentLocationLayer);\n           }\n         }\n         selectFeature.activate();\n" . ($args['locationMode'] == 'multi' ? "  jQuery('#sample-location-name').val(data[0].name);" : "") . "       }});\n  }\n  if(!loadParent) selectFeature.activate();\n  if(parent_id != '' || loadParent==false){\n    jQuery.getJSON(\"" . data_entry_helper::$base_url . "/index.php/services/data/location?mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&callback=?&orderby=name\"+" . $loctypequery . "+(loadParent ? '&parent_id='+parent_id : ''),\n      function(data) {\n        if (data.length>0) {\n          if(setPermissionState) setPermissionsNoSite();\n          if(child_id=='') selectFeature.activate(); // we have things we can select\n          if(setSelectOptions)\n            jQuery(\"#" . $options['MainFieldID'] . "\").append('<option value=\"\">" . lang::get("LANG_CommonEmptyLocationID") . "</option>');\n          var parser = new OpenLayers.Format.WKT();\n          var locationList = [];\n          for (var i=0;i<data.length;i++){\n            var centreFeature = false;\n            var feature;\n            SiteNum++;\n            if(data[i].boundary_geom){\n              feature = parser.read(data[i].boundary_geom); // assume map projection=900913, if GEOMETRYCOLLECTION this will be an array or its children!\n              var centre = false;\n              if(data[i].centroid_geom) {\n                centreFeature = parser.read(data[i].centroid_geom); // assume map projection=900913\n                centreFeature=convertFeature(centreFeature, \$('#map')[0].map.projection);\n              }\n              var pointFeature = false;\n              var lineFeature = false;\n              var areaFeature = false;\n              if(typeof(feature)=='object'&&(feature instanceof Array)){\n                for(var j=0; j< feature.length; j++){\n                  switch(feature[j].geometry.CLASS_NAME){\n                    case \"OpenLayers.Geometry.Point\":\n                    case \"OpenLayers.Geometry.MultiPoint\":\n                      pointFeature = feature[j];\n                      break;\n                    case \"OpenLayers.Geometry.LineString\":\n                    case \"OpenLayers.Geometry.MultiLineString\":\n                      lineFeature = feature[j];\n                      break;\n                    default:\n                      areaFeature = feature[j];\n                      break;\n                  }\n                }\n              } else {\n                switch(feature.geometry.CLASS_NAME){\n                  case \"OpenLayers.Geometry.Point\":\n                  case \"OpenLayers.Geometry.MultiPoint\":\n                    pointFeature = feature;\n                    break;\n                  case \"OpenLayers.Geometry.LineString\":\n                  case \"OpenLayers.Geometry.MultiLineString\":\n                    lineFeature = feature;\n                    break;\n                  default:\n                    areaFeature = feature;\n                    break;\n                }\n              }\n              if(areaFeature) {\n                areaFeature.attributes = {highlighted: false, 'new': false, canEdit: checkEditable(false, data[i].id), SiteNum: SiteNum, data: data[i]};\n                areaFeature=convertFeature(areaFeature, \$('#map')[0].map.projection);\n                SiteAreaLayer.addFeatures([areaFeature]);\n                if(!centreFeature) centreFeature = new OpenLayers.Feature.Vector(getCentroid(areaFeature.geometry));\n              }\n              if(lineFeature) {\n                lineFeature.attributes = {highlighted: false, 'new': false, canEdit: checkEditable(false, data[i].id), SiteNum: SiteNum, data: data[i]};\n                lineFeature=convertFeature(lineFeature, \$('#map')[0].map.projection);\n                SitePathLayer.addFeatures([lineFeature]);\n                if(!centreFeature) centreFeature = new OpenLayers.Feature.Vector(getCentroid(lineFeature.geometry));\n              }\n              if(pointFeature) {\n                pointFeature.attributes = {highlighted: false, 'new': false, canEdit: checkEditable(false, data[i].id), SiteNum: SiteNum, data: data[i]};\n                pointFeature=convertFeature(pointFeature, \$('#map')[0].map.projection);\n                SitePointLayer.addFeatures([pointFeature]);\n                if(!centreFeature) centreFeature = new OpenLayers.Feature.Vector(getCentroid(pointFeature.geometry));\n              }\n            } else {\n              // no boundary, only a centre point.\n              feature = parser.read(data[i].centroid_geom); // assume map projection=900913\n              feature=convertFeature(feature, \$('#map')[0].map.projection);\n              centreFeature = feature.clone();\n              feature.attributes = {highlighted: false, 'new': false, canEdit: checkEditable(false, data[i].id), SiteNum: SiteNum, data: data[i]};\n              SitePointLayer.addFeatures([feature]);\n            }\n            centreFeature.attributes = {highlighted: false, 'new': false, canEdit: checkEditable(false, data[i].id), SiteNum: SiteNum, data: data[i]};\n" . ($args['SecondaryLocationTypeTerm'] != '' && $options['AdminMode'] ? "            if(data[i].location_type_id == {$secondary}){\n              centreFeature.style = jQuery.extend({}, SiteListSecondaryLabelStyleHash);\n            } else \n  " : "") . "            centreFeature.style = jQuery.extend({}, SiteListPrimaryLabelStyleHash);\n            centreFeature.style.label = data[i].name;\n            SiteLabelLayer.addFeatures([centreFeature]);\n            locationList.push({id : data[i].id, feature : centreFeature});\n            if(setSelectOptions){\n              if(child_id != '' && data[i].id == child_id){\n                jQuery(\"#" . $options['MainFieldID'] . "\").append('<option value=\"'+data[i].id+'\" selected=\"selected\">'+data[i].name+'</option>');\n              } else {\n                jQuery(\"#" . $options['MainFieldID'] . "\").append('<option value=\"'+data[i].id+'\">'+data[i].name+'</option>');\n              }\n            }\n            if(child_id==data[i].id && setPermissionState){\n              if(centreFeature.attributes.canEdit){\n                setPermissionsOldEditableSite();\n              } else {\n                setPermissionsOldReadOnlySite()\n              }\n            }\n            if(typeof hook_ChildFeatureLoad != 'undefined') hook_ChildFeatureLoad(feature, data[i], child_id, childArgs);\n          }\n          recalcNumSites();\n          " . ($args['locationMode'] == 'single' || $args['locationMode'] == 'filtered' ? "" : "if(setSelectOptions) ") . "populateExtensions(locationList);\n        } else if(setSelectOptions){\n          if(setPermissionState) setPermissionsNoParent();\n          jQuery('#" . $options['MainFieldID'] . "').append('<option value=\"\">" . lang::get("LANG_NoSitesInSquare") . "</option>');\n        }\n    });\n  } else {\n    if(setPermissionState) setPermissionsNoParent();\n    if(setSelectOptions)\n      jQuery('#" . $options['MainFieldID'] . "').append('<option value=\"\">" . lang::get("LANG_CommonChooseParentFirst") . "</option>');\n  }\n};\nloadChildFeatures = function(parent_id, setSelectOptions){\n// this is only used when changing the parent: need to keep current highlighted features.\n  SiteNum=1;\n  for(var i=SiteLabelLayer.features.length-1; i >= 0; i--) {\n    if(SiteLabelLayer.features[i].attributes.highlighted == false) {\n      SiteLabelLayer.destroyFeatures([SiteLabelLayer.features[i]]);\n    } else {\n      SiteLabelLayer.features[i].attributes.SiteNum == SiteNum;\n    }\n  }\n  for(var i=SiteAreaLayer.features.length-1; i >= 0; i--) {\n    if(SiteAreaLayer.features[i].attributes.highlighted == false) {\n      SiteAreaLayer.destroyFeatures([SiteAreaLayer.features[i]]);\n    } else {\n      SiteAreaLayer.features[i].attributes.SiteNum == SiteNum;\n    }\n  }\n  for(var i=SitePathLayer.features.length-1; i >= 0; i--) {\n    if(SitePathLayer.features[i].attributes.highlighted == false) {\n      SitePathLayer.destroyFeatures([SitePathLayer.features[i]]);\n    } else {\n      SitePathLayer.features[i].attributes.SiteNum == SiteNum;\n    }\n  }\n  for(var i=SitePointLayer.features.length-1; i >= 0; i--) {\n    if(SitePointLayer.features[i].attributes.highlighted == false) {\n      SitePointLayer.destroyFeatures([SitePointLayer.features[i]]);\n      } else {\n      SitePointLayer.features[i].attributes.SiteNum == SiteNum;\n    }\n  }\n  if(setSelectOptions)\n    jQuery('#" . $options['MainFieldID'] . "').find('option').not(':selected').remove();\n" . ($args['locationMode'] != 'multi' && $args['siteNameTermListID'] != "" ? "  jQuery('#location-name').find('option').removeAttr('disabled');\n" : "") . "  recalcNumSites();\n  jQuery.getJSON(\"" . data_entry_helper::$base_url . "/index.php/services/data/location?mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&callback=?&orderby=name\"+" . $loctypequery . "+'&parent_id='+parent_id,\n      function(data) {\n        if (data.length>0) {\n          if(setSelectOptions)\n            jQuery(\"#" . $options['MainFieldID'] . "\").append('<option value=\"\">" . lang::get("LANG_CommonEmptyLocationID") . "</option>');\n          var parser = new OpenLayers.Format.WKT();\n          var locationList = [];\n          for (var i=0;i<data.length;i++){\n            var centreFeature = false;\n            var feature;\n            SiteNum++;\n            if(data[i].boundary_geom){\n              feature = parser.read(data[i].boundary_geom); // assume map projection=900913, if GEOMETRYCOLLECTION this will be an array or its children!\n              var centre = false;\n              if(data[i].centroid_geom) {\n                centreFeature = parser.read(data[i].centroid_geom); // assume map projection=900913\n                centreFeature=convertFeature(centreFeature, \$('#map')[0].map.projection);\n              }\n              var pointFeature = false;\n              var lineFeature = false;\n              var areaFeature = false;\n              if(typeof(feature)=='object'&&(feature instanceof Array)){\n                for(var j=0; j< feature.length; j++){\n                  switch(feature[j].geometry.CLASS_NAME){\n                    case \"OpenLayers.Geometry.Point\":\n                    case \"OpenLayers.Geometry.MultiPoint\":\n                      pointFeature = feature[j];\n                      break;\n                    case \"OpenLayers.Geometry.LineString\":\n                    case \"OpenLayers.Geometry.MultiLineString\":\n                      lineFeature = feature[j];\n                      break;\n                    default:\n                      areaFeature = feature[j];\n                      break;\n                  }\n                }\n              } else {\n                switch(feature.geometry.CLASS_NAME){\n                  case \"OpenLayers.Geometry.Point\":\n                  case \"OpenLayers.Geometry.MultiPoint\":\n                    pointFeature = feature;\n                    break;\n                  case \"OpenLayers.Geometry.LineString\":\n                  case \"OpenLayers.Geometry.MultiLineString\":\n                    lineFeature = feature;\n                    break;\n                  default:\n                    areaFeature = feature;\n                    break;\n                }\n              }\n              if(areaFeature) {\n                areaFeature.attributes = {highlighted: false, 'new': false, canEdit: checkEditable(false, data[i].id), SiteNum: SiteNum, data: data[i]};\n                areaFeature=convertFeature(areaFeature, \$('#map')[0].map.projection);\n                SiteAreaLayer.addFeatures([areaFeature]);\n                if(!centreFeature) centreFeature = new OpenLayers.Feature.Vector(getCentroid(areaFeature.geometry));\n              }\n              if(lineFeature) {\n                lineFeature.attributes = {highlighted: false, 'new': false, canEdit: checkEditable(false, data[i].id), SiteNum: SiteNum, data: data[i]};\n                lineFeature=convertFeature(lineFeature, \$('#map')[0].map.projection);\n                SitePathLayer.addFeatures([lineFeature]);\n                if(!centreFeature) centreFeature = new OpenLayers.Feature.Vector(getCentroid(lineFeature.geometry));\n              }\n              if(pointFeature) {\n                pointFeature.attributes = {highlighted: false, 'new': false, canEdit: checkEditable(false, data[i].id), SiteNum: SiteNum, data: data[i]};\n                pointFeature=convertFeature(pointFeature, \$('#map')[0].map.projection);\n                SitePointLayer.addFeatures([pointFeature]);\n                if(!centreFeature) centreFeature = new OpenLayers.Feature.Vector(getCentroid(pointFeature.geometry));\n              }\n            } else {\n              // no boundary, only a centre point.\n              feature = parser.read(data[i].centroid_geom); // assume map projection=900913\n              feature=convertFeature(feature, \$('#map')[0].map.projection);\n              centreFeature = feature.clone();\n              feature.attributes = {highlighted: false, 'new': false, canEdit: checkEditable(false, data[i].id), SiteNum: SiteNum, data: data[i]};\n              SitePointLayer.addFeatures([feature]);\n            }\n            centreFeature.attributes = {highlighted: false, 'new': false, canEdit: checkEditable(false, data[i].id), SiteNum: SiteNum, data: data[i]};\n" . ($args['SecondaryLocationTypeTerm'] != '' && $options['AdminMode'] ? "            if(data[i].location_type_id == {$secondary}){\n              centreFeature.style = jQuery.extend({}, SiteListSecondaryLabelStyleHash);\n            } else \n  " : "") . "            centreFeature.style = jQuery.extend({}, SiteListPrimaryLabelStyleHash);\n            centreFeature.style.label = data[i].name;\n            SiteLabelLayer.addFeatures([centreFeature]);\n            locationList.push({id : data[i].id, feature : centreFeature});\n            if(setSelectOptions){\n              jQuery(\"#" . $options['MainFieldID'] . "\").append('<option value=\"'+data[i].id+'\">'+data[i].name+'</option>');\n            }\n            if(typeof hook_ChildFeatureLoad != 'undefined') hook_ChildFeatureLoad(feature, data[i], '', {});\n          }\n          recalcNumSites();\n          " . ($args['locationMode'] == 'single' || $args['locationMode'] == 'filtered' ? "" : "if(setSelectOptions) ") . "populateExtensions(locationList);\n        }\n  });\n};\npopulateExtensions = function(locids){\n// first get the list of attributes, sorted by location_id. Locations are in name order not ID order.\n// rip out the list of attribute captions.\n// loop through list of locations,\n// Binary search attribute list for my locations\n// Run through its attributes and do translate\n";
    if ($args['extendLocationNameTemplate'] != "") {
        data_entry_helper::$javascript .= "  locList = [];\n  for(var i=0;i<locids.length;i++){\n    var template = \"" . $args['extendLocationNameTemplate'] . "\".replace('{name}',locids[i].feature.attributes.data.name);\n    template = template.replace('{code}',locids[i].feature.attributes.data.code==null?'-':locids[i].feature.attributes.data.code);\n    locList.push({id : locids[i].id,\n        feature : locids[i].feature,\n        template : template});\n  }\n  jQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/data/location_attribute_value' +\n            '?mode=json&view=list&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&orderby=location_id'+" . $loctypequery . "+'&callback=?', function(data) {\n    if(data instanceof Array && data.length>0){\n      function locBinarySearch(attList, location_id){ // this makes assumptions about the location attribute list contents and order.\n        var startIndex = 0,\n            stopIndex = attList.length - 1;\n        while(startIndex <= stopIndex){\n          var middle = Math.floor((stopIndex + startIndex)/2);\n          if (attList[middle].location_id == location_id) {\n            // there will be more than one attribute per location. Scan back.\n            while(middle > 0 && attList[middle-1].location_id == location_id) middle--;\n            return middle;\n          }\n          //adjust search area\n          if (parseInt(location_id) < parseInt(attList[middle].location_id)){\n            stopIndex = middle - 1;\n          } else {\n            startIndex = middle + 1;\n          }\n        }\n        return -1;\n      }\n      templateReplace = function(template, location_id, attList){\n        var attrid = locBinarySearch(attList, location_id);\n        if(attrid >= 0) {\n          while(attrid < attList.length && attList[attrid].location_id == location_id) {\n            if (attList[attrid].id){\n              template = template.replace('{'+attList[attrid].caption+'}',(attList[attrid].termlist_id != null ? convertTerm(parseInt(attList[attrid].raw_value)) : attList[attrid].value));\n            }\n            attrid++;\n          }\n        }";
        $attrArgs = array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']);
        $locationAttributes = data_entry_helper::getAttributes($attrArgs, false);
        foreach ($locationAttributes as $locAttr) {
            data_entry_helper::$javascript .= "\n        template = template.replace('{" . $locAttr["untranslatedCaption"] . "}','-');";
        }
        data_entry_helper::$javascript .= "\n        return template;\n      };\n      for (var j=0;j<locList.length;j++){\n        locList[j].template = templateReplace(locList[j].template, locList[j].id, data);\n        SiteLabelLayer.removeFeatures([locList[j].feature]);\n        locList[j].feature.style.label = locList[j].template;\n        SiteLabelLayer.addFeatures([locList[j].feature]);\n" . ($args['locationMode'] != 'filtered' ? "        var myOption = jQuery(\"#" . $options['MainFieldID'] . "\").find('option').filter('[value='+locList[j].id+']').empty();\n" . ($args['SecondaryLocationTypeTerm'] != '' && $options['AdminMode'] ? "        if(locList[j].feature.attributes.data.location_type_id == {$primary})\n          myOption.css('color','red');\n" : "") . "        myOption.append(locList[j].template);" : "") . "\n      }\n    }});\n";
    }
    data_entry_helper::$javascript .= "\n}\ngetwkt = function(geometry, incFront, incBrackets){\n  var retVal;\n  retVal = '';\n  switch(geometry.CLASS_NAME){\n    case \"OpenLayers.Geometry.Point\":\n      return((incFront!=false ? 'POINT' : '')+(incBrackets!=false ? '(' : '')+geometry.x+' '+geometry.y+(incBrackets!=false ? ')' : ''));\n      break;\n    case \"OpenLayers.Geometry.MultiPoint\":\n      retVal = 'MULTIPOINT(';\n      for(var i=0; i< geometry.components.length; i++)\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[i], false, true);\n      retVal += ')';\n      break;\n    case \"OpenLayers.Geometry.LineString\":\n      retVal = (incFront!=false ? 'LINESTRING' : '')+'(';\n      for(var i=0; i< geometry.components.length; i++)\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[i], false, false);\n      retVal += ')';\n      break;\n    case \"OpenLayers.Geometry.MultiLineString\":\n      retVal = 'MULTILINESTRING(';\n      for(var i=0; i< geometry.components.length; i++)\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[i], false, true);\n      retVal += ')';\n      break;\n    case \"OpenLayers.Geometry.Polygon\": // only do outer ring\n      retVal = (incFront!=false ? 'POLYGON' : '')+'((';\n      for(var i=0; i< geometry.components[0].components.length; i++)\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[0].components[i], false, false);\n      retVal += '))';\n      break;\n    case \"OpenLayers.Geometry.MultiPolygon\":\n      retVal = 'MULTIPOLYGON(';\n      for(var i=0; i< geometry.components.length; i++)\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[i], false, true);\n      retVal += ')';\n      break;\n    case \"OpenLayers.Geometry.Collection\":\n      retVal = 'GEOMETRYCOLLECTION(';\n      for(var i=0; i< geometry.components.length; i++)\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[i], true, true);\n      retVal += ')';\n      break;\n  }\n  return retVal;\n}\nsetGeomFields = function(){\n  // use centre of Area as centroid\n  // Build the combined Geometry, ignore label\n  var geomstack = [];\n  var completeGeom;\n  var centreGeom;\n  var centreSrefGeom;\n  var mySiteNum;\n  var allFeatures = SiteAreaLayer.features.concat(SitePathLayer.features,SitePointLayer.features);\n  for(var i=allFeatures.length-1; i>=0; i--){\n    if(allFeatures[i].attributes.highlighted == true){\n      geomstack.push(allFeatures[i].geometry.clone()); // needs to be a clone as we don't want to transform the original geoms.\n      mySiteNum = allFeatures[i].attributes.SiteNum;\n    }\n  }\n  if(geomstack.length == 0){\n" . ($args['locationMode'] != 'multi' ? "    jQuery(\"#imp-boundary-geom\").val('');\n    jQuery(\"#imp-geom\").val('');\n    jQuery('#imp-sref').val('');\n    jQuery('#imp-srefX').val('');\n    jQuery('#imp-srefY').val('');\n" : "") . "    return;\n  } else if (geomstack.length == 1){\n    completeGeom = geomstack[0];\n  } else {\n    completeGeom = new OpenLayers.Geometry.Collection(geomstack);\n  }\n  centreSrefGeom=getCentroid(completeGeom);\n  // the geometry is in the map projection: if this doesn't match indicia's internal one, then must convert.\n  if (SiteAreaLayer.map.projection.projcode!='EPSG:900913' && SiteAreaLayer.map.projection.projcode!='EPSG:3857') { \n    completeGeom.transform(SiteAreaLayer.map.projection,  new OpenLayers.Projection('EPSG:900913'));\n  }\n  var boundaryWKT = getwkt(completeGeom, true, true);\n  centreGeom=getCentroid(completeGeom);\n  var centreWKT = getwkt(centreGeom, true, true);\n" . ($args['locationMode'] == 'multi' ? "  var highlighted = gethighlight();\n  hook_multisite_setGeomFields(highlighted[0], boundaryWKT, centreWKT);\n" : "  jQuery(\"#imp-boundary-geom\").val(boundaryWKT);\n  jQuery(\"#imp-geom\").val(centreWKT);\n  setSref(centreSrefGeom, 'TBC');  // forces the sref to be generated.\n") . "}\nsetDrawnGeom = function() {\n  // need to leave the location parent id enabled. Don't need to set geometries as we are using an existing location.\n  setPermissionsNewSite();\n  clearLocation(true, 'maybe');\n  if(jQuery('#dummy-parent-id').length>0 && jQuery('[name=location\\:parent_id]').length>0 &&\n      jQuery('#dummy-parent-id').val() != jQuery('[name=location\\:parent_id]').val())\n    jQuery('[name=location\\:parent_id]').val(jQuery('#dummy-parent-id').val()).change();\n" . ($creatorAttr ? "  jQuery('[name=locAttr:" . $creatorAttr . "],[name^=locAttr:" . $creatorAttr . ":]').val('" . $user->name . "');\n" : "") . "};\nremoveDrawnGeom = function(SiteNum){\n  var highlighted=gethighlight();\n  if(highlighted.length > 0 && highlighted[0].attributes.SiteNum == SiteNum) {\n    unhighlightAll();\n  }\n  for(var i=SiteLabelLayer.features.length-1; i>=0; i--)\n    if(SiteLabelLayer.features[i].attributes['new'] == true && SiteLabelLayer.features[i].attributes.SiteNum == SiteNum)\n      SiteLabelLayer.destroyFeatures([SiteLabelLayer.features[i]]);\n  for(var i=SiteAreaLayer.features.length-1; i>=0; i--)\n    if(SiteAreaLayer.features[i].attributes['new'] == true && SiteAreaLayer.features[i].attributes.SiteNum == SiteNum)\n      SiteAreaLayer.destroyFeatures([SiteAreaLayer.features[i]]);\n  for(var i=SitePathLayer.features.length-1; i>=0; i--)\n    if(SitePathLayer.features[i].attributes['new'] == true && SitePathLayer.features[i].attributes.SiteNum == SiteNum)\n      SitePathLayer.destroyFeatures([SitePathLayer.features[i]]);\n  for(var i=SitePointLayer.features.length-1; i>=0; i--)\n    if(SitePointLayer.features[i].attributes['new'] == true && SitePointLayer.features[i].attributes.SiteNum == SiteNum)\n      SitePointLayer.destroyFeatures([SitePointLayer.features[i]]);\n  recalcNumSites();\n}\nresetVertices = function(){\n  var allFeatures = SiteAreaLayer.features.concat(SitePathLayer.features,SitePointLayer.features);\n  for(var i=allFeatures.length-1; i>=0; i--){\n    if(typeof allFeatures[i].attributes['new'] == 'undefined'){ // not one of ours, so must be a vertex\n      var layer= allFeatures[i].layer;\n      layer.removeFeatures([allFeatures[i]]);\n      allFeatures[i].style=dragPointStyleHash;\n      layer.addFeatures([allFeatures[i]]);\n    }\n  }\n  // Oddball case is single points: in this case they use the actual point to drag not a proxy vertex.\n  if(modPointFeature.feature){\n    if(modPointFeature.feature.geometry.CLASS_NAME == \"OpenLayers.Geometry.Point\") {\n      var layer= modPointFeature.feature.layer;\n      layer.removeFeatures([modPointFeature.feature]);\n      modPointFeature.feature.style=dragPointStyleHash;\n      layer.addFeatures([modPointFeature.feature]);\n    }\n  } else {\n    for(var i=SitePointLayer.features.length-1; i>=0; i--){\n      if(SitePointLayer.features[i].style != null){\n        var feature = SitePointLayer.features[i];\n        var layer = feature.layer;\n        layer.removeFeatures([feature]);\n        feature.style=null;\n        layer.addFeatures([feature]);\n      }\n    }\n  }\n  SitePointLayer.redraw();\n}\nreplaceGeom = function(feature, layer, modControl, geom, highlight, setFields){\n  if(modControl.feature)\n    modControl.unselectFeature(modControl.feature);\n  var newfeature = new OpenLayers.Feature.Vector(geom, {});\n  newfeature.attributes = feature.attributes;\n  layer.destroyFeatures([feature]);\n  layer.addFeatures([newfeature]);\n  modControl.selectFeature(newfeature);\n  selectFeature.highlight(newfeature);\n  newfeature.attributes.highlighted=true;\n  resetVertices();\n  if(setFields) setGeomFields();\n}\naddAndSelectNewGeom = function(layer, modControl, geom, highlight){\n  SiteNum++;\n  var feature = new OpenLayers.Feature.Vector(geom, {highlighted: false, 'new': true, canEdit: true, SiteNum: SiteNum});\n  layer.addFeatures([feature]);\n  modControl.selectFeature(feature);\n  feature.attributes.highlighted=true;\n  selectFeature.highlight(feature);\n  resetVertices();\n  setGeomFields();\n  recalcNumSites();\n  return feature;\n}\naddToExistingFeatureSet = function(existingFeatures, layer, modControl, geom, highlight){\n  var feature = new OpenLayers.Feature.Vector(geom, {});\n  feature.attributes = existingFeatures[0].attributes;\n  layer.addFeatures([feature]);\n  modControl.selectFeature(feature);\n  selectFeature.highlight(feature);\n  feature.attributes.highlighted=true;\n  resetVertices();\n  setGeomFields();\n}\nunhighlightAll = function(){\n  if(modAreaFeature.feature) modAreaFeature.unselectFeature(modAreaFeature.feature);\n  if(modPathFeature.feature) modPathFeature.unselectFeature(modPathFeature.feature);\n  if(modPointFeature.feature) modPointFeature.unselectFeature(modPointFeature.feature);\n  var highlighted = gethighlight();\n  for(var i=0; i<highlighted.length; i++) {\n    highlighted[i].attributes.highlighted = false;\n    selectFeature.unhighlight(highlighted[i]);\n  }\n  resetVertices();\n}\nhighlightMe = function(id, SiteNum){\n  var allFeatures = SiteAreaLayer.features.concat(SitePathLayer.features,SitePointLayer.features,SiteLabelLayer.features);\n  for(var i=0; i<allFeatures.length; i++){\n    if((typeof allFeatures[i].attributes.data != 'undefined' &&\n          typeof allFeatures[i].attributes.data.id != 'undefined' &&\n          allFeatures[i].attributes.data.id == id) || \n        (typeof allFeatures[i].attributes.SiteNum != 'undefined' &&\n          allFeatures[i].attributes.SiteNum == SiteNum)){\n      allFeatures[i].attributes.highlighted = true;\n      selectFeature.highlight(allFeatures[i]);\n    }\n  }\n}\ngethighlight = function(){\n  var allFeatures = SiteAreaLayer.features.concat(SitePathLayer.features,SitePointLayer.features,SiteLabelLayer.features);\n  var features=[];\n  for(var i=0; i<allFeatures.length; i++){\n    if(allFeatures[i].attributes.highlighted==true){\n      features.push(allFeatures[i]);\n    }}\n  return features;\n}\n// default is to add a dummy new empty label\nif (typeof hook_new_site_added == 'undefined')\n hook_new_site_added = function(feature, SiteNum) {\n  var centreGeom;\n  var centrefeature;\n  if(!feature){\n    var div = jQuery('#map')[0];\n    var mapCentre = div.map.getCenter();\n    centreGeom = new OpenLayers.Geometry.Point(mapCentre.lon, mapCentre.lat);\n  } else {\n    centreGeom = getCentroid(feature.geometry);\n  }\n  centrefeature = new OpenLayers.Feature.Vector(centreGeom);\n  centrefeature.attributes['new']=true;\n  centrefeature.attributes.highlighted=true;\n  centrefeature.attributes.SiteNum=SiteNum;\n  centrefeature.style = jQuery.extend({}, SiteListPrimaryLabelStyleHash);\n  SiteLabelLayer.addFeatures([centrefeature]);\n  SitePointLayer.redraw();\n};\naddDrawnPointToSelection = function(geometry) {\n  // we assume that we have a point geometry.\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "  if(ParentLocationLayer.features.length == 0) return;\n  if(!ParentLocationLayer.features[0].geometry.intersects(geometry))\n    alert(\"" . lang::get('LANG_PointOutsideParent') . "\");\n" : "") . (isset($args['oneTypeAtATime']) && $args['oneTypeAtATime'] ? "  if(modPathFeature.feature) modPathFeature.unselectFeature(modPathFeature.feature);\n  if(modAreaFeature.feature) modAreaFeature.unselectFeature(modAreaFeature.feature);\n  SitePathLayer.destroyFeatures();\n  SiteAreaLayer.destroyFeatures();\n" : "") . "  var highlightedFeatures = gethighlight();\n" . (!$options['AdminMode'] || isset($args['adminsCanCreate']) && $args['adminsCanCreate'] ? "  if(highlightedFeatures.length == 0){\n    setDrawnGeom();\n    // No currently selected feature. Create a new one.\n    feature = addAndSelectNewGeom(SitePointLayer, modPointFeature, geometry, false);\n    hook_new_site_added(feature, feature.attributes.SiteNum);\n    if(typeof addPGPoint != 'undefined') addPGPoint(geometry);\n    return true;\n  }\n" : "  if(highlightedFeatures.length == 0) return true;\n") . "  var selectedFeature = false;\n  // a site is already selected so the Drawn/Specified state stays unaltered\n  for(var i=0; i<SitePointLayer.features.length; i++){\n    if(SitePointLayer.features[i].attributes.highlighted == true){\n      selectedFeature = SitePointLayer.features[i];\n      break;\n    }}\n  if(highlightedFeatures[0].attributes['new'] == true){\n    if(!selectedFeature) {\n      addToExistingFeatureSet(highlightedFeatures, SitePointLayer, modPointFeature, geometry, false);\n      if(typeof addPGPoint != 'undefined') addPGPoint(geometry);\n      return true;\n    }\n  } else { // highlighted is existing\n    if(highlightedFeatures[0].attributes.canEdit){\n      if(!selectedFeature) {\n        addToExistingFeatureSet(highlightedFeatures, SitePointLayer, modPointFeature, geometry, false);\n        if(typeof addPGPoint != 'undefined') addPGPoint(geometry);\n        return true;\n      }\n    } else {\n      return true;\n    }\n  }\n" . ($args['usePoints'] == 'single' ? "\n  if(typeof clearPGrid != 'undefined') clearPGrid(geometry);\n  replaceGeom(selectedFeature, SitePointLayer, modPointFeature, geometry, false, true);" : "\n  if(typeof addPGPoint != 'undefined') addPGPoint(geometry);\n  if(selectedFeature.geometry.CLASS_NAME == \"OpenLayers.Geometry.MultiPoint\") {\n    modPointFeature.unselectFeature(selectedFeature);\n    selectedFeature.geometry.addPoint(geometry);\n    modPointFeature.selectFeature(selectedFeature);\n    selectFeature.highlight(selectedFeature);\n    selectedFeature.attributes.highlighted = true;\n    resetVertices();\n    setGeomFields();\n  } else { // is OpenLayers.Geometry.Point\n    var CompoundGeom = new OpenLayers.Geometry.MultiPoint([selectedFeature.geometry, geometry]);\n    replaceGeom(selectedFeature, SitePointLayer, modPointFeature, CompoundGeom, false, true);\n  }") . "\n  return true;\n}\naddDrawnLineToSelection = function(geometry) {\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "  if(ParentLocationLayer.features.length == 0) return;\n" : "") . "  var points = geometry.getVertices();\n  if(points.length < 2){\n    alert(\"" . lang::get('LANG_TooFewLinePoints') . "\");\n    return false;\n  }\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "  var centre = getCentroid(geometry);\n  if(!ParentLocationLayer.features[0].geometry.intersects(centre))\n    alert(\"" . lang::get('LANG_LineOutsideParent') . "\");\n" : "") . (isset($args['oneTypeAtATime']) && $args['oneTypeAtATime'] ? "  if(modPointFeature.feature) modPointFeature.unselectFeature(modPointFeature.feature);\n  if(modAreaFeature.feature) modAreaFeature.unselectFeature(modAreaFeature.feature);\n  SitePointLayer.destroyFeatures();\n  SiteAreaLayer.destroyFeatures();\n" : "") . "  var highlightedFeatures = gethighlight();\n" . (!$options['AdminMode'] || isset($args['adminsCanCreate']) && $args['adminsCanCreate'] ? "  if(highlightedFeatures.length == 0){\n    setDrawnGeom();\n    // No currently selected feature. Create a new one.\n    feature = addAndSelectNewGeom(SitePathLayer, modPathFeature, geometry, true);\n    hook_new_site_added(feature, feature.attributes.SiteNum);\n    return true;\n  }\n" : "  if(highlightedFeatures.length == 0) return true;\n") . "\n  var selectedFeature = false;\n  for(var i=0; i<highlightedFeatures.length; i++){\n    if(highlightedFeatures[i].geometry.CLASS_NAME == \"OpenLayers.Geometry.LineString\" ||\n        highlightedFeatures[i].geometry.CLASS_NAME == \"OpenLayers.Geometry.MultiLineString\") {\n      selectedFeature = highlightedFeatures[i];\n      break;\n    }}\n  // a site is already selected so the Drawn/Specified state stays unaltered\n  if(highlightedFeatures[0].attributes['new'] == true){\n    if(!selectedFeature) {\n      addToExistingFeatureSet(highlightedFeatures, SitePathLayer, modPathFeature, geometry, true);\n      return true;\n    }\n  } else { // highlighted is existing\n    if(highlightedFeatures[0].attributes.canEdit){\n      if(!selectedFeature) {\n        addToExistingFeatureSet(highlightedFeatures, SitePathLayer, modPathFeature, geometry, true);\n        return true;\n      }\n    } else {\n      return true;\n    }\n  }\n  " . ($args['useLines'] == 'single' ? "\n  replaceGeom(selectedFeature, SitePathLayer, modPathFeature, geometry, true, true);" : "\n  if(selectedFeature.geometry.CLASS_NAME == \"OpenLayers.Geometry.MultiLineString\") {\n    modPathFeature.unselectFeature(selectedFeature);\n    selectedFeature.geometry.addComponents([geometry]);\n    modPathFeature.selectFeature(selectedFeature);\n    selectFeature.highlight(selectedFeature);\n    selectedFeature.attributes.highlighted = true;\n    resetVertices();\n    setGeomFields();\n  } else { // is OpenLayers.Geometry.LineString\n    var CompoundGeom = new OpenLayers.Geometry.MultiLineString([selectedFeature.geometry, geometry]);\n    replaceGeom(selectedFeature, SitePathLayer, modPathFeature, CompoundGeom, true, true);\n  }") . "\n  return true;\n}\naddDrawnPolygonToSelection = function(geometry) {\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "  if(ParentLocationLayer.features.length == 0) return;\n" : "") . "  var points = geometry.components[0].getVertices();\n  if(points.length < 3){\n    alert(\"" . lang::get('LANG_TooFewPoints') . "\");\n    return false;\n  }\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "  var centre = getCentroid(geometry);\n  if(!ParentLocationLayer.features[0].geometry.intersects(centre))\n    alert(\"" . lang::get('LANG_PolygonOutsideParent') . "\");\n" : "") . (isset($args['oneTypeAtATime']) && $args['oneTypeAtATime'] ? "  if(modPointFeature.feature) modPointFeature.unselectFeature(modPointFeature.feature);\n  if(modPathFeature.feature) modPathFeature.unselectFeature(modPathFeature.feature);\n  SitePointLayer.destroyFeatures();\n  SitePathLayer.destroyFeatures();\n" : "") . "  var highlightedFeatures = gethighlight();\n" . (!$options['AdminMode'] || isset($args['adminsCanCreate']) && $args['adminsCanCreate'] ? "  if(highlightedFeatures.length == 0){\n    setDrawnGeom();\n    // No currently selected feature. Create a new one.\n    feature = addAndSelectNewGeom(SiteAreaLayer, modAreaFeature, geometry, true);\n    hook_new_site_added(feature, feature.attributes.SiteNum);\n    return true;\n  }\n" : "  if(highlightedFeatures.length == 0) return true;\n") . "\n  var selectedFeature = false;\n  for(var i=0; i<highlightedFeatures.length; i++){\n    if(highlightedFeatures[i].geometry.CLASS_NAME == \"OpenLayers.Geometry.Polygon\" ||\n        highlightedFeatures[i].geometry.CLASS_NAME == \"OpenLayers.Geometry.MultiPolygon\") {\n      selectedFeature = highlightedFeatures[i];\n      break;\n    }}\n  // a site is already selected so the Drawn/Specified state stays unaltered\n  if(highlightedFeatures[0].attributes['new'] == true){\n    if(!selectedFeature) {\n      addToExistingFeatureSet(highlightedFeatures, SiteAreaLayer, modAreaFeature, geometry, true);\n      return true;\n    }\n  } else { // highlighted is existing\n    if(highlightedFeatures[0].attributes.canEdit){\n      if(!selectedFeature) {\n        addToExistingFeatureSet(highlightedFeatures, SiteAreaLayer, modAreaFeature, geometry, true);\n        return true;\n      }\n    } else {\n      return true;\n    }\n  }\n  " . ($args['usePolygons'] == 'single' ? "\n  replaceGeom(selectedFeature, SiteAreaLayer, modAreaFeature, geometry, true, true);" : "\n  if(selectedFeature.geometry.CLASS_NAME == \"OpenLayers.Geometry.MultiPolygon\") {\n    modAreaFeature.unselectFeature(selectedFeature);\n    selectedFeature.geometry.addComponents([geometry]);\n    modAreaFeature.selectFeature(selectedFeature);\n    selectFeature.highlight(selectedFeature);\n    selectedFeature.attributes.highlighted = true;\n    resetVertices();\n    setGeomFields();\n  } else { // is OpenLayers.Geometry.Polygon\n    var CompoundGeom = new OpenLayers.Geometry.MultiPolygon([selectedFeature.geometry, geometry]);\n    replaceGeom(selectedFeature, SiteAreaLayer, modAreaFeature, CompoundGeom, true, true);\n  }") . "\n  return true;\n}\nonFeatureModified = function(evt) {\n  var feature = evt.feature;\n  switch(feature.geometry.CLASS_NAME){\n    case \"OpenLayers.Geometry.Point\":\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "      if(!ParentLocationLayer.features[0].geometry.intersects(feature.geometry))\n        alert(\"" . lang::get('LANG_PointOutsideParent') . "\");\n" : "") . "      if(typeof modPGPoint != 'undefined') modPGPoint(feature.geometry);\n      break;\n    case \"OpenLayers.Geometry.MultiPoint\":\n      if(feature.geometry.components.length == 0){\n        modPointFeature.unselectFeature(feature);\n        SitePointLayer.destroyFeatures([feature]);\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "     } else {\n        var centre = getCentroid(feature.geometry);\n        if(!ParentLocationLayer.features[0].geometry.intersects(centre))\n          alert(\"" . lang::get('LANG_PointOutsideParent') . "\");\n" : "") . "      }\n      if(typeof modPGPoint != 'undefined') modPGPoint(feature.geometry);\n      break;\n    case \"OpenLayers.Geometry.LineString\":\n      points = feature.geometry.getVertices();\n      if(points.length < 2){\n        alert(\"" . lang::get('LANG_TooFewLinePoints') . "\");\n        modPathFeature.unselectFeature(feature);\n        SitePathLayer.destroyFeatures([feature]);\n      }\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "      else {\n        var centre = getCentroid(feature.geometry);\n        if(!ParentLocationLayer.features[0].geometry.intersects(centre))\n          alert(\"" . lang::get('LANG_LineOutsideParent') . "\");\n      }\n" : "") . "      break;\n    case \"OpenLayers.Geometry.MultiLineString\":\n      for(i=feature.geometry.components.length-1; i>=0; i--) {\n        points = feature.geometry.components[i].getVertices();\n        if(points.length < 2){\n          alert(\"" . lang::get('LANG_TooFewLinePoints') . "\");\n          var selectedFeature = modPathFeature.feature;\n          modPathFeature.unselectFeature(selectedFeature);\n          selectFeature.unhighlight(selectedFeature);\n          SitePathLayer.removeFeatures([selectedFeature]);\n          selectedFeature.geometry.removeComponents([feature.geometry.components[i]]);\n          SitePathLayer.addFeatures([selectedFeature]);\n          modPathFeature.selectFeature(selectedFeature);\n          selectFeature.highlight(selectedFeature);\n          selectedFeature.attributes.highlighted = true;\n        }\n      }\n      if(feature.geometry.components.length == 0){\n        modPathFeature.unselectFeature(feature);\n        SitePathLayer.destroyFeatures([feature]);\n      }\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "      else {\n        var centre = getCentroid(feature.geometry);\n        if(!ParentLocationLayer.features[0].geometry.intersects(centre))\n          alert(\"" . lang::get('LANG_LineOutsideParent') . "\");\n      }\n" : "") . "      break;\n    case \"OpenLayers.Geometry.Polygon\": // only do outer ring\n      points = feature.geometry.components[0].getVertices();\n      if(points.length < 3){\n        alert(\"" . lang::get('LANG_TooFewPoints') . "\");\n        modAreaFeature.unselectFeature(feature);\n        SiteAreaLayer.destroyFeatures([feature]);\n      }\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "      else {\n        var centre = getCentroid(feature.geometry);\n        if(!ParentLocationLayer.features[0].geometry.intersects(centre))\n          alert(\"" . lang::get('LANG_CentreOutsideParent') . "\");\n      }\n" : "") . "      break;\n    case \"OpenLayers.Geometry.MultiPolygon\":\n      for(i=feature.geometry.components.length-1; i>=0; i--) {\n        points = feature.geometry.components[i].components[0].getVertices();\n        if(points.length < 3){\n          alert(\"" . lang::get('LANG_TooFewPoints') . "\");\n          var selectedFeature = modAreaFeature.feature;\n          modAreaFeature.unselectFeature(selectedFeature);\n          selectFeature.unhighlight(selectedFeature);\n          SiteAreaLayer.removeFeatures([selectedFeature]);\n          selectedFeature.geometry.removeComponents([feature.geometry.components[i]]);\n          SiteAreaLayer.addFeatures([selectedFeature]);\n          modAreaFeature.selectFeature(selectedFeature);\n          selectFeature.highlight(selectedFeature);\n          selectedFeature.attributes.highlighted = true;\n        }\n      }\n      if(feature.geometry.components.length == 0){\n        modAreaFeature.unselectFeature(feature);\n        SiteAreaLayer.destroyFeatures([feature]);\n      }\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "      else {\n        var centre = getCentroid(feature.geometry);\n        if(!ParentLocationLayer.features[0].geometry.intersects(centre))\n          alert(\"" . lang::get('LANG_CentreOutsideParent') . "\");\n      }\n" : "") . "      break;\n  }\n  resetVertices();\n  setGeomFields();\n}\n// TBD should only include next when siteNameTermListID set\nsetNameDropDowns = function(disable, value){\n  jQuery('#dummy-name').find('*').removeAttr('disabled');\n  if(disable === true){\n  \tjQuery('#dummy-name').val('').attr('disabled','disabled');\n  \treturn;\n  }\n  if(disable === false)\n  \tjQuery('#dummy-name').removeAttr('disabled');\n  if(value===false && jQuery('#dummy-name').val() !== '') value=jQuery('#dummy-name').val()\n  if(value !== '')\n    jQuery('#dummy-name').find('option').filter('[value=]').attr('disabled','disabled');\n  jQuery('#dummy-name').find('option').each(function (index, option){\n  // TBD convert this to look at the features.\n      if((value == false || jQuery(option).val() != value) &&\n          jQuery('.cggrid-row,.cgAddedRow').find('.cggrid-name').filter('[value='+jQuery(option).val()+']').length > 0)\n        jQuery(option).attr('disabled','disabled');\n  });\n  if(value!==false) jQuery('#dummy-name').val(value);\n};\n/********************************/\n/* Define Map Control callbacks */\n/********************************/\nCancelSketch = function(layer){\n  for(var i = editControl.controls.length-1; i>=0; i--)\n    if(editControl.controls[i].CLASS_NAME == \"OpenLayers.Control.DrawFeature\" && editControl.controls[i].active)\n      editControl.controls[i].cancel();\n};\nUndoSketchPoint = function(layer){\n  for(var i = editControl.controls.length-1; i>=0; i--)\n    if(editControl.controls[i].CLASS_NAME == \"OpenLayers.Control.DrawFeature\" && editControl.controls[i].active)\n      editControl.controls[i].undo();\n};\nRemoveNewSite = function(){\n  // can only remove the site if highlighted,\n  var highlighted = gethighlight();\n  if(highlighted.length == 0 || !highlighted[0].attributes['new']) return;\n  if(confirm('" . lang::get('LANG_ConfirmRemoveDrawnSite') . "')){\n    if(typeof hook_RemoveNewSite != 'undefined')\n      hook_RemoveNewSite();\n    clearLocation(true, true);\n    removeDrawnGeom(highlighted[0].attributes.SiteNum);\n    recalcNumSites();\n    setGeomFields();\n    if(typeof setNameDropDowns != 'undefined')\n      setNameDropDowns(true, false);\n  }\n};\nStartNewSite = function(){\n  var keepName=false;\n" . ($args['locationMode'] == 'parent' ? "  if(jQuery('#" . $options['ChooseParentFieldID'] . "').val()==''){\n    alert('" . lang::get('LANG_MustSelectParentFirst') . "');\n    return;\n  };" : "") . "\n" . ($args['locationMode'] == 'multi' ? "  unhighlightAll();\n" . (isset($args['siteNameTermListID']) && $args['siteNameTermListID'] != '' ? "  setNameDropDowns(false, '');\n" : "  jQuery('#dummy-name').val('');\n") : "  keepName = jQuery('#" . $options['MainFieldID'] . "').val() == '';\n  // first remove any existing new location.\n  var highlighted = gethighlight();\n  var found=false;\n  // only confirm if have something drawn on map: ie ignore label\n  for(i=0; i<highlighted.length; i++) found = found || (highlighted[i].layer != SiteLabelLayer && highlighted[i].attributes['new']==true)\n  if(found && !confirm('" . lang::get('LANG_ConfirmRemoveDrawnSite') . "')) return false;\n  if(highlighted.length>0 && highlighted[0].attributes['new']==true) removeDrawnGeom(highlighted[0].attributes.SiteNum); // remove label here\n  unhighlightAll();\n  jQuery('#" . $options['MainFieldID'] . ",#sample-location-id').val(''); // reset id field.\n") . "  setPermissionsNewSite(); // need to leave the location parent id enabled.\n  clearLocation(true, !keepName);\n  if(jQuery('#dummy-parent-id').length>0 && jQuery('[name=location\\:parent_id]').length>0 &&\n      jQuery('#dummy-parent-id').val() != jQuery('[name=location\\:parent_id]').val())\n    jQuery('[name=location\\:parent_id]').val(jQuery('#dummy-parent-id').val()).change();\n" . ($creatorAttr ? "  jQuery('[name=locAttr:" . $creatorAttr . "],[name^=locAttr:" . $creatorAttr . ":]').val('" . $user->name . "');\n" : "") . "  // No currently selected feature. Create a dummy label new one.\n  SiteNum++;\n  hook_new_site_added(false, SiteNum);\n  // Programatic activation does not rippleout to deactivate other draw features, so deactivate all first.\n  for(var i=0; i<editControl.controls.length; i++)\n    if(editControl.controls[i].CLASS_NAME == \"OpenLayers.Control.DrawFeature\")\n      editControl.controls[i].deactivate();\n  // we assume there is at least one drawing control: activate the first one.\n  selectFeature.activate();\n  for(var i=0; i<editControl.controls.length; i++){\n    if(editControl.controls[i].CLASS_NAME == \"OpenLayers.Control.DrawFeature\"){\n      selectFeature.deactivate();\n      editControl.controls[i].activate();\n      // new site will have no vertices yet...\n      return;\n    }}\n}\nZoomToFeature = function(feature){\n  var div = jQuery('#map')[0];\n  var bounds=feature.geometry.bounds.clone();\n  // extend the boundary to include a buffer, so the map does not zoom too tight.\n  var dy = (bounds.top-bounds.bottom) * div.settings.maxZoomBuffer;\n  var dx = (bounds.right-bounds.left) * div.settings.maxZoomBuffer;\n  bounds.top = bounds.top + dy;\n  bounds.bottom = bounds.bottom - dy;\n  bounds.right = bounds.right + dx;\n  bounds.left = bounds.left - dx;\n  if (div.map.getZoomForExtent(bounds) > div.settings.maxZoom) {\n    // if showing something small, don't zoom in too far\n    div.map.setCenter(bounds.getCenterLonLat(), div.settings.maxZoom);\n  } else {\n    // Set the default view to show something triple the size of the grid square\n    // Assume this is within the map extent\n    div.map.zoomToExtent(bounds);\n  }\n};\nZoomToSite = function(){\n  var div = jQuery('#map')[0];\n  if(modPointFeature.feature){\n    return ZoomToFeature(modPointFeature.feature);}\n  if(modPathFeature.feature){\n    return ZoomToFeature(modPathFeature.feature);}\n  if(modAreaFeature.feature){\n    return ZoomToFeature(modAreaFeature.feature);}\n  var highlighted = gethighlight();\n  if(highlighted.length>0){\n    var div = jQuery('#map')[0];\n    var bounds=highlighted[0].geometry.bounds.clone();\n    \$.each(highlighted, function(idx, feat){\n      bounds.extend(feat.geometry.bounds);\n    });\n    // extend the boundary to include a buffer, so the map does not zoom too tight.\n    var dy = (bounds.top-bounds.bottom) * div.settings.maxZoomBuffer;\n    var dx = (bounds.right-bounds.left) * div.settings.maxZoomBuffer;\n    bounds.top = bounds.top + dy;\n    bounds.bottom = bounds.bottom - dy;\n    bounds.right = bounds.right + dx;\n    bounds.left = bounds.left - dx;\n    if (div.map.getZoomForExtent(bounds) > div.settings.maxZoom) {\n      // if showing something small, don't zoom in too far\n      div.map.setCenter(bounds.getCenterLonLat(), div.settings.maxZoom);\n    } else {\n      // Set the default view to show something triple the size of the grid square\n      // Assume this is within the map extent\n      div.map.zoomToExtent(bounds);\n    }\n  }\n};\nZoomToParent = function(){\n  if(ParentLocationLayer.features.length > 0)\n    zoomToLayerExtent(ParentLocationLayer);\n};\nZoomToCountry = function(){\n\tvar div = jQuery('#map')[0];\n\tvar center = new OpenLayers.LonLat(" . $args['map_centroid_long'] . "," . $args['map_centroid_lat'] . ");\n\tcenter.transform(div.map.displayProjection, div.map.projection);\n\tdiv.map.setCenter(center, " . (int) $args['map_zoom'] . ");\n}\n/***********************************/\n/* Define Controls for use on Map. */\n/***********************************/\nselectFeatureActivate = function(){\n    if(modAreaFeature.feature) modAreaFeature.unselectFeature(modAreaFeature.feature);\n    if(modPathFeature.feature) modPathFeature.unselectFeature(modPathFeature.feature);\n    if(modPointFeature.feature) modPointFeature.unselectFeature(modPointFeature.feature);\n    modAreaFeature.deactivate();\n    modPathFeature.deactivate();\n    modPointFeature.deactivate();\n    resetVertices();\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "    if(!ParentLocationLayer.features.length) {\n      selectFeature.deactivate();\n      return false;\n    }\n" : "") . "    return true;\n};\npolygonDrawActivate = function(){\n  if(modPointFeature.feature) modPointFeature.unselectFeature(modPointFeature.feature);\n  if(modPathFeature.feature) modPathFeature.unselectFeature(modPathFeature.feature);\n  selectFeature.deactivate();\n  modPointFeature.deactivate();\n  modPathFeature.deactivate();\n  resetVertices();\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "  if(!ParentLocationLayer.features.length) {\n    polygonDraw.deactivate();\n    return false;\n  }\n" : "") . "  highlighted = gethighlight();\n  if(highlighted.length == 0){\n" . (!$options['AdminMode'] || isset($args['adminsCanCreate']) && $args['adminsCanCreate'] ? "    modAreaFeature.activate();\n    return true;\n  }\n  if(highlighted[0].attributes['new'] == true){\n    modAreaFeature.activate();\n    for(var i=0; i<SiteAreaLayer.features.length; i++){\n      if(SiteAreaLayer.features[i].attributes.highlighted == true){\n        modAreaFeature.selectFeature(SiteAreaLayer.features[i]);}}\n    resetVertices();\n    return true;\n" : "    polygonDraw.deactivate();\n    selectFeature.activate();\n    return false;\n") . "  }\n  // highlight feature is an existing one.\n  if(highlighted[0].attributes.canEdit){\n    modAreaFeature.activate();\n    for(var i=0; i<SiteAreaLayer.features.length; i++){\n      if(SiteAreaLayer.features[i].attributes.highlighted == true){\n        modAreaFeature.selectFeature(SiteAreaLayer.features[i]);}}\n    resetVertices();\n    return true;\n  }\n  polygonDraw.deactivate();\n  selectFeature.activate();\n  return false;\n};\nlineDrawActivate = function(){\n  if(modPointFeature.feature) modPointFeature.unselectFeature(modPointFeature.feature);\n  if(modAreaFeature.feature) modAreaFeature.unselectFeature(modAreaFeature.feature);\n  selectFeature.deactivate();\n  modPointFeature.deactivate();\n  modAreaFeature.deactivate();\n  resetVertices();\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "  if(!ParentLocationLayer.features.length) {\n    lineDraw.deactivate();\n    return false;\n  }\n" : "") . "  highlighted = gethighlight();\n  if(highlighted.length == 0){\n" . (!$options['AdminMode'] || isset($args['adminsCanCreate']) && $args['adminsCanCreate'] ? "    modPathFeature.activate();\n    return true;\n  }\n  if(highlighted[0].attributes['new'] == true){\n    modPathFeature.activate();\n    for(var i=0; i<SitePathLayer.features.length; i++){\n      if(SitePathLayer.features[i].attributes.highlighted == true){\n        modPathFeature.selectFeature(SitePathLayer.features[i]);}}\n    resetVertices();\n    return true;\n" : "    lineDraw.deactivate();\n    selectFeature.activate();\n    return false;\n") . "  }\n  // highlight feature is an existing one.\n  if(highlighted[0].attributes.canEdit){\n    modPathFeature.activate();\n    for(var i=0; i<SitePathLayer.features.length; i++){\n      if(SitePathLayer.features[i].attributes.highlighted == true){\n        modPathFeature.selectFeature(SitePathLayer.features[i]);}}\n    resetVertices();\n    return true;\n  }\n  lineDraw.deactivate();\n  selectFeature.activate();\n  return false;\n};\npointDrawDeactivate = function(){\n  if(typeof removePopups != 'undefined') removePopups();\n  jQuery(\"#pointgrid\").hide();\n};\npointDrawActivate = function(){\n  jQuery(\"#pointgrid\").show();\n  if(modAreaFeature.feature) modAreaFeature.unselectFeature(modAreaFeature.feature);\n  if(modPathFeature.feature) modPathFeature.unselectFeature(modPathFeature.feature);\n  selectFeature.deactivate();\n  modAreaFeature.deactivate();\n  modPathFeature.deactivate();\n  resetVertices();\n" . ($args['locationMode'] != 'single' && $args['locationMode'] != 'filtered' ? "  if(!ParentLocationLayer.features.length) {\n    pointDraw.deactivate();\n    return false;\n  }\n" : "") . "  highlighted = gethighlight();\n  if(highlighted.length == 0){\n" . (!$options['AdminMode'] || isset($args['adminsCanCreate']) && $args['adminsCanCreate'] ? "    modPointFeature.activate();\n    return true;\n  }\n  if(highlighted[0].attributes['new'] == true){\n    modPointFeature.activate();\n    for(var i=0; i<SitePointLayer.features.length; i++){\n      if(SitePointLayer.features[i].attributes.highlighted == true){\n        modPointFeature.selectFeature(SitePointLayer.features[i]);\n        resetVertices();}}\n    if(typeof populatePGrid != 'undefined') populatePGrid();\n    return true;\n" : "    pointDraw.deactivate();\n    selectFeature.activate();\n    return false;\n") . "  }\n  // highlight feature is an existing one.\n  if(highlighted[0].attributes.canEdit){\n    modPointFeature.activate();\n    for(var i=0; i<SitePointLayer.features.length; i++){\n      if(SitePointLayer.features[i].attributes.highlighted == true){\n        modPointFeature.selectFeature(SitePointLayer.features[i]);\n        resetVertices();}}\n    if(typeof populatePGrid != 'undefined') populatePGrid();\n    return true;\n  }\n  pointDraw.deactivate();\n  selectFeature.activate();\n  return false;\n};\nMyEditingToolbar=OpenLayers.Class(\n\t\tOpenLayers.Control.Panel,{\n\t\t\tinitialize:function(layer,options){\n\t\t\t\tOpenLayers.Control.Panel.prototype.initialize.apply(this,[options]);\n\t\t\t\tthis.addControls([selectFeature\n" . ($args['usePolygons'] != 'none' ? "\t\t\t\t         ,polygonDraw\n" : '') . ($args['useLines'] != 'none' ? "\t\t\t\t         ,lineDraw\n" : '') . ($args['usePoints'] != 'none' ? "\t\t\t\t         ,pointDraw\n" : '') . ($args['usePolygons'] != 'none' || $args['useLines'] != 'none' ? "\t\t\t\t         ,new OpenLayers.Control.Button({displayClass: \"olControlCancelSketch\", trigger: CancelSketch, title: '" . lang::get('LANG_CancelSketchTooltip') . "'})\n\t\t\t\t         ,new OpenLayers.Control.Button({displayClass: \"olControlUndoSketchPoint\", trigger: UndoSketchPoint, title: '" . lang::get('LANG_UndoSketchPointTooltip') . "'})\n" : '') . (!$options['AdminMode'] || isset($args['adminsCanCreate']) && $args['adminsCanCreate'] ? "\t\t\t\t         ,new OpenLayers.Control.Button({displayClass: \"olControlRemoveNewSite\", trigger: RemoveNewSite, title: '" . lang::get('LANG_RemoveNewSite') . "'})\n\t\t\t\t         ,new OpenLayers.Control.Button({displayClass: \"olControlStartNewSite\", trigger: StartNewSite, title: '" . lang::get('LANG_StartNewSite') . "'})\n" : '') . "\t\t\t\t         ,new OpenLayers.Control.Button({displayClass: \"olControlZoomToSite\", trigger: ZoomToSite, title: '" . lang::get('LANG_ZoomToSite') . "'})\n" . ($args['locationMode'] != 'single' ? "\t\t\t\t         ,new OpenLayers.Control.Button({displayClass: \"olControlZoomToSquare\", trigger: ZoomToParent, title: '" . lang::get('LANG_ZoomToParent') . "'})\n" : '') . "\t\t\t\t         ,new OpenLayers.Control.Button({displayClass: \"olControlZoomToCountry\", trigger: ZoomToCountry, title: '" . lang::get('LANG_ZoomToCountry') . "'})\n\t\t\t\t         ]);\n\t},\n\tCLASS_NAME:\"MyEditingToolbar\"});\ndeactivateControls = function(){\n  if(typeof editControl != 'undefined'){\n    for(var i = editControl.controls.length-1; i>=0; i--){\n      if(editControl.controls[i].CLASS_NAME == \"OpenLayers.Control.DrawFeature\" ||\n         editControl.controls[i].CLASS_NAME == \"OpenLayers.Control.SelectFeature\") {\n        editControl.controls[i].deactivate();\n    }}}\n};\nsetSpecifiedLocation = function() {\n  var highlighted = gethighlight();\n  if(highlighted[0].attributes.canEdit){\n    setPermissionsOldEditableSite(false);\n  } else {\n    // need to leave the location parent id enabled. Don't need to set geometries as we are using an existing location.\n    setPermissionsOldReadOnlySite();\n  }\n}\nonFeatureSelect = function(evt) {\n  var feature = evt.feature;\n  if(feature.attributes.highlighted==true) return false;\n" . ($args['locationMode'] == 'multi' ? "  unhighlightAll();\n" : "  var willRemove = false;\n  var allFeatures = SiteAreaLayer.features.concat(SitePathLayer.features,SitePointLayer.features);\n  for(var i=0; i<allFeatures.length; i++)\n    willRemove = willRemove || (allFeatures[i].attributes['new']==true);\n  if(willRemove && !confirm('" . lang::get('LANG_ConfirmRemoveDrawnSite') . "')) return false;\n  var highlighted = gethighlight();\n  if(highlighted.length > 0 && highlighted[0].attributes['new'])\n    removeDrawnGeom(highlighted[0].attributes.SiteNum);\n  else\n    // Any highlighted existing features should be unhighlighted.\n    unhighlightAll();\n  jQuery(\"#" . $options['MainFieldID'] . ",#sample-location-id\").val(feature.attributes.data.id);\n") . "  ZoomToFeature(feature);\n  // now highlight the new ones\n  highlightMe(false, feature.attributes.SiteNum); // need to fetch SiteNum in case highlight new.\n  loadLocation(feature);\n  return false;\n}\nmodAreaFeature = new OpenLayers.Control.ModifyFeature(SiteAreaLayer,{standalone: true});\nmodPathFeature = new OpenLayers.Control.ModifyFeature(SitePathLayer,{standalone: true});\nmodPointFeature = new OpenLayers.Control.ModifyFeature(SitePointLayer,{standalone: true});\nselectFeature = new OpenLayers.Control.SelectFeature([SiteAreaLayer,SitePathLayer,SitePointLayer,SiteLabelLayer],{'displayClass':'olControlSelectFeature', title: '" . lang::get('LANG_SelectTooltip') . "'});\nselectFeature.events.on({'activate': selectFeatureActivate});\npolygonDraw = new OpenLayers.Control.DrawFeature(SiteAreaLayer,OpenLayers.Handler.Polygon,{'displayClass':'olControlDrawFeaturePolygon', drawFeature: addDrawnPolygonToSelection, title: '" . lang::get('LANG_PolygonTooltip') . "'});\npolygonDraw.events.on({'activate': polygonDrawActivate});\nlineDraw = new OpenLayers.Control.DrawFeature(SitePathLayer,OpenLayers.Handler.Path,{'displayClass':'olControlDrawFeaturePath', drawFeature: addDrawnLineToSelection, title: '" . lang::get('LANG_LineTooltip') . "'});\nlineDraw.events.on({'activate': lineDrawActivate});\npointDraw = new OpenLayers.Control.DrawFeature(SitePointLayer,OpenLayers.Handler.Point,{'displayClass':'olControlDrawFeaturePoint', drawFeature: addDrawnPointToSelection, title: '" . lang::get('LANG_PointTooltip') . "'});\npointDraw.events.on({'activate': pointDrawActivate, 'deactivate': pointDrawDeactivate});\neditControl = new MyEditingToolbar(SiteAreaLayer, {allowDepress: false, 'displayClass':'olControlEditingToolbar'});\n\nmapInitialisationHooks.push(function(mapdiv) {\n\t// try to identify if this map is the main one\n\tif(mapdiv.id=='map'){\n\t\tmapdiv.map.addControl(modAreaFeature);\n\t\tmapdiv.map.addControl(modPathFeature);\n\t\tmapdiv.map.addControl(modPointFeature);\n\t\tmodAreaFeature.deactivate();\n\t\tmodPathFeature.deactivate();\n\t\tmodPointFeature.deactivate();\n\t\tmapdiv.map.addControl(editControl);\n" . (isset($args['mousePosControl']) && $args['mousePosControl'] ? "\t\tjQuery('.olControlEditingToolbar').append('<span id=\"mousePos\"></span>');\n\t\tvar mousePosCtrl = new OpenLayers.Control.MousePosition({\n\t\t  div: document.getElementById('mousePos'),\n\t\t  prefix: 'LUREF:',\n\t\t  displayProjection: new OpenLayers.Projection('EPSG:2169'),\n\t\t  emptyString: '',\n\t\t  numDigits: 0 \n\t\t});\n\t\tmapdiv.map.addControl(mousePosCtrl);\n" : "") . "\t\teditControl.activate();\n\t\tif(SiteAreaLayer.map.editLayer){\n\t\t\tSiteAreaLayer.map.editLayer.clickControl.deactivate();\n\t\t\tSiteAreaLayer.map.editLayer.destroyFeatures();\n\t\t}\n\t\tmapdiv.map.events.on({'zoomend': function(){\n\t\t  if(jQuery('#map')[0].map.zoom >= " . $args['labelZoomLevel'] . "){\n\t\t    if(!SiteLabelLayer.getVisibility())\n\t\t      SiteLabelLayer.setVisibility(true);\n\t\t  } else {\n\t \t   if(SiteLabelLayer.getVisibility())\n\t \t     SiteLabelLayer.setVisibility(false);\n\t \t }\n\t\t}});\n\t\tmapdiv.map.events.triggerEvent('zoomend');\n";
    // If entity to load is set, then we are highlighting an existing location, can't modify, but can start drawing another site.
    if (isset(data_entry_helper::$entity_to_load['location:id'])) {
        switch ($args['locationMode']) {
            // TBD fieldname should be ParentFieldName
            case 'multi':
                data_entry_helper::$javascript .= "\t\tloadFeatures(" . data_entry_helper::$entity_to_load['sample:location_id'] . ",'',{initial: true}, true, true, true, true, true);\n";
                break;
            case 'single':
                data_entry_helper::$javascript .= "\t\tloadFeatures(''," . data_entry_helper::$entity_to_load['location:id'] . ",{initial: true}, false, false, false, false, true);\n";
                break;
            case 'filtered':
                $activeParent = false;
                $filterAttrs = explode(',', $args['filterAttrs']);
                foreach ($filterAttrs as $idx => $filterAttr) {
                    $filterAttr = explode(':', $filterAttr);
                    if ($filterAttr[0] == 'Parent' && $filterAttr[1] == "true") {
                        $activeParent = true;
                    }
                }
                if ($activeParent) {
                    data_entry_helper::$javascript .= "\t\tloadFeatures(" . data_entry_helper::$entity_to_load['location:parent_id'] . "," . data_entry_helper::$entity_to_load['location:id'] . ",{initial: true}, true, false, false, false, true);\n";
                } else {
                    data_entry_helper::$javascript .= "\t\tloadFeatures(''," . data_entry_helper::$entity_to_load['location:id'] . ",{initial: true}, false, false, false, false, true);\n";
                }
                break;
            default:
                // mode = parent
                data_entry_helper::$javascript .= "\t\tloadFeatures(" . data_entry_helper::$entity_to_load['location:parent_id'] . "," . data_entry_helper::$entity_to_load['location:id'] . ",{initial: true}, true, true, false, false, true);\n";
        }
    } else {
        if ($args['locationMode'] == 'single') {
            data_entry_helper::$javascript .= "\t\tloadFeatures('','',{initial: true}, false, false, false, true, true);\n";
        } else {
            if ($args['locationMode'] == 'filtered') {
                $activeParent = false;
                $filterAttrs = explode(',', $args['filterAttrs']);
                foreach ($filterAttrs as $idx => $filterAttr) {
                    $filterAttr = explode(':', $filterAttr);
                    if ($filterAttr[0] == 'Parent' && $filterAttr[1] == "true") {
                        $activeParent = true;
                    }
                }
                if (!$activeParent) {
                    data_entry_helper::$javascript .= "\t\tloadFeatures('','',{initial: true}, false, false, false, true, false);\n";
                }
            } else {
                // either multi, parent with none specified at the moment.
                data_entry_helper::$javascript .= "\t\tsetPermissionsNoParent();\n";
            }
        }
    }
    data_entry_helper::$javascript .= "}});\nSiteLabelLayer.events.on({\n    'beforefeatureselected': onFeatureSelect\n  });\nSiteAreaLayer.events.on({\n    'beforefeatureselected': onFeatureSelect\n    ,'featuremodified': onFeatureModified\n  });\nSitePathLayer.events.on({\n    'beforefeatureselected': onFeatureSelect\n    ,'featuremodified': onFeatureModified\n  });\nSitePointLayer.events.on({\n    'beforefeatureselected': onFeatureSelect\n    ,'featuremodified': onFeatureModified\n  });\n";
    if ($args['locationMode'] != 'multi') {
        data_entry_helper::$javascript .= "\nhook_ChildFeatureLoad = function(feature, data, child_id, childArgs){\n  if(child_id == '' || data.id != child_id){\n";
        if ($args['locationMode'] != 'filtered' && isset($args['duplicateNameCheck']) && $args['duplicateNameCheck'] == 'enforce') {
            data_entry_helper::$javascript .= "    var clearVal = jQuery('#location-name').val() == data.name;\n";
            if ($args['siteNameTermListID'] != "") {
                data_entry_helper::$javascript .= "    jQuery('#location-name').find('option').filter('[value='+data.name+']').attr('disabled','disabled');\n";
            }
            data_entry_helper::$javascript .= "    if(clearVal) jQuery('#location-name').val('');\n";
        }
        data_entry_helper::$javascript .= "    return;\n  }\n  var pointFeature = false;\n  var lineFeature = false;\n  var areaFeature = false;\n  if(typeof(feature)=='object'&&(feature instanceof Array)){\n    for(var j=0; j< feature.length; j++){\n      switch(feature[j].geometry.CLASS_NAME){\n        case \"OpenLayers.Geometry.Point\":\n        case \"OpenLayers.Geometry.MultiPoint\":\n          pointFeature = feature[j];\n          break;\n        case \"OpenLayers.Geometry.LineString\":\n        case \"OpenLayers.Geometry.MultiLineString\":\n          lineFeature = feature[j];\n          break;\n        default:\n          areaFeature = feature[j];\n          break;\n      }\n    }\n  } else {\n    switch(feature.geometry.CLASS_NAME){\n      case \"OpenLayers.Geometry.Point\":\n      case \"OpenLayers.Geometry.MultiPoint\":\n        pointFeature = feature;\n        break;\n      case \"OpenLayers.Geometry.LineString\":\n      case \"OpenLayers.Geometry.MultiLineString\":\n        lineFeature = feature;\n        break;\n      default:\n        areaFeature = feature;\n      break;\n    }\n  }\n  var Zoomed=false;\n  if(areaFeature) {\n    areaFeature.attributes.highlighted=true;\n    selectFeature.highlight(areaFeature);\n    ZoomToFeature(areaFeature);\n    Zoomed=true;\n  }\n  if(lineFeature) {\n    lineFeature.attributes.highlighted=true;\n    selectFeature.highlight(lineFeature);\n    if(!Zoomed) ZoomToFeature(lineFeature);\n    Zoomed=true;\n  }\n  if(pointFeature) {\n    pointFeature.attributes.highlighted=true;\n    selectFeature.highlight(pointFeature);\n    if(!Zoomed) ZoomToFeature(pointFeature);\n  }\n//  setGeomFields();\n};\njQuery('#location-name').change(function(){";
        if ($args['locationMode'] != 'filtered' && isset($args['duplicateNameCheck']) && ($args['duplicateNameCheck'] == true || $args['duplicateNameCheck'] == 'check' || $args['duplicateNameCheck'] == 'enforce')) {
            data_entry_helper::$javascript .= "\n  for(var i=0; i< SiteLabelLayer.features.length; i++){\n    if(SiteLabelLayer.features[i].attributes['new'] == false){\n      if(jQuery(this).val() == SiteLabelLayer.features[i].attributes.data.name){\n        alert(\"" . lang::get('LANG_DuplicateName') . "\");\n" . ($args['duplicateNameCheck'] == 'enforce' ? "\t\t jQuery(this).val('');\n" : "") . "      }\n    }\n  }";
        }
        data_entry_helper::$javascript .= "\n  jQuery('#sample-location-name').val(jQuery(this).val());\n});\njQuery('#location-id').change(function(){\n  jQuery('#sample-location-id').val(jQuery(this).val());\n  });\n//  jQuery(\"#location-name\").val('');\n// In order to change this value, there must be a list of values: therefore the parent has been filled in\n// With a parent filled in, there are 3 states\n// If nothing is selected, then the mod control allows selection of an existing feature, or the draw controls allow the creation of a new site.\n// With a new site in progress, then the mod control allows modification of the new site or selection of an existing feature, or the draw controls allow the additional of elements to the new site.\n// With a existing site selected, then the mod control allows selection of a different existing feature, or the draw controls allow the creation of a new site.\n// the state of the mod and draw controls re enabling stays the same before and afterwards.\nmainFieldChange = function(resetName){\n  // this is only used when not multisite.\n  var highlighted = gethighlight();\n  var found=false;\n  var myVal = jQuery('#" . $options['MainFieldID'] . "').val();\n  // only confirm if have something drawn on map: ie ignore label\n  for(i=0; i<highlighted.length; i++){\n    if(highlighted[i].layer != SiteLabelLayer && highlighted[i].attributes['new']==true)\n      found=true;\n  }\n  if(found){\n    if(!confirm('" . lang::get('LANG_ConfirmRemoveDrawnSite') . "')) return false;\n  }\n  if(highlighted.length>0 && highlighted[0].attributes['new']==true){\n    removeDrawnGeom(highlighted[0].attributes.SiteNum);\n  }\n  jQuery('#sample-location-id').val(myVal);\n  unhighlightAll();\n  pointDraw.deactivate();\n  lineDraw.deactivate();\n  polygonDraw.deactivate();\n  selectFeature.activate();\n  setPermissionsNoSite();\n  if(myVal=='') {\n    clearLocation(true, resetName);\n    return;\n  }\n  // at this point we have selected an existing site.\n  highlightMe(myVal, false);\n  ZoomToSite();\n  var allFeatures = SiteAreaLayer.features.concat(SitePathLayer.features,SitePointLayer.features);\n  for(var i=0; i<allFeatures.length; i++){\n    if(typeof allFeatures[i].attributes.data != 'undefined' &&\n        typeof allFeatures[i].attributes.data.id != 'undefined' &&\n        allFeatures[i].attributes.data.id == myVal){\n      loadLocation(allFeatures[i]); // sets permissions.\n      return;\n    }\n  }\n  clearLocation(true, true);\n}\njQuery('#" . $options['MainFieldID'] . "').change(function(){mainFieldChange(true)});\n";
    }
    if ($args['locationMode'] == 'multi' && isset(data_entry_helper::$entity_to_load["sample:updated_by_id"])) {
        // only set if data loaded from db, not error condition
        iform_mnhnl_set_editable($auth, $args, $node, array(), $options['AdminMode'], $loctypeParam);
        // TBD sort 2169 hardcode
        // this required when adding sites when editting existing samples
        $retVal .= "<input type=\"hidden\" id=\"imp-sref-system\" name=\"location:centroid_sref_system\" value=\"2169\" >";
        // multiple site: parent sample points to parent location in location_id, not parent_id. Each site has own subsample.
        // can not change the (parent) location of the main sample, as this will reset all the attached samples and sites, so rendering entered data useless. Just delete.
        return $retVal . "\n<input type=\"hidden\" name =\"sample:location_id\" value=\"" . data_entry_helper::$entity_to_load["sample:location_id"] . "\" >\n  <p>" . $options['ParentLabel'] . ' : ' . data_entry_helper::$entity_to_load["location:name"] . '</p>
' . ($args['includeNumSites'] ? "<label for=\"dummy-num-sites\" class=\"auto-width\">" . lang::get('LANG_NumSites') . ":</label> <input id=\"dummy-num-sites\" name=\"dummy:num-sites\" class=\"checkNumSites narrow\" readonly=\"readonly\"><br />\n" : '') . "<p>" . $options['Instructions2'] . "</p>\n" . ($options['AdminMode'] && (!isset($args['adminsCanCreate']) || !$args['adminsCanCreate']) ? '<p>' . lang::get('LANG_LocModTool_CantCreate') . '</p>' : '') . ($args['siteNameTermListID'] == '' ? "<label for=\"dummy-name\">" . $options['NameLabel'] . ":</label> <input id=\"dummy-name\" name=\"dummy:name\" class='wide required'><br />\n" : data_entry_helper::select(array('label' => $options['NameLabel'], 'id' => 'dummy-name', 'fieldname' => 'dummy:name', 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'term', 'blankText' => '', 'class' => 'checkGrid', 'extraParams' => $auth['read'] + array('termlist_id' => $args['siteNameTermListID'], 'orderby' => 'id'))));
    }
    $retVal .= "<input type='hidden' id=\"sample-location-name\" name=\"sample:location_name\" value=\"" . htmlspecialchars(data_entry_helper::$entity_to_load['sample:location_name']) . "\" />";
    if ($args['includeLocTools'] && function_exists('iform_loctools_listlocations')) {
        $locations = iform_loctools_listlocations($node);
    } else {
        $locations = 'all';
    }
    if ($args['locationMode'] == 'parent' || $args['locationMode'] == 'multi') {
        if (!isset($args['loctoolsLocTypeID'])) {
            return "locationMode == parent, loctoolsLocTypeID not set.";
        }
        iform_mnhnl_set_editable($auth, $args, $node, array(), $args['locationMode'] == 'parent' ? "conditional" : $options['AdminMode'], $loctypeParam);
        $locOptions = array('validation' => array('required'), 'label' => $options['ChooseParentLabel'], 'id' => $options['ChooseParentFieldID'], 'table' => 'location', 'fieldname' => $options['ChooseParentFieldName'], 'valueField' => 'id', 'captionField' => 'name', 'template' => 'select', 'itemTemplate' => 'select_item', 'columns' => 'id,name', 'extraParams' => array_merge($auth['read'], array('parent_id' => 'NULL', 'view' => 'detail', 'orderby' => 'name', 'location_type_id' => $args['loctoolsLocTypeID'], 'deleted' => 'f')));
        $locResponse = data_entry_helper::get_population_data($locOptions);
        if (isset($locResponse['error'])) {
            return "PARENT LOOKUP ERROR:  " . $locResponse['error'];
        }
        $opts = "";
        if (!isset(data_entry_helper::$entity_to_load[$options['ParentFieldName']])) {
            $opts = str_replace(array('{value}', '{caption}', '{selected}'), array('', htmlentities(lang::get('LANG_CommonParentBlank')), ''), $indicia_templates[$locOptions['itemTemplate']]);
        }
        foreach ($locResponse as $record) {
            $include = false;
            if ($locations == 'all') {
                $include = true;
            } else {
                if (in_array($record["id"], $locations)) {
                    $include = true;
                }
            }
            if ($include == true) {
                $opts .= str_replace(array('{value}', '{caption}', '{selected}'), array($record[$locOptions['valueField']], htmlentities($record[$locOptions['captionField']]), isset(data_entry_helper::$entity_to_load[$options['ParentFieldName']]) ? data_entry_helper::$entity_to_load[$options['ParentFieldName']] == $record[$locOptions['valueField']] ? 'selected=selected' : '' : ''), $indicia_templates[$locOptions['itemTemplate']]);
            }
        }
        $locOptions['items'] = $opts;
        $retVal .= '<p>' . $options['Instructions1'] . '</p>' . data_entry_helper::apply_template($locOptions['template'], $locOptions) . ($args['includeNumSites'] ? '<label for="dummy-num-sites" class="auto-width">' . lang::get('LANG_NumSites') . ':</label> <input id="dummy-num-sites" name="dummy:num-sites" class="checkNumSites narrow" readonly="readonly"><br />
' : '') . '<p>' . $options['Instructions2'] . '</p>' . ($options['AdminMode'] && (!isset($args['adminsCanCreate']) || !$args['adminsCanCreate']) ? '<p>' . lang::get('LANG_LocModTool_CantCreate') . '</p>' : '');
    }
    if ($args['locationMode'] == 'parent') {
        $retVal .= "<input type='hidden' id=\"sample-location-id\" name=\"sample:location_id\" value='" . data_entry_helper::$entity_to_load['sample:location_id'] . "' />";
        data_entry_helper::$javascript .= "\njQuery(\"#" . $options['ChooseParentFieldID'] . "\").change(function(){\n  jQuery(\"#imp-geom,#imp-boundary-geom,#imp-sref,#imp-srefX,#imp-srefY,#" . $options['MainFieldID'] . ",#" . $options['ParentFieldID'] . ",#sample-location-id,#location-name,#sample-location-name\").val('');\n  jQuery(\"#location_location_type_id\").val('{$primary}');\n  loadFeatures(this.value, '', {initial: false}, true, true, true, true, true);\n  if(typeof hook_mnhnl_parent_changed != 'undefined')\n    hook_mnhnl_parent_changed();\n});\njQuery(\"#" . $options['ParentFieldID'] . "\").change(function(){\n  if(jQuery(this).val() != '') {\n    // we have a new parent location, so draw boundary\n    jQuery.getJSON(\"" . data_entry_helper::$base_url . "/index.php/services/data/location/\"+jQuery(this).val()+\"?mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&callback=?\",\n      function(data) {\n       if (data.length>0) {\n         var parser = new OpenLayers.Format.WKT();\n         if(data[0].boundary_geom){ // only one location if any\n           var feature = parser.read(data[0].boundary_geom)\n           feature=convertFeature(feature, \$('#map')[0].map.projection);\n           ParentLocationLayer.destroyFeatures();\n           ParentLocationLayer.addFeatures([feature]);\n           zoomToLayerExtent(ParentLocationLayer);\n         }\n       }});\n" . ($options['AdminMode'] ? "    // in admin mode we have to reset the location name drop downs.\n    jQuery('#location-name').find('option').removeAttr('disabled');\n" . (isset($args['duplicateNameCheck']) && ($args['duplicateNameCheck'] == true || $args['duplicateNameCheck'] == 'check' || $args['duplicateNameCheck'] == 'enforce') ? "    jQuery.getJSON(\"" . data_entry_helper::$base_url . "/index.php/services/data/location?parent_id=\"+jQuery(this).val()+\"&location_type_id" . $primary . "&mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&callback=?\",\n      function(data) {\n        if (data.length>0) {\n          var currentName = jQuery('#location-name').val();\n          var currentID = jQuery('#" . $options['MainFieldID'] . "').val();\n          // first check if there is a clash and give a warning\n          for(var di=0; di<data.length; di++){\n            if(currentName == data[di].name && currentID != data[di].id && currentID != ''){\n              alert(\"" . lang::get('This site name is already in use in the new square. Please choose another.') . "\");\n              break; // only display one message\n            }\n          }\n" . ($args['duplicateNameCheck'] == 'enforce' ? "          // if enforce, disable all options for existing and reset the name value if needed.\n          for(var di=0; di<data.length; di++){\n            if(data[di].name == parseInt(data[di].name) && currentID != data[di].id)\n              // only disable fields for existing locations for numeric names and which are not me. \n              jQuery('#location-name').find('option').filter('[value='+data[di].name+']').attr('disabled','disabled');\n          }\n          // finally if enforce and there is a clash, reset the value. This will then automatically take first available.\n          for(var di=0; di<data.length; di++){\n            if(currentName == data[di].name && currentID != data[di].id)\n              jQuery('#location-name').val('');\n          }\n" : "") . "\n       }});\n" : "") : "") . "  } else\n    ParentLocationLayer.destroyFeatures();\n});\n";
        // choose a single site from a parent, so built site selector drop down.
        // parent uses ID locModTool
        $opts = "";
        $locOptions = array('label' => $options['MainFieldLabel'], 'id' => $options['MainFieldID'], 'table' => 'location', 'fieldname' => $options['MainFieldName'], 'valueField' => 'id', 'captionField' => 'name', 'template' => 'select', 'itemTemplate' => 'select_item', 'nocache' => true, 'extraParams' => array_merge($auth['read'], array('parent_id' => data_entry_helper::$entity_to_load["location:parent_id"], 'view' => 'detail', 'orderby' => 'name', 'location_type_id' => $loctypeParam, 'deleted' => 'f')));
        if (isset(data_entry_helper::$entity_to_load["sample:id"])) {
            // if preloaded, then drop down is dependant on value in parent field: if not then get user to enter parent first
            $response = data_entry_helper::get_population_data($locOptions);
            // OK as parent_id filled in: not likely to be large number.
            if (isset($response['error'])) {
                return "CHILD LOOKUP ERROR:  " . $response['error'];
            }
            $opts .= str_replace(array('{value}', '{caption}', '{selected}'), array('', htmlentities(lang::get('LANG_CommonEmptyLocationID')), ''), $indicia_templates[$locOptions['itemTemplate']]);
            foreach ($response as $record) {
                $caption = htmlspecialchars($record[$locOptions['captionField']]);
                // it will be extended using a attribute template by JS
                $opts .= str_replace(array('{value}', '{caption}', '{selected}'), array($record[$locOptions['valueField']], htmlentities($caption), isset(data_entry_helper::$entity_to_load['location:id']) ? data_entry_helper::$entity_to_load['sample:location_id'] == $record[$locOptions['valueField']] ? 'selected=selected' : '' : ''), $indicia_templates[$locOptions['itemTemplate']]);
            }
        } else {
            $opts = "<option >" . lang::get("LANG_CommonChooseParentFirst") . "</option>";
        }
        $locOptions['items'] = $opts;
        // single site requires all location data in main form. Mult site must have array: depends on implementation so left to actual form.
        $retVal .= data_entry_helper::apply_template($locOptions['template'], $locOptions) . "<br />";
        if ($options['AdminMode']) {
            $locOptions = array('validation' => array('required'), 'label' => $options['ParentLabel'], 'id' => $options['ParentFieldID'], 'fieldname' => $options['ParentFieldName'], 'valueField' => 'id', 'captionField' => 'name', 'template' => 'select', 'itemTemplate' => 'select_item');
            $opts = str_replace(array('{value}', '{caption}', '{selected}'), array('', '', ''), $indicia_templates[$locOptions['itemTemplate']]);
            foreach ($locResponse as $record) {
                $include = false;
                if ($locations == 'all') {
                    $include = true;
                } else {
                    if (in_array($record["id"], $locations)) {
                        $include = true;
                    }
                }
                if ($include == true) {
                    $opts .= str_replace(array('{value}', '{caption}', '{selected}'), array($record[$locOptions['valueField']], htmlentities($record[$locOptions['captionField']]), isset(data_entry_helper::$entity_to_load[$options['ParentFieldName']]) ? data_entry_helper::$entity_to_load[$options['ParentFieldName']] == $record[$locOptions['valueField']] ? 'selected=selected' : '' : ''), $indicia_templates[$locOptions['itemTemplate']]);
                }
            }
            $locOptions['items'] = $opts;
            $retVal .= data_entry_helper::apply_template($locOptions['template'], $locOptions);
        } else {
            $retVal .= "<input type='hidden' id=\"" . $options['ParentFieldID'] . "\" name=\"" . $options['ParentFieldName'] . "\" value=\"" . (isset(data_entry_helper::$entity_to_load[$options['ParentFieldName']]) ? data_entry_helper::$entity_to_load[$options['ParentFieldName']] : "") . "\" />";
        }
        if ($args['siteNameTermListID'] == '') {
            $retVal .= "<label for=\"location-name\">" . $options['NameLabel'] . ":</label> <input type='text' id=\"location-name\" name=\"location:name\" class='required wide' value=\"" . htmlspecialchars(data_entry_helper::$entity_to_load['location:name']) . "\" /><span class='deh-required'>*</span><br/>";
        } else {
            $retVal .= data_entry_helper::select(array('label' => $options['NameLabel'], 'id' => 'location-name', 'fieldname' => 'location:name', 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'term', 'extraParams' => $auth['read'] + array('termlist_id' => $args['siteNameTermListID'], 'orderby' => 'id')));
        }
    } else {
        if ($args['locationMode'] == 'multi') {
            //TBD sort 2169 hardcode
            $retVal .= "<input type=\"hidden\" id=\"imp-sref-system\" name=\"location:centroid_sref_system\" value=\"2169\" >";
            // multiSite needs the location name.
            if ($args['siteNameTermListID'] == '') {
                $retVal .= "<label for=\"dummy-name\">" . $options['NameLabel'] . ":</label> <input type='text' id=\"dummy-name\" name=\"dummy:name\" class='wide' value=\"" . htmlspecialchars(data_entry_helper::$entity_to_load['location:name']) . "\" /><span class='deh-required'>*</span><br/>";
            } else {
                $retVal .= data_entry_helper::select(array('label' => $options['NameLabel'], 'id' => 'dummy-name', 'fieldname' => 'dummy:name', 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'term', 'blankText' => '', 'class' => 'checkGrid', 'extraParams' => $auth['read'] + array('termlist_id' => $args['siteNameTermListID'], 'orderby' => 'id')));
            }
            data_entry_helper::$javascript .= "\njQuery(\"#" . $options['ChooseParentFieldID'] . "\").change(function(){\n  if(typeof hook_mnhnl_parent_changed != 'undefined')\n    hook_mnhnl_parent_changed();\n  loadFeatures(this.value, '', {initial : false}, true, true, true, true, true);\n});\n";
        } else {
            if ($args['locationMode'] == 'single') {
                // no parent look up: actual name is a text entry field.
                $location_list_args = array('nocache' => true, 'includeCodeField' => true, 'label' => lang::get('LANG_CommonLocationNameLabel'), 'NameBlankText' => lang::get('LANG_Location_Name_Blank_Text'), 'fieldname' => 'location:id', 'id' => $options['MainFieldID'], 'columns' => 'id,name,code,location_type_id', 'extraParams' => array_merge(array('view' => 'detail', 'orderby' => 'name', 'website_id' => $args['website_id'], 'location_type_id' => $loctypeParam), $auth['read']), 'table' => 'location', 'template' => 'select', 'itemTemplate' => 'select_item', 'filterField' => 'parent_id', 'size' => 3);
                // Idea here is to get a list of all locations in order to build drop downs.
                $responseRecords = data_entry_helper::get_population_data($location_list_args);
                if (isset($responseRecords['error'])) {
                    return $responseRecords['error'];
                }
                iform_mnhnl_set_editable($auth, $args, $node, $responseRecords, 'conditional', $loctypeParam);
                $usedCodes = array();
                $maxCode = 0;
                $NameOpts = '';
                foreach ($responseRecords as $record) {
                    if ($record['name'] != '') {
                        $item = array('selected' => data_entry_helper::$entity_to_load['location:id'] == $record['id'] ? 'selected=\\"selected\\"' : '', 'value' => $record['id'], 'caption' => htmlspecialchars(utf8_decode($record['name'])));
                        $NameOpts .= data_entry_helper::mergeParamsIntoTemplate($item, $location_list_args['itemTemplate']);
                        if ($record['code'] != '') {
                            $usedCodes[] = "\"" . $record['code'] . "\"";
                            if ($maxCode < $record['code']) {
                                $maxCode = $record['code'];
                            }
                        }
                    }
                }
                data_entry_helper::$javascript .= "\nvar usedCodes = [" . implode(',', $usedCodes) . "];\nvar defaultCode = " . ($maxCode + 1) . ";\n";
                $retVal .= '<p>' . $options['Instructions2'] . '</p>' . ($options['AdminMode'] && (!isset($args['adminsCanCreate']) || !$args['adminsCanCreate']) ? '<p>' . lang::get('LANG_LocModTool_CantCreate') . '</p>' : '') . '<fieldset><legend>' . lang::get('Existing locations') . '</legend>';
                if ($NameOpts != '') {
                    $location_list_args['items'] = str_replace(array('{value}', '{caption}', '{selected}'), array('', htmlentities($location_list_args['NameBlankText']), ''), $indicia_templates[$location_list_args['itemTemplate']]) . $NameOpts;
                    $retVal .= data_entry_helper::apply_template($location_list_args['template'], $location_list_args);
                    if ($args['SecondaryLocationTypeTerm'] != '' && $options['AdminMode']) {
                        $retVal .= '<p>' . lang::get("LANG_Multiple_Location_Types") . '</p>';
                    }
                } else {
                    $retVal .= '<p>' . lang::get("LANG_NoSites") . '</p>';
                }
                $retVal .= "</fieldset><label for=\"location-name\">" . $options['NameLabel'] . ":</label> <input id=\"location-name\" name=\"location:name\" class='wide required' value=\"" . htmlspecialchars(data_entry_helper::$entity_to_load['location:name']) . "\"><span class=\"deh-required\">*</span><br />\n      <input type='hidden' id=\"sample-location-id\" name=\"sample:location_id\" value='" . data_entry_helper::$entity_to_load['sample:location_id'] . "' />";
            } else {
                // single location, filtered.
                data_entry_helper::$javascript .= "indiciaData.filterMode=true;\n";
                iform_mnhnl_set_editable($auth, $args, $node, array(), 'conditional', $loctypeParam);
                $retVal .= '<p>' . $options['Instructions2'] . '</p>' . ($options['AdminMode'] && (!isset($args['adminsCanCreate']) || !$args['adminsCanCreate']) ? '<p>' . lang::get('LANG_LocModTool_CantCreate') . '</p>' : '');
                $filterAttrs = explode(',', $args['filterAttrs']);
                // filter attributes are assumed to be text (could extend later)
                $attrArgs = array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']);
                if (array_key_exists('location:id', data_entry_helper::$entity_to_load) && data_entry_helper::$entity_to_load['location:id'] != "") {
                    // if we have location Id to load, use it to get attribute values
                    $attrArgs['id'] = data_entry_helper::$entity_to_load['location:id'];
                }
                $locationAttributes = data_entry_helper::getAttributes($attrArgs, false);
                if ($args['LocationTypeTerm'] == '' && isset($args['loctoolsLocTypeID'])) {
                    $args['LocationTypeTerm'] = $args['loctoolsLocTypeID'];
                }
                $primary = iform_mnhnl_getTermID($auth, 'indicia:location_types', $args['LocationTypeTerm']);
                $filterAttrs[] = "Name";
                // always add the location name special case to the filter list.
                $defaultsFunction = "";
                $loadFunction = "hook_loadFilters = function(){\n";
                $initFunctions = "";
                $prevAttr = null;
                $prevFilterAttr = null;
                $prevIdx = null;
                $attrList = array();
                $includeCommune = true;
                $location_list_args = array('nocache' => true, 'extraParams' => array_merge(array('orderby' => 'id', 'view' => 'detail', 'website_id' => $args['website_id'], 'location_type_id' => $primary), $auth['read']), 'columns' => 'id,name,parent_id', 'table' => 'location');
                $locList = data_entry_helper::get_population_data($location_list_args);
                if (isset($locList['error'])) {
                    return $locList['error'];
                }
                $location_attr_list_args = array('nocache' => true, 'extraParams' => array_merge(array('orderby' => 'location_id', 'view' => 'list', 'website_id' => $args['website_id'], 'location_type_id' => $primary), $auth['read']), 'table' => 'location_attribute_value');
                $locAttrList = data_entry_helper::get_population_data($location_attr_list_args);
                if (isset($locAttrList['error'])) {
                    return $locAttrList['error'];
                }
                $locTextList = array();
                $locListCount = count($locList);
                $locAttrListCount = count($locAttrList);
                for ($i = 0, $j = 0; $i < $locListCount; $i++) {
                    while ($j < $locAttrListCount && $locAttrList[$j]['location_id'] < $locList[$i]['id']) {
                        $j++;
                    }
                    $locAttrTextList = array();
                    while ($j < $locAttrListCount && $locAttrList[$j]['location_id'] == $locList[$i]['id']) {
                        $locAttrTextList[] = '"' . $locAttrList[$j]['location_attribute_id'] . '":"' . $locAttrList[$j]['raw_value'] . '"';
                        $j++;
                    }
                    $locTextList[] = "{'id':" . $locList[$i]['id'] . ", 'name':\"" . $locList[$i]['name'] . "\", 'parent_id':\"" . $locList[$i]['parent_id'] . "\", 'attrs': {" . implode(",", $locAttrTextList) . "}}";
                }
                data_entry_helper::$javascript .= "\nvar locations = [\n" . implode(",\n", $locTextList) . "];\n";
                foreach ($filterAttrs as $idx => $filterAttr) {
                    $filterAttr = explode(':', $filterAttr);
                    $attr = "";
                    if ($filterAttr[0] != "Name" && $filterAttr[0] != "Parent") {
                        foreach ($locationAttributes as $locationAttribute) {
                            if ($locationAttribute['untranslatedCaption'] == $filterAttr[0] || $filterAttr[0] == "Shape" && $locationAttribute['untranslatedCaption'] == $filterAttr[1]) {
                                $attr = $locationAttribute;
                            }
                        }
                        if ($attr == "") {
                            return '<p>' . lang::get("Location Module: Could not find attribute ") . $filterAttr[$filterAttr[0] == "Shape" ? 1 : 0] . '</p>';
                        }
                    }
                    $nextIdx = $idx + 1;
                    while ($nextIdx < count($filterAttrs)) {
                        $fparts = explode(':', $filterAttrs[$nextIdx]);
                        if ($fparts[0] != 'Parent' || $fparts[1] == "true") {
                            break;
                        }
                        $nextIdx++;
                    }
                    // need to add functionality to tie locations to a square, even if not in use (for sites form)
                    // also this form must fill in a hidden commune field.
                    switch ($filterAttr[0]) {
                        case "Parent":
                            //special case, assume only one of these in a form. Not required
                            // field 1: editable true or false
                            // field 2: display warning if outside true or false
                            // field 3: location_type term
                            $parentLocTypeID = iform_mnhnl_getTermID($auth, 'indicia:location_types', $filterAttr[3]);
                            // proxiedurl,featurePrefix,featureType,[geometryName],featureNS,srsName[,propertyNames]
                            $protocol = explode(',', $args['locationLayerLookup']);
                            data_entry_helper::$javascript .= "\nhook_setSref_" . $idx . " = function(geom){ // map projection\n  // srsName should be in map projection.\n  var protocol = new OpenLayers.Protocol.WFS({\n      url:  '" . $protocol[0] . "',featurePrefix: '" . $protocol[1] . "',featureType: '" . $protocol[2] . "',geometryName:'boundary_geom',featureNS: '" . $protocol[3] . "',srsName: '" . $protocol[4] . "',version: '1.1.0',propertyNames: ['boundary_geom','name']\n     ,callback: function(a1){\n        if(a1.error && (typeof a1.error.success == 'undefined' || a1.error.success == false)){\n          alert(\"" . lang::get('LANG_ParentLookUpFailed') . "\");\n          return;\n        }\n        if(a1.features.length > 0) {\n            var id = a1.features[0].fid.slice(" . (strlen($protocol[2]) + 1) . ")\n";
                            if ($filterAttr[1] == "true") {
                                data_entry_helper::$javascript .= "          if(jQuery('#filterSelect" . $idx . "').val() == '' || // not currently filled in\n              (jQuery('#filterSelect" . $idx . "').val() != id && confirm(\"" . lang::get('LANG_PositionInDifferentParent') . "\"))) {\n            ParentLocationLayer.destroyFeatures();\n            ParentLocationLayer.addFeatures(a1.features); // TBD check geometry system - convert?\n            jQuery('#filterSelect" . $idx . "').val(id);\n            jQuery('#" . $options['ParentFieldID'] . "').val(id);\n";
                                foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                    // just need index, so don't explode
                                    if ($idx1 > $idx && $idx1 < count($filterAttrs) - 1) {
                                        // don't do name
                                        data_entry_helper::$javascript .= "            filterLoad" . $idx1 . "();\n";
                                    }
                                }
                                // update drop downs, but leave values as they are.
                                data_entry_helper::$javascript .= "          }\n";
                            } else {
                                data_entry_helper::$javascript .= "          jQuery('#" . $options['ParentFieldID'] . "').val(id);\n          jQuery('#" . $options['ChooseParentFieldID'] . "').val(a1.features[0].attributes['name']);\n";
                            }
                            data_entry_helper::$javascript .= "\n          loadChildFeatures(id, true); // load in children onto map\n        } else {\n" . ($filterAttr[2] == 'true' ? "        alert(\"" . lang::get('LANG_PositionOutsideParent') . "\");\n" : '') . "          jQuery('#" . $options['ParentFieldID'] . "').val('');\n          jQuery('#" . ($filterAttr[1] == "true" ? "filterSelect" . $idx : $options['ChooseParentFieldID']) . "').val('');\n        }\n      }\n    });\n  filter = new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.AND, filters:[\n  \t\t\tnew OpenLayers.Filter.Spatial({type: OpenLayers.Filter.Spatial.CONTAINS,property: 'boundary_geom',value: geom}),\n  \t\t\tnew OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.EQUAL_TO, property: 'location_type_id', value: '" . $parentLocTypeID . "'})]});\n  protocol.read({filter: filter});\n};\n";
                            if ($filterAttr[1] == "true") {
                                // filterable.
                                // set up the parent list, cacheable
                                $locOptions = array('label' => lang::get('LANG_CommonParentLabel'), 'id' => 'filterSelect' . $idx, 'table' => 'location', 'fieldname' => $options['ChooseParentFieldName'], 'valueField' => 'id', 'captionField' => 'name', 'template' => 'select', 'itemTemplate' => 'select_item', 'validation' => array('required'), 'columns' => 'id,name', 'extraParams' => array_merge($auth['read'], array('parent_id' => 'NULL', 'view' => 'detail', 'orderby' => 'name', 'location_type_id' => $parentLocTypeID, 'deleted' => 'f')));
                                $locResponse = data_entry_helper::get_population_data($locOptions);
                                if (isset($locResponse['error'])) {
                                    return "PARENT LOOKUP ERROR:  " . $locResponse['error'];
                                }
                                $opts = str_replace(array('{value}', '{caption}', '{selected}'), array('', lang::get('LANG_FirstChooseParentFilter'), ''), $indicia_templates[$locOptions['itemTemplate']]);
                                foreach ($locResponse as $record) {
                                    $include = false;
                                    if ($locations == 'all') {
                                        $include = true;
                                    } else {
                                        if (in_array($record["id"], $locations)) {
                                            $include = true;
                                        }
                                    }
                                    if ($include == true) {
                                        $opts .= str_replace(array('{value}', '{caption}', '{selected}'), array($record[$locOptions['valueField']], htmlentities($record[$locOptions['captionField']]), isset(data_entry_helper::$entity_to_load[$options['ParentFieldName']]) ? data_entry_helper::$entity_to_load[$options['ParentFieldName']] == $record[$locOptions['valueField']] ? 'selected=selected' : '' : ''), $indicia_templates[$locOptions['itemTemplate']]);
                                    }
                                }
                                $locOptions['items'] = $opts;
                                $retVal .= data_entry_helper::apply_template($locOptions['template'], $locOptions);
                                if ($options['AdminMode']) {
                                    // In admin mode assume can reassign to any location: admins should have access to all squares.
                                    $location_list_args = array('view' => 'detail', 'extraParams' => array_merge(array('orderby' => 'name', 'website_id' => $args['website_id']), $auth['read']), 'location_type_id' => $parentLocTypeID, 'default' => data_entry_helper::$entity_to_load[$options['ParentFieldName']], 'validation' => array('required'), 'label' => $options['ParentLabel'], 'id' => $options['ParentFieldID'], 'fieldname' => $options['ParentFieldName'], 'blankText' => '');
                                    $retVal .= data_entry_helper::location_select($location_list_args);
                                } else {
                                    $retVal .= "<input type='hidden' id='" . $options['ParentFieldID'] . "' name='" . $options['ParentFieldName'] . "' value='" . (isset(data_entry_helper::$entity_to_load[$options['ParentFieldName']]) ? data_entry_helper::$entity_to_load[$options['ParentFieldName']] : "") . "' />";
                                }
                                data_entry_helper::$javascript .= "indiciaData.filterParent=true;\n// load the counts to the end of the parent drop down list. Do only once. Equivalent to filterLoad" . $idx . "\njQuery('#filterSelect" . $idx . " option').each(function(idx, elem){\n  if(elem.value=='') return;\n  for(i=0, j=0; i< locations.length; i++){\n    if(locations[i]['parent_id']==elem.value) j++;\n  }\n  if(j) elem.text=elem.text+' ('+j+')';\n});\ndisplayParent = function(zoom){\n  var parent_id = jQuery('#filterSelect" . $idx . "').val();\n  loadFeatures(parent_id, '', {initial : false}, true, false, zoom, false, false);\n}\njQuery('#filterSelect" . $idx . "').change(function(){\n  jQuery('#" . $options['ParentFieldID'] . "').val(jQuery(this).val());\n  SetFilterNewLocation();\n";
                                foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                    if ($idx1 > $idx) {
                                        data_entry_helper::$javascript .= "  filterReset" . $idx1 . "();\n";
                                    }
                                }
                                data_entry_helper::$javascript .= "  if(jQuery(this).val()!=''){\n";
                                foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                    if ($idx1 > $idx) {
                                        data_entry_helper::$javascript .= "    filterLoad" . $idx1 . "();\n";
                                    }
                                }
                                data_entry_helper::$javascript .= "  }\n  displayParent(true);\n});\n";
                                $defaultsFunction .= "  if(keepFilter){\n    jQuery('#" . $options['ParentFieldID'] . "').val(jQuery('#filterSelect" . $idx . "').val());\n  } else {\n    jQuery('#filterSelect" . $idx . "').val('');\n  }\n";
                                $prevFilterAttr = $filterAttr;
                                $prevAttr = $attr;
                                $prevIdx = $idx;
                            } else {
                                // not filterable: just readonly field
                                $retVal .= '<input id="' . $options['ParentFieldID'] . '" name="' . $options['ParentFieldName'] . '" type="hidden" value="' . (isset(data_entry_helper::$entity_to_load[$options['ParentFieldName']]) && data_entry_helper::$entity_to_load[$options['ParentFieldName']] != "" && data_entry_helper::$entity_to_load[$options['ParentFieldName']] != null ? data_entry_helper::$entity_to_load[$options['ParentFieldName']] : '') . '">' . '<input id="' . $options['ChooseParentFieldID'] . '" name="dummy" value="" disabled="disabled" >';
                                $loadFunction .= "  populate" . $idx . "();\n";
                                data_entry_helper::$javascript .= "\n\$('#sample-location-id').before('<label>" . lang::get('LANG_CommonParentLabel') . ":</label> ');\n\$('#" . $options['ChooseParentFieldID'] . "').insertBefore('#sample-location-id');\n\$('#sample-location-id').before('<br/>');\npopulate" . $idx . " = function(){\n  jQuery('#" . $options['ChooseParentFieldID'] . "').val('');\n  if(jQuery('#" . $options['ParentFieldID'] . "').val()!='' && jQuery('#" . $options['ParentFieldID'] . "').val() != null){\n    var protocol = new OpenLayers.Protocol.WFS({\n        url:  '" . $protocol[0] . "',featurePrefix: '" . $protocol[1] . "',featureType: '" . $protocol[2] . "',geometryName:'boundary_geom',featureNS: '" . $protocol[3] . "',srsName: '" . $protocol[4] . "',version: '1.1.0',propertyNames: ['boundary_geom','name']\n       ,callback: function(a1){\n          if(a1.error && (typeof a1.error.success == 'undefined' || a1.error.success == false)){\n            alert(\"" . lang::get('LANG_ParentLookUpFailed') . "\");\n          } else if(a1.features.length > 0) {\n            jQuery('#" . $options['ChooseParentFieldID'] . "').val(a1.features[0].attributes['name']);\n        }}});\n    var filter = new OpenLayers.Filter.FeatureId({fids: ['" . $protocol[2] . ".'+jQuery('#" . $options['ParentFieldID'] . "').val()]});\n    protocol.read({filter: filter});\n  }\n};\nfilterLoad" . $idx . " = function(){\n  populate" . $idx . "();\n};\npopulate" . $idx . "();\nfilterReset" . $idx . " = function(){\n  jQuery('#" . $options['ChooseParentFieldID'] . "').val('');\n};";
                            }
                            // have to extract id from fid.
                            break;
                        case "Shape":
                            //special case: geoserver shape file look up, assume only one of these in a form.
                            // 0 = "Shape"
                            // 1 = Attribute Caption, e.g. "Commune"
                            // 2 = display warning if outside list (will be set to blank)
                            // 3 = optional location type term filter
                            // 4 = buffer
                            // Note that for Commune readonly displays, the normal Commune functionality is used, e.g. in the Amphibians Squares where the Commune must be kept in line so the Amphibian Sites can use it.
                            $parentLocTypeID = $filterAttr[3] != '' ? iform_mnhnl_getTermID($auth, 'indicia:location_types', $filterAttr[3]) : -1;
                            // proxiedurl,featurePrefix,featureType,geometryName,featureNS,srsName,propertyNames
                            if ($filterAttr[1] == "Commune") {
                                $includeCommune = false;
                            }
                            $protocol = explode(',', $filterAttr[1] == "Commune" ? $args['communeLayerLookup'] : $args['locationLayerLookup']);
                            $retVal .= '<input id="' . $attr['id'] . '" class="filterFields" name="' . $attr['fieldname'] . '" type="hidden" value="' . $attr['default'] . '"><label>' . $attr['caption'] . ':</label> <select class="required" id="filterSelect' . $idx . '"></select><span class="deh-required">*</span><br/>';
                            $attrList[] = array('id' => $attr['attributeId'], 'shape' => true);
                            data_entry_helper::$javascript .= "\ndisplayShape = function(zoom){\n  ParentLocationLayer.destroyFeatures();\n  if(jQuery('#filterSelect" . $idx . "').val()=='') return;\n  var protocol = new OpenLayers.Protocol.WFS({ // WFS request is to be made in the map projection\n    url:  '" . $protocol[0] . "',featurePrefix: '" . $protocol[1] . "',featureType: '" . $protocol[2] . "',geometryName: '" . $protocol[3] . "',featureNS: '" . $protocol[4] . "',srsName: '" . $protocol[5] . "',version: '1.1.0',propertyNames: ['" . $protocol[6] . "','" . $protocol[3] . "']\n   ,callback:function(data){\n      if(data.features.length>0){ // feature is in map projection\n        ParentLocationLayer.addFeatures(data.features); // TBD check geometry system - convert?\n        if(zoom) ZoomToParent();\n      }}});\n  var filter = new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.EQUAL_TO, property: '" . $protocol[6] . "', value: jQuery('#filterSelect" . $idx . "').val()});\n" . ($filterAttr[3] != '' ? "  filter = new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.AND, filters:[filter, new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.EQUAL_TO, property: 'location_type_id', value: '" . $parentLocTypeID . "'})]});\n" : '') . "  protocol.read({filter: filter});\n}\nfilterLoad" . $idx . " = function(){\n  var protocol = new OpenLayers.Protocol.WFS({\n    url:  '" . $protocol[0] . "',featurePrefix: '" . $protocol[1] . "',featureType: '" . $protocol[2] . "',geometryName: '" . $protocol[3] . "',featureNS: '" . $protocol[4] . "',srsName: '" . $protocol[5] . "',version: '1.1.0',sortBy: '" . $protocol[6] . "',propertyNames: ['" . $protocol[6] . ($filterAttr[3] != '' ? "','location_type_id" : '') . "']\n    ,callback:function(data){\n      jQuery('#filterSelect" . $idx . "').empty().append('<option value=\"\">" . lang::get("Please select...") . "</option>');\n      var names=[];\n      for(var i=0; i<data.features.length; i++) names.push(data.features[i].attributes['" . $protocol[6] . "']);\n      names.sort(); // the sort WFS does not work...\n      for(var i=0; i<names.length; i++) {\n        for(j=0, count=0; j< locations.length; j++){\n          if(locations[j].attrs['" . $attr['attributeId'] . "']==names[i]) {\n            count++;\n            locations[j].shapeFound=true;\n          }\n        }\n        jQuery('#filterSelect" . $idx . "').append('<option value=\"'+names[i]+'\">'+names[i]+(count?' ('+count+')':'')+'</option>');\n      }\n      for(j=0; j< locations.length; j++){ // add any communes which are in the locations but not in the shape file.\n        if(typeof locations[j].shapeFound == 'undefined'){\n          for(i=0, count=0; i< locations.length; i++){\n            if(locations[j].attrs['" . $attr['attributeId'] . "']==locations[i].attrs['" . $attr['attributeId'] . "']) {\n              count++;\n              locations[i].shapeFound=true;\n            }\n          }\n          jQuery('#filterSelect" . $idx . "').append('<option value=\"'+locations[j].attrs['" . $attr['attributeId'] . "']+'\">'+locations[j].attrs['" . $attr['attributeId'] . "']+' ('+count+')'+'</option>');\n        }\n      }\n      if(jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val()!=''){\n        jQuery('#filterSelect" . $idx . "').val(jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val());\n        displayShape(false);\n      }\n  }});\n  protocol.read(" . ($filterAttr[3] != '' ? "{filter: new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.EQUAL_TO, property: 'location_type_id', value: '" . $parentLocTypeID . "'})}" : '') . ");\n}\n// this is only done once\nfilterLoad" . $idx . "();\nhook_setSref_" . $idx . " = function(geom){ // map projection\n  // srsName should be in map projection.\n  var protocol = new OpenLayers.Protocol.WFS({\n      url:  '" . $protocol[0] . "',featurePrefix: '" . $protocol[1] . "',featureType: '" . $protocol[2] . "',geometryName:'" . $protocol[3] . "',featureNS: '" . $protocol[4] . "',srsName: '" . $protocol[5] . "',version: '1.1.0',propertyNames: [\"" . $protocol[6] . "\",'" . $protocol[3] . "']\n     ,callback: function(a1){\n        if(a1.error && (typeof a1.error.success == 'undefined' || a1.error.success == false)){\n          alert(\"" . lang::get('LANG_' . $filterAttr[1] . 'LookUpFailed') . "\");\n          return;\n        }\n        if(a1.features.length > 0) {\n          if(jQuery('#filterSelect" . $idx . "').val() == '' || // not currently filled in\n              (jQuery('#filterSelect" . $idx . "').val() != a1.features[0].attributes[\"" . $protocol[6] . "\"] && confirm(\"" . lang::get('LANG_PositionInDifferent' . $filterAttr[1]) . "\"))) {\n            ParentLocationLayer.destroyFeatures();\n            ParentLocationLayer.addFeatures(a1.features); // feature should be in map projection\n            jQuery('#filterSelect" . $idx . "').val(a1.features[0].attributes[\"" . $protocol[6] . "\"]);\n            jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val(a1.features[0].attributes[\"" . $protocol[6] . "\"]);\n";
                            foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                // just need index, so don't explode
                                if ($idx1 > $idx && $idx1 < count($filterAttrs) - 1) {
                                    // don't do name
                                    data_entry_helper::$javascript .= "            filterLoad" . $idx1 . "();\n";
                                }
                            }
                            data_entry_helper::$javascript .= "          } // else user choose not to change\n        } else {\n";
                            if (!isset($args['communeLayerBuffer']) || $args['communeLayerBuffer'] == "") {
                                // No buffer in definition
                                data_entry_helper::$javascript .= "          if(jQuery('#filterSelect" . $idx . "').val() == '') { // not currently filled in\n            alert(\"" . lang::get('LANG_PositionOutside' . $filterAttr[1] . "_1") . "\");\n          } else if(!confirm(\"" . lang::get('LANG_PositionOutside' . $filterAttr[1] . "_2") . "\")) {\n            jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val('');\n            jQuery('#filterSelect" . $idx . "').val('');\n            ParentLocationLayer.destroyFeatures();\n          }\n";
                            } else {
                                // buffer set
                                data_entry_helper::$javascript .= "          //  Get list of communes within buffer of geom\n          var protocol = new OpenLayers.Protocol.WFS({\n              url:  '" . $protocol[0] . "',featurePrefix: '" . $protocol[1] . "',featureType: '" . $protocol[2] . "',geometryName:'" . $protocol[3] . "',featureNS: '" . $protocol[4] . "',srsName: '" . $protocol[5] . "',version: '1.1.0',propertyNames: [\"" . $protocol[6] . "\",'" . $protocol[3] . "']\n             ,callback: function(a1){\n                var replace = false,\n                    reset = false;\n                if(a1.error && (typeof a1.error.success == 'undefined' || a1.error.success == false)){\n                  alert(\"" . lang::get('LANG_' . $filterAttr[1] . 'LookUpFailed') . "\");\n                  return;\n                }\n                if(a1.features.length == 0) {\n                  if(jQuery('#filterSelect" . $idx . "').val() == '') { // not currently filled in\n                    alert(\"" . str_replace('{DISTANCE}', $args['communeLayerBuffer'], lang::get('LANG_PositionOutside' . $filterAttr[1] . "_3")) . "\");\n                  } else if(!confirm(\"" . str_replace('{DISTANCE}', $args['communeLayerBuffer'], lang::get('LANG_PositionOutside' . $filterAttr[1] . "_4")) . "\")) {\n                    reset = true;\n                  }\n                } else {\n                  var closest = 0;\n                  if(a1.features.length >= 0) {\n                    for(var i=0; i< a1.features.length; i++){\n                      var distance, thisDistance = geom.distanceTo(a1.features[i].geometry, {});\n                      if(i==0 || thisDistance<distance){\n                        closest=i;\n                        distance=thisDistance;\n                      }\n                    }\n                  }\n                  if(jQuery('#filterSelect" . $idx . "').val() == '') { // not currently filled in\n                    if(confirm(\"" . lang::get('LANG_PositionOutside' . $filterAttr[1] . "_5") . "\".replace(/SHAPE/g, a1.features[closest].attributes['" . $protocol[6] . "']))){\n                      replace = true;\n                    }\n                  } else if(jQuery('#filterSelect" . $idx . "').val() == a1.features[closest].attributes[\"" . $protocol[6] . "\"]){\n                    if(confirm(\"" . lang::get('LANG_PositionOutside' . $filterAttr[1] . "_6") . "\".replace(/SHAPE/g, a1.features[closest].attributes['" . $protocol[6] . "']))){\n                      replace = true;\n                    } else {\n                      reset = true;\n                    }\n                  } else { // doesn't match\n                    if(confirm(\"" . lang::get('LANG_PositionOutside' . $filterAttr[1] . "_7") . "\".replace(/SHAPE/g, a1.features[closest].attributes['" . $protocol[6] . "']).replace(/OLD/g, jQuery('#filterSelect" . $idx . "').val()))){\n                      replace = true;\n                    }\n                  }\n                }\n                if(reset) {\n                  jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val('');\n                  jQuery('#filterSelect" . $idx . "').val('');\n                  ParentLocationLayer.destroyFeatures();\n                } else if(replace){\n                  ParentLocationLayer.destroyFeatures();\n                  ParentLocationLayer.addFeatures([a1.features[closest]]); // feature should be in map projection\n                  jQuery('#filterSelect" . $idx . "').val(a1.features[closest].attributes['" . $protocol[6] . "']);\n                  jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val(a1.features[closest].attributes['" . $protocol[6] . "']);\n";
                                foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                    // just need index, so don't explode
                                    if ($idx1 > $idx && $idx1 < count($filterAttrs) - 1) {
                                        // don't do name
                                        data_entry_helper::$javascript .= "                  filterLoad" . $idx1 . "();\n";
                                    }
                                }
                                data_entry_helper::$javascript .= "\n                }\n              }\n          });\n          var filter = new OpenLayers.Filter.Spatial({type: OpenLayers.Filter.Spatial.DWITHIN, property: '" . $protocol[3] . "', value: geom, distance: '" . $args['communeLayerBuffer'] . "'});\n" . ($filterAttr[3] != '' ? "          filter = new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.AND,\n               filters:[filter,\n\t\t                new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.EQUAL_TO, property: 'location_type_id', value: '" . $parentLocTypeID . "'})]});\n" : '') . "          protocol.read({filter: filter});\n";
                            }
                            data_entry_helper::$javascript .= "        }\n      }\n  });\n  var filter = new OpenLayers.Filter.Spatial({type: OpenLayers.Filter.Spatial.CONTAINS,property: '" . $protocol[3] . "',value: geom});\n" . ($filterAttr[3] != '' ? "  filter = new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.AND, filters:[filter, new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.EQUAL_TO, property: 'location_type_id', value: '" . $parentLocTypeID . "'})]});\n" : '') . "  protocol.read({filter: filter});\n};\njQuery('#filterSelect" . $idx . "').change(function(){\n  jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val(jQuery('#filterSelect" . $idx . "').val());\n  SetFilterNewLocation();\n";
                            foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                if ($idx1 > $idx) {
                                    data_entry_helper::$javascript .= "    filterReset" . $idx1 . "();\n";
                                }
                            }
                            data_entry_helper::$javascript .= "  if(jQuery(this).val()!=''){\n";
                            foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                if ($idx1 > $idx) {
                                    data_entry_helper::$javascript .= "    filterLoad" . $idx1 . "();\n";
                                }
                            }
                            data_entry_helper::$javascript .= "  }\n  displayShape(true);\n});\n";
                            $defaultsFunction .= "  if(keepFilter){\n    jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val(jQuery('#filterSelect" . $idx . "').val());\n  } else {\n    jQuery('#filterSelect" . $idx . "').val('');\n  }\n";
                            $loadFunction .= "  jQuery('#filterSelect" . $idx . "').val(jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val());\ndisplayShape(false);\n";
                            $prevFilterAttr = $filterAttr;
                            $prevAttr = $attr;
                            $prevIdx = $idx;
                            break;
                        case "Name":
                            //special case:
                            $retVal .= '<fieldset><legend>' . lang::get('Existing locations') . '</legend><label>' . $options['FilterNameLabel'] . ':</label> ' . '<select id="' . $options['MainFieldID'] . '" name="' . $options['MainFieldName'] . '" disabled="disabled">' . '<option value="">' . lang::get("None") . '</option>' . (array_key_exists($options['MainFieldName'], data_entry_helper::$entity_to_load) && data_entry_helper::$entity_to_load[$options['MainFieldName']] != "" ? '<option value="' . data_entry_helper::$entity_to_load[$options['MainFieldName']] . '" selected="selected">' . data_entry_helper::$entity_to_load['location:name'] . '</option>' : '') . '</select><br/></fieldset>';
                            // when a field is changed on the drop down, all following ones are reset.
                            // filterLoad function creates the drop down, based on filters. Assumes all filters are filled in - if not then sets to current value.
                            // the existing locations filter drop down runs the location ID. the site name is the location name.
                            data_entry_helper::$javascript .= "\n// when " . $options['MainFieldID'] . " changes the location will be loaded, including " . $options['MainFieldName'] . "\nfilterLoad" . $idx . " = function(){\n  jQuery('#location-name').data('newValue','');\n  if(jQuery('#" . $options['MainFieldID'] . "').val() != '' && jQuery('#" . $options['MainFieldID'] . "').val() != null)\n    jQuery('#" . $options['MainFieldID'] . "').data('storedValue',jQuery('#" . $options['MainFieldID'] . "').val())\n      .data('storedCaption',jQuery('#" . $options['MainFieldID'] . "').find(':selected')[0].text);\n  else\n    jQuery('#" . $options['MainFieldID'] . "').data('storedValue','').data('storedCaption','ERROR');\n  if(";
                            $condition = '';
                            foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                if ($idx1 >= $idx) {
                                    continue;
                                }
                                $filterAttr1 = explode(':', $filterAttr1);
                                foreach ($locationAttributes as $locationAttribute1) {
                                    if ($filterAttr1[0] == "Parent") {
                                        if ($filterAttr1[1] == "true") {
                                            $condition .= ($condition == '' ? '' : ' || ') . "jQuery('#location\\\\:parent_id').val()== ''";
                                        }
                                    } else {
                                        if ($locationAttribute1['untranslatedCaption'] == ($filterAttr1[0] == "Shape" ? $filterAttr1[1] : $filterAttr1[0])) {
                                            $condition .= ($condition == '' ? '' : ' || ') . "jQuery('#locAttr\\\\:" . $locationAttribute1['attributeId'] . "').val()== ''";
                                        }
                                    }
                                }
                            }
                            data_entry_helper::$javascript .= $condition . "){\n\tif(jQuery('#" . $options['MainFieldID'] . "').data('storedValue')==null || jQuery('#" . $options['MainFieldID'] . "').data('storedValue')=='')\n      jQuery('#" . $options['MainFieldID'] . "').empty().attr('disabled','disabled').append('<option value=\"\">" . lang::get("First fill in filter options above") . "</option>');\n    else\n      jQuery('#" . $options['MainFieldID'] . "').empty().append('<option selected=\"selected\" value=\"'+jQuery('#" . $options['MainFieldID'] . "').data('storedValue')+'\">'+jQuery('#" . $options['MainFieldID'] . "').data('storedCaption')+'</option>');\n    return;\n  }\n  parent_id=jQuery('[name=location\\\\:parent_id]');\n  if(parent_id.length!=0) parent_id=parent_id.val();\n  // work out new name value: ignores shape attribute and parent_id. options for drop down\n  for(i=0, newName = 1, results=[]; i<locations.length; i++){\n    match=true;\n    for(j=0; j<location_attrs.length; j++)\n      if(jQuery('#locAttr\\\\:'+location_attrs[j].id).val()!=locations[i].attrs[location_attrs[j].id]) match=false;\n    if(match && parseInt(locations[i].name)>=newName) newName=parseInt(locations[i].name)+1;\n    if(typeof indiciaData.filterParent != 'undefined' && locations[i].parent_id!=parent_id) match=false;\n    if(match) results.push(locations[i]);\n  }\n  jQuery('#location-name').data('newValue',newName);\n  if(jQuery('#location-name').val()=='' && (jQuery('#location-id').val()=='' || jQuery('#location-id').val()==null)) jQuery('#location-name').val(newName);\n  // next work out existing sites list\n  jQuery('#" . $options['MainFieldID'] . "').empty(); // clear list\n  var stored = jQuery('#" . $options['MainFieldID'] . "').data('storedValue');\n  if(results.length>0) {\n    jQuery('#" . $options['MainFieldID'] . "').removeAttr('disabled').append('<option value=\"\">" . lang::get("Please select...") . "</option>');\n    for (var i=0;i<results.length;i++)\n      jQuery('#" . $options['MainFieldID'] . "').append('<option value=\"'+results[i].id+'\">'+results[i].name+'</option>');\n    if(stored!=null && stored!=''){\n      if(jQuery('#" . $options['MainFieldID'] . "').find('option').filter('[value='+stored+']').length>0){\n        jQuery('#" . $options['MainFieldID'] . "').val(stored);\n      } else {\n        jQuery('#" . $options['MainFieldID'] . "').prepend('<option selected=\"selected\" value=\"'+stored+'\">'+jQuery('#" . $options['MainFieldID'] . "').data('storedCaption')+'</option>');\n      }\n    }\n  } else {\n    if(stored!=null && stored!='')\n      jQuery('#" . $options['MainFieldID'] . "').prepend('<option selected=\"selected\" value=\"'+stored+'\">'+jQuery('#" . $options['MainFieldID'] . "').data('storedCaption')+'</option>');\n    else\n      jQuery('#" . $options['MainFieldID'] . "').attr('disabled','disabled').empty().append('<option value=\"\">" . lang::get("None available") . "</option>');\n  }\n  var options=\$('#location-name option');\n  if(options.length>0){\n    options.removeAttr('disabled');\n    options.not(':selected').each(function(idx,elem){\n      if(results.length>0) {\n        for (var i=0;i<results.length;i++){\n          if(results[i].name == elem.value) \$(elem).attr('disabled','disabled');\n        }\n      }});\n  }\n};\nfilterReset" . $idx . " = function(){\n  // filterResets also clear the main field. \n  jQuery('#" . $options['MainFieldID'] . "').empty().attr('disabled','disabled').append('<option value=\"\">" . lang::get("First fill in filter options above") . "</option>');\n  jQuery('#location-name').data('newValue','');\n};";
                            if (array_key_exists('location:id', data_entry_helper::$entity_to_load) && data_entry_helper::$entity_to_load['location:id'] != "") {
                                $initFunctions .= "\nfilterLoad" . $idx . "(true);";
                            } else {
                                $initFunctions .= "\nfilterReset" . $idx . "();";
                            }
                            // $defaultsFunction .= "  jQuery('#location-name').val(jQuery('#location-name').data('newValue'));\n";
                            $defaultsFunction .= "  filterLoad" . $idx . "(true)\n";
                            $loadFunction .= "  filterLoad" . $idx . "(true);\n";
                            break;
                        default:
                            $attr['class'] = (isset($attr['class']) ? $attr['class'] . " " : "") . "filterFields";
                            $ctrl = data_entry_helper::outputAttribute($attr, array('class' => "filterFields")) . '<span id="filter' . $idx . '"><label class="auto-width">' . lang::get("or pick one previously used") . ':</label> ' . '<select id="filterSelect' . $idx . '" ></select></span>';
                            $retVal .= str_replace('<br/>', '', $ctrl) . '<br />';
                            $attrList[] = array('id' => $attr['attributeId'], 'shape' => false);
                            if (count($filterAttr) > 1) {
                                data_entry_helper::add_resource('json');
                                data_entry_helper::add_resource('autocomplete');
                                data_entry_helper::$javascript .= "\njQuery('#locAttr\\\\:" . $attr['attributeId'] . "').autocomplete('" . data_entry_helper::$base_url . "/index.php/services/data/termlists_term', {\n      extraParams : {\n        view : 'detail',\n        orderby : 'term',\n        mode : 'json',\n        qfield : 'term',\n        auth_token: '" . $auth['read']['auth_token'] . "',\n        nonce: '" . $auth['read']['nonce'] . "',\n        termlist_id: '" . $filterAttr[1] . "'\n      },\n      max: 10000,\n      mustMatch : true,\n      parse: function(data) {\n        var results = [];\n        jQuery.each(data, function(i, item) {\n          results[results.length] = {'data' : item,'result' : item.term,'value' : item.term};\n        });\n        return results;\n      },\n      formatItem: function(item) {return item.term;}\n  });\njQuery('#locAttr\\\\:" . $attr['attributeId'] . "').result(function(data,value){\n  jQuery(this).change();\n});";
                            }
                            data_entry_helper::$javascript .= "\njQuery('#filterSelect" . $idx . "').change(function(){\n  jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').data('store',jQuery('#filterSelect" . $idx . "').val()).val(jQuery('#filterSelect" . $idx . "').val());\n  SetFilterNewLocation();\n  if(jQuery(this).val()==''){\n";
                            foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                if ($idx1 > $idx) {
                                    data_entry_helper::$javascript .= "    filterReset" . $idx1 . "();\n";
                                }
                            }
                            data_entry_helper::$javascript .= "  } else {\n";
                            foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                if ($idx1 > $idx) {
                                    data_entry_helper::$javascript .= "    filterLoad" . $idx1 . "();\n";
                                }
                            }
                            data_entry_helper::$javascript .= "  }});\n\njQuery('#locAttr\\\\:" . $attr['attributeId'] . "').data('store',jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val()).change(function(){\n  jQuery(this).data('store',jQuery(this).val());\n  if(jQuery(this).val()=='') {\n    jQuery('#filterSelect" . $idx . "').val('');\n";
                            foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                if ($idx1 > $idx) {
                                    data_entry_helper::$javascript .= "    filterReset" . $idx1 . "();\n";
                                }
                            }
                            data_entry_helper::$javascript .= "    } else {\n    if(jQuery('#filterSelect" . $idx . "').find('option').filter('[value='+jQuery(this).val()+']').length>0)\n      jQuery('#filterSelect" . $idx . "').val(jQuery(this).val());\n    else\n      jQuery('#filterSelect" . $idx . "').val('');\n";
                            foreach ($filterAttrs as $idx1 => $filterAttr1) {
                                if ($idx1 > $idx) {
                                    data_entry_helper::$javascript .= "    filterLoad" . $idx1 . "();\n";
                                }
                            }
                            data_entry_helper::$javascript .= "  }});\n\n// loads in the drop down list for a filter attribute.\n// Triggered in several places: when the filter above changes value\nfilterLoad" . $idx . " = function(){\n  var match, results, results1;\n  var id=jQuery('#" . $options['MainFieldID'] . "').val();\n  if(checkEditable(id=='',id))\n    jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').removeAttr('disabled');\n  parent_id=jQuery('[name=location\\\\:parent_id]');\n  if(parent_id.length!=0) parent_id=parent_id.val();\n  for(i=0, results=[]; i<locations.length; i++){\n    match=true;\n    if(typeof indiciaData.filterParent != 'undefined' && locations[i].parent_id!=parent_id) match=false;\n    for(j=0; j<location_attrs.length; j++) {\n      if(location_attrs[j].id==" . $attr['attributeId'] . ") break;\n      if(jQuery('#locAttr\\\\:'+location_attrs[j].id).val()!=locations[i].attrs[location_attrs[j].id]) match=false;\n    }\n    if(match) results.push(locations[i].attrs[\"" . $attr['attributeId'] . "\"]);\n  }\n  jQuery('#filterSelect" . $idx . "').empty();\n  if(results.length>0) {\n    results.sort();\n    for(i=1, results1=[results[0]]; i<results.length; i++)\n      if(results[i]!=results[i-1]) results1.push(results[i]);\n    jQuery('#filter" . $idx . "').show();\n    jQuery('#filterSelect" . $idx . "').append('<option value=\"\">" . lang::get("Please select...") . "</option>');\n    for (var i=0;i<results1.length;i++){\n      // for each results, need to work out count of matching locations.\n      for(var k=0, count=0; k<locations.length; k++){\n        match=true;\n        if(typeof indiciaData.filterParent != 'undefined' && locations[k].parent_id!=parent_id) match=false;\n        for(var j=0; j<location_attrs.length; j++) {\n          if(location_attrs[j].id==" . $attr['attributeId'] . ") {\n            if(locations[k].attrs[location_attrs[j].id]!=results1[i]) match=false;\n            break;\n          }\n          if(jQuery('#locAttr\\\\:'+location_attrs[j].id).val()!=locations[k].attrs[location_attrs[j].id]) match=false;\n        }\n        if(match) count++;\n      }\n      jQuery('#filterSelect" . $idx . "').append('<option value=\"'+results1[i]+'\" '+(results1[i] == jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val() ? 'selected=\"selected\"' : '')+'>'+results1[i]+' ('+count+')'+'</option>');\n    }\n  } else\n    jQuery('#filter" . $idx . "').hide();\n};\nfilterReset" . $idx . " = function(){\n  jQuery('#locAttr\\\\:" . $attr['attributeId'] . "').val('');\n  filterLoad" . $idx . "();\n};";
                            if (array_key_exists('location:id', data_entry_helper::$entity_to_load) && data_entry_helper::$entity_to_load['location:id'] != "") {
                                $initFunctions .= "\nfilterLoad" . $idx . "();";
                            } else {
                                $initFunctions .= "\nfilterReset" . $idx . "();";
                            }
                            $defaultsFunction .= "  filterLoad" . $idx . "();\n";
                            $loadFunction .= "  filterLoad" . $idx . "();\n";
                            $prevFilterAttr = $filterAttr;
                            $prevAttr = $attr;
                            $prevIdx = $idx;
                            break;
                    }
                }
                $creatorAttr = iform_mnhnl_getAttrID($auth, $args, 'location', 'Creator');
                global $user;
                if ($creatorAttr) {
                    $defaultsFunction .= "  jQuery('#locAttr\\:" . $creatorAttr . "').val('" . $user->name . "');\n";
                }
                $communeAttr = iform_mnhnl_getAttrID($auth, $args, 'location', 'Commune');
                if (!(isset($args['communeLayerLookup']) && $args['communeLayerLookup'] != '') || !$communeAttr) {
                    $includeCommune = false;
                } else {
                    $parts = explode(',', $args['communeLayerLookup']);
                }
                data_entry_helper::$javascript .= "\nSetFilterNewLocation = function(){\n  var id=jQuery('#" . $options['MainFieldID'] . "').val();\n  if(checkEditable(id=='',id)) return;\n  setPermissionsNewSite();\n  clearLocation(true,'maybe');\n};\nhook_set_defaults = function(keepFilter){\n" . $defaultsFunction . "\n};\n" . $loadFunction . "\n};\nhook_setSref = function(geom){ // geom is in map projection.\n  jQuery('#map').ajaxStop(function(event){\n";
                if ($includeCommune) {
                    data_entry_helper::$javascript .= "\n  jQuery('[name=locAttr\\:{$communeAttr}],[name^=locAttr\\:{$communeAttr}\\:]').val('');\n  var communeProtocol = new OpenLayers.Protocol.WFS({\n      url:  '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $parts[0]) . "',\n      featurePrefix: '" . $parts[1] . "',\n      featureType: '" . $parts[2] . "',\n      geometryName:'" . $parts[3] . "',\n      featureNS: '" . $parts[4] . "',\n      srsName: '" . $parts[5] . "',\n      version: '1.1.0',\n      propertyNames: ['" . $parts[6] . "']\n     ,callback: function(a1){\n        if(a1.error && (typeof a1.error.success == 'undefined' || a1.error.success == false)){\n          alert(\"" . lang::get('LANG_CommuneLookUpFailed') . "\");\n          return;\n        }\n        if(a1.features.length > 0) {\n          jQuery('[name=locAttr\\:{$communeAttr}],[name^=locAttr\\:{$communeAttr}\\:]').val(a1.features[0].attributes[\"" . $parts[6] . "\"]);\n        } else {\n";
                    if (!isset($args['communeLayerBuffer']) || $args['communeLayerBuffer'] == "") {
                        // No buffer in definition
                        data_entry_helper::$javascript .= "          alert(\"" . lang::get('LANG_PositionOutsideCommune_1') . "\");\n";
                    } else {
                        // buffer set
                        data_entry_helper::$javascript .= "          //  Get list of communes within buffer of geom\n          var protocol = new OpenLayers.Protocol.WFS({\n              url:  '" . $parts[0] . "',featurePrefix: '" . $parts[1] . "',featureType: '" . $parts[2] . "',geometryName:'" . $parts[3] . "',featureNS: '" . $parts[4] . "',srsName: '" . $parts[5] . "',version: '1.1.0',propertyNames: [\"" . $parts[6] . "\"]\n             ,callback: function(a1){\n                var replace = false,\n                    reset = false;\n                if(a1.error && (typeof a1.error.success == 'undefined' || a1.error.success == false)){\n                  alert(\"" . lang::get('LANG_CommuneLookUpFailed') . "\");\n                  return;\n                }\n                if(a1.features.length == 0) {\n                  alert(\"" . str_replace('{DISTANCE}', $args['communeLayerBuffer'], lang::get('LANG_PositionOutsideCommune_3')) . "\");\n                } else {\n                  var closest = 0;\n                  if(a1.features.length >= 0) {\n                    for(var i=0; i< a1.features.length; i++){\n                      var distance, thisDistance = geom.distanceTo(a1.features[i].geometry, {});\n                      if(i==0 || thisDistance<distance){\n                        closest=i;\n                        distance=thisDistance;\n                      }\n                    }\n                  }\n                  alert(\"" . lang::get('LANG_PositionOutside' . $filterAttr[1] . "_5A") . "\".replace(/SHAPE/g, a1.features[closest].attributes['" . $parts[6] . "']));\n                  jQuery('[name=locAttr\\:{$communeAttr}],[name^=locAttr\\:{$communeAttr}\\:]').val(a1.features[closest].attributes[\"" . $parts[6] . "\"]);\n                }\n              }\n          });\n          var filter = new OpenLayers.Filter.Spatial({type: OpenLayers.Filter.Spatial.DWITHIN, property: '" . $parts[3] . "', value: geom, distance: '" . $args['communeLayerBuffer'] . "'});\n          protocol.read({filter: filter});\n";
                    }
                    data_entry_helper::$javascript .= "        }\n      }\n  });\n  var filter = new OpenLayers.Filter.Spatial({type: OpenLayers.Filter.Spatial.CONTAINS,property: '" . $parts[3] . "',value: geom});\n  communeProtocol.read({filter: filter});\n";
                }
                foreach ($filterAttrs as $idx => $filterAttr) {
                    $filterAttr = explode(':', $filterAttr);
                    if ($filterAttr[0] == "Parent" || $filterAttr[0] == "Shape") {
                        data_entry_helper::$javascript .= "    hook_setSref_" . $idx . "(geom);\n";
                    }
                    // map projection
                }
                $locAttrText = array();
                foreach ($attrList as $filterAttr) {
                    $locAttrText[] = "  {'id':'" . $filterAttr['id'] . "', 'shape':" . ($filterAttr['shape'] ? 'true' : 'false') . "}";
                }
                data_entry_helper::$javascript .= "    \$(this).unbind(event);\n  });\n};\nlocation_attrs = [" . implode(",\n", $locAttrText) . "];";
                if ($includeCommune) {
                    data_entry_helper::$javascript .= "jQuery('[name=locAttr\\:{$communeAttr}],[name^=locAttr\\:{$communeAttr}\\:]').attr('readonly','readonly');\n";
                }
                if (isset($args['autoGenSiteName']) && $args['autoGenSiteName']) {
                    $retVal .= "<label for=\"location-name\">" . $options['NameLabel'] . ":</label> <input type='text' id=\"location-name\" name=\"location:name\" " . ($options['AdminMode'] ? "class='required integer' min='1'" : "class='required' readonly='readonly'") . " value=\"" . htmlspecialchars(data_entry_helper::$entity_to_load['location:name']) . "\" /><span class='deh-required'>*</span><br/>";
                } else {
                    if ($args['siteNameTermListID'] == '') {
                        $retVal .= "<label for=\"location-name\">" . $options['NameLabel'] . ":</label> <input type='text' id=\"location-name\" name=\"location:name\" class='wide required' value=\"" . htmlspecialchars(data_entry_helper::$entity_to_load['location:name']) . "\" /><span class='deh-required'>*</span><br/>";
                    } else {
                        $retVal .= data_entry_helper::select(array('label' => $options['NameLabel'], 'id' => 'location-name', 'fieldname' => 'location:name', 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'term', 'blankText' => '', 'validation' => array('required'), 'extraParams' => $auth['read'] + array('termlist_id' => $args['siteNameTermListID'], 'orderby' => 'id')));
                    }
                }
                data_entry_helper::$javascript .= $initFunctions;
                $retVal .= "<input type='hidden' id=\"sample-location-id\" name=\"sample:location_id\" value='" . data_entry_helper::$entity_to_load['sample:location_id'] . "' />";
            }
        }
    }
    if (isset($args['includeLocationCode']) && $args['includeLocationCode']) {
        $retVal .= "<label for=\"location-code\">" . $options['CodeLabel'] . ":</label> <input id=\"location-code\" class=\"integer\" min=1 name=\"location:code\" value=\"" . htmlspecialchars(data_entry_helper::$entity_to_load['location:code']) . "\" dbCode=\"" . htmlspecialchars(data_entry_helper::$entity_to_load['location:code']) . "\"><br />";
    }
    // Move any Attribute fields side by side.
    if (isset($args['removeBreakLocAttrIDs']) && $args['removeBreakLocAttrIDs'] != "") {
        $removeBreakLocAttrIDs = explode(':', $args['removeBreakLocAttrIDs']);
        foreach ($removeBreakLocAttrIDs as $removeBreakLocAttrID) {
            data_entry_helper::$javascript .= "\njQuery('[name=locAttr\\:" . $removeBreakLocAttrID . "],[name^=locAttr\\:" . $removeBreakLocAttrID . "\\:]').css('margin-right', '20px').nextAll('br').eq(0).remove();";
        }
    }
    return $retVal;
}
Ejemplo n.º 18
0
 /**
  * Get the location module control
  */
 protected static function get_control_locationmodule($auth, $args, $tabalias, $options)
 {
     global $indicia_templates, $user;
     // have to override the name of the imp-geom to point to the location centroid_geometry
     $smpAttributes = 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']));
     foreach ($smpAttributes as $attrId => $attr) {
         if (strcasecmp($attr['caption'], 'CMS User ID') == 0) {
             $userIdAttr = $attrId;
         }
     }
     $locAttributes = data_entry_helper::getAttributes(array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']));
     foreach ($locAttributes as $attrId => $attr) {
         if (strcasecmp($attr['untranslatedCaption'], 'village') == 0) {
             $villageAttr = $attrId;
         } else {
             if (strcasecmp($attr['untranslatedCaption'], 'commune') == 0) {
                 $communeAttr = $attrId;
             }
         }
     }
     if (!isset($villageAttr)) {
         return lang::get('This form must be used with a survey that has the Village Location attribute associated with it.');
     }
     if (!isset($communeAttr)) {
         return lang::get('This form must be used with a survey that has the Commune Location attribute associated with it.');
     }
     // at this point the entity to load either holds location data if there has been an error, or needs
     // to be populated with it.
     // we are assuming no loctools.
     if (array_key_exists('sample:location_id', data_entry_helper::$entity_to_load) && !array_key_exists('location:id', data_entry_helper::$entity_to_load)) {
         data_entry_helper::load_existing_record($auth['read'], 'location', data_entry_helper::$entity_to_load['sample:location_id']);
         // next two are a bit of a bodge to get map control to display initial feature from location table
         // the sample:wkt and sample:geom should not be passed through to POST.
         data_entry_helper::$entity_to_load['location:geom'] = data_entry_helper::$entity_to_load['location:centroid_geom'];
         data_entry_helper::$entity_to_load['sample:geom'] = data_entry_helper::$entity_to_load['location:centroid_geom'];
         data_entry_helper::$entity_to_load['sample:wkt'] = data_entry_helper::$entity_to_load['location:centroid_geom'];
     }
     // self::add_resource('json');
     $location_list_args = array_merge(array('nocache' => true, 'includeCodeField' => true, 'NameLabel' => lang::get('LANG_Location_Name_Label'), 'NameBlankText' => lang::get('LANG_Location_Name_Blank_Text'), 'NameFieldName' => 'dummy:location_name_DD', 'NameID' => 'imp-location-name', 'view' => 'detail', 'extraParams' => array_merge(array('orderby' => 'name', 'website_id' => $args['website_id']), $auth['read']), 'table' => 'location', 'template' => 'select', 'itemTemplate' => 'select_item', 'filterField' => 'parent_id', 'size' => 3), $options);
     if (array_key_exists('location_type_id', $options)) {
         $location_list_args['extraParams'] += array('location_type_id' => $options['location_type_id']);
     }
     // Idea here is to get a list of all locations in order to build drop downs.
     // control used can be configured on Indicia
     $responseRecords = data_entry_helper::get_population_data($location_list_args);
     // The way this will work: have 2 drop downs: code and name. Doesn't matter what they are set to
     // investigate self::init_linked_lists($options);
     if (isset($responseRecords['error'])) {
         return $responseRecords['error'];
     }
     $attributeRecords = array(array());
     $attribute_list_args = array_merge(array('nocache' => true, 'view' => 'list', 'extraParams' => array_merge(array('orderby' => 'name', 'website_id' => $args['website_id']), $auth['read']), 'table' => 'location_attribute_value'), $options);
     $attributeResponse = data_entry_helper::get_population_data($attribute_list_args);
     foreach ($attributeResponse as $record) {
         $attributeRecords[$record['location_id']][$record['location_attribute_id']] = $record;
     }
     $NameOpts = '';
     foreach ($responseRecords as $record) {
         if ($record['name'] != '') {
             $item = array('selected' => array_key_exists('location:id', data_entry_helper::$entity_to_load) && data_entry_helper::$entity_to_load['location:id'] == $record['id'] ? 'selected' : '', 'value' => $record['id'], 'caption' => $record['name'] . ' (' . (isset($attributeRecords[$record['id']][$communeAttr]['text_value']) ? $attributeRecords[$record['id']][$communeAttr]['text_value'] : '-') . ' / ' . (isset($attributeRecords[$record['id']][$villageAttr]['text_value']) ? $attributeRecords[$record['id']][$villageAttr]['text_value'] : '-') . ') n° ' . ($record['code'] != '' ? $record['code'] : '-'));
             $NameOpts .= data_entry_helper::mergeParamsIntoTemplate($item, $location_list_args['itemTemplate']);
         }
     }
     $r = '<fieldset><legend>' . lang::get('Existing Locations') . '</legend><input type="hidden" id="imp-location" name="location:id" value="' . (array_key_exists('location:id', data_entry_helper::$entity_to_load) ? data_entry_helper::$entity_to_load['location:id'] : '') . '" >';
     if ($NameOpts != '') {
         $location_list_args['label'] = $location_list_args['NameLabel'];
         $location_list_args['fieldname'] = $location_list_args['NameFieldName'];
         $location_list_args['id'] = $location_list_args['NameID'];
         $location_list_args['items'] = str_replace(array('{value}', '{caption}', '{selected}'), array('', htmlentities($location_list_args['NameBlankText'])), $indicia_templates[$location_list_args['itemTemplate']]) . $NameOpts;
         $r .= data_entry_helper::apply_template($location_list_args['template'], $location_list_args);
     }
     $isAdmin = user_access('IForm n' . $node->nid . ' admin');
     data_entry_helper::$javascript .= "\nsetLocationEditable = function(enableFields){\n  var enableItems;\n  var disableItems;\n  disableItems = '[name=location\\:id]" . ($isAdmin ? "" : ",[name=location\\:code]") . "'; //clearing the location so no ID, so disable \n  enableItems = '[name=locations_website\\:website_id]'; // but have to activate website record \n  if(!enableFields){\n    if(jQuery('#map')[0].map != undefined) jQuery('#map')[0].map.editLayer.clickControl.deactivate()\n    disableItems = disableItems + '" . ($isAdmin ? ",[name=location\\:code]" : "") . ",[name=location\\:name],[name=location\\:comment],[name^=locAttr\\:],#imp-sref-lat,#imp-sref-long,#imp-sref-system,#imp-geom';\n  } else {\n    if(jQuery('#map')[0].map != undefined) jQuery('#map')[0].map.editLayer.clickControl.activate()\n    enableItems = enableItems + '" . ($isAdmin ? ",[name=location\\:code]" : "") . ",[name=location\\:name],[name=location\\:comment],[name^=locAttr\\:],#imp-sref-lat,#imp-sref-long,#imp-sref-system,#imp-geom';\n  }\n  jQuery(enableItems).removeAttr('disabled');\n  jQuery(disableItems).attr('disabled',true);\n};\nclearLocation = function(){\n  jQuery('[name=location\\:id],[name=location\\:code],[name=location\\:name],[name=location\\:comment],#imp-sref,#imp-sref-lat,#imp-sref-long,#imp-geom').val('');\n  // first need to remove any hidden multiselect checkbox unclick fields\n  jQuery('[name^=locAttr\\:]').filter('.multiselect').remove();\n  // rename, to be safe, removing any [] at the end or any attribute value id\n  jQuery('[name^=locAttr\\:]').each(function(){\n    var name = jQuery(this).attr('name').split(':');\n    if(name[1].indexOf('[]') > 0) name[1] = name[1].substr(0, name[1].indexOf('[]'));\n    jQuery(this).attr('name', name[0]+':'+name[1]);\n  });\n  // Then add [] to multiple choice checkboxes.\n  jQuery('[name^=locAttr\\:]').filter(':checkbox').removeAttr('checked').each(function(){\n    var myName = jQuery(this).attr('name').split(':');\n    var similar = jQuery('[name='+myName[0]+'\\:'+myName[1]+'],[name='+myName[0]+'\\:'+myName[1]+'\\[\\]]').filter(':checkbox');\n    if(similar.length > 1)\n      jQuery(this).attr('name', myName[0]+':'+myName[1]+'[]');\n  });\n  // radio buttons all share the same name, only one checked.\n  jQuery('[name^=locAttr\\:]').filter(':radio').removeAttr('checked');\n  // checkboxes are all unchecked\n  // boolean checkboxes have extra field to force zero if unselected, but there are no attributes of that type in use for this form at the moment, so leave uncoded.\n  jQuery('[name^=locAttr\\:]').filter(':text').val('');\n  checkRadioStatus();\n};\nloadLocation = function(myValue){\n  if (myValue!=='') {\n    // Change the location control requests the location's geometry to place on the map.\n    jQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/data/sample?location_id='+myValue +\n            '&mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&callback=?', function(sdata) {\n      " . ($isAdmin ? "" : "\n      // Count returns: normal bods can edit provided that they encoded all samples on this location.\n      if (sdata instanceof Array && sdata.length>0) {\n        var sampleList=[];\n        for (var i=0;i<sdata.length;i++)\n          sampleList.push(sdata[i].id);\n        jQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/data/sample_attribute_values' +\n            '?mode=json&view=list&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&callback=?&sample_attribute_id={$userIdAttr}&query='+escape(JSON.stringify({'in': ['sample_id', sampleList]})), function(sadata) {\n          if (sadata instanceof Array && sadata.length>0) {\n            for (var i=0;i<sadata.length;i++)\n              if(sadata[i].value != " . $user->uid . ") return;\n            setLocationEditable(true);\n          }});\n      }") . "\n      jQuery('[name=location\\:id]').val(myValue).removeAttr('disabled');\n      jQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/data/location/'+myValue +\n            '?mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&callback=?', function(data) {\n       // store value in saved field?\n       if (data instanceof Array && data.length>0) {\n        jQuery('[name=location\\:code]').val(data[0].code);\n        jQuery('[name=location\\:name]').val(data[0].name);\n        jQuery('[name=location\\:comment]').val(data[0].comment);\n        jQuery('#imp-sref-system').val(data[0].centroid_sref_system);\n        jQuery('#imp-geom').val(data[0].centroid_geom);\n        jQuery('#imp-sref').val(data[0].centroid_sref);\n        var refxy = data[0].centroid_sref.split(' ');\n        var refx = refxy[0].split(',');\n        jQuery('#imp-sref-lat').val(refx[0]);\n        jQuery('#imp-sref-long').val(refxy[1]).change();\n        jQuery('[name=locations_website\\:website_id]').attr('disabled','disabled');\n       }\n      });\n      jQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/data/location_attribute_value' +\n            '?mode=json&view=list&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&location_id='+myValue+'&callback=?', function(data) {\n       if(data instanceof Array && data.length>0){\n        for (var i=0;i<data.length;i++){\n          if (data[i].id) { // && (data[i].iso == null || data[i].iso == '' || data[i].iso == '" . $language . "')\n            var radiobuttons = jQuery('[name=locAttr\\:'+data[i]['location_attribute_id']+'],[name^=locAttr\\:'+data[i]['location_attribute_id']+'\\:]').filter(':radio');\n            var multicheckboxes = jQuery('[name=locAttr\\:'+data[i]['location_attribute_id']+'\\[\\]],[name^=locAttr\\:'+data[i]['location_attribute_id']+':]').filter(':checkbox');\n            // at the moment there are no boolean checkboxes so don't code for them\n            if(radiobuttons.length > 0){ // radio buttons all share the same name, only one checked.\n              radiobuttons.attr('name', 'locAttr:'+data[i]['location_attribute_id']+':'+data[i].id)\n                  .filter('[value='+data[i].raw_value+']').attr('checked', 'checked');\n            } else if(multicheckboxes.length > 0){ // individually named\n              multicheckboxes = multicheckboxes.filter('[value='+data[i].raw_value+']')\n                        .attr('name', 'locAttr:'+data[i]['location_attribute_id']+':'+data[i].id).attr('checked', 'checked');\n              multicheckboxes.each(function(){\n                jQuery('<input type=\"hidden\" value=\"0\" class=\"multiselect\" >').attr('name', jQuery(this).attr('name')).insertBefore(this);\n              });\n            } // at the moment there are no boolean checkboxes so don't code for them\n            else {\n              jQuery('[name=locAttr\\:'+data[i]['location_attribute_id']+']')\n                      .attr('name', 'locAttr:'+data[i]['location_attribute_id']+':'+data[i].id).val(data[i].raw_value);\n            }\n          }\n        }\n       }\n       checkRadioStatus();\n      });\n    });\n  } else\n    setLocationEditable(false);\n};\njQuery('#imp-location-name').change(function(){\n  var myValue = jQuery('#imp-location-name').val();\n  jQuery('#imp-location').val(myValue).change();\n  clearLocation();\n  setLocationEditable(" . ($isAdmin ? "true" : "false") . ");\n  loadLocation(myValue);\n  });\nnewLocation = function(){\n  jQuery('#imp-location').val('').change();\n  jQuery('#imp-location').attr('disabled');\n  jQuery('#imp-location-name').val('');\n  clearLocation();\n  setLocationEditable(true);\n};\njQuery('#imp-location').change(function(){\n  jQuery('#imp-location').removeAttr('disabled');\n});\n";
     if (array_key_exists('sample:id', data_entry_helper::$entity_to_load)) {
         if ($isAdmin || !array_key_exists('sample:location_id', data_entry_helper::$entity_to_load)) {
             // existing sample, either admin or not existing location (validation error situation)
             data_entry_helper::$onload_javascript .= "\nsetLocationEditable(true);";
         } else {
             data_entry_helper::$onload_javascript .= "\nsetLocationEditable(false);\njQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/data/sample?location_id=" . data_entry_helper::$entity_to_load['sample:location_id'] . "' +\n            '&mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&callback=?', function(sdata) {\n      // Count returns: normal bods can edit provided that they encoded all samples on this location.\n      if (sdata instanceof Array && sdata.length>0) {\n        var sampleList=[];\n        for (var i=0;i<sdata.length;i++)\n          sampleList.push(sdata[i].id);\n        jQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/data/sample_attribute_values' +\n            '?mode=json&view=list&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&callback=?&sample_attribute_id={$userIdAttr}&query='+escape(JSON.stringify({'in': ['sample_id', sampleList]})), function(sadata) {\n          if (sadata instanceof Array && sadata.length>0) {\n            for (var i=0;i<sadata.length;i++)\n              if(sadata[i].value != " . $user->uid . ") return;\n            setLocationEditable(true);\n          }});\n      }})\n      ";
         }
     } else {
         // newSample
         if (self::$mode == 1) {
             // newSample mode rather than error situation
             data_entry_helper::$onload_javascript .= "\nclearLocation();\nsetLocationEditable(false);";
         } else {
             if ($isAdmin || !array_key_exists('sample:location_id', data_entry_helper::$entity_to_load)) {
                 data_entry_helper::$onload_javascript .= "\nsetLocationEditable(true);";
             } else {
                 data_entry_helper::$onload_javascript .= "\nsetLocationEditable(false);\njQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/data/sample?location_id=" . data_entry_helper::$entity_to_load['sample:location_id'] . "' +\n            '&mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&callback=?', function(sdata) {\n      // Count returns: normal bods can edit provided that they encoded all samples on this location.\n      if (sdata instanceof Array && sdata.length>0) {\n        var sampleList=[];\n        for (var i=0;i<sdata.length;i++)\n          sampleList.push(sdata[i].id);\n        jQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/data/sample_attribute_values' +\n            '?mode=json&view=list&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&callback=?&sample_attribute_id={$userIdAttr}&query='+escape(JSON.stringify({'in': ['sample_id', sampleList]})), function(sadata) {\n          if (sadata instanceof Array && sadata.length>0) {\n            for (var i=0;i<sadata.length;i++)\n              if(sadata[i].value != " . $user->uid . ") return;\n            setLocationEditable(true);\n          }});\n      }})";
             }
         }
     }
     $r .= '<input type="button" value="' . lang::get('Create New Location') . '" onclick="newLocation();">' . '<input type="hidden" id="locations_website:website_id" name="locations_website:website_id" value="' . $args['website_id'] . '" disabled="' . (array_key_exists('location:id', data_entry_helper::$entity_to_load) ? 'disabled' : '') . '" />' . '</fieldset>' . '<label for="location:name">' . lang::get('LANG_Location_Name_Label') . ':</label>' . '<input type="text" id="location:name" name="location:name" class="required" value="' . data_entry_helper::$entity_to_load['location:name'] . '" /><span class="deh-required">*</span><br/>';
     if ($location_list_args['includeCodeField']) {
         $r .= '<label for="location:code">' . lang::get('LANG_Location_Code_Label') . ':</label><input type="text" id="location:code" name="location:code" disabled="disabled" value="' . data_entry_helper::$entity_to_load['location:code'] . '" /><br/>';
     }
     return $r;
 }
Ejemplo n.º 19
0
 protected static function getEntity($args, $auth)
 {
     data_entry_helper::$entity_to_load = array();
     if (!empty($_GET['zoom_id'])) {
         self::zoom_map_when_adding($auth['read'], 'location', $_GET['zoom_id']);
     } else {
         data_entry_helper::load_existing_record($auth['read'], 'location', $_GET['location_id'], 'detail', false, true);
     }
 }
Ejemplo n.º 20
0
 protected static function getEntity($args, $auth)
 {
     data_entry_helper::$entity_to_load = array();
     data_entry_helper::load_existing_record($auth['read'], 'person', $_GET['person_id'], 'detail', false, false);
 }
 private static function reload_form_data($loadedSampleId, $args, $auth)
 {
     $form_data = array();
     if (!$loadedSampleId) {
         // required
         return $form_data;
     }
     // load the sample
     data_entry_helper::load_existing_record($auth['read'], 'sample', $loadedSampleId);
     $form_data = array_merge(data_entry_helper::$entity_to_load, $form_data);
     // if we have a subject_observation, then we just load that,
     // otherwise we need all the subjects_observations in the sample
     $filter = array();
     if (count(self::$subjectObservationIds) === 1) {
         $filter = array('id' => self::$subjectObservationIds[0]);
         self::$subjectObservationIds = array();
     }
     // load the subject_observation(s) for this sample
     $options = array('table' => 'subject_observation', 'extraParams' => $auth['read'] + array('sample_id' => $loadedSampleId, 'view' => 'detail') + $filter, 'nocache' => true);
     $subjectObservations = data_entry_helper::get_population_data($options);
     // add each subject_observation to the form data
     for ($idx = 0; $idx < count($subjectObservations); $idx++) {
         $subjectObservation = $subjectObservations[$idx];
         self::$subjectObservationIds[] = $subjectObservation['id'];
         // prefix the keys and load to form data
         $fieldprefix = 'idn:' . $idx . ':subject_observation:';
         $keys = array_keys($subjectObservation);
         foreach ($keys as $key) {
             $form_data[$fieldprefix . $key] = $subjectObservation[$key];
         }
     }
     // load the subject_observation_attribute(s) for this sample
     $query = array('in' => array('subject_observation_id', self::$subjectObservationIds));
     $filter = array('query' => json_encode($query));
     $options = array('table' => 'subject_observation_attribute_value', 'extraParams' => $auth['read'] + $filter, 'nocache' => true);
     $sjoAttrs = data_entry_helper::get_population_data($options);
     // add each subject_observation_attribute to the form data
     for ($idx = 0; $idx < count($subjectObservations); $idx++) {
         $subjectObservation = $subjectObservations[$idx];
         // prefix the keys and load to form data
         $fieldprefix = 'idn:' . $idx . ':sjoAttr:';
         foreach ($sjoAttrs as $sjoAttr) {
             if ($sjoAttr['subject_observation_id'] === $subjectObservation['id']) {
                 if (!empty($sjoAttr['id'])) {
                     $form_data[$fieldprefix . $sjoAttr['subject_observation_attribute_id'] . ':' . $sjoAttr['id']] = $sjoAttr['raw_value'];
                 }
             }
         }
     }
     // load the occurrence(s) for this sample
     $query = array('in' => array('subject_observation_id', self::$subjectObservationIds));
     $filter = array('query' => json_encode($query));
     $options = array('table' => 'occurrences_subject_observation', 'extraParams' => $auth['read'] + array('view' => 'detail') + $filter, 'nocache' => true);
     $osos = data_entry_helper::get_population_data($options);
     $occurrenceIds = array();
     foreach ($osos as $oso) {
         $occurrenceIds[] = $oso['occurrence_id'];
     }
     $query = array('in' => array('id', $occurrenceIds));
     $filter = array('query' => json_encode($query));
     $options = array('table' => 'occurrence', 'extraParams' => $auth['read'] + array('view' => 'detail') + $filter, 'nocache' => true);
     $occurrences = data_entry_helper::get_population_data($options);
     $query = array('in' => array('occurrence_id', $occurrenceIds));
     $filter = array('query' => json_encode($query));
     $options = array('table' => 'occurrence_image', 'extraParams' => $auth['read'] + array('view' => 'list') + $filter, 'nocache' => true);
     $occurrence_images = data_entry_helper::get_population_data($options);
     // add each occurrence, occurrences_subject_observation and occurrence_image to the form data
     for ($idx = 0; $idx < count($subjectObservations); $idx++) {
         $subjectObservation = $subjectObservations[$idx];
         // note, this code would break with more than one occurrence on the subject_observation
         // fortunately, that can't happen with this form yet, but may do with associations?
         // prefix the keys and load to form data
         foreach ($osos as $oso) {
             if ($oso['subject_observation_id'] === $subjectObservation['id']) {
                 foreach ($occurrences as $occurrence) {
                     if ($oso['occurrence_id'] === $occurrence['id']) {
                         $fieldprefix = 'idn:' . $idx . ':occurrences_subject_observation:';
                         $keys = array_keys($oso);
                         foreach ($keys as $key) {
                             $form_data[$fieldprefix . $key] = $oso[$key];
                         }
                         $fieldprefix = 'idn:' . $idx . ':occurrence:';
                         $keys = array_keys($occurrence);
                         foreach ($keys as $key) {
                             $form_data[$fieldprefix . $key] = $occurrence[$key];
                             if ($key == 'taxon' && $args['species_ctrl'] == 'autocomplete') {
                                 $form_data[$fieldprefix . 'taxa_taxon_list_id:taxon'] = $occurrence[$key];
                             }
                         }
                     }
                 }
                 foreach ($occurrence_images as $occurrence_image) {
                     if ($oso['occurrence_id'] === $occurrence_image['occurrence_id']) {
                         $fieldprefix = 'idn:' . $idx . ':occurrence_image:';
                         $fieldsuffix = ':' . $occurrence_image['path'];
                         $keys = array_keys($occurrence_image);
                         foreach ($keys as $key) {
                             $form_data[$fieldprefix . $key . $fieldsuffix] = $occurrence_image[$key];
                         }
                     }
                 }
             }
         }
     }
     // load the identifiers_subject_observation(s) for this sample
     $query = array('in' => array('subject_observation_id', self::$subjectObservationIds));
     $filter = array('query' => json_encode($query));
     $options = array('table' => 'identifiers_subject_observation', 'extraParams' => $auth['read'] + array('view' => 'detail') + $filter, 'nocache' => true);
     $isos = data_entry_helper::get_population_data($options);
     // load the identifiers_subject_observation_attributes(s) for this sample
     $isoIds = array();
     foreach ($isos as $iso) {
         $isoIds[] = $iso['id'];
     }
     $query = array('in' => array('identifiers_subject_observation_id', $isoIds));
     $filter = array('query' => json_encode($query));
     $options = array('table' => 'identifiers_subject_observation_attribute_value', 'extraParams' => $auth['read'] + $filter, 'nocache' => true);
     $isoAttrs = data_entry_helper::get_population_data($options);
     // load the identifier(s) for this sample
     $identifierIds = array();
     foreach ($isos as $iso) {
         $identifierIds[] = $iso['identifier_id'];
     }
     $query = array('in' => array('id', $identifierIds));
     $filter = array('query' => json_encode($query));
     $options = array('table' => 'identifier', 'extraParams' => $auth['read'] + array('view' => 'detail') + $filter, 'nocache' => true);
     $identifiers = data_entry_helper::get_population_data($options);
     // load the identifier_attributes(s) for this sample
     $query = array('in' => array('identifier_id', $identifierIds));
     $filter = array('query' => json_encode($query));
     $options = array('table' => 'identifier_attribute_value', 'extraParams' => $auth['read'] + $filter, 'nocache' => true);
     $idnAttrs = data_entry_helper::get_population_data($options);
     // add each identifier to the form data
     for ($idx = 0; $idx < count($subjectObservations); $idx++) {
         $subjectObservation = $subjectObservations[$idx];
         // prefix the keys and load to form data
         foreach ($isos as $iso) {
             if ($iso['subject_observation_id'] === $subjectObservation['id']) {
                 foreach ($identifiers as $identifier) {
                     if ($iso['identifier_id'] === $identifier['id']) {
                         if ($identifier['identifier_type_id'] == $args['neck_collar_type']) {
                             $identifier_type = 'neck-collar';
                         } elseif ($identifier['identifier_type_id'] == $args['enscribed_colour_ring_type']) {
                             if (substr($identifier['coded_value'], 0, 1) == 'L') {
                                 $identifier_type = 'colour-left';
                             } elseif (substr($identifier['coded_value'], 0, 1) == 'R') {
                                 $identifier_type = 'colour-right';
                             }
                         } elseif ($identifier['identifier_type_id'] == $args['metal_ring_type']) {
                             $identifier_type = 'metal';
                         } else {
                             $identifier_type = '';
                         }
                         $fieldprefix = 'idn:' . $idx . ':' . $identifier_type . ':identifiers_subject_observation:';
                         $keys = array_keys($iso);
                         foreach ($keys as $key) {
                             $form_data[$fieldprefix . $key] = $iso[$key];
                         }
                         $fieldprefix = 'idn:' . $idx . ':' . $identifier_type . ':identifier:';
                         $form_data[$fieldprefix . 'checkbox'] = 'on';
                         $keys = array_keys($identifier);
                         foreach ($keys as $key) {
                             $form_data[$fieldprefix . $key] = $identifier[$key];
                         }
                         $fieldprefix = 'idn:' . $idx . ':' . $identifier_type . ':idnAttr:';
                         foreach ($idnAttrs as $idnAttr) {
                             if ($iso['identifier_id'] === $idnAttr['identifier_id']) {
                                 if ($idnAttr['multi_value'] === 't') {
                                     $form_data[$fieldprefix . $idnAttr['identifier_attribute_id']][] = $idnAttr['raw_value'];
                                 } else {
                                     $form_data[$fieldprefix . $idnAttr['identifier_attribute_id']] = $idnAttr['raw_value'];
                                 }
                             }
                         }
                         $fieldprefix = 'idn:' . $idx . ':' . $identifier_type . ':isoAttr:';
                         foreach ($isoAttrs as $isoAttr) {
                             if ($iso['id'] === $isoAttr['identifiers_subject_observation_id']) {
                                 if (!empty($isoAttr['id'])) {
                                     $form_data[$fieldprefix . $isoAttr['identifiers_subject_observation_attribute_id'] . ':' . $isoAttr['id']] = $isoAttr['raw_value'];
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     return $form_data;
 }
 public static function get_occurrences_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.';
     }
     drupal_add_js('misc/tableheader.js');
     // for sticky heading
     data_entry_helper::add_resource('jquery_form');
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     // did the parent sample previously exist? Default is no.
     $existing = false;
     $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));
     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;
         data_entry_helper::load_existing_record($auth['read'], 'sample', $parentSampleId);
     } 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;
         }
     }
     $sample = data_entry_helper::get_population_data(array('table' => 'sample', 'extraParams' => $auth['read'] + array('view' => 'detail', 'id' => $parentSampleId, 'deleted' => 'f')));
     $sample = $sample[0];
     $parentLocId = $sample['location_id'];
     $date = $sample['date_start'];
     if (!function_exists('module_exists') || !module_exists('easy_login')) {
         // work out the CMS User sample ID.
         $sampleMethods = helper_base::get_termlist_terms($auth, 'indicia:sample_methods', array('Transect'));
         $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']));
         if (false == ($cmsUserAttr = extract_cms_user_attr($attributes))) {
             return 'Easy Login not active: This form is designed to be used with the CMS User ID attribute setup for samples in the survey.';
         }
     }
     // find any attributes that apply to transect section samples.
     $sampleMethods = helper_base::get_termlist_terms($auth, 'indicia:sample_methods', array('Transect Section'));
     $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));
     //  the parent sample and sub-samples have already been created: can't cache in case a new section added.
     // need to specify sample_method as this must be different to those used in species map.
     // Only returns section based subsamples, not map.
     $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' => $sampleMethods[0]['id'], 'smpattrs' => implode(',', array_keys($attributes))), 'nocache' => true));
     // transcribe the response array into a couple of forms that are useful elsewhere - one for outputting JSON so the JS knows about
     // the samples, and another for lookup of sample data by code later.
     $subSampleJson = array();
     $subSamplesByCode = array();
     foreach ($subSamples as $subSample) {
         $subSampleJson[] = '"' . $subSample['code'] . '": ' . $subSample['sample_id'];
         $subSamplesByCode[$subSample['code']] = $subSample;
     }
     data_entry_helper::$javascript .= "indiciaData.samples = { " . implode(', ', $subSampleJson) . "};\n";
     if ($existing) {
         // Only need to load the occurrences for a pre-existing sample
         $attrs = array($args['occurrence_attribute_id']);
         if (isset($args['occurrence_attribute_id_2']) && $args['occurrence_attribute_id_2'] != "") {
             $attrs[] = $args['occurrence_attribute_id_2'];
         }
         if (isset($args['occurrence_attribute_id_3']) && $args['occurrence_attribute_id_3'] != "") {
             $attrs[] = $args['occurrence_attribute_id_3'];
         }
         if (isset($args['occurrence_attribute_id_4']) && $args['occurrence_attribute_id_4'] != "") {
             $attrs[] = $args['occurrence_attribute_id_4'];
         }
         $o = data_entry_helper::get_population_data(array('report' => 'reports_for_prebuilt_forms/UKBMS/ukbms_occurrences_list_for_parent_sample', 'extraParams' => $auth['read'] + array('view' => 'detail', 'sample_id' => $parentSampleId, 'survey_id' => $args['survey_id'], 'date_from' => '', 'date_to' => '', 'taxon_group_id' => '', 'smpattrs' => '', 'occattrs' => implode(',', $attrs)), 'nocache' => true));
         // build an array keyed for easy lookup
         $occurrences = array();
         foreach ($o as $occurrence) {
             $occurrences[$occurrence['sample_id'] . ':' . $occurrence['taxon_meaning_id']] = array('ttl_id' => $occurrence['taxa_taxon_list_id'], 'taxon_meaning_id' => $occurrence['taxon_meaning_id'], 'o_id' => $occurrence['occurrence_id'], 'processed' => false);
             foreach ($attrs as $attr) {
                 $occurrences[$occurrence['sample_id'] . ':' . $occurrence['taxon_meaning_id']]['value_' . $attr] = $occurrence['attr_occurrence_' . $attr];
                 $occurrences[$occurrence['sample_id'] . ':' . $occurrence['taxon_meaning_id']]['a_id_' . $attr] = $occurrence['attr_id_occurrence_' . $attr];
             }
         }
         // store it in data for JS to read when populating the grid
         data_entry_helper::$javascript .= "indiciaData.existingOccurrences = " . json_encode($occurrences) . ";\n";
     } else {
         data_entry_helper::$javascript .= "indiciaData.existingOccurrences = {};\n";
     }
     $occ_attributes = data_entry_helper::getAttributes(array('valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => 'occAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'multiValue' => false));
     data_entry_helper::$javascript .= "indiciaData.occurrence_attribute = [];\n";
     data_entry_helper::$javascript .= "indiciaData.occurrence_attribute_ctrl = [];\n";
     $defAttrOptions = array('extraParams' => $auth['read'] + array('orderby' => 'id'), 'suffixTemplate' => 'nosuffix');
     foreach (array($args['occurrence_attribute_id'], isset($args['occurrence_attribute_id_2']) && $args['occurrence_attribute_id_2'] != "" ? $args['occurrence_attribute_id_2'] : $args['occurrence_attribute_id'], isset($args['occurrence_attribute_id_3']) && $args['occurrence_attribute_id_3'] != "" ? $args['occurrence_attribute_id_3'] : $args['occurrence_attribute_id'], isset($args['occurrence_attribute_id_4']) && $args['occurrence_attribute_id_4'] != "" ? $args['occurrence_attribute_id_4'] : $args['occurrence_attribute_id']) as $idx => $attr) {
         unset($occ_attributes[$attr]['caption']);
         $ctrl = data_entry_helper::outputAttribute($occ_attributes[$attr], $defAttrOptions);
         data_entry_helper::$javascript .= "indiciaData.occurrence_attribute[" . ($idx + 1) . "] = {$attr};\n";
         data_entry_helper::$javascript .= "indiciaData.occurrence_attribute_ctrl[" . ($idx + 1) . "] = jQuery('" . str_replace("\n", "", $ctrl) . "');\n";
     }
     $sections = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('view' => 'detail', 'parent_id' => $parentLocId, 'deleted' => 'f'), 'nocache' => true));
     usort($sections, "ukbms_stis_sectionSort");
     $location = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('view' => 'detail', 'id' => $parentLocId)));
     $r = "<h2>" . $location[0]['name'] . " on " . $date . "</h2><div id=\"tabs\">\n";
     $tabs = array('#grid1' => t($args['species_tab_1']));
     // tab 1 is required.
     if (isset($args['second_taxon_list_id']) && $args['second_taxon_list_id'] != '') {
         $tabs['#grid2'] = t(isset($args['species_tab_2']) && $args['species_tab_2'] != '' ? $args['species_tab_2'] : 'Species Tab 2');
     }
     if (isset($args['third_taxon_list_id']) && $args['third_taxon_list_id'] != '') {
         $tabs['#grid3'] = t(isset($args['species_tab_3']) && $args['species_tab_3'] != '' ? $args['species_tab_3'] : 'Species Tab 3');
     }
     if (isset($args['fourth_taxon_list_id']) && $args['fourth_taxon_list_id'] != '') {
         $tabs['#grid4'] = t(isset($args['species_tab_4']) && $args['species_tab_4'] != '' ? $args['species_tab_4'] : 'Species Tab 4');
     }
     if (isset($args['map_taxon_list_id']) && $args['map_taxon_list_id'] != '') {
         $tabs['#gridmap'] = t(isset($args['species_map_tab']) && $args['species_map_tab'] != '' ? $args['species_map_tab'] : 'Map Based Tab');
     }
     $tabs['#notes'] = lang::get('Notes');
     $r .= data_entry_helper::tab_header(array('tabs' => $tabs));
     data_entry_helper::enable_tabs(array('divId' => 'tabs', 'style' => 'Tabs'));
     $commonSelected = isset($args['start_with_common_species']) && $args['start_with_common_species'] ? 'selected="selected"' : '';
     // will assume that first table is based on abundance count, so do totals
     $r .= '<div id="grid1">' . '<label for="listSelect">' . lang::get('Use species list') . ' :</label><select id="listSelect"><option value="full">' . lang::get('All species') . '</option><option value="common"' . $commonSelected . '>' . lang::get('Common species') . '</option><option value="here">' . lang::get('Species known at this site') . '</option><option value="mine">' . lang::get('Species I have recorded') . '</option><option value="filled">' . lang::get('Species with data') . '</option></select>' . '<span id="listSelectMsg"></span>';
     $r .= '<table id="transect-input1" class="ui-widget species-grid"><thead class="table-header">';
     $r .= '<tr><th class="ui-widget-header">' . lang::get('Sections') . '</th>';
     foreach ($sections as $idx => $section) {
         $r .= '<th class="ui-widget-header col-' . ($idx + 1) . '">' . $section['code'] . '</th>';
     }
     $r .= '<th class="ui-widget-header">' . lang::get('Total') . '</th>';
     $r .= '</tr></thead>';
     $r .= '<tbody class="ui-widget-content">';
     // output rows at the top for any transect section level sample attributes
     $rowClass = '';
     foreach ($attributes as $attr) {
         $r .= '<tr ' . $rowClass . ' id="smp-' . $attr['attributeId'] . '"><td>' . $attr['caption'] . '</td>';
         $rowClass = $rowClass == '' ? 'class="alt-row"' : '';
         unset($attr['caption']);
         foreach ($sections as $idx => $section) {
             // output a cell with the attribute - tag it with a class & id to make it easy to find from JS.
             $attrOpts = array('class' => 'smp-input smpAttr-' . $section['code'], 'id' => $attr['fieldname'] . ':' . $section['code'], 'extraParams' => $auth['read']);
             // if there is an existing value, set it and also ensure the attribute name reflects the attribute value id.
             if (isset($subSamplesByCode[$section['code']])) {
                 // but have to take into account possibility that this field has been blanked out, so deleting the attribute.
                 if (isset($subSamplesByCode[$section['code']]['attr_id_sample_' . $attr['attributeId']]) && $subSamplesByCode[$section['code']]['attr_id_sample_' . $attr['attributeId']] != '') {
                     $attrOpts['fieldname'] = $attr['fieldname'] . ':' . $subSamplesByCode[$section['code']]['attr_id_sample_' . $attr['attributeId']];
                     $attr['default'] = $subSamplesByCode[$section['code']]['attr_sample_' . $attr['attributeId']];
                 } else {
                     $attr['default'] = isset($_POST[$attr['fieldname']]) ? $_POST[$attr['fieldname']] : '';
                 }
             } else {
                 $attr['default'] = isset($_POST[$attr['fieldname']]) ? $_POST[$attr['fieldname']] : '';
             }
             $r .= '<td class="col-' . ($idx + 1) . ' ' . ($idx % 5 == 0 ? 'first' : '') . '">' . data_entry_helper::outputAttribute($attr, $attrOpts) . '</td>';
         }
         $r .= '<td class="ui-state-disabled first"></td>';
         $r .= '</tr>';
     }
     $r .= '</tbody>';
     $r .= '<tbody class="ui-widget-content occs-body"></tbody>';
     $r .= '<tfoot><tr><td>Total</td>';
     foreach ($sections as $idx => $section) {
         $r .= '<td class="col-' . ($idx + 1) . ' ' . ($idx % 5 == 0 ? 'first' : '') . ' col-total"></td>';
     }
     $r .= '<td class="ui-state-disabled first"></td></tr></tfoot>';
     $r .= '</table>' . '<span id="taxonLookupControlContainer"><label for="taxonLookupControl" class="auto-width">' . lang::get('Add species to list') . ':</label> <input id="taxonLookupControl" name="taxonLookupControl" ></span>';
     $r .= '<br /><a href="' . $args['my_walks_page'] . '" class="button">' . lang::get('Finish') . '</a></div>';
     $extraParams = array_merge($auth['read'], array('taxon_list_id' => $args['taxon_list_id'], 'preferred' => 't', 'allow_data_entry' => 't', 'view' => 'cache', 'orderby' => 'taxonomic_sort_order'));
     if (!empty($args['main_taxon_filter_field']) && !empty($args['main_taxon_filter'])) {
         $extraParams[$args['main_taxon_filter_field']] = helper_base::explode_lines($args['main_taxon_filter']);
     }
     $taxa = data_entry_helper::get_population_data(array('table' => 'taxa_taxon_list', 'extraParams' => $extraParams));
     data_entry_helper::$javascript .= "indiciaData.speciesList1List = [";
     $first = true;
     foreach ($taxa as $taxon) {
         data_entry_helper::$javascript .= ($first ? "\n" : ",\n") . "{'id':" . $taxon['id'] . ",'taxon_meaning_id':" . $taxon['taxon_meaning_id'] . ",'preferred_language_iso':'" . $taxon["preferred_language_iso"] . "','default_common_name':'" . str_replace("'", "\\'", $taxon["default_common_name"]) . "'}";
         $first = false;
     }
     data_entry_helper::$javascript .= "];\n";
     if (!empty($args['common_taxon_list_id'])) {
         $extraParams = array_merge($auth['read'], array('taxon_list_id' => $args['common_taxon_list_id'], 'preferred' => 't', 'allow_data_entry' => 't', 'view' => 'cache', 'orderby' => 'taxonomic_sort_order'));
         if (!empty($args['common_taxon_filter_field']) && !empty($args['common_taxon_filter'])) {
             $extraParams[$args['common_taxon_filter_field']] = helper_base::explode_lines($args['common_taxon_filter']);
         }
         $taxa = data_entry_helper::get_population_data(array('table' => 'taxa_taxon_list', 'extraParams' => $extraParams));
         data_entry_helper::$javascript .= "indiciaData.speciesList1SubsetList = [";
         $first = true;
         foreach ($taxa as $taxon) {
             data_entry_helper::$javascript .= ($first ? "\n" : ",\n") . "{'id':" . $taxon['id'] . ",'taxon_meaning_id':" . $taxon['taxon_meaning_id'] . ",'preferred_language_iso':'" . $taxon["preferred_language_iso"] . "','default_common_name':'" . str_replace("'", "\\'", $taxon["default_common_name"]) . "'}";
             $first = false;
         }
         data_entry_helper::$javascript .= "];\n";
         $swc = isset($args['start_with_common_species']) && $args['start_with_common_species'] ? 'true' : 'false';
         data_entry_helper::$javascript .= "indiciaData.startWithCommonSpecies={$swc};\n";
     }
     $allTaxonMeaningIdsAtTransect = data_entry_helper::get_population_data(array('report' => 'reports_for_prebuilt_forms/UKBMS/ukbms_taxon_meanings_at_transect', 'extraParams' => $auth['read'] + array('location_id' => $parentLocId, 'survey_id' => $args['survey_id']), 'nocache' => true));
     data_entry_helper::$javascript .= "indiciaData.allTaxonMeaningIdsAtTransect = [";
     $first = true;
     foreach ($allTaxonMeaningIdsAtTransect as $taxon) {
         data_entry_helper::$javascript .= ($first ? "" : ",") . $taxon['taxon_meaning_id'];
         $first = false;
     }
     data_entry_helper::$javascript .= "];\n";
     if (isset($args['second_taxon_list_id']) && $args['second_taxon_list_id'] != '') {
         $isNumber = $occ_attributes[isset($args['occurrence_attribute_id_2']) && $args['occurrence_attribute_id_2'] != "" ? $args['occurrence_attribute_id_2'] : $args['occurrence_attribute_id']]["data_type"] == 'I';
         $r .= '<div id="grid2"><p id="grid2-loading">' . lang::get('Loading - Please Wait') . '</p>' . (isset($args['supress_tab_msg']) && $args['supress_tab_msg'] ? '' : '<p>' . lang::get('LANG_Tab_Msg') . '</p>') . '<table id="transect-input2" class="ui-widget species-grid"><thead class="table-header">';
         $r .= '<tr><th class="ui-widget-header">' . lang::get('Sections') . '</th>';
         foreach ($sections as $idx => $section) {
             $r .= '<th class="ui-widget-header col-' . ($idx + 1) . '">' . $section['code'] . '</th>';
         }
         $r .= ($isNumber ? '<th class="ui-widget-header">' . lang::get('Total') . '</th>' : '') . '</tr></thead>';
         // No output rows at the top for any transect section level sample attributes in second grid.
         $r .= '<tbody class="ui-widget-content occs-body"></tbody>';
         if ($isNumber) {
             $r .= '<tfoot><tr><td>Total</td>';
             foreach ($sections as $idx => $section) {
                 $r .= '<td class="col-' . ($idx + 1) . ' ' . ($idx % 5 == 0 ? 'first' : '') . ' col-total"></td>';
             }
             $r .= '<td class="ui-state-disabled first"></td></tr></tfoot>';
         }
         $r .= '</table>';
         if (!isset($args['force_second']) || !$args['force_second']) {
             $r .= '<label for="taxonLookupControl2" class="auto-width">' . lang::get('Add species to list') . ':</label> <input id="taxonLookupControl2" name="taxonLookupControl2" >';
         }
         $r .= '<br /><a href="' . $args['my_walks_page'] . '" class="button">' . lang::get('Finish') . '</a></div>';
     }
     if (isset($args['third_taxon_list_id']) && $args['third_taxon_list_id'] != '') {
         $isNumber = $occ_attributes[isset($args['occurrence_attribute_id_3']) && $args['occurrence_attribute_id_3'] != "" ? $args['occurrence_attribute_id_3'] : $args['occurrence_attribute_id']]["data_type"] == 'I';
         $r .= '<div id="grid3"><p id="grid3-loading">' . lang::get('Loading - Please Wait') . '</p>' . (isset($args['supress_tab_msg']) && $args['supress_tab_msg'] ? '' : '<p>' . lang::get('LANG_Tab_Msg') . '</p>') . '<table id="transect-input3" class="ui-widget species-grid"><thead class="table-header">';
         $r .= '<tr><th class="ui-widget-header">' . lang::get('Sections') . '</th>';
         foreach ($sections as $idx => $section) {
             $r .= '<th class="ui-widget-header col-' . ($idx + 1) . '">' . $section['code'] . '</th>';
         }
         $r .= ($isNumber ? '<th class="ui-widget-header">' . lang::get('Total') . '</th>' : '') . '</tr></thead>';
         // No output rows at the top for any transect section level sample attributes in second grid.
         $r .= '<tbody class="ui-widget-content occs-body"></tbody>';
         if ($isNumber) {
             $r .= '<tfoot><tr><td>Total</td>';
             foreach ($sections as $idx => $section) {
                 $r .= '<td class="col-' . ($idx + 1) . ' ' . ($idx % 5 == 0 ? 'first' : '') . ' col-total"></td>';
             }
             $r .= '<td class="ui-state-disabled first"></td></tr></tfoot>';
         }
         $r .= '</table>';
         if (!isset($args['force_third']) || !$args['force_third']) {
             $r .= '<label for="taxonLookupControl3" class="auto-width">' . lang::get('Add species to list') . ':</label> <input id="taxonLookupControl3" name="taxonLookupControl3" >';
         }
         $r .= '<br /><a href="' . $args['my_walks_page'] . '" class="button">' . lang::get('Finish') . '</a></div>';
     }
     if (isset($args['fourth_taxon_list_id']) && $args['fourth_taxon_list_id'] != '') {
         $isNumber = $occ_attributes[isset($args['occurrence_attribute_id_4']) && $args['occurrence_attribute_id_4'] != "" ? $args['occurrence_attribute_id_4'] : $args['occurrence_attribute_id']]["data_type"] == 'I';
         $r .= '<div id="grid4"><p id="grid4-loading">' . lang::get('Loading - Please Wait') . '</p>' . (isset($args['supress_tab_msg']) && $args['supress_tab_msg'] ? '' : '<p>' . lang::get('LANG_Tab_Msg') . '</p>') . '<table id="transect-input4" class="ui-widget species-grid"><thead class="table-header">';
         $r .= '<tr><th class="ui-widget-header">' . lang::get('Sections') . '</th>';
         foreach ($sections as $idx => $section) {
             $r .= '<th class="ui-widget-header col-' . ($idx + 1) . '">' . $section['code'] . '</th>';
         }
         $r .= ($isNumber ? '<th class="ui-widget-header">' . lang::get('Total') . '</th>' : '') . '</tr></thead>';
         // No output rows at the top for any transect section level sample attributes in second grid.
         $r .= '<tbody class="ui-widget-content occs-body"></tbody>';
         if ($isNumber) {
             $r .= '<tfoot><tr><td>Total</td>';
             foreach ($sections as $idx => $section) {
                 $r .= '<td class="col-' . ($idx + 1) . ' ' . ($idx % 5 == 0 ? 'first' : '') . ' col-total"></td>';
             }
             $r .= '<td class="ui-state-disabled first"></td></tr></tfoot>';
         }
         $r .= '</table>';
         if (!isset($args['force_fourth']) || !$args['force_fourth']) {
             $r .= '<label for="taxonLookupControl4" class="auto-width">' . lang::get('Add species to list') . ':</label> <input id="taxonLookupControl4" name="taxonLookupControl4" >';
         }
         $r .= '<br /><a href="' . $args['my_walks_page'] . '" class="button">' . lang::get('Finish') . '</a></div>';
     }
     $reloadPath = self::getReloadPath();
     if (isset($args['map_taxon_list_id']) && $args['map_taxon_list_id'] != '') {
         // TODO convert to AJAX.
         data_entry_helper::enable_validation('entry_form');
         $value = helper_base::explode_lines_key_value_pairs($args['defaults']);
         $value = isset($value['occurrence:record_status']) ? $value['occurrence:record_status'] : 'C';
         $r .= '<div id="gridmap">' . "\n" . '<form method="post" id="entry_form" action="' . $reloadPath . '">' . $auth['write'] . '<p>When using this page, please remember that the data is not saved to the database as you go (which is the case for the previous tabs). In order to save the data entered in this page you must click on the Save button at the bottom of the page.</p>' . '<input type="hidden" id="website_id" name="website_id" value="' . $args["website_id"] . '" />' . '<input type="hidden" id="survey_id" name="sample:survey_id" value="' . $args["survey_id"] . '" />' . '<input type="hidden" id="occurrence:record_status" name="occurrence:record_status" value="' . $value . '" />' . '<input type="hidden" name="sample:id" value="' . data_entry_helper::$entity_to_load['sample:id'] . '"/>' . '<input type="hidden" name="page" value="speciesmap"/>' . '<input type="hidden" name="sample:location_id" value="' . $parentLocId . '"/>';
         if (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');
         }
         $r .= '<input type="hidden" name="sample:date" value="' . data_entry_helper::$entity_to_load['sample:date'] . '"/>';
         // leave the sample_method as it is stored now.
         // Dont need the place search, as we will zoom in to the main location. TODO
         $options = iform_map_get_map_options($args, $auth["read"]);
         if (isset(data_entry_helper::$entity_to_load["sample:geom"])) {
             $options["initialFeatureWkt"] = data_entry_helper::$entity_to_load["sample:wkt"];
         }
         $options["tabDiv"] = "gridmap";
         $olOptions = iform_map_get_ol_options($args);
         if (!isset($options["standardControls"])) {
             $options["standardControls"] = array("layerSwitcher", "panZoomBar");
         }
         $r .= data_entry_helper::map_panel($options, $olOptions);
         // [species map]
         $r .= self::control_speciesmap($auth, $args, "gridmap", array());
         /**
          * The speciesmapsummary is not implemented here
          */
         $r .= '<input type="submit" class="indicia-button" id="save-button" value="' . lang::get('Save') . '" /></form></div>';
         data_entry_helper::$javascript .= "var speciesMapTabHandler = function(event, ui) {\n  if (ui.panel.id=='" . $options["tabDiv"] . "') {\n    if (indiciaData.ParentSampleLayer.features.length > 0) {\n      var bounds=indiciaData.ParentSampleLayer.getDataExtent();\n      bounds.extend(indiciaData.SubSampleLayer.getDataExtent());\n      // extend the boundary to include a buffer, so the map does not zoom too tight.\n      bounds.scale(1.2);\n      indiciaData.ParentSampleLayer.map.zoomToExtent(bounds);\n    }\n  }\n};\njQuery(jQuery('#" . $options["tabDiv"] . "').parent()).bind('tabsshow', speciesMapTabHandler);\n";
     } else {
         // enable validation on the comments form in order to include the simplified ajax queuing for the autocomplete.
         data_entry_helper::enable_validation('notes_form');
     }
     // for the comment form, we want to ensure that if there is a timeout error that it reloads the
     // data as stored in the DB.
     $reloadParts = explode('?', $reloadPath, 2);
     // fragment is always at the end. discard this.
     if (count($reloadParts) > 1) {
         $params = explode('#', $reloadParts[1], 2);
         $params = $params[0] . "&sample_id=" . $parentSampleId;
     } else {
         $reloadParts = explode('#', $reloadParts[0], 2);
         $params = "sample_id=" . $parentSampleId;
     }
     $r .= "<div id=\"notes\">\n";
     $r .= "<form method=\"post\" id=\"notes_form\" action=\"" . $reloadParts[0] . '?' . $params . "#notes\">\n";
     $r .= $auth['write'];
     $r .= '<input type="hidden" name="sample:id" value="' . $parentSampleId . '" />';
     $r .= '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>';
     $r .= '<input type="hidden" name="survey_id" value="' . $args['survey_id'] . '"/>';
     $r .= '<input type="hidden" name="page" value="notes"/>';
     $r .= '<p  class="page-notice ui-state-highlight ui-corner-all">' . lang::get('When using this page, please remember that the data is not saved to the database as you go (which is the case for the previous tabs). In order to save the data entered in this page you must click on the Submit button at the bottom of the page.') . '</p>';
     $r .= data_entry_helper::textarea(array('fieldname' => 'sample:comment', 'label' => lang::get('Notes'), 'helpText' => "Use this space to input comments about this week's walk."));
     $r .= '<input type="submit" value="' . lang::get('Submit') . '" id="save-button"/>';
     $r .= '</form>';
     $r .= '<br /><a href="' . $args['my_walks_page'] . '" class="button">' . lang::get('Finish') . '</a>';
     $r .= '</div></div>';
     // A stub form for AJAX posting when we need to create an occurrence
     $r .= '<form style="display: none" id="occ-form" method="post" action="' . iform_ajaxproxy_url($node, 'occurrence') . '">';
     $r .= '<input name="website_id" value="' . $args['website_id'] . '"/>';
     $r .= '<input name="survey_id" value="' . $args["survey_id"] . '" />';
     $r .= '<input name="occurrence:id" id="occid" />';
     $r .= '<input name="occurrence:deleted" id="occdeleted" />';
     $r .= '<input name="occurrence:zero_abundance" id="occzero" />';
     $r .= '<input name="occurrence:taxa_taxon_list_id" id="ttlid" />';
     $r .= '<input name="occurrence:sample_id" id="occ_sampleid"/>';
     if (isset($args["sensitiveAttrID"]) && $args["sensitiveAttrID"] != "" && isset($args["sensitivityPrecision"]) && $args["sensitivityPrecision"] != "") {
         $locationTypes = helper_base::get_termlist_terms($auth, 'indicia:location_types', array(empty($args['transect_type_term']) ? 'Transect' : $args['transect_type_term']));
         $site_attributes = data_entry_helper::getAttributes(array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'] + array('id' => $args["sensitiveAttrID"]), 'location_type_id' => $locationTypes[0]['id'], 'survey_id' => $args['survey_id'], 'id' => $parentLocId));
         $r .= '<input name="occurrence:sensitivity_precision" id="occSensitive" value="' . (count($site_attributes) > 0 && $site_attributes[$args["sensitiveAttrID"]]['default'] == "1" ? $args["sensitivityPrecision"] : '') . '"/>';
     }
     $r .= '<input name="occAttr:' . $args['occurrence_attribute_id'] . '" id="occattr"/>';
     $r .= '<input name="transaction_id" id="transaction_id"/>';
     $r .= '<input name="user_id" value="' . hostsite_get_user_field('user_id', 1) . '"/>';
     $r .= '</form>';
     // A stub form for AJAX posting when we need to update a sample
     $r .= '<form style="display: none" id="smp-form" method="post" action="' . iform_ajaxproxy_url($node, 'sample') . '">';
     $r .= '<input name="website_id" value="' . $args['website_id'] . '"/>';
     $r .= '<input name="sample:id" id="smpid" />';
     $r .= '<input name="sample:parent_id" value="' . $parentSampleId . '" />';
     $r .= '<input name="sample:survey_id" value="' . $args['survey_id'] . '" />';
     $r .= '<input name="sample:sample_method_id" value="' . $sampleMethods[0]['id'] . '" />';
     $r .= '<input name="sample:entered_sref" id="smpsref" />';
     $r .= '<input name="sample:entered_sref_system" id="smpsref_system" />';
     $r .= '<input name="sample:location_id" id="smploc" />';
     $r .= '<input name="sample:date" value="' . $date . '" />';
     // include a stub input for each transect section sample attribute
     foreach ($attributes as $attr) {
         $r .= '<input id="' . $attr['fieldname'] . '" />';
     }
     $r .= '</form>';
     // tell the Javascript where to get species from.
     // @todo handle diff species lists.
     data_entry_helper::add_resource('jquery_ui');
     data_entry_helper::add_resource('json');
     data_entry_helper::add_resource('autocomplete');
     data_entry_helper::$javascript .= "indiciaData.speciesList1 = " . $args['taxon_list_id'] . ";\n";
     if (!empty($args['main_taxon_filter_field']) && !empty($args['main_taxon_filter'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesList1FilterField = '" . $args['main_taxon_filter_field'] . "';\n";
         $filterLines = helper_base::explode_lines($args['main_taxon_filter']);
         data_entry_helper::$javascript .= "indiciaData.speciesList1FilterValues = '" . json_encode($filterLines) . "';\n";
     }
     data_entry_helper::$javascript .= "bindSpeciesAutocomplete(\"taxonLookupControl\",\"table#transect-input1\",\"" . data_entry_helper::$base_url . "index.php/services/data\", \"" . $args['taxon_list_id'] . "\",\n  indiciaData.speciesList1FilterField, indiciaData.speciesList1FilterValues, {\"auth_token\" : \"" . $auth['read']['auth_token'] . "\", \"nonce\" : \"" . $auth['read']['nonce'] . "\"},\n  \"" . lang::get('LANG_Duplicate_Taxon') . "\", 25, 1);\n\nindiciaData.speciesList1Subset = " . (isset($args['common_taxon_list_id']) && $args['common_taxon_list_id'] != "" ? $args['common_taxon_list_id'] : "-1") . ";\n";
     if (!empty($args['common_taxon_filter_field']) && !empty($args['common_taxon_filter'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesList1SubsetFilterField = '" . $args['common_taxon_filter_field'] . "';\n";
         $filterLines = helper_base::explode_lines($args['common_taxon_filter']);
         data_entry_helper::$javascript .= "indiciaData.speciesList1SubsetFilterValues = '" . json_encode($filterLines) . "';\n";
     }
     data_entry_helper::$javascript .= "indiciaData.speciesList2 = " . (isset($args['second_taxon_list_id']) && $args['second_taxon_list_id'] != "" ? $args['second_taxon_list_id'] : "-1") . ";\n";
     if (!empty($args['second_taxon_filter_field']) && !empty($args['second_taxon_filter'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesList2FilterField = '" . $args['second_taxon_filter_field'] . "';\n";
         $filterLines = helper_base::explode_lines($args['second_taxon_filter']);
         data_entry_helper::$javascript .= "indiciaData.speciesList2FilterValues = " . json_encode($filterLines) . ";\n";
     }
     data_entry_helper::$javascript .= "indiciaData.speciesList2Force = " . (isset($args['force_second']) && $args['force_second'] ? 'true' : 'false') . ";\n";
     if (!isset($args['force_second']) || !$args['force_second']) {
         data_entry_helper::$javascript .= "bindSpeciesAutocomplete(\"taxonLookupControl2\",\"table#transect-input2\",\"" . data_entry_helper::$base_url . "index.php/services/data\", indiciaData.speciesList2,\n  indiciaData.speciesList2FilterField, indiciaData.speciesList2FilterValues, {\"auth_token\" : \"" . $auth['read']['auth_token'] . "\", \"nonce\" : \"" . $auth['read']['nonce'] . "\"},\n  \"" . lang::get('LANG_Duplicate_Taxon') . "\", 25, 2);\n\n";
     }
     data_entry_helper::$javascript .= "indiciaData.speciesList3 = " . (isset($args['third_taxon_list_id']) && $args['third_taxon_list_id'] != "" ? $args['third_taxon_list_id'] : "-1") . ";\n";
     if (!empty($args['third_taxon_filter_field']) && !empty($args['third_taxon_filter'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesList3FilterField = '" . $args['third_taxon_filter_field'] . "';\n";
         $filterLines = helper_base::explode_lines($args['third_taxon_filter']);
         data_entry_helper::$javascript .= "indiciaData.speciesList3FilterValues = " . json_encode($filterLines) . ";\n";
     }
     data_entry_helper::$javascript .= "indiciaData.speciesList3Force = " . (isset($args['force_third']) && $args['force_third'] ? 'true' : 'false') . ";\n";
     if (!isset($args['force_third']) || !$args['force_third']) {
         data_entry_helper::$javascript .= "bindSpeciesAutocomplete(\"taxonLookupControl3\",\"table#transect-input3\",\"" . data_entry_helper::$base_url . "index.php/services/data\", indiciaData.speciesList3,\n    indiciaData.speciesList3FilterField, indiciaData.speciesList3FilterValues, {\"auth_token\" : \"" . $auth['read']['auth_token'] . "\", \"nonce\" : \"" . $auth['read']['nonce'] . "\"},\n    \"" . lang::get('LANG_Duplicate_Taxon') . "\", 25, 3);\n\n";
     }
     data_entry_helper::$javascript .= "indiciaData.speciesList4 = " . (isset($args['fourth_taxon_list_id']) && $args['fourth_taxon_list_id'] != "" ? $args['fourth_taxon_list_id'] : "-1") . ";\n";
     if (!empty($args['fourth_taxon_filter_field']) && !empty($args['fourth_taxon_filter'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesList4FilterField = '" . $args['fourth_taxon_filter_field'] . "';\n";
         $filterLines = helper_base::explode_lines($args['fourth_taxon_filter']);
         data_entry_helper::$javascript .= "indiciaData.speciesList4FilterValues = " . json_encode($filterLines) . ";\n";
     }
     data_entry_helper::$javascript .= "indiciaData.speciesList4Force = " . (isset($args['force_fourth']) && $args['force_fourth'] ? 'true' : 'false') . ";\n";
     // allow js to do AJAX by passing in the information it needs to post forms
     if (!isset($args['force_fourth']) || !$args['force_fourth']) {
         data_entry_helper::$javascript .= "bindSpeciesAutocomplete(\"taxonLookupControl4\",\"table#transect-input4\",\"" . data_entry_helper::$base_url . "index.php/services/data\", indiciaData.speciesList4,\n  indiciaData.speciesList4FilterField, indiciaData.speciesList4FilterValues, {\"auth_token\" : \"" . $auth['read']['auth_token'] . "\", \"nonce\" : \"" . $auth['read']['nonce'] . "\"},\n  \"" . lang::get('LANG_Duplicate_Taxon') . "\", 25, 4);\n\n";
     }
     data_entry_helper::$javascript .= "indiciaData.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.transect = " . $parentLocId . ";\n";
     data_entry_helper::$javascript .= "indiciaData.parentSample = " . $parentSampleId . ";\n";
     data_entry_helper::$javascript .= "indiciaData.sections = " . json_encode($sections) . ";\n";
     if (function_exists('module_exists') && module_exists('easy_login')) {
         data_entry_helper::$javascript .= "indiciaData.easyLogin = true;\n";
         $userId = hostsite_get_user_field('indicia_user_id');
         if (!empty($userId)) {
             data_entry_helper::$javascript .= "indiciaData.UserID = " . $userId . ";\n";
         } else {
             return '<p>Easy Login active but could not identify user</p>';
         }
         // something is wrong
     } else {
         data_entry_helper::$javascript .= "indiciaData.easyLogin = false;\n";
         data_entry_helper::$javascript .= "indiciaData.CMSUserAttrID = " . $cmsUserAttr['attributeId'] . ";\n";
         data_entry_helper::$javascript .= "indiciaData.CMSUserID = " . $user->uid . ";\n";
     }
     // Do an AJAX population of the grid rows.
     data_entry_helper::$javascript .= "loadSpeciesList();\njQuery('#tabs').bind('tabsshow', function(event, ui) {\n    var target = ui.panel;\n    // first get rid of any previous tables\n    jQuery('table.sticky-header').remove();\n    jQuery('table.sticky-enabled thead.tableHeader-processed').removeClass('tableHeader-processed');\n    jQuery('table.sticky-enabled.tableheader-processed').removeClass('tableheader-processed');\n    jQuery('table.species-grid.sticky-enabled').removeClass('sticky-enabled');\n    var table = jQuery('#'+target.id+' table.species-grid');\n    if(table.length > 0) {\n        table.addClass('sticky-enabled');\n        if(typeof Drupal.behaviors.tableHeader == 'object') // Drupal 7\n          Drupal.behaviors.tableHeader.attach(table.parent());\n        else // Drupal6 : it is a function\n          Drupal.behaviors.tableHeader(target);\n    }\n    // remove any hanging autocomplete select list.\n    jQuery('.ac_results').hide();\n});";
     return $r;
 }
 public static function get_occurrences_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.';
     }
     drupal_add_js('misc/tableheader.js');
     // for sticky heading
     data_entry_helper::add_resource('jquery_form');
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     // did the parent sample previously exist? Default is no.
     $existing = false;
     $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));
     if (isset($_POST['sample:id'])) {
         // have just posted an edit to the existing sample
         $sampleId = $_POST['sample:id'];
         $existing = true;
         data_entry_helper::load_existing_record($auth['read'], 'sample', $sampleId);
     } else {
         if (isset($response['outer_id'])) {
             // have just posted a new sample.
             $sampleId = $response['outer_id'];
         } else {
             $sampleId = $_GET['sample_id'];
             $existing = true;
         }
     }
     $sample = data_entry_helper::get_population_data(array('table' => 'sample', 'extraParams' => $auth['read'] + array('view' => 'detail', 'id' => $sampleId, 'deleted' => 'f')));
     $sample = $sample[0];
     $date = $sample['date_start'];
     if (!function_exists('module_exists') || !module_exists('easy_login')) {
         // work out the CMS User sample ID.
         $sampleMethods = helper_base::get_termlist_terms($auth, 'indicia:sample_methods', array('Field Observation'));
         $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']));
         if (false == ($cmsUserAttr = extract_cms_user_attr($attributes))) {
             return 'Easy Login not active: This form is designed to be used with the CMS User ID attribute setup for samples in the survey.';
         }
     }
     $allTaxonMeaningIdsAtSample = array();
     if ($existing) {
         // Only need to load the occurrences for a pre-existing sample
         $o = data_entry_helper::get_population_data(array('report' => 'reports_for_prebuilt_forms/UKBMS/ukbms_occurrences_list_for_sample', 'extraParams' => $auth['read'] + array('view' => 'detail', 'sample_id' => $sampleId, 'survey_id' => $args['survey_id'], 'date_from' => '', 'date_to' => '', 'taxon_group_id' => '', 'smpattrs' => '', 'occattrs' => $args['occurrence_attribute_ids']), 'nocache' => true));
         // build an array keyed for easy lookup
         $occurrences = array();
         $attrs = explode(',', $args['occurrence_attribute_ids']);
         if (!isset($o['error'])) {
             foreach ($o as $occurrence) {
                 if (!in_array($occurrence['taxon_meaning_id'], $allTaxonMeaningIdsAtSample)) {
                     $allTaxonMeaningIdsAtSample[] = $occurrence['taxon_meaning_id'];
                 }
                 $occurrences[$occurrence['taxon_meaning_id']] = array('ttl_id' => $occurrence['taxa_taxon_list_id'], 'ttl_id' => $occurrence['taxa_taxon_list_id'], 'preferred_ttl_id' => $occurrence['preferred_ttl_id'], 'o_id' => $occurrence['occurrence_id'], 'processed' => false);
                 foreach ($attrs as $attr) {
                     $occurrences[$occurrence['taxon_meaning_id']]['value_' . $attr] = $occurrence['attr_occurrence_' . $attr];
                     $occurrences[$occurrence['taxon_meaning_id']]['a_id_' . $attr] = $occurrence['attr_id_occurrence_' . $attr];
                 }
             }
         }
         // store it in data for JS to read when populating the grid
         data_entry_helper::$javascript .= "indiciaData.existingOccurrences = " . json_encode($occurrences) . ";\n";
     } else {
         data_entry_helper::$javascript .= "indiciaData.existingOccurrences = {};\n";
     }
     $occ_attributes = data_entry_helper::getAttributes(array('valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => 'occAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'multiValue' => false));
     data_entry_helper::$javascript .= "indiciaData.occurrence_totals = [];\n";
     data_entry_helper::$javascript .= "indiciaData.occurrence_attribute = [];\n";
     data_entry_helper::$javascript .= "indiciaData.occurrence_attribute_ctrl = [];\n";
     $defAttrOptions = array('extraParams' => $auth['read'] + array('orderby' => 'id'), 'suffixTemplate' => 'nosuffix');
     $occ_attributes_captions = array();
     foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
         $occ_attributes_captions[$idx] = $occ_attributes[$attr]['caption'];
         unset($occ_attributes[$attr]['caption']);
         $ctrl = data_entry_helper::outputAttribute($occ_attributes[$attr], $defAttrOptions);
         data_entry_helper::$javascript .= "indiciaData.occurrence_totals[" . $idx . "] = [];\n";
         data_entry_helper::$javascript .= "indiciaData.occurrence_attribute[" . $idx . "] = {$attr};\n";
         data_entry_helper::$javascript .= "indiciaData.occurrence_attribute_ctrl[" . $idx . "] = jQuery('" . str_replace("\n", "", $ctrl) . "');\n";
     }
     //    $r = "<h2>".$location[0]['name']." on ".$date."</h2>\n";
     $r = '<div id="tabs">';
     $tabs = array('#grid1' => t($args['species_tab_1']));
     // tab 1 is required.
     if (isset($args['taxon_list_id_2']) && $args['taxon_list_id_2'] != '') {
         $tabs['#grid2'] = t(isset($args['species_tab_2']) && $args['species_tab_2'] != '' ? $args['species_tab_2'] : 'Species Tab 2');
     }
     if (isset($args['taxon_list_id_3']) && $args['taxon_list_id_3'] != '') {
         $tabs['#grid3'] = t(isset($args['species_tab_3']) && $args['species_tab_3'] != '' ? $args['species_tab_3'] : 'Species Tab 3');
     }
     if (isset($args['taxon_list_id_4']) && $args['taxon_list_id_4'] != '') {
         $tabs['#grid4'] = t(isset($args['species_tab_4']) && $args['species_tab_4'] != '' ? $args['species_tab_4'] : 'Species Tab 4');
     }
     $tabs['#notes'] = lang::get('Notes');
     $r .= data_entry_helper::tab_header(array('tabs' => $tabs));
     data_entry_helper::enable_tabs(array('divId' => 'tabs', 'style' => 'Tabs'));
     // will assume that first table is based on abundance count, so do totals
     $r .= '<div id="grid1"><table id="observation-input1" class="ui-widget species-grid"><thead class="table-header"><tr><th class="ui-widget-header"></th>';
     foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
         $r .= '<th class="ui-widget-header col-' . ($idx + 1) . '">' . $occ_attributes_captions[$idx] . '</th>';
     }
     $r .= '<th class="ui-widget-header">' . lang::get('Total') . '</th></tr></thead>';
     $r .= '<tbody class="ui-widget-content occs-body"></tbody><tfoot><tr><td>Total</td>';
     foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
         $r .= '<td class="col-' . ($idx + 1) . ' ' . ($idx % 5 == 0 ? 'first' : '') . ' col-total"></td>';
     }
     $r .= '<td class="ui-state-disabled first"></td></tr></tfoot></table><br /><a href="' . $args['my_obs_page'] . '" class="button">' . lang::get('Finish') . '</a></div>';
     $extraParams = array_merge($auth['read'], array('taxon_list_id' => $args['taxon_list_id_1'], 'preferred' => 't', 'allow_data_entry' => 't', 'view' => 'cache', 'orderby' => 'taxonomic_sort_order'));
     if (!empty($args['taxon_filter_field_1']) && !empty($args['taxon_filter_1'])) {
         $extraParams[$args['taxon_filter_field_1']] = helper_base::explode_lines($args['taxon_filter_1']);
     }
     $taxa = data_entry_helper::get_population_data(array('table' => 'taxa_taxon_list', 'extraParams' => $extraParams));
     data_entry_helper::$javascript .= "indiciaData.speciesList1List = [";
     $first = true;
     foreach ($taxa as $taxon) {
         data_entry_helper::$javascript .= ($first ? "\n" : ",\n") . "{'id':" . $taxon['id'] . ",'taxon_meaning_id':" . $taxon['taxon_meaning_id'] . ",'preferred_language_iso':'" . $taxon["preferred_language_iso"] . "','default_common_name':'" . str_replace("'", "\\'", $taxon["default_common_name"]) . "'}";
         $first = false;
     }
     data_entry_helper::$javascript .= "];\n";
     data_entry_helper::$javascript .= "indiciaData.allTaxonMeaningIdsAtSample = [" . implode(',', $allTaxonMeaningIdsAtSample) . "];\n";
     if (isset($args['taxon_list_id_2']) && $args['taxon_list_id_2'] != '') {
         $r .= '<div id="grid2"><p id="grid2-loading">' . lang::get('Loading - Please Wait') . '</p><table id="observation-input2" class="ui-widget species-grid"><thead class="table-header"><tr><th class="ui-widget-header"></th>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<th class="ui-widget-header col-' . ($idx + 1) . '">' . $occ_attributes_captions[$idx] . '</th>';
         }
         $r .= '<th class="ui-widget-header">' . lang::get('Total') . '</th></tr></thead><tbody class="ui-widget-content occs-body"></tbody><tfoot><tr><td>Total</td>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<td class="col-' . ($idx + 1) . ' ' . ($idx % 5 == 0 ? 'first' : '') . ' col-total"></td>';
         }
         $r .= '<td class="ui-state-disabled first"></td></tr></tfoot></table><br /><a href="' . $args['my_obs_page'] . '" class="button">' . lang::get('Finish') . '</a></div>';
     }
     if (isset($args['taxon_list_id_3']) && $args['taxon_list_id_3'] != '') {
         $r .= '<div id="grid3"><p id="grid3-loading">' . lang::get('Loading - Please Wait') . '</p><table id="observation-input3" class="ui-widget species-grid"><thead class="table-header"><tr><th class="ui-widget-header"></th>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<th class="ui-widget-header col-' . ($idx + 1) . '">' . $occ_attributes_captions[$idx] . '</th>';
         }
         $r .= '<th class="ui-widget-header">' . lang::get('Total') . '</th></tr></thead><tbody class="ui-widget-content occs-body"></tbody><tfoot><tr><td>Total</td>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<td class="col-' . ($idx + 1) . ' ' . ($idx % 5 == 0 ? 'first' : '') . ' col-total"></td>';
         }
         $r .= '<td class="ui-state-disabled first"></td></tr></tfoot></table><br /><a href="' . $args['my_obs_page'] . '" class="button">' . lang::get('Finish') . '</a></div>';
     }
     if (isset($args['taxon_list_id_4']) && $args['taxon_list_id_4'] != '') {
         $r .= '<div id="grid4"><p id="grid4-loading">' . lang::get('Loading - Please Wait') . '</p><table id="observation-input4" class="ui-widget species-grid"><thead class="table-header"><tr><th class="ui-widget-header"></th>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<th class="ui-widget-header col-' . ($idx + 1) . '">' . $occ_attributes_captions[$idx] . '</th>';
         }
         $r .= '<th class="ui-widget-header">' . lang::get('Total') . '</th></tr></thead><tbody class="ui-widget-content occs-body"></tbody><tfoot><tr><td>Total</td>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<td class="col-' . ($idx + 1) . ' ' . ($idx % 5 == 0 ? 'first' : '') . ' col-total"></td>';
         }
         $r .= '<td class="ui-state-disabled first"></td></tr></tfoot></table>';
         $r .= '<label for="taxonLookupControl4" class="auto-width">' . lang::get('Add species to list') . ':</label> <input id="taxonLookupControl4" name="taxonLookupControl4" >';
         $r .= '<br /><a href="' . $args['my_obs_page'] . '" class="button">' . lang::get('Finish') . '</a></div>';
     }
     // for the comment form, we want to ensure that if there is a timeout error that it reloads the
     // data as stored in the DB.
     $reload = data_entry_helper::get_reload_link_parts();
     $reload['params']['sample_id'] = $parentSampleId;
     unset($reload['params']['new']);
     $reloadPath = $reload['path'];
     if (count($reload['params'])) {
         // decode params prior to encoding to prevent double encoding.
         foreach ($reload['params'] as $key => $param) {
             $reload['params'][$key] = urldecode($param);
         }
         $reloadPath .= '?' . http_build_query($reload['params']);
     }
     // fragment is always at the end. discard this.
     $reloadPath = explode('#', $reloadPath, 2);
     $reloadPath = $reloadPath[0];
     $r .= "<div id=\"notes\"><form method=\"post\" id=\"notes_form\" action=\"" . $reloadPath . "#notes\">\n";
     $r .= $auth['write'];
     $r .= '<input type="hidden" name="sample:id" value="' . $sampleId . '" />' . '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>' . '<input type="hidden" name="survey_id" value="' . $args['survey_id'] . '"/>' . '<input type="hidden" name="page" value="notes"/>';
     $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('When using this page, please remember that the data is not saved to the database as you go (which is the case for the previous tabs). In order to save the data entered in this page you must click on the Submit button at the bottom of the page.') . '</p>';
     $r .= data_entry_helper::textarea(array('fieldname' => 'sample:comment', 'label' => lang::get('Notes'), 'helpText' => "Use this space to input comments about this week's walk."));
     $r .= '<input type="submit" value="' . lang::get('Submit') . '" id="save-button"/></form>';
     $r .= '<br /><a href="' . $args['my_walks_page'] . '" class="button">' . lang::get('Finish') . '</a></div></div>';
     // enable validation on the comments form in order to include the simplified ajax queuing for the autocomplete.
     data_entry_helper::enable_validation('notes_form');
     // A stub form for AJAX posting when we need to create an occurrence
     $r .= '<form style="display: none" id="occ-form" method="post" action="' . iform_ajaxproxy_url($node, 'occurrence') . '">';
     $r .= '<input name="website_id" value="' . $args['website_id'] . '"/>';
     $r .= '<input name="occurrence:id" id="occid" />';
     $r .= '<input name="occurrence:taxa_taxon_list_id" id="ttlid" />';
     $r .= '<input name="occurrence:sample_id" value="' . $sampleId . '"/>';
     $r .= '<input name="occAttr:" id="occattr"/>';
     $r .= '<input name="transaction_id" id="transaction_id"/>';
     $r .= '<input name="user_id" value="' . hostsite_get_user_field('user_id', 1) . '"/>';
     $r .= '</form>';
     // tell the Javascript where to get species from.
     data_entry_helper::add_resource('jquery_ui');
     data_entry_helper::add_resource('json');
     data_entry_helper::add_resource('autocomplete');
     data_entry_helper::$javascript .= "indiciaData.speciesList1 = " . $args['taxon_list_id_1'] . ";\n";
     if (!empty($args['taxon_filter_field_1']) && !empty($args['taxon_filter_1'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesList1FilterField = '" . $args['taxon_filter_field_1'] . "';\n";
         $filterLines = helper_base::explode_lines($args['taxon_filter_1']);
         data_entry_helper::$javascript .= "indiciaData.speciesList1FilterValues = '" . json_encode($filterLines) . "';\n";
     }
     data_entry_helper::$javascript .= "indiciaData.speciesList2 = " . (isset($args['taxon_list_id_2']) && $args['taxon_list_id_2'] != "" ? $args['taxon_list_id_2'] : "-1") . ";\n";
     if (!empty($args['taxon_filter_field_2']) && !empty($args['taxon_filter_2'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesList2FilterField = '" . $args['taxon_filter_field_2'] . "';\n";
         $filterLines = helper_base::explode_lines($args['taxon_filter_2']);
         data_entry_helper::$javascript .= "indiciaData.speciesList2FilterValues = " . json_encode($filterLines) . ";\n";
     }
     data_entry_helper::$javascript .= "indiciaData.speciesList3 = " . (isset($args['taxon_list_id_3']) && $args['taxon_list_id_3'] != "" ? $args['taxon_list_id_3'] : "-1") . ";\n";
     if (!empty($args['taxon_filter_field_3']) && !empty($args['taxon_filter_3'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesList3FilterField = '" . $args['taxon_filter_field_3'] . "';\n";
         $filterLines = helper_base::explode_lines($args['taxon_filter_3']);
         data_entry_helper::$javascript .= "indiciaData.speciesList3FilterValues = " . json_encode($filterLines) . ";\n";
     }
     data_entry_helper::$javascript .= "indiciaData.speciesList4 = " . (isset($args['taxon_list_id_4']) && $args['taxon_list_id_4'] != "" ? $args['taxon_list_id_4'] : "-1") . ";\n";
     if (!empty($args['taxon_filter_field_4']) && !empty($args['taxon_filter_4'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesList4FilterField = '" . $args['taxon_filter_field_4'] . "';\n";
         $filterLines = helper_base::explode_lines($args['taxon_filter_4']);
         data_entry_helper::$javascript .= "indiciaData.speciesList4FilterValues = " . json_encode($filterLines) . ";\n";
     }
     // allow js to do AJAX by passing in the information it needs to post forms
     data_entry_helper::$javascript .= "bindSpeciesAutocomplete(\"taxonLookupControl4\",\"table#observation-input4\",\"" . data_entry_helper::$base_url . "index.php/services/data\", indiciaData.speciesList4,\n  indiciaData.speciesList4FilterField, indiciaData.speciesList4FilterValues, {\"auth_token\" : \"" . $auth['read']['auth_token'] . "\", \"nonce\" : \"" . $auth['read']['nonce'] . "\"},\n  \"" . lang::get('LANG_Duplicate_Taxon') . "\", 25, 4);\n\n";
     data_entry_helper::$javascript .= "indiciaData.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.sample = " . $sampleId . ";\n";
     if (function_exists('module_exists') && module_exists('easy_login')) {
         data_entry_helper::$javascript .= "indiciaData.easyLogin = true;\n";
         $userId = hostsite_get_user_field('indicia_user_id');
         if (!empty($userId)) {
             data_entry_helper::$javascript .= "indiciaData.UserID = " . $userId . ";\n";
         } else {
             return '<p>Easy Login active but could not identify user</p>';
         }
         // something is wrong
     } else {
         data_entry_helper::$javascript .= "indiciaData.easyLogin = false;\n";
         data_entry_helper::$javascript .= "indiciaData.CMSUserAttrID = " . $cmsUserAttr['attributeId'] . ";\n";
         data_entry_helper::$javascript .= "indiciaData.CMSUserID = " . $user->uid . ";\n";
     }
     // Do an AJAX population of the grid rows.
     data_entry_helper::$javascript .= "loadSpeciesList();\njQuery('#tabs').bind('tabsshow', function(event, ui) {\n    var target = ui.panel;\n    // first get rid of any previous tables\n    jQuery('table.sticky-header').remove();\n    jQuery('table.sticky-enabled thead.tableHeader-processed').removeClass('tableHeader-processed');\n    jQuery('table.sticky-enabled.tableheader-processed').removeClass('tableheader-processed');\n    jQuery('table.species-grid.sticky-enabled').removeClass('sticky-enabled');\n    var table = jQuery('#'+target.id+' table.species-grid');\n    if(table.length > 0) {\n        table.addClass('sticky-enabled');\n        if(typeof Drupal.behaviors.tableHeader == 'object') // Drupal 7\n          Drupal.behaviors.tableHeader.attach(table.parent());\n        else // Drupal6 : it is a function\n          Drupal.behaviors.tableHeader(target);\n    }\n    // remove any hanging autocomplete select list.\n    jQuery('.ac_results').hide();\n});";
     return $r;
 }
 /**
  * Preparing to display an existing sample with occurrences.
  * When displaying a grid of occurrences, just load the sample and data_entry_helper::species_checklist 
  * will load the occurrences.
  * When displaying just one occurrence we must load the sample and the occurrence
  */
 protected static function getEntity($args, $auth)
 {
     data_entry_helper::$entity_to_load = array();
     if (self::getGridMode($args)) {
         // multi-record mode using a checklist grid. We really just need to know the sample ID.
         if (self::$loadedOccurrenceId && !self::$loadedSampleId) {
             $response = data_entry_helper::get_population_data(array('table' => 'occurrence', 'extraParams' => $auth['read'] + array('id' => self::$loadedOccurrenceId, 'view' => 'detail')));
             if (count($response) != 0) {
                 //we found an occurrence so use it to detect the sample
                 self::$loadedSampleId = $response[0]['sample_id'];
             }
         }
     } else {
         // single record entry mode. We want to load the occurrence entity and to know the sample ID.
         if (self::$loadedOccurrenceId) {
             data_entry_helper::load_existing_record($auth['read'], 'occurrence', self::$loadedOccurrenceId, 'detail', false, true);
         } elseif (self::$loadedSampleId) {
             $response = data_entry_helper::get_population_data(array('table' => 'occurrence', 'extraParams' => $auth['read'] + array('sample_id' => self::$loadedSampleId, 'view' => 'detail')));
             self::$loadedOccurrenceId = $response[0]['id'];
             data_entry_helper::load_existing_record_from($response[0], $auth['read'], 'occurrence', self::$loadedOccurrenceId, 'detail', false, true);
         }
         self::$loadedSampleId = data_entry_helper::$entity_to_load['occurrence:sample_id'];
     }
     // Load the sample record
     if (self::$loadedSampleId) {
         data_entry_helper::load_existing_record($auth['read'], 'sample', self::$loadedSampleId, 'detail', false, true);
         // If there is a parent sample - load it next so the details overwrite the child sample.
         if (!empty(data_entry_helper::$entity_to_load['sample:parent_id'])) {
             data_entry_helper::load_existing_record($auth['read'], 'sample', data_entry_helper::$entity_to_load['sample:parent_id']);
             self::$loadedSampleId = data_entry_helper::$entity_to_load['sample:id'];
         }
     }
     // Ensure that if we are used to load a different survey's data, then we get the correct survey attributes. We can change args
     // because the caller passes by reference.
     $args['survey_id'] = data_entry_helper::$entity_to_load['sample:survey_id'];
     $args['sample_method_id'] = data_entry_helper::$entity_to_load['sample:sample_method_id'];
     // enforce that people only access their own data, unless explicitly have permissions
     $editor = !empty($args['edit_permission']) && function_exists('user_access') && user_access($args['edit_permission']);
     if ($editor) {
         return;
     }
     $readOnly = !empty($args['ro_permission']) && function_exists('user_access') && user_access($args['ro_permission']);
     if (function_exists('hostsite_get_user_field') && data_entry_helper::$entity_to_load['sample:created_by_id'] != 1 && data_entry_helper::$entity_to_load['sample:created_by_id'] !== hostsite_get_user_field('indicia_user_id')) {
         if ($readOnly) {
             self::$mode = self::MODE_EXISTING_RO;
         } else {
             throw new exception(lang::get('Attempt to access a record you did not create'));
         }
     }
 }
 /**
  * Return the generated form output.
  * @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 array $response When this form is reloading after saving a submission, contains the response from the service call.
  *                        Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  */
 public static function get_form($args, $nid, $response = null)
 {
     global $user;
     //    if (!function_exists('module_exists') || !module_exists('iform_ajaxproxy'))
     //      return 'This form must be used in Drupal with the Indicia AJAX Proxy module enabled.';
     if (!function_exists('module_exists') || !module_exists('easy_login')) {
         return 'FATAL INTERNAL CONFIGURATION ERROR: This form must be used in Drupal with the Easy Login module enabled.';
     }
     if (!function_exists('module_exists') || !module_exists('species_packages')) {
         return 'FATAL INTERNAL CONFIGURATION ERROR: This form must be used in Drupal with the custom species_packages module enabled.';
     }
     // assuming easy login
     $userId = hostsite_get_user_field('indicia_user_id');
     if (empty($userId)) {
         return '<p>FATAL ERROR: Could not identify user.</p>';
     }
     // something is wrong
     $r = isset($response['error']) ? data_entry_helper::dump_errors($response) : '';
     iform_load_helpers(array('map_helper', 'report_helper'));
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     self::$sampleId = null;
     self::$occurrenceId = false;
     if (isset(data_entry_helper::$entity_to_load['sample:id']) && data_entry_helper::$entity_to_load['sample:id'] != "") {
         // have just posted a (failed) edit to an existing parent sample.
         self::$sampleId = data_entry_helper::$entity_to_load['sample:id'];
     } else {
         if (isset(data_entry_helper::$entity_to_load['sample:survey_id']) && data_entry_helper::$entity_to_load['sample:survey_id'] != "") {
             // have just posted a (failed) edit to a new parent sample.
             self::$sampleId = null;
         } else {
             if (isset($response['outer_id'])) {
                 // have just successfully posted either a new parent sample, or an update to an existing one.
                 self::$sampleId = $response['outer_id'];
                 data_entry_helper::load_existing_record($auth['read'], 'sample', self::$sampleId, 'detail', false, true);
                 if (!isset($_POST['force_page_reload'])) {
                     return self::get_success_page($args, $auth, $response['outer_id']);
                 }
                 drupal_set_message(lang::get('The Transect you have just saved specified the Species Package to be used. The Transect has been reloaded below, and the Species tab now contains the Species Grid for the Species Package, which will allow you to enter the species data.'));
             } else {
                 if (isset($_GET['sample_id']) && intval($_GET['sample_id']) == $_GET['sample_id']) {
                     self::$sampleId = $_GET['sample_id'];
                     data_entry_helper::load_existing_record($auth['read'], 'sample', self::$sampleId, 'detail', false, true);
                 } else {
                     self::$sampleId = null;
                 }
             }
         }
     }
     if (isset($_GET['occurrence_id']) && intval($_GET['occurrence_id']) == $_GET['occurrence_id']) {
         self::$occurrenceId = $_GET['occurrence_id'];
         if (self::$sampleId == null) {
             // fill in the sample_id from the occurrence if don't already have it
             $occurrence = data_entry_helper::get_population_data(array('table' => 'occurrence', 'extraParams' => $auth['read'] + array('view' => 'detail', 'id' => self::$occurrenceId)));
             // this throws an error exception if any error.
             // this gives
             if (count($occurrence) == 1) {
                 $subsample = data_entry_helper::get_population_data(array('table' => 'sample', 'extraParams' => $auth['read'] + array('view' => 'detail', 'id' => $occurrence[0]['sample_id'])));
                 if (count($subsample) == 1) {
                     self::$sampleId = $subsample[0]['parent_id'];
                     data_entry_helper::load_existing_record($auth['read'], 'sample', self::$sampleId, 'detail', false, true);
                 }
             }
         }
     }
     if (isset(data_entry_helper::$entity_to_load['sample:survey_id']) && data_entry_helper::$entity_to_load['sample:survey_id'] != $args['survey_id']) {
         drupal_set_message(t('The data entry form you have selected to use is configured for a particular survey:') . ' ID ' . $args['survey_id'] . ' ' . t('The sample you have chosen to view is not assigned to this survey.'), 'error');
         drupal_goto('<front>');
     }
     if (isset(data_entry_helper::$entity_to_load['sample:parent_id']) && data_entry_helper::$entity_to_load['sample:parent_id'] != '' && data_entry_helper::$entity_to_load['sample:parent_id'] !== null) {
         drupal_set_message(t('An attempt has been made to access a non top level sample.'));
         drupal_goto('<front>');
     }
     $survey = data_entry_helper::get_population_data(array('table' => 'survey', 'extraParams' => $auth['read'] + array('view' => 'detail', 'id' => $args['survey_id'], 'website_id' => $args['website_id'])));
     if (count($survey) != 1) {
         return "FATAL INTERNAL CONFIGURATION ERROR: Supplied form survey_id value (" . $args['survey_id'] . ") is not valid survey for this website (" . $args['website_id'] . ").<br/>";
     }
     $surveyTitle = $survey[0]['title'];
     if (self::$sampleId == null) {
         $packages = species_packages_get_packages($user->uid, $args['survey_id']);
         if ($packages === false || is_array($packages) && count($packages) == 0) {
             drupal_set_message(t('You have not yet selected a species package that is compatible with survey') . ' : &quot;' . $surveyTitle . '&quot;', 'error');
             drupal_set_message(str_replace('#link#', '<a href="' . url('user/' . $user->uid . '/edit') . '">' . t('this link') . '</a>', t('You can set the species package on your user account page, which can be accessed using #link#. If you have already selected a species package, and wish to add another or wish to change your selection, please contact your Hub Manager.')));
             drupal_goto('<front>');
         }
         self::$readOnly = false;
     } else {
         self::$readOnly = !isset($response['error']) && data_entry_helper::$entity_to_load['sample:created_by_id'] != hostsite_get_user_field('indicia_user_id') && (empty($args['edit_permission']) || !hostsite_user_has_permission($args['edit_permission']));
     }
     if (self::$readOnly) {
         drupal_set_message(t('In order to save changes to existing records, you must either be the creator of the entry, or have been given the appropriate permission.'));
     }
     // In readonly mode, the forms are replaced by divs and there are no save buttons.
     //    $r .= '<span style="display:none;">'.print_r($packages,true).'</span>';
     //	$r .= '<span style="display:none;">'.print_r(array($user->uid, $args, $packageAttr), true).'</span>' .
     $attributes = data_entry_helper::getAttributes(array('id' => self::$sampleId, 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'sample_method_id' => $args['transect_level_sample_method_id']));
     $packageAttr = self::extract_package_attr($attributes, true);
     if (!$packageAttr) {
         return "FATAL INTERNAL CONFIGURATION ERROR: This form must be used with a survey which has a &#x22;Species Package&#x22; sample attribute defined for it (integer, required on parent).<br/>";
     }
     self::_remove_options($args);
     $r .= (self::$readOnly ? '<div id="data_entry_form">' : '<form method="post" id="data_entry_form">' . $auth['write']) . '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>' . (isset(data_entry_helper::$entity_to_load['sample:id']) ? '<input type="hidden" name="sample:id" value="' . data_entry_helper::$entity_to_load['sample:id'] . '"/>' : '') . '<input type="hidden" name="sample:survey_id" value="' . $args['survey_id'] . '"/>' . '<input type="hidden" name="sample:sample_method_id" value="' . $args['transect_level_sample_method_id'] . '" />';
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         $r .= "<h2>" . data_entry_helper::$entity_to_load['sample:location_name'] . " on " . data_entry_helper::$entity_to_load['sample:date'] . (self::$readOnly ? ' ' . lang::get('READ ONLY') : '') . "</h2>\n";
     }
     $r .= "<div id=\"tabs\">\n";
     $tabs = array();
     $smpTab = self::get_sample_tab($args, $nid, $auth, $attributes, $packageAttr);
     $mediaTab = self::get_media_tab($args, $nid, $auth);
     $occTab = self::get_occurrences_tab($args, $nid, $auth, $packageAttr);
     // Note this messes with the templates, so done last just in case
     $tabs['#sample'] = t($args['sample_tab_label']);
     if ($occTab != "") {
         $tabs['#occurrences'] = t($args['occurrence_tab_label']);
     }
     if ($mediaTab != "") {
         $tabs['#media'] = t($args['media_tab_label']);
     }
     $r .= data_entry_helper::tab_header(array('tabs' => $tabs));
     data_entry_helper::enable_tabs(array('divId' => 'tabs', 'style' => 'Tabs', 'active' => $occTab != "" && (self::$occurrenceId || self::$sampleId) ? 'occurrences' : 'sample'));
     $r .= $smpTab . $occTab . $mediaTab . '</div>' . (self::$readOnly ? '</div>' : '</form>');
     if (!self::$readOnly) {
         // custom version of enable validation code
         data_entry_helper::$validated_form_id = 'data_entry_form';
         data_entry_helper::$javascript .= "indiciaData.validatedFormId = '" . data_entry_helper::$validated_form_id . "';\n";
         // prevent double submission of the form
         data_entry_helper::$javascript .= "\$('#data_entry_form').submit(function(e) {\r\n  if (typeof \$('#data_entry_form').valid === 'undefined' || \$('#data_entry_form').valid()) {\r\n    if (typeof indiciaData.formSubmitted==='undefined' || !indiciaData.formSubmitted) {\r\n      \$('<p>" . lang::get('Please wait whilst the data is saved.') . "</p>').dialog({ title: '" . lang::get('Saving Data') . "', buttons: { '" . lang::get('OK') . "' : function() { \$( this ).dialog('close'); } } });\r\n      indiciaData.formSubmitted=true;\r\n    } else {\r\n      e.preventDefault();\r\n      return false;\r\n    }\r\n  }\r\n});\n";
         data_entry_helper::add_resource('validation');
     }
     return $r;
 }
 /**
  * Return the generated form output.
  * @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 object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  * @todo: Implement this method 
  */
 public static function get_form($args, $node, $response = null)
 {
     require_once drupal_get_path('module', 'iform') . '/client_helpers/map_helper.php';
     if (function_exists('url')) {
         $args['section_edit_path'] = url($args['section_edit_path']);
     }
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $settings = array('locationTypes' => helper_base::get_termlist_terms($auth, 'indicia:location_types', array('Transect', 'Transect Section')), 'locationId' => isset($_GET['id']) ? $_GET['id'] : null);
     data_entry_helper::$javascript .= "indiciaData.sections = {};\n";
     if ($settings['locationId']) {
         data_entry_helper::load_existing_record($auth['read'], 'location', $settings['locationId']);
         $settings['sections'] = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('view' => 'detail', 'parent_id' => $settings['locationId'], 'deleted' => 'f'), 'nocache' => true));
         foreach ($settings['sections'] as $section) {
             $code = strtolower($section['code']);
             data_entry_helper::$javascript .= "indiciaData.sections.{$code} = {'geom':'" . $section['boundary_geom'] . "','id':'" . $section['id'] . "'};\n";
         }
     } else {
         $settings['sections'] = array();
     }
     $settings['attributes'] = data_entry_helper::getAttributes(array('id' => $settings['locationId'], 'valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'location_type_id' => $settings['locationTypes'][0]['id'], 'multiValue' => true));
     if (false == ($settings['cmsUserAttr'] = extract_cms_user_attr($settings['attributes']))) {
         return 'This form is designed to be used with the CMS User ID attribute setup for locations in the survey.';
     }
     // keep a copy of the location_attribute_id so we can use it later.
     self::$cmsUserAttrId = $settings['cmsUserAttr']['attributeId'];
     $r = '<form method="post" id="input-form">';
     $r .= $auth['write'];
     $r .= '<div id="controls">';
     $customAttributeTabs = array_merge(array('Site Details' => array('[*]')), get_attribute_tabs($settings['attributes']));
     if (count($customAttributeTabs) > 1) {
         $headerOptions = array('tabs' => array());
         foreach ($customAttributeTabs as $tab => $content) {
             $alias = preg_replace('/[^a-zA-Z0-9]/', '', strtolower($tab));
             $headerOptions['tabs']['#' . $alias] = lang::get($tab);
         }
         $r .= data_entry_helper::tab_header($headerOptions);
         data_entry_helper::enable_tabs(array('divId' => 'controls', 'style' => $args['interface'], 'progressBar' => isset($args['tabProgress']) && $args['tabProgress'] == true));
     }
     foreach ($customAttributeTabs as $tab => $content) {
         if ($tab == 'Site Details') {
             $r .= self::get_site_tab($auth, $args, $settings);
         } else {
             $alias = preg_replace('/[^a-zA-Z0-9]/', '', strtolower($tab));
             $r .= "\n<div id=\"{$alias}\">\n";
             $r .= get_attribute_html($settings['attributes'], $args, array('extraParams' => $auth['read']), $tab);
             $r .= "</div>\n";
         }
     }
     $r .= '</div>';
     // controls
     $r .= '<input type="submit" value="' . lang::get('Save') . '" class="ui-state-default ui-corner-all" />';
     $r .= '</form>';
     data_entry_helper::enable_validation('input-form');
     if (function_exists('drupal_set_breadcrumb')) {
         $breadcrumb = array();
         $breadcrumb[] = l(lang::get('Home'), '<front>');
         $breadcrumb[] = l(lang::get('Sites'), $args['sites_list_path']);
         if ($settings['locationId']) {
             $breadcrumb[] = data_entry_helper::$entity_to_load['location:name'];
         } else {
             $breadcrumb[] = lang::get('New Site');
         }
         drupal_set_breadcrumb($breadcrumb);
     }
     return $r;
 }