/**
    * Return the generated form output.
    * @return Form HTML.
    */
   public static function get_form($args, $node, $response = null)
   {
       global $user;
       global $custom_terms;
       $logged_in = $user->uid > 0;
       $r = '';
       // Get authorisation tokens to update and read from the Warehouse.
       $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
       $readAuth = $auth['read'];
       $svcUrl = data_entry_helper::$base_url . '/index.php/services';
       drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/jquery.form.js', 'module');
       data_entry_helper::link_default_stylesheet();
       data_entry_helper::add_resource('jquery_ui');
       $language = iform_lang_iso_639_2($args['language']);
       if ($args['language'] != 'en') {
           data_entry_helper::add_resource('jquery_ui_' . $args['language']);
       }
       // If not logged in: Display an information message.
       // This form should only be called in POST mode when setting the location allocation.
       //  All other posting is now done via AJAX.
       // When invoked by GET there are the following modes:
       // No additional arguments: mode 0.
       // Additional argument - new : mode 1.
       // Additional argument - sample_id=<id> : mode 2.
       // Additional argument - occurrence_id=<id> : mode 3.
       // Additional arguments - merge_sample_id1=<id>&merge_sample_id2=<id> : mode 2.1
       $mode = 0;
       // default mode : output survey selector
       // mode 1: output the main Data Entry page: occurrence list or add/edit occurrence tabs hidden. "Survey" tab active
       // mode 2: output the main Data Entry page, display existing sample. Active tab determined by iform params. No occurence details filled in.
       // mode 2.1: sample 2 has all its occurrences merged into sample 1. sample 2 is then flagged as deleted. sample 1 is then viewed as in normal mode 2.
       // mode 3: output the main Data Entry page, display existing occurrence. "Edit Occurrence" tab active. Occurence details filled in.
       $surveyReadOnly = false;
       // On top of this, things can be flagged as readonly. RO mode 2+4 means no Add Occurrence tab.
       if (!$logged_in) {
           return lang::get('LANG_not_logged_in');
       }
       $parentSample = array();
       $parentLoadID = null;
       $childSample = array();
       $childLoadID = null;
       $thisOccID = -1;
       // IDs have to be >0, so this is outside the valid range
       // Load up attribute details
       $sample_walk_direction_id = self::getAttrID($auth, $args, 'sample', self::ATTR_WALK);
       $sample_reliability_id = self::getAttrID($auth, $args, 'sample', self::ATTR_RELIABILITY);
       $sample_visit_number_id = self::getAttrID($auth, $args, 'sample', self::ATTR_VISIT);
       $sample_wind_id = self::getAttrID($auth, $args, 'sample', self::ATTR_WIND);
       $sample_precipitation_id = self::getAttrID($auth, $args, 'sample', self::ATTR_RAIN);
       $sample_temperature_id = self::getAttrID($auth, $args, 'sample', self::ATTR_TEMP);
       $sample_cloud_id = self::getAttrID($auth, $args, 'sample', self::ATTR_CLOUD);
       $sample_start_time_id = self::getAttrID($auth, $args, 'sample', self::ATTR_START_TIME);
       $sample_end_time_id = self::getAttrID($auth, $args, 'sample', self::ATTR_END_TIME);
       $sample_closure_id = self::getAttrID($auth, $args, 'sample', self::ATTR_CLOSED);
       $uid_attr_id = self::getAttrID($auth, $args, 'sample', self::ATTR_UID);
       $email_attr_id = self::getAttrID($auth, $args, 'sample', self::ATTR_EMAIL);
       $username_attr_id = self::getAttrID($auth, $args, 'sample', self::ATTR_USERNAME);
       $occurrence_confidence_id = self::getAttrID($auth, $args, 'occurrence', self::ATTR_CONFIDENCE);
       $occurrence_count_id = self::getAttrID($auth, $args, 'occurrence', self::ATTR_COUNT);
       $occurrence_approximation_id = self::getAttrID($auth, $args, 'occurrence', self::ATTR_APPROXIMATION);
       $occurrence_territorial_id = self::getAttrID($auth, $args, 'occurrence', self::ATTR_TERRITORIAL);
       $occurrence_atlas_code_id = self::getAttrID($auth, $args, 'occurrence', self::ATTR_ATLAS_CODE);
       $occurrence_overflying_id = self::getAttrID($auth, $args, 'occurrence', self::ATTR_OVERFLYING);
       if (!$sample_closure_id) {
           return '<p>This form must be used with a survey which has the "' . self::ATTR_CLOSED . '" sample attribute allocated to it. Survey_id = ' . $args['survey_id'];
       }
       if (!$uid_attr_id) {
           return '<p>This form must be used with a survey which has the "' . self::ATTR_UID . '" sample attribute allocated to it. Survey_id = ' . $args['survey_id'];
       }
       if (!$email_attr_id) {
           return '<p>This form must be used with a survey which has the "' . self::ATTR_EMAIL . '" sample attribute allocated to it. Survey_id = ' . $args['survey_id'];
       }
       if (!$username_attr_id) {
           return '<p>This form must be used with a survey which has the "' . self::ATTR_USERNAME . '" sample attribute allocated to it. Survey_id = ' . $args['survey_id'];
       }
       if (!$sample_walk_direction_id) {
           return '<p>This form must be used with a survey which has the "' . self::ATTR_WALK . '" sample attribute allocated to it. Survey_id = ' . $args['survey_id'];
       }
       if (!$sample_visit_number_id) {
           return '<p>This form must be used with a survey which has the "' . self::ATTR_VISIT . '" sample attribute allocated to it. Survey_id = ' . $args['survey_id'];
       }
       if (!$occurrence_count_id) {
           return '<p>This form must be used with a survey which has the "' . self::ATTR_COUNT . '" occurrence attribute allocated to it. Survey_id = ' . $args['survey_id'];
       }
       if (!$occurrence_territorial_id) {
           return '<p>This form must be used with a survey which has the "' . self::ATTR_TERRITORIAL . '" occurrence attribute allocated to it. Survey_id = ' . $args['survey_id'];
       }
       if (!$occurrence_atlas_code_id) {
           return '<p>This form must be used with a survey which has the "' . self::ATTR_ATLAS_CODE . '" occurrence attribute allocated to it. Survey_id = ' . $args['survey_id'];
       }
       if ($_POST) {
           if (!array_key_exists('website_id', $_POST)) {
               // non Indicia POST, in this case must be the location allocations. add check to ensure we don't corrept the data by accident
               if (iform_loctools_checkaccess($node, 'admin') && array_key_exists('mnhnlbtw', $_POST)) {
                   iform_loctools_deletelocations($node);
                   foreach ($_POST as $key => $value) {
                       $parts = explode(':', $key);
                       if ($parts[0] == 'location' && $value) {
                           iform_loctools_insertlocation($node, $value, $parts[1]);
                       }
                   }
               }
           }
       } else {
           if (array_key_exists('merge_sample_id1', $_GET) && array_key_exists('merge_sample_id2', $_GET) && user_access($args['edit_permission'])) {
               $mode = 2;
               // first check can access the 2 samples given
               $parentLoadID = $_GET['merge_sample_id1'];
               $url = $svcUrl . '/data/sample/' . $parentLoadID . "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"];
               $session = curl_init($url);
               curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
               $entity = json_decode(curl_exec($session), true);
               if (count($entity) == 0 || $entity[0]["parent_id"]) {
                   return '<p>' . lang::get('LANG_No_Access_To_Sample') . ' ' . $parentLoadID . '</p>';
               }
               // The check for id2 is slightly different: there is the possiblity that someone will F5/refresh their browser, after the transfer and delete have taken place.
               // In this case we carry on, but do not do the transfer and delete.
               $url = $svcUrl . '/data/sample/' . $_GET['merge_sample_id2'] . "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"];
               $session = curl_init($url);
               curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
               $entity = json_decode(curl_exec($session), true);
               if (count($entity) > 0 && !$entity[0]["parent_id"]) {
                   // now get child samples and point to new parent.
                   $url = $svcUrl . '/data/sample?mode=json&view=detail&auth_token=' . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . '&parent_id=' . $_GET['merge_sample_id2'];
                   $session = curl_init($url);
                   curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
                   $entities = json_decode(curl_exec($session), true);
                   if (count($entities) > 0) {
                       foreach ($entities as $entity) {
                           $Model = data_entry_helper::wrap(array('id' => $entity['id'], 'parent_id' => $_GET['merge_sample_id1']), 'sample');
                           $request = data_entry_helper::$base_url . "/index.php/services/data/save";
                           $postargs = 'submission=' . json_encode($Model) . '&auth_token=' . $auth['write_tokens']['auth_token'] . '&nonce=' . $auth['write_tokens']['nonce'] . '&persist_auth=true';
                           $postresponse = data_entry_helper::http_post($request, $postargs, false);
                           // the response array will always feature an output, which is the actual response or error message. if it is not json format, assume error text, and json encode that.
                           $response = $postresponse['output'];
                           if (!json_decode($response, true)) {
                               return "<p>" . lang::get('LANG_Error_When_Moving_Sample') . ": id " . $entity['id'] . " : " . $response;
                           }
                       }
                   }
                   // finally delete the no longer used sample
                   $Model = data_entry_helper::wrap(array('id' => $_GET['merge_sample_id2'], 'deleted' => 'true'), 'sample');
                   $request = data_entry_helper::$base_url . "/index.php/services/data/save";
                   $postargs = 'submission=' . json_encode($Model) . '&auth_token=' . $auth['write_tokens']['auth_token'] . '&nonce=' . $auth['write_tokens']['nonce'] . '&persist_auth=true';
                   $postresponse = data_entry_helper::http_post($request, $postargs, false);
                   // the response array will always feature an output, which is the actual response or error message. if it is not json format, assume error text, and json encode that.
                   $response = $postresponse['output'];
                   if (!json_decode($response, true)) {
                       return "<p>" . lang::get('LANG_Error_When_Deleting_Sample') . ": id " . $entity['id'] . " : " . $response;
                   }
               }
           } else {
               if (array_key_exists('sample_id', $_GET)) {
                   $mode = 2;
                   $parentLoadID = $_GET['sample_id'];
               } else {
                   if (array_key_exists('occurrence_id', $_GET)) {
                       $mode = 3;
                       $childLoadID = $_GET['occurrence_id'];
                       $thisOccID = $childLoadID;
                   } else {
                       if (array_key_exists('new', $_GET)) {
                           $mode = 1;
                       }
                   }
               }
           }
           // else default to mode 0
       }
       // define language strings so they can be used for validation translation.
       data_entry_helper::$javascript .= "var translations = [\n";
       foreach ($custom_terms as $key => $value) {
           if (substr($key, 0, 4) != "LANG") {
               data_entry_helper::$javascript .= "  {key: \"" . $key . "\", translated: \"" . $value . "\"},\n";
           }
       }
       data_entry_helper::$javascript .= "];\n";
       // define layers for all maps.
       // each argument is a comma separated list eg:
       // "Name:Lux Outline,URL:http://localhost/geoserver/wms,LAYERS:indicia:nation2,SRS:EPSG:2169,FORMAT:image/png,minScale:0,maxScale:1000000,units:m";
       $optionsArray_Location = array();
       $options = explode(',', $args['locationLayer']);
       foreach ($options as $option) {
           $parts = explode(':', $option);
           $optionName = $parts[0];
           unset($parts[0]);
           $optionsArray_Location[$optionName] = implode(':', $parts);
       }
       // Work out list of locations this user can see.
       $locations = iform_loctools_listlocations($node);
       if ($locations != 'all') {
           data_entry_helper::$javascript .= "var locationList = [" . implode(',', $locations) . "];\n";
       }
       drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/hasharray.js', 'module');
       drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/jquery.datagrid.js', 'module');
       if (method_exists(get_called_class(), 'getHeaderHTML')) {
           $r .= call_user_func(array(get_called_class(), 'getHeaderHTML'), $args);
       }
       // Work out list of locations this user can see.
       // $locations = iform_loctools_listlocations($node);
       ///////////////////////////////////////////////////////////////////
       // default mode 0 : display a page with tabs for survey selector,
       // locations allocator and reports (last two require permissions)
       ///////////////////////////////////////////////////////////////////
       if ($mode == 0) {
           // If the user has permissions, add tabs so can choose to see
           // locations allocator
           $tabs = array('#surveyList' => lang::get('LANG_Surveys'));
           if (iform_loctools_checkaccess($node, 'admin')) {
               $tabs['#setLocations'] = lang::get('LANG_Allocate_Locations');
           }
           if (iform_loctools_checkaccess($node, 'superuser')) {
               $tabs['#downloads'] = lang::get('LANG_Download');
           }
           if (count($tabs) > 1) {
               $r .= "<div id=\"controls\">" . data_entry_helper::enable_tabs(array('divId' => 'controls', 'active' => '#surveyList')) . "<div id=\"temp\"></div>";
               $r .= data_entry_helper::tab_header(array('tabs' => $tabs));
           }
           if ($locations == 'all') {
               $useloclist = 'NO';
               $loclist = '-1';
           } else {
               // an empty list will cause an sql error, lids must be > 0, so push a -1 to prevent the error.
               if (empty($locations)) {
                   $locations[] = -1;
               }
               $useloclist = 'YES';
               $loclist = implode(',', $locations);
           }
           // Create the Survey list datagrid for this user.
           drupal_add_js("jQuery(document).ready(function(){\n  \$('div#smp_grid').indiciaDataGrid('rpt:reports_for_prebuilt_forms/MNHNL/mnhnl_btw_list_samples', {\n    indiciaSvc: '" . $svcUrl . "',\n    dataColumns: ['location_name', 'date', 'num_visit', 'num_occurrences', 'num_taxa'],\n    reportColumnTitles: {location_name : '" . lang::get('LANG_Transect') . "', date : '" . lang::get('LANG_Date') . "', num_visit : '" . lang::get('LANG_Visit_No') . "', num_occurrences : '" . lang::get('LANG_Num_Occurrences') . "', num_taxa : '" . lang::get('LANG_Num_Species') . "'},\n    actionColumns: {" . lang::get('LANG_Show') . " : \"" . url('node/' . $node->nid, array('query' => 'sample_id=£id£')) . "\"},\n    auth : { nonce : '" . $readAuth['nonce'] . "', auth_token : '" . $readAuth['auth_token'] . "'},\n    parameters : { survey_id : '" . $args['survey_id'] . "', visit_attr_id : '" . $sample_visit_number_id . "', closed_attr_id : '" . $sample_closure_id . "', use_location_list : '" . $useloclist . "', locations : '" . $loclist . "'},\n    itemsPerPage : 12,\n    condCss : {field : 'closed', value : '0', css: 'mnhnl-btw-highlight'},\n    cssOdd : ''\n  });\n});\n      ", 'inline');
           data_entry_helper::$javascript .= "\n// Create Layers.\nvar locationListLayer;\nmapInitialisationHooks.push(function (div) {\n      \"use strict\";";
           if ($locations == 'all' || $loclist != '-1') {
               data_entry_helper::$javascript .= "\n  var WMSoptions = {SERVICE: 'WMS', VERSION: '1.1.0', STYLES: '',\n        SRS: div.map.projection.proj.srsCode, /* Now takes it from map */\n        FORMAT: '" . $optionsArray_Location['FORMAT'] . "',\n        TRANSPARENT: 'true', ";
               if ($locations != 'all') {
                   // when given a restricted feature list we have to use the feature id to filter in order to not go over 2000 char limit on the URL
                   // Can only generate the feature id if we access a table directly, not through a view. Go direct to the locations table.
                   // don't need to worry about parent_id in this case as we know exactly which features we want.
                   // need to use btw_transects view for unrestricted so we can filter by parent_id=NULL.
                   $locFeatures = array();
                   foreach ($locations as $location) {
                       $locFeatures[] = "locations." . $location;
                   }
                   data_entry_helper::$javascript .= "\n        LAYERS: 'indicia:locations',\n        FEATUREID: '" . implode(',', $locFeatures) . "'";
               } else {
                   data_entry_helper::$javascript .= " LAYERS: '" . $optionsArray_Location['LAYERS'] . "', CQL_FILTER: 'website_id=" . $args['website_id'] . "'";
               }
               data_entry_helper::$javascript .= "\n  };\n  locationListLayer = new OpenLayers.Layer.WMS('" . $optionsArray_Location['Name'] . "',\n        '" . (function_exists(iform_proxy_url) ? iform_proxy_url($optionsArray_Location['URL']) : $optionsArray_Location['URL']) . "',\n        WMSoptions, {\n        minScale: " . $optionsArray_Location['minScale'] . ",\n        maxScale: " . $optionsArray_Location['maxScale'] . ",\n        units: '" . $optionsArray_Location['units'] . "',\n        isBaseLayer: false,\n        singleTile: true\n  });\n  div.map.addLayer(locationListLayer);\n});\n";
           }
           $r .= '
 <div id="surveyList" class="mnhnl-btw-datapanel"><div id="smp_grid"></div>
   <form><input type="button" value="' . lang::get('LANG_Add_Survey') . '" onclick="window.location.href=\'' . url('node/' . $node->nid, array('query' => 'new')) . '\'"></form></div>';
           // Add the locations allocator if user has admin rights.
           if (iform_loctools_checkaccess($node, 'admin')) {
               $r .= '
 <div id="setLocations" class="mnhnl-btw-datapanel">
   <form method="post">
     <input type="hidden" id="mnhnlbtw" name="mnhnlbtw" value="mnhnlbtw" />';
               $url = $svcUrl . '/data/location?mode=json&view=detail&auth_token=' . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . "&parent_id=NULL&orderby=name&columns=id,name,parent_id";
               $session = curl_init($url);
               curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
               $entities = json_decode(curl_exec($session), true);
               $userlist = iform_loctools_listusers($node);
               if (!empty($entities)) {
                   foreach ($entities as $entity) {
                       if (!$entity["parent_id"]) {
                           // only assign parent locations.
                           $r .= "\n<label for=\"location:" . $entity["id"] . "\">" . $entity["name"] . ":</label><select id=\"location:" . $entity["id"] . "\" name=\"location:" . $entity["id"] . "\"><option value=\"\" >&lt;" . lang::get('LANG_Not_Allocated') . "&gt;</option>";
                           $defaultuserid = iform_loctools_getuser($node, $entity["id"]);
                           foreach ($userlist as $uid => $a_user) {
                               $r .= "<option value=\"" . $uid . "\" " . ($uid == $defaultuserid ? 'selected="selected" ' : '') . ">" . $a_user->name . "</option>";
                           }
                           $r .= "</select>";
                       }
                   }
               }
               $r .= "\n      <input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('Save Location Allocations') . "\" />\n    </form>\n  </div>";
           }
           // Add the downloader if user has manager (superuser) rights.
           if (iform_loctools_checkaccess($node, 'superuser')) {
               $r .= '
 <div id="downloads" class="mnhnl-btw-datapanel">
   <form method="post" action="' . data_entry_helper::$base_url . '/index.php/services/report/requestReport?report=reports_for_prebuilt_forms/MNHNL/mnhnl_btw_transect_direction_report.xml&reportSource=local&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth['nonce'] . '&mode=csv">
     <p>' . lang::get('LANG_Direction_Report') . '</p>
     <input type="hidden" name="params" value=\'{"survey_id":' . $args['survey_id'] . ', "direction_attr_id":' . $sample_walk_direction_id . ', "closed_attr_id":' . $sample_closure_id . '}\' />
     <input type="submit" class="ui-state-default ui-corner-all" value="' . lang::get('LANG_Direction_Report_Button') . '">
   </form>
   <form method="post" action="' . data_entry_helper::$base_url . '/index.php/services/report/requestReport?report=reports_for_prebuilt_forms/MNHNL/mnhnl_btw_verified_data_report.xml&reportSource=local&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth['nonce'] . '&mode=csv">
     <p>' . lang::get('LANG_Verified_Data_Report') . '</p>
     <input type="hidden" name="params" value=\'{"survey_id":' . $args['survey_id'] . '}\' />
     <input type="submit" class="ui-state-default ui-corner-all" value="' . lang::get('LANG_Verified_Data_Report_Button') . '">
   </form>
   <form method="post" action="' . data_entry_helper::$base_url . '/index.php/services/report/requestReport?report=reports_for_prebuilt_forms/MNHNL/mnhnl_btw_download_report_2.xml&reportSource=local&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth['nonce'] . '&mode=csv">
     <p>' . lang::get('LANG_Initial_Download') . '</p>
     <input type="hidden" name="params" value=\'{"survey_id":' . $args['survey_id'] . ', "closed_attr_id":' . $sample_closure_id . ', "download": "INITIAL", "quality": "!R", "occattrs": "' . $occurrence_confidence_id . ',' . $occurrence_count_id . ',' . $occurrence_approximation_id . ',' . $occurrence_territorial_id . ',' . $occurrence_atlas_code_id . ',' . $occurrence_overflying_id . '", "smpattrs" : "' . $sample_walk_direction_id . ',' . $sample_reliability_id . ',' . $sample_visit_number_id . ',' . $sample_wind_id . ',' . $sample_precipitation_id . ',' . $sample_temperature_id . ',' . $sample_cloud_id . ',' . $sample_start_time_id . ',' . $sample_end_time_id . ',' . $sample_closure_id . ',' . $uid_attr_id . ',' . $email_attr_id . ',' . $username_attr_id . '"}\' />
     <input type="submit" class="ui-state-default ui-corner-all" value="' . lang::get('LANG_Initial_Download_Button') . '">
   </form>
   <form method="post" action="' . data_entry_helper::$base_url . '/index.php/services/report/requestReport?report=reports_for_prebuilt_forms/MNHNL/mnhnl_btw_download_report_2.xml&reportSource=local&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth['nonce'] . '&mode=csv">
     <p>' . lang::get('LANG_Confirm_Download') . '</p>
     <input type="hidden" name="params" value=\'{"survey_id":' . $args['survey_id'] . ', "closed_attr_id":' . $sample_closure_id . ', "download": "CONFIRM", "quality": "V", "occattrs": "' . $occurrence_confidence_id . ',' . $occurrence_count_id . ',' . $occurrence_approximation_id . ',' . $occurrence_territorial_id . ',' . $occurrence_atlas_code_id . ',' . $occurrence_overflying_id . '", "smpattrs" : "' . $sample_walk_direction_id . ',' . $sample_reliability_id . ',' . $sample_visit_number_id . ',' . $sample_wind_id . ',' . $sample_precipitation_id . ',' . $sample_temperature_id . ',' . $sample_cloud_id . ',' . $sample_start_time_id . ',' . $sample_end_time_id . ',' . $sample_closure_id . ',' . $uid_attr_id . ',' . $email_attr_id . ',' . $username_attr_id . '"}\' />
     <input type="submit" class="ui-state-default ui-corner-all" value="' . lang::get('LANG_Confirm_Download_Button') . '">
   </form>
   <form method="post" action="' . data_entry_helper::$base_url . '/index.php/services/report/requestReport?report=reports_for_prebuilt_forms/MNHNL/mnhnl_btw_download_report_2.xml&reportSource=local&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth['nonce'] . '&mode=csv">
     <p>' . lang::get('LANG_Final_Download') . '</p>
     <input type="hidden" name="params" value=\'{"survey_id":' . $args['survey_id'] . ', "closed_attr_id":' . $sample_closure_id . ', "download": "FINAL", "quality": "V", "occattrs": "' . $occurrence_confidence_id . ',' . $occurrence_count_id . ',' . $occurrence_approximation_id . ',' . $occurrence_territorial_id . ',' . $occurrence_atlas_code_id . ',' . $occurrence_overflying_id . '", "smpattrs" : "' . $sample_walk_direction_id . ',' . $sample_reliability_id . ',' . $sample_visit_number_id . ',' . $sample_wind_id . ',' . $sample_precipitation_id . ',' . $sample_temperature_id . ',' . $sample_cloud_id . ',' . $sample_start_time_id . ',' . $sample_end_time_id . ',' . $sample_closure_id . ',' . $uid_attr_id . ',' . $email_attr_id . ',' . $username_attr_id . '"}\' />
     <input type="submit" class="ui-state-default ui-corner-all" value="' . lang::get('LANG_Final_Download_Button') . '">
   </form>
   <form method="post" action="' . data_entry_helper::$base_url . '/index.php/services/report/requestReport?report=reports_for_prebuilt_forms/MNHNL/mnhnl_btw_download_report_2.xml&reportSource=local&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth['nonce'] . '&mode=csv">
     <p>' . lang::get('LANG_Complete_Final_Download') . '</p>
     <input type="hidden" name="params" value=\'{"survey_id":' . $args['survey_id'] . ', "closed_attr_id":' . $sample_closure_id . ', "download": "OFF", "quality": "NA", "occattrs": "' . $occurrence_confidence_id . ',' . $occurrence_count_id . ',' . $occurrence_approximation_id . ',' . $occurrence_territorial_id . ',' . $occurrence_atlas_code_id . ',' . $occurrence_overflying_id . '", "smpattrs" : "' . $sample_walk_direction_id . ',' . $sample_reliability_id . ',' . $sample_visit_number_id . ',' . $sample_wind_id . ',' . $sample_precipitation_id . ',' . $sample_temperature_id . ',' . $sample_cloud_id . ',' . $sample_start_time_id . ',' . $sample_end_time_id . ',' . $sample_closure_id . ',' . $uid_attr_id . ',' . $email_attr_id . ',' . $username_attr_id . '"}\' />
     <input type="submit" class="ui-state-default ui-corner-all" value="' . lang::get('LANG_Complete_Final_Download_Button') . '">
   </form>
 </div>';
           }
           // Create Map
           $options = iform_map_get_map_options($args, $readAuth);
           $olOptions = iform_map_get_ol_options($args);
           //      if($locations == 'all' || $loclist != '-1')
           //        $options['layers'] = array('locationListLayer');
           $options['searchLayer'] = 'false';
           $options['editLayer'] = 'false';
           $options['initialFeatureWkt'] = null;
           $options['proxy'] = '';
           $options['scroll_wheel_zoom'] = false;
           $options['width'] = 'auto';
           // TBD remove from arglist
           $r .= "<div class=\"mnhnl-btw-mappanel\">\n" . data_entry_helper::map_panel($options, $olOptions) . "</div>\n";
           data_entry_helper::$javascript .= "\n\$('#controls').bind('tabsshow', function(event, ui) {\n  var y = \$('.mnhnl-btw-datapanel:visible').outerHeight(true) + \$('.mnhnl-btw-datapanel:visible').position().top;\n  if(y < \$('.mnhnl-btw-mappanel').outerHeight(true)+ \$('.mnhnl-btw-mappanel').position().top){\n    y = \$('.mnhnl-btw-mappanel').outerHeight(true)+ \$('.mnhnl-btw-mappanel').position().top;\n  }\n  \$('#controls').height(y - \$('#controls').position().top);\n});\n";
           if (count($tabs) > 1) {
               // close tabs div if present
               $r .= "</div>";
           }
           if (method_exists(get_called_class(), 'getTrailerHTML')) {
               $r .= call_user_func(array(get_called_class(), 'getTrailerHTML'), $args);
           }
           return $r;
       }
       ///////////////////////////////////////////////////////////////////
       // At this point there are 3 modes:
       // Adding a new survey
       // editing/showing an existing survey
       // editing/showing an existing occurrence
       // First load the occurrence (and its position sample) if provided
       // Then load the parent sample if provided, or derived from occurrence.
       // $occReadOnly is set if the occurrence has been downloaded. Not even an admin user can modify it in this case.
       data_entry_helper::$javascript .= "\n// Create Layers.\nvar locationLayer, occListLayer, control;\nmapInitialisationHooks.push(function (div) {\n  \"use strict\";\n  // Create vector layers: one to display the location onto, and another for the occurrence list\n  // the default edit layer is used for the occurrences themselves\n  var locStyleMap = new OpenLayers.StyleMap({\n      'default': new OpenLayers.Style({\n        fillColor: 'Green',\n        strokeColor: 'Black',\n        fillOpacity: 0.2,\n        strokeWidth: 1\n  })});\n  locationLayer = new OpenLayers.Layer.Vector('" . lang::get("LANG_Location_Layer") . "', {styleMap: locStyleMap});\n  var occStyleMap = new OpenLayers.StyleMap({\n      'default': new OpenLayers.Style({\n        pointRadius: 3,\n        fillColor: 'Red',\n        fillOpacity: 0.3,\n        strokeColor: 'Red',\n        strokeWidth: 1\n  })});\n  occListLayer = new OpenLayers.Layer.Vector(\"" . lang::get("LANG_Occurrence_List_Layer") . "\", {styleMap: occStyleMap});\n  div.map.addLayer(locationLayer);\n  div.map.addLayer(occListLayer);\n  var control = new OpenLayers.Control.SelectFeature(occListLayer);\n  occListLayer.map.addControl(control);\n  function onPopupClose(evt) {\n    // 'this' is the popup.\n    control.unselect(this.feature);\n  }\n  function onFeatureSelect(evt) {\n    feature = evt.feature;\n    popup = new OpenLayers.Popup.FramedCloud(\"featurePopup\",\n               feature.geometry.getBounds().getCenterLonLat(),\n                             new OpenLayers.Size(100,100),\n                             feature.attributes.taxon + \" (\" + feature.attributes.count + \")\",\n                             null, true, onPopupClose);\n    feature.popup = popup;\n    popup.feature = feature;\n    feature.layer.map.addPopup(popup);\n  }\n  function onFeatureUnselect(evt) {\n    feature = evt.feature;\n    if (feature.popup) {\n        popup.feature = null;\n        feature.layer.map.removePopup(feature.popup);\n        feature.popup.destroy();\n        feature.popup = null;\n    }\n  }\n  occListLayer.events.on({\n    'featureselected': onFeatureSelect,\n    'featureunselected': onFeatureUnselect\n  });\n  control.activate();\n});\n";
       $occReadOnly = false;
       $childSample = array();
       if ($childLoadID) {
           // load the occurrence and its associated sample (which holds the position)
           $url = $svcUrl . '/data/occurrence/' . $childLoadID;
           $url .= "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"];
           $session = curl_init($url);
           curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
           $entity = json_decode(curl_exec($session), true);
           if (count($entity) == 0) {
               return '<p>' . lang::get('LANG_No_Access_To_Occurrence') . '</p>';
           }
           foreach ($entity[0] as $key => $value) {
               $childSample['occurrence:' . $key] = $value;
           }
           if ($entity[0]['downloaded_flag'] == 'F') {
               // Final download complete, now readonly
               $occReadOnly = true;
           }
           $url = $svcUrl . '/data/sample/' . $childSample['occurrence:sample_id'];
           $url .= "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"];
           $session = curl_init($url);
           curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
           $entity = json_decode(curl_exec($session), true);
           if (count($entity) == 0) {
               return '<p>' . lang::get('LANG_No_Access_To_Occurrence') . '</p>';
           }
           foreach ($entity[0] as $key => $value) {
               $childSample['sample:' . $key] = $value;
           }
           $childSample['sample:geom'] = '';
           // value received from db is not WKT, which is assumed by all the code.
           $childSample['taxon'] = $childSample['occurrence:taxon'];
           $parentLoadID = $childSample['sample:parent_id'];
       }
       $parentSample = array();
       if ($parentLoadID) {
           // load the container master sample
           $url = $svcUrl . '/data/sample/' . $parentLoadID;
           $url .= "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"];
           $session = curl_init($url);
           curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
           $entity = json_decode(curl_exec($session), true);
           if (count($entity) == 0) {
               return '<p>' . lang::get('LANG_No_Access_To_Sample') . '</p>';
           }
           foreach ($entity[0] as $key => $value) {
               $parentSample['sample:' . $key] = $value;
           }
           if (is_array($locations) && !in_array($entity[0]["location_id"], $locations)) {
               return '<p>' . lang::get('LANG_No_Access_To_Location') . '</p>';
           }
           if ($entity[0]["parent_id"]) {
               return '<p>' . lang::get('LANG_No_Access_To_Sample') . '</p>';
           }
           $parentSample['sample:date'] = $parentSample['sample:date_start'];
           // bit of a bodge
           $childSample['sample:date'] = $parentSample['sample:date'];
           // enforce a match between child and parent sample dates
           // default values for attributes from DB are picked up automatically.
       }
       data_entry_helper::$entity_to_load = $parentSample;
       $attributes = data_entry_helper::getAttributes(array('id' => data_entry_helper::$entity_to_load['sample:id'], 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $readAuth));
       $closedFieldName = $attributes[$sample_closure_id]['fieldname'];
       $closedFieldValue = data_entry_helper::check_default_value($closedFieldName, array_key_exists('default', $attributes[$sample_closure_id]) ? $attributes[$sample_closure_id]['default'] : '0');
       // default is not closed
       if ($closedFieldValue == '') {
           $closedFieldValue = '0';
       }
       if ($closedFieldValue == '1' && !user_access($args['edit_permission'])) {
           // sample has been closed, no admin perms. Everything now set to read only.
           $surveyReadOnly = true;
           $disabledText = "disabled=\"disabled\"";
           $defAttrOptions = array('extraParams' => $readAuth, 'disabled' => $disabledText);
       } else {
           // sample editable. Admin users can modify closed samples.
           $disabledText = "";
           $defAttrOptions = array('extraParams' => $readAuth);
       }
       // with the AJAX code, we deal with the validation semi manually: Form name is meant be invalid as we only want code included.
       data_entry_helper::enable_validation(null);
       $r .= "<div id=\"controls\">\n";
       $activeTab = 'survey';
       // mode 1 = new Sample, display sample.
       if ($mode == 2) {
           // have specified a sample ID
           if ($args["on_edit_survey_nav"] == "survey") {
               $activeTab = 'survey';
           } else {
               if ($surveyReadOnly || $args["on_edit_survey_nav"] == "list") {
                   $activeTab = 'occurrenceList';
               } else {
                   $activeTab = 'occurrence';
               }
           }
           if ($surveyReadOnly) {
               data_entry_helper::$javascript .= "jQuery('#occ-form').hide();";
           }
       } else {
           if ($mode == 3) {
               // have specified an occurrence ID
               $activeTab = 'occurrence';
           }
       }
       // Set Up form tabs.
       $r .= data_entry_helper::enable_tabs(array('divId' => 'controls', 'active' => $activeTab));
       $r .= "<div id=\"temp\"></div>";
       $r .= data_entry_helper::tab_header(array('tabs' => array('#survey' => lang::get('LANG_Survey'), '#occurrence' => lang::get($surveyReadOnly || $occReadOnly ? 'LANG_Show_Occurrence' : (isset($childSample['sample:id']) ? 'LANG_Edit_Occurrence' : 'LANG_Add_Occurrence')), '#occurrenceList' => lang::get('LANG_Occurrence_List'))));
       // Set up main Survey Form.
       $r .= "<div id=\"survey\" class=\"mnhnl-btw-datapanel\">\n  <p id=\"read-only-survey\"><strong>" . lang::get('LANG_Read_Only_Survey') . "</strong></p>";
       if (user_access($args['edit_permission']) && array_key_exists('sample:id', data_entry_helper::$entity_to_load)) {
           // check for other surveys of same date/transect: only if admin user.
           $url = $svcUrl . '/data/sample?mode=json&view=detail&auth_token=' . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . "&date_start=" . $parentSample['sample:date_start'] . "&location_id=" . $parentSample['sample:location_id'];
           $session = curl_init($url);
           curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
           $entity = json_decode(curl_exec($session), true);
           if (count($entity) > 1) {
               // ignore ourselves!
               $r .= "<div id=\"mergeSurveys\"><p><strong>" . lang::get('LANG_Found_Mergable_Surveys') . "</strong></p>";
               foreach ($entity as $survey) {
                   if ($survey['id'] != $parentSample['sample:id']) {
                       $r .= "<form action=\"" . url('node/' . $node->nid, array()) . "\" method=\"get\"><input type=\"submit\" value=\"" . lang::get('LANG_Merge_With_ID') . " " . $survey['id'] . "\"><input type=\"hidden\" name=\"merge_sample_id1\" value=\"" . $parentSample['sample:id'] . "\" /><input type=\"hidden\" name=\"merge_sample_id2\" value=\"" . $survey['id'] . "\" /></form>";
                   }
               }
               $r .= "</div>";
           }
       }
       $r .= "<form id=\"SurveyForm\" action=\"" . iform_ajaxproxy_url($node, 'sample') . "\" method=\"post\">\n    <input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n    <input type=\"hidden\" id=\"sample:survey_id\" name=\"sample:survey_id\" value=\"" . $args['survey_id'] . "\" />";
       if (array_key_exists('sample:id', data_entry_helper::$entity_to_load)) {
           $r .= "<input type=\"hidden\" id=\"sample:id\" name=\"sample:id\" value=\"" . data_entry_helper::$entity_to_load['sample:id'] . "\" />\n";
       } else {
           $r .= "<input type=\"hidden\" id=\"sample:id\" name=\"sample:id\" value=\"\" disabled=\"disabled\" />\n";
           // GvB 19/Nov/2012 : change to user detail defaults
           // logic is now much simpler, and they are only included/created if the sample is new.
           $fieldName = $attributes[$uid_attr_id]['fieldname'];
           $fieldValue = data_entry_helper::check_default_value($fieldName, $user->uid);
           $r .= "<input type=\"hidden\" name=\"" . $fieldName . "\" value=\"" . $fieldValue . "\" />\n";
           $fieldName = $attributes[$email_attr_id]['fieldname'];
           $fieldValue = data_entry_helper::check_default_value($fieldName, $user->mail);
           $r .= "<input type=\"hidden\" name=\"" . $fieldName . "\" value=\"" . $fieldValue . "\" />\n";
           $fieldName = $attributes[$username_attr_id]['fieldname'];
           $fieldValue = data_entry_helper::check_default_value($fieldName, $user->name);
           $r .= "<input type=\"hidden\" name=\"" . $fieldName . "\" value=\"" . $fieldValue . "\" />\n";
       }
       $defAttrOptions['validation'] = array('required');
       if ($locations == 'all') {
           $locOptions = array_merge(array('label' => lang::get('LANG_Transect')), $defAttrOptions);
           $locOptions['extraParams'] = array_merge(array('parent_id' => 'NULL', 'view' => 'detail', 'orderby' => 'name'), $locOptions['extraParams']);
           $r .= data_entry_helper::location_select($locOptions);
       } else {
           // can't use location select due to location filtering.
           $r .= "<label for=\"imp-location\">" . lang::get('LANG_Transect') . ":</label>\n<select id=\"imp-location\" name=\"sample:location_id\" " . $disabled_text . " class=\" \"  >";
           $url = $svcUrl . '/data/location?mode=json&view=detail&parent_id=NULL&orderby=name&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth["nonce"];
           $session = curl_init($url);
           curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
           $entities = json_decode(curl_exec($session), true);
           if (!empty($entities)) {
               foreach ($entities as $entity) {
                   if (in_array($entity["id"], $locations)) {
                       if ($entity["id"] == data_entry_helper::$entity_to_load['sample:location_id']) {
                           $selected = 'selected="selected"';
                       } else {
                           $selected = '';
                       }
                       $r .= "<option value=\"" . $entity["id"] . "\" " . $selected . ">" . $entity["name"] . "</option>";
                   }
               }
           }
           $r .= "</select><span class=\"deh-required\">*</span><br />";
       }
       $languageFilteredAttrOptions = $defAttrOptions + array('language' => iform_lang_iso_639_2($args['language']));
       $r .= data_entry_helper::outputAttribute($attributes[$sample_walk_direction_id], $languageFilteredAttrOptions) . ($sample_reliability_id ? data_entry_helper::outputAttribute($attributes[$sample_reliability_id], $languageFilteredAttrOptions) : "<span style=\"display: none;\">Sample attribute '" . self::ATTR_RELIABILITY . "' not assigned to this survey</span>") . data_entry_helper::outputAttribute($attributes[$sample_visit_number_id], array_merge($languageFilteredAttrOptions, array('default' => 1, 'noBlankText' => true)));
       if (isset(data_entry_helper::$entity_to_load['sample:date']) && preg_match('/^(\\d{4})/', data_entry_helper::$entity_to_load['sample:date'])) {
           // Date has 4 digit year first (ISO style) - convert date to expected output format
           $d = new DateTime(data_entry_helper::$entity_to_load['sample:date']);
           data_entry_helper::$entity_to_load['sample:date'] = $d->format('d/m/Y');
       }
       if ($args['language'] != 'en') {
           data_entry_helper::add_resource('jquery_ui_' . $args['language']);
       }
       // this will autoload the jquery_ui resource. The date_picker does not have access to the args.
       if ($surveyReadOnly) {
           $r .= data_entry_helper::text_input(array_merge($defAttrOptions, array('label' => lang::get('LANG_Date'), 'fieldname' => 'sample:date', 'disabled' => $disabledText)));
       } else {
           $r .= data_entry_helper::date_picker(array('label' => lang::get('LANG_Date'), 'fieldname' => 'sample:date', 'class' => 'vague-date-picker'));
       }
       $r .= ($sample_wind_id ? data_entry_helper::outputAttribute($attributes[$sample_wind_id], $languageFilteredAttrOptions) : "<span style=\"display: none;\">Sample attribute '" . self::ATTR_WIND . "' not assigned to this survey</span>") . ($sample_precipitation_id ? data_entry_helper::outputAttribute($attributes[$sample_precipitation_id], $languageFilteredAttrOptions) : "<span style=\"display: none;\">Sample attribute '" . self::ATTR_RAIN . "' not assigned to this survey</span>") . ($sample_temperature_id ? data_entry_helper::outputAttribute($attributes[$sample_temperature_id], array_merge($defAttrOptions, array('suffixTemplate' => 'nosuffix'))) . "<span class=\"attr-trailer\"> &deg;C</span><br />" : "<span style=\"display: none;\">Sample attribute '" . self::ATTR_TEMP . "' not assigned to this survey</span>") . ($sample_cloud_id ? data_entry_helper::outputAttribute($attributes[$sample_cloud_id], $defAttrOptions) : "<span style=\"display: none;\">Sample attribute '" . self::ATTR_CLOUD . "' not assigned to this survey</span>") . ($sample_start_time_id ? data_entry_helper::outputAttribute($attributes[$sample_start_time_id], array_merge($defAttrOptions, array('suffixTemplate' => 'nosuffix'))) . "<span class=\"attr-trailer\"> hh:mm</span><br />" : "<span style=\"display: none;\">Sample attribute '" . self::ATTR_START_TIME . "' not assigned to this survey</span>") . ($sample_end_time_id ? data_entry_helper::outputAttribute($attributes[$sample_end_time_id], array_merge($defAttrOptions, array('suffixTemplate' => 'nosuffix'))) . "<span class=\"attr-trailer\"> hh:mm</span><br />" : "<span style=\"display: none;\">Sample attribute '" . self::ATTR_END_TIME . "' not assigned to this survey</span>");
       data_entry_helper::$javascript .= "\njQuery('.attr-trailer').prev('br').remove();\n";
       unset($defAttrOptions['suffixTemplate']);
       unset($defAttrOptions['validation']);
       if (user_access($args['edit_permission'])) {
           //  users with admin permissions can override the closing of the
           // sample by unchecking the checkbox.
           // Because this is attached to the sample, we have to include the sample required fields in the
           // the post. This means they can't be disabled, so we enable all fields in this case.
           // Normal users can only set this to closed, and they do this using a button/hidden field.
           $r .= data_entry_helper::outputAttribute($attributes[$sample_closure_id], $defAttrOptions);
           // In addition admin users can delete a survey/sample.
           $r .= data_entry_helper::checkbox(array('label' => lang::get('Deleted'), 'fieldname' => 'sample:deleted', 'id' => 'main-sample-deleted'));
       } else {
           // hidden closed
           $r .= "<input type=\"hidden\" id=\"main-sample-closed\" name=\"" . $closedFieldName . "\" value=\"" . $closedFieldValue . "\" />\n";
       }
       data_entry_helper::$javascript .= "\n\$.validator.messages.required = \"" . lang::get('validation_required') . "\";\n\$.validator.defaults.onsubmit = false; // override default - so that we handle all submission validation.\n";
       if (!$surveyReadOnly) {
           // NB that we don't even include the buttons when readonly.
           data_entry_helper::$javascript .= "\njQuery('#read-only-survey').hide();\njQuery('#ro-sur-occ-warn').hide();\n";
           $r .= "<input type=button id=\"close1\" class=\"ui-state-default ui-corner-all \" value=\"" . lang::get('LANG_Save_Survey_Details') . "\";\n        onclick=\"var result = \$('#SurveyForm input').valid();\n          var result2 = \$('#SurveyForm select').valid();\n          if (!result || !result2) {\n              return;\n            }\n            jQuery('#close1').addClass('loading-button');\n            jQuery('#SurveyForm').submit();\">\n";
           if (!user_access($args['edit_permission'])) {
               if ($mode == 1) {
                   data_entry_helper::$javascript .= "jQuery('#close2').hide();\n";
               }
               $r .= "<input type=button id=\"close2\" class=\"ui-state-default ui-corner-all \" value=\"" . lang::get('LANG_Save_Survey_And_Close') . "\"\n        onclick=\"if(confirm('" . lang::get('LANG_Close_Survey_Confirm') . "')){\n          var result = \$('#SurveyForm input').valid();\n          var result2 = \$('#SurveyForm select').valid();\n          if (!result || !result2) {\n              return;\n            }\n            jQuery('#main-sample-closed').val('1');\n            jQuery('#close2').addClass('loading-button');\n            jQuery('#SurveyForm').submit();\n          };\">\n";
           }
       }
       $r .= "</form></div>\n";
       data_entry_helper::$javascript .= "\nalertIndiciaError = function(data){\n\tvar errorString = \"" . lang::get('LANG_Indicia_Warehouse_Error') . "\";\n\tif(data.error){\terrorString = errorString + ' : ' + data.error;\t}\n\tif(data.errors){\n\t\tfor (var i in data.errors){\n\t\t\terrorString = errorString + ' : ' + data.errors[i];\n\t\t}\n\t}\n\talert(errorString);\n\t// the most likely cause is authentication failure - eg the read authentication has timed out.\n\t// prevent further use of the form:\n\t\$('.loading-panel').remove();\n\t\$('.loading-hide').removeClass('loading-hide');\n};\nerrorPos = null;\nclearErrors = function(formSel) {\n\tjQuery(formSel).find('.inline-error').remove();\n\terrorPos = null;\n};\nmyScrollTo = function(selector){\n\tjQuery(selector).filter(':visible').each(function(){\n\t\tif(errorPos == null || jQuery(this).offset().top < errorPos){\n\t\t\terrorPos = jQuery(this).offset().top;\n\t\t\twindow.scroll(0,errorPos);\n\t\t}\n\t});\n};\nmyScrollToError = function(){\n\tjQuery('.inline-error,.error').filter(':visible').prev().each(function(){\n\t\tif(errorPos == null || jQuery(this).offset().top < errorPos){\n\t\t\terrorPos = jQuery(this).offset().top;\n\t\t\twindow.scroll(0,errorPos);\n\t\t}\n\t});\n};\njQuery('#SurveyForm').ajaxForm({\n\tasync: false,\n\tdataType:  'json',\n    beforeSubmit:   function(data, obj, options){\n    \tvar valid = true;\n    \tclearErrors('form#SurveyForm');\n    \tif (!jQuery('form#SurveyForm > input').valid()) {\n\t\t\tmyScrollToError();\n  \t\t\tjQuery('.loading-button').removeClass('loading-button');\n\t\t\treturn false;\n  \t\t};\n  \t\tSurveyFormRetVal = true;\n  \t\tif(jQuery('#main-sample-deleted:checked').length == 0){ // only do check if not deleting\n          jQuery.ajax({ // now check if there are any other samples with this combination of date and location\n            type: 'GET',\n            url: \"" . $svcUrl . "/data/sample?mode=json&view=detail\" +\n                \"&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n                \"&orderby=id&callback=?&location_id=\"+jQuery('#imp-location').val()+\"&date_start=\"+jQuery('#SurveyForm [name=sample\\:date]').val(),\n            data: {},\n            success: function(detData) {\n              for(i=0, j=0; i< detData.length; i++){\n                if(detData[i].id != jQuery('#SurveyForm [name=sample\\:id]').val()) j++;\n              }\n              if(j) {\n              \tSurveyFormRetVal = confirm(\"" . lang::get('LANG_Survey_Already_Exists') . "\");\n              }\n            },\n            dataType: 'json',\n            async: false\n          });\n        }\n\t\treturn SurveyFormRetVal;\n\t},\n    success:   function(data){\n       // this will leave all the fields populated.\n       \tif(data.success == 'multiple records' && data.outer_table == 'sample'){\n          jQuery('#occ-form').show();\n          jQuery('#na-occ-warn,#mergeSurveys').hide();";
       if (!user_access($args['edit_permission'])) {
           // don't need to worry about record_status value for non admins as they can't modify when closed.
           data_entry_helper::$javascript .= "\n          if(jQuery('#main-sample-closed').val() == '1'){\n            jQuery('#read-only-survey,#ro-sur-occ-warn').show();\n            jQuery('#close1,#close2,#occ-form').hide(); //can't enter any more occurrences\n            jQuery('#SurveyForm').children().attr('disabled','disabled');\n          };\n";
       } else {
           data_entry_helper::$javascript .= "\n          jQuery('#occurrence\\\\:record_status').val(jQuery('#smpAttr\\\\:" . $attributes[$sample_closure_id]['attributeId'] . ":checked').length > 0 ? 'C' : 'I');\n          if(jQuery('#main-sample-deleted:checked').length > 0){\n            jQuery('#return-to-main').click();\n            return;\n          };\n";
       }
       data_entry_helper::$javascript .= "// If sample_id filled in -> we have a previously saved collection, so possibly have subsamples.\nif(jQuery('#SurveyForm > input[name=sample\\:id]').val() != ''){\n    // Put up warning dialogue that we are checking the subsamples: include a progress bar: set to zero%.\n    var dialog = \$('<span id=\"subsample-progress-span\"><p>'+\"" . lang::get('Please wait whilst some data integrity checks are carried out.') . "\"+'</p><div id=\"subsample-progress\"></div></span>').dialog({ title: \"" . lang::get('Checks') . "\", zIndex: 4000 });\n    jQuery('#subsample-progress').progressbar({value: 0});\n    jQuery.ajax({ // get all subsamples/occurrences to check if the dates match\n            type: 'GET',\n            url: \"" . $svcUrl . "/report/requestReport?report=library/occurrences/occurrences_list_for_parent_sample.xml&reportSource=local&mode=json&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n                \"&callback=?&sample_id=\"+data.outer_id+\"&survey_id=&date_from=&date_to=&taxon_group_id=&smpattrs=&occattrs=\",\n            data: {},\n            success: function(subData) {\n              jQuery('#subsample-progress').data('max',subData.length+1);\n              var mainDate = \$.datepicker.formatDate('yy-mm-dd', jQuery('#SurveyForm > input[name=sample\\:date]').datepicker(\"getDate\"));\n              for(i=0; i< subData.length; i++){ // loop through all subsamples\n                jQuery('#subsample-progress').progressbar('option','value',(i+1)*100/jQuery('#subsample-progress').data('max'));\n                var values = {};\n                var url = '';\n                // Check if date on subsamples matches supersample date: if not set up a post array for the sample, with correct date.\n                if(subData[i].date_start != mainDate){\n                  values['sample:id']=subData[i].sample_id;\n                  values['sample:date']=mainDate;\n                  url=\"" . iform_ajaxproxy_url($node, 'sample') . "\";\n                }\n";
       // Send AJAX request to set occurrence to 'C' if closed : use sync
       if (!user_access($args['edit_permission'])) {
           data_entry_helper::$javascript .= "                if(jQuery('#main-sample-closed').val() == '1'){\n";
       } else {
           data_entry_helper::$javascript .= "                if(jQuery('#smpAttr\\\\:" . $attributes[$sample_closure_id]['attributeId'] . ":checked').length > 0){\n";
       }
       // If records are already verified, they are left verified, as if the records themselves are saved
       // they will flagged as no longer verified: But have to force a re verification if date is changed.
       data_entry_helper::$javascript .= "\n                  if(subData[i].record_status == 'I' || typeof values['sample:id'] != 'undefined'){\n                    values['occurrence:id']=subData[i].occurrence_id;\n                    values['occurrence:record_status']='C';\n                    url=(url == '' ? \"" . iform_ajaxproxy_url($node, 'occurrence') . "\" : \"" . iform_ajaxproxy_url($node, 'smp-occ') . "\");\n                  }\n                } else { // any occurrences on unclosed collections must be flagged as 'I' - reopening unverifies.\n                  if(subData[i].record_status != 'I'){\n                    values['occurrence:id']=subData[i].occurrence_id;\n                    values['occurrence:record_status']='I';\n                    url=(url == '' ? \"" . iform_ajaxproxy_url($node, 'occurrence') . "\" : \"" . iform_ajaxproxy_url($node, 'smp-occ') . "\");\n                  }\n                }\n                if(url!=''){\n                  values['website_id']=" . $args['website_id'] . ";\n                  jQuery.ajax({ type: 'POST', url: url, data: values, dataType: 'json', async: false});\n                }\n              }\n            },\n            dataType: 'json',\n            async: false\n    });\n    dialog.dialog('close');\n    dialog.dialog('destroy');\n    jQuery('#subsample-progress-span').remove();\n}\n\n\t\t\twindow.scroll(0,0);\n            jQuery('#SurveyForm > input[name=sample\\:id]').removeAttr('disabled').val(data.outer_id);\n            jQuery('#occ-form > input[name=sample\\:parent_id]').val(data.outer_id);\n            jQuery('#occ-form > input[name=sample\\:date]').val(jQuery('#SurveyForm > input[name=sample\\:date]').val());\n            loadAttributes('sample_attribute_value', 'sample_attribute_id', 'sample_id', data.outer_id, 'smpAttr');\n            switch(\"" . $args["on_save_survey_nav"] . "\"){\n\t\t\t\tcase \"list\":\n\t\t\t\t\tvar a = \$('ul.ui-tabs-nav a')[2];\n\t\t\t\t\t\$(a).click();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"survey\":\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:";
       if (!user_access($args['edit_permission'])) {
           data_entry_helper::$javascript .= "\n\t\t\t\t\tif(jQuery('#main-sample-closed').val() == 0){\n\t\t\t\t\t\tvar a = \$('ul.ui-tabs-nav a')[1];\n\t\t\t\t\t\t\$(a).click();\n\t\t\t\t\t};";
       } else {
           data_entry_helper::$javascript .= "\n\t\t\t\t\tvar a = \$('ul.ui-tabs-nav a')[1];\n\t\t\t\t\t\$(a).click();";
       }
       data_entry_helper::$javascript .= "\n\t\t\t\t\tbreak;\n\t\t\t}\n        } else {\n\t\t\tif(data.error){\n\t\t\t\tvar lastIndex = data.error.lastIndexOf('Validation error');\n    \t\t\tif (lastIndex != -1 && lastIndex  == (data.error.length - 16)){\n\t\t\t\t\tif(data.errors){\n\t\t\t\t\t\t// TODO translation\n\t\t\t\t\t\tfor (i in data.errors){\n\t\t\t\t\t\t\tvar label = \$('<p/>').addClass('inline-error').html(data.errors[i]);\n\t\t\t\t\t\t\tlabel.insertAfter('[name='+i+']');\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmyScrollToError();\n\t\t\t\t\t\treturn;\n  \t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\talertIndiciaError(data);\n        }\n\t},\n    complete: function (){\n  \t\tjQuery('.loading-button').removeClass('loading-button');\n  \t}\n});\n// In this case, all the samples attributes are on the survey tab, and all the occurrence attributes are on the occurrence tab. No need to worry about getting the correct form.\nloadAttributes = function(attributeTable, attributeKey, key, keyValue, prefix){\n    jQuery.ajax({\n        type: \"GET\",\n        url: \"" . $svcUrl . "/data/\" + attributeTable + \"?mode=json&view=list\" +\n        \t\"&reset_timeout=true&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&\" + key + \"=\" + keyValue + \"&callback=?\",\n        data: {},\n        success: (function(attrPrefix, attrKey) {\n          var retVal = function(attrdata) {\n            if(!(attrdata instanceof Array)){\n              alertIndiciaError(attrdata);\n            } else if (attrdata.length>0) {\n              for (var i=0;i<attrdata.length;i++){\n                // in all cases if the attribute already has the <prefix>:<X>:<Y> format name we leave. Other wise we update <prefix>:<X> to <prefix>:<X>:<Y>\n                // We leave all values unchanged.\n                // need to be careful about Cloud: this is a drop down, but it is not language specific: the termlist is\n                // always in english, so the iso won't match.\n                if (attrdata[i].id){\n                  if (attrdata[i].iso == null || attrdata[i].iso == '') // no iso - not a look up.\n                    jQuery('[name='+attrPrefix+'\\:'+attrdata[i][attrKey]+']').attr('name', attrPrefix+':'+attrdata[i][attrKey]+':'+attrdata[i].id);\n                  else {\n                    if (attrdata[i].iso == '" . $language . "') // this is our actual language so OK\n                      jQuery('[name='+attrPrefix+'\\:'+attrdata[i][attrKey]+']').attr('name', attrPrefix+':'+attrdata[i][attrKey]+':'+attrdata[i].id);\n                    else {// not our language: look up all the other attrs, and if we don't find one of this id for our language, use this one.\n                      var found = false;\n                      for (var j=0;j<attrdata.length;j++)\n                        found = found || (i!=j && attrdata[i][attrKey] == attrdata[j][attrKey] && attrdata[j].iso == '" . $language . "');\n                      if(!found)\n                        jQuery('[name='+attrPrefix+'\\:'+attrdata[i][attrKey]+']').attr('name', attrPrefix+':'+attrdata[i][attrKey]+':'+attrdata[i].id);\n                    }\n                  }\n                }\n              }\n            }};\n          return retVal;\n          })(prefix, attributeKey),\n\t\tdataType: 'json',\n\t    async: false\n\t});\n}";
       // Set up Occurrence List tab: don't include when creating a new sample as it will have no occurrences
       // Grid populated at a later point
       $r .= "<div id=\"occurrenceList\" class=\"mnhnl-btw-datapanel\"><div id=\"occ_grid\"></div>\n  <form method=\"post\" action=\"" . data_entry_helper::$base_url . "/index.php/services/report/requestReport?report=reports_for_prebuilt_forms/MNHNL/mnhnl_btw_occurrences_report.xml&reportSource=local&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth['nonce'] . "&mode=csv\">\n    <input type=\"hidden\" id=\"params\" name=\"params\" value='{\"survey_id\":" . $args['survey_id'] . ", \"sample_id\":" . data_entry_helper::$entity_to_load['sample:id'] . "}' />\n    <input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Download_Occurrences') . "\">\n  </form></div>";
       if ($occReadOnly) {
           // NB that we don't even include the buttons when readonly.
           data_entry_helper::$javascript .= "\njQuery('#ro-occ-occ-warn').show();\njQuery('#ro-sur-occ-warn').hide();\n";
       } else {
           data_entry_helper::$javascript .= "\njQuery('#ro-occ-occ-warn').hide();\n";
       }
       if ($mode == 1) {
           data_entry_helper::$javascript .= "jQuery('#occ-form').hide();";
       } else {
           data_entry_helper::$javascript .= "jQuery('#na-occ-warn').hide();";
       }
       // Set up Occurrence tab: don't allow entry of a new occurrence until after top level sample is saved.
       data_entry_helper::$entity_to_load = $childSample;
       $attributes = data_entry_helper::getAttributes(array('id' => data_entry_helper::$entity_to_load['occurrence:id'], 'valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => 'occAttr', 'extraParams' => $readAuth));
       $extraParams = $readAuth + array('taxon_list_id' => $args['list_id'], 'view' => 'detail', 'query' => urlencode(json_encode(array('in' => array('language_iso', array('lat', iform_lang_iso_639_2($args['language'])))))));
       if ($occReadOnly) {
           // if the occurrence has been downloaded, no one can modify it.
           $disabledText = "disabled=\"disabled\"";
           $defAttrOptions['disabled'] = $disabledText;
       }
       $species_ctrl_args = array('label' => lang::get('LANG_Species'), 'fieldname' => 'occurrence:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 2, 'extraParams' => $extraParams, 'disabled' => $disabledText, 'defaultCaption' => data_entry_helper::$entity_to_load['occurrence:taxon']);
       $r .= "  <div id=\"occurrence\" class=\"mnhnl-btw-datapanel\">\n    <p id=\"ro-occ-occ-warn\"><strong>" . lang::get('LANG_Read_Only_Occurrence') . "</strong></p>\n    <p id=\"ro-sur-occ-warn\"><strong>" . lang::get('LANG_Read_Only_Survey') . "</strong></p>\n    <p id=\"na-occ-warn\"><strong>" . lang::get('LANG_Page_Not_Available') . "</strong></p>\n    <form method=\"post\" id=\"occ-form\" action=\"" . iform_ajaxproxy_url($node, 'smp-occ') . "\" >\n    <input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n    <input type=\"hidden\" id=\"sample:survey_id\" name=\"sample:survey_id\" value=\"" . $args['survey_id'] . "\" />\n    <input type=\"hidden\" id=\"sample:parent_id\" name=\"sample:parent_id\" value=\"" . $parentSample['sample:id'] . "\" />\n    <input type=\"hidden\" id=\"sample:date\" name=\"sample:date\" value=\"" . data_entry_helper::$entity_to_load['sample:date'] . "\" />\n    <input type=\"hidden\" id=\"sample:id\" name=\"sample:id\" value=\"" . data_entry_helper::$entity_to_load['sample:id'] . "\" />\n    <input type=\"hidden\" id=\"occurrence:id\" name=\"occurrence:id\" value=\"" . data_entry_helper::$entity_to_load['occurrence:id'] . "\" />\n    <input type=\"hidden\" id=\"occurrence:record_status\" name=\"occurrence:record_status\" value=\"" . ($closedFieldValue == '0' ? 'I' : 'C') . "\" />\n    <input type=\"hidden\" id=\"occurrence:downloaded_flag\" name=\"occurrence:downloaded_flag\" value=\"N\" />\n    " . data_entry_helper::autocomplete($species_ctrl_args) . "\n    " . ($occurrence_confidence_id ? data_entry_helper::outputAttribute($attributes[$occurrence_confidence_id], array_merge($languageFilteredAttrOptions, array('noBlankText' => ''))) : "<span style=\"display: none;\">Occurrence attribute '" . self::ATTR_CONFIDENCE . "' not assigned to this survey</span>") . "\n    " . data_entry_helper::sref_and_system(array('label' => lang::get('LANG_Spatial_ref'), 'systems' => array('2169' => 'Luref (Gauss Luxembourg)'))) . "\n    <p>" . lang::get('LANG_Click_on_map') . "</p>\n    " . data_entry_helper::outputAttribute($attributes[$occurrence_count_id], array_merge($defAttrOptions, array('default' => 1))) . "\n    " . ($occurrence_approximation_id ? data_entry_helper::outputAttribute($attributes[$occurrence_approximation_id], $defAttrOptions) : "<span style=\"display: none;\">Occurrence attribute '" . self::ATTR_APPROXIMATION . "' not assigned to this survey</span>") . "\n    " . data_entry_helper::outputAttribute($attributes[$occurrence_territorial_id], array_merge($defAttrOptions, array('default' => 1, 'id' => 'occ-territorial'))) . "\n    " . data_entry_helper::outputAttribute($attributes[$occurrence_atlas_code_id], $languageFilteredAttrOptions) . "\n    " . ($occurrence_overflying_id ? data_entry_helper::outputAttribute($attributes[$occurrence_overflying_id], $defAttrOptions) : "<span style=\"display: none;\">Occurrence attribute '" . self::ATTR_OVERFLYING . "' not assigned to this survey</span>") . "\n    " . data_entry_helper::textarea(array('label' => lang::get('LANG_Comment'), 'fieldname' => 'occurrence:comment', 'disabled' => $disabledText));
       if (!$surveyReadOnly && !$occReadOnly) {
           if ($mode == 3) {
               $r .= data_entry_helper::checkbox(array('label' => lang::get('Delete'), 'fieldname' => 'sample:deleted', 'id' => 'occ-sample-deleted'));
           }
           $r .= "<input type=\"submit\" id=\"occ-submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Save_Occurrence_Details') . "\" />";
       }
       $r .= "  </form>\n";
       data_entry_helper::$javascript .= "\n// because of ID tracking it is easier to rebuild entire list etc.\nretriggerGrid = function(){\n  \$('div#occ_grid').empty();\n  occListLayer.destroyFeatures();\n  activateAddList = 1;\n  thisOccID = -1;\n  \$('div#occ_grid').indiciaDataGrid('rpt:reports_for_prebuilt_forms/MNHNL/mnhnl_btw_list_occurrences', {\n    indiciaSvc: '" . $svcUrl . "',\n    dataColumns: ['taxon', 'territorial', 'count'],\n    reportColumnTitles: {taxon : '" . lang::get('LANG_Species') . "', territorial : '" . lang::get('LANG_Territorial') . "', count : '" . lang::get('LANG_Count') . "'},\n    actionColumns: {'" . lang::get('LANG_Show') . "' : \"" . url('node/' . $node->nid, array('query' => 'occurrence_id=£id£')) . "\",\n            '" . lang::get('LANG_Highlight') . "' : \"script:highlight(£id£);\"},\n    auth : { nonce : '" . $readAuth['nonce'] . "', auth_token : '" . $readAuth['auth_token'] . "'},\n    parameters : { survey_id : '" . $args['survey_id'] . "',\n            parent_id : jQuery('#SurveyForm [name=sample\\:id]').val(),\n            territorial_attr_id : '" . $occurrence_territorial_id . "',\n            count_attr_id : '" . $occurrence_count_id . "'},\n    itemsPerPage : 12,\n    callback : addListFeature ,\n    cssOdd : ''\n  });\n}\n\njQuery('#occ-form').ajaxForm({\n\tasync: false,\n\tdataType:  'json',\n    beforeSubmit:   function(data, obj, options){\n    \tvar valid = true;\n    \tclearErrors('form#occ-form');\n    \tif (!jQuery('form#occ-form > input').valid()) { valid = false; }\n    \tif (!jQuery('form#occ-form > select').valid()) { valid = false; }\n    \tif(!valid) {\n\t\t\tmyScrollToError();\n\t\t\treturn false;\n\t\t};\n\t\tjQuery('#occ-submit').addClass('loading-button');\n\t\treturn true;\n\t},\n    success:   function(data){\n       // this will leave all the fields populated.\n       \tif(data.success == 'multiple records' && data.outer_table == 'sample'){\n\t\t\twindow.scroll(0,0);\n\t\t\t// cant use reset form, as returns it to original values: if this was called with occurrence_id =<x> then it would repopulate with original occurrence's values\n\t\t\t// website_id, survey_id, record_status, downloaded_flag, sample:entered_sref_system are constants and are left alone. parent_id, date are only set referring to parent sample.\n\t\t\tjQuery('form#occ-form').find('[name^=occAttr\\:]').each(function(){\n\t\t\t\tvar name = jQuery(this).attr('name').split(':');\n\t\t\t\tjQuery(this).attr('name', name[0]+':'+name[1]);\n\t\t\t});\n\t\t\tjQuery('form#occ-form').find('[name=occurrence\\:id],[name=sample\\:id]').val('').attr('disabled', 'disabled');\n\t\t\tjQuery('form#occ-form').find('[name=occurrence\\:taxa_taxon_list_id],[name=occurrence\\:taxa_taxon_list_id\\:taxon],[name=sample\\:entered_sref],[name=sample\\:geom],[name=occurrence\\:comment]').val('');\n\t\t\tjQuery('form#occ-form').find('[name=occAttr\\:" . $occurrence_confidence_id . "]').find('option').removeAttr('selected');\n\t\t\tjQuery('form#occ-form').find('[name=occAttr\\:" . $occurrence_count_id . "]').val('1');\n\t\t\tjQuery('form#occ-form').find('input[name=occAttr\\:" . $occurrence_approximation_id . "],input[name=occAttr\\:" . $occurrence_overflying_id . "]').removeAttr('checked','checked');\n\t\t\tjQuery('form#occ-form').find('#occ-territorial').attr('checked','checked');\n\t\t\tjQuery('label[for=occ-sample-deleted]').remove(); // sample deleted only applicable when editing an existing occurrence. After saving reverts to Add Occurreence: no delete. Remove label then actual checkbox\n\t\t\tjQuery('form#occ-form').find('[name=sample\\:deleted]').remove(); // This removes both parts of the checkbox.\n\t\t\tsetAtlasStatus();\n\t\t\tretriggerGrid();\n\t\t\tlocationLayer.map.editLayer.destroyFeatures();\n\t\t\tvar a = \$('ul.ui-tabs-nav a')[1];\n\t\t\t\$(a).empty().html('<span>" . lang::get('LANG_Add_Occurrence') . "</span>');\n\t\t\tswitch(\"" . $args["on_save_occurrence_nav"] . "\"){\n\t\t\t\tcase \"list\":\n\t\t\t\t\ta = \$('ul.ui-tabs-nav a')[2];\n\t\t\t\t\t\$(a).click();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"survey\":\n\t\t\t\t\ta = \$('ul.ui-tabs-nav a')[0];\n\t\t\t\t\t\$(a).click();\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n        } else {\n\t\t\tif(data.error){\n\t\t\t\tvar lastIndex = data.error.lastIndexOf('Validation error');\n    \t\t\tif (lastIndex != -1 && lastIndex  == (data.error.length - 16)){\n\t\t\t\t\tif(data.errors){\n\t\t\t\t\t\t// TODO translation\n\t\t\t\t\t\tfor (i in data.errors){\n\t\t\t\t\t\t\tvar label = \$('<p/>').addClass('inline-error').html(data.errors[i]);\n\t\t\t\t\t\t\tlabel.insertAfter('[name='+i+']');\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmyScrollToError();\n\t\t\t\t\t\treturn;\n  \t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\talertIndiciaError(data);\n        }\n\t},\n    complete: function (){\n  \t\tjQuery('.loading-button').removeClass('loading-button');\n  \t}\n});\nsetAtlasStatus = function() {\n  if (jQuery(\"#occ-territorial:checked\").length == 0) {\n      jQuery(\"select[name=occAttr\\:" . $occurrence_atlas_code_id . "],select[name^=occAttr\\:" . $occurrence_atlas_code_id . "\\:]\").val('');\n  } else {\n      if(jQuery(\"select[name=occAttr\\:" . $occurrence_atlas_code_id . "],select[name^=occAttr\\:" . $occurrence_atlas_code_id . "\\:]\").val() == '') {\n        // Find the BB02 option (depends on the language what val it has)\n        var bb02;\n        jQuery.each(jQuery(\"select[name=occAttr\\:" . $occurrence_atlas_code_id . "],select[name^=occAttr\\:" . $occurrence_atlas_code_id . "\\:]\").find('option'), function(index, option) {\n          if (option.text.substr(0,4)=='BB02') {\n            bb02 = option.value;\n            return; // just from the each loop\n          }\n        });\n        jQuery(\"select[name=occAttr\\:" . $occurrence_atlas_code_id . "],select[name^=occAttr\\:" . $occurrence_atlas_code_id . "\\:]\").val(bb02);\n      }\n  }\n};\njQuery(\"#occ-territorial\").change(setAtlasStatus);\nif(\$.browser.msie) {\n    jQuery(\"#occ-territorial\").click(function() {\n        \$(this).change();\n    });\n}\n\n";
       if ($mode != 3) {
           data_entry_helper::$javascript .= "setAtlasStatus();\n";
       }
       // reset the atlas when not looking at a old occurrence.
       $r .= '</div>';
       // add map panel.
       $options = iform_map_get_map_options($args, $readAuth);
       $olOptions = iform_map_get_ol_options($args);
       // $options['layers'] = array('locationLayer', 'occListLayer');
       $options['searchLayer'] = 'false';
       $options['initialFeatureWkt'] = null;
       $options['proxy'] = '';
       $options['scroll_wheel_zoom'] = false;
       $options['width'] = 'auto';
       // TBD remove from arglist
       $r .= "<div class=\"mnhnl-btw-mappanel\">\n";
       $r .= data_entry_helper::map_panel($options, $olOptions);
       // for timing reasons, all the following has to be done after the map is loaded.
       // 1) feature selector for occurrence list must have the map present to attach the control
       // 2) location placer must have the location layer populated and the map present in
       //    order to zoom the map into the location.
       // 3) occurrence list feature adder must have map present in order to zoom into any
       //    current selection.
       data_entry_helper::$onload_javascript .= "\n\n\nlocationChange = function(obj){\n  locationLayer.destroyFeatures();\n  if(obj.value != ''){\n    jQuery.getJSON(\"" . $svcUrl . "\" + \"/data/location/\"+obj.value +\n      \"?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . "\" +\n      \"&callback=?\", function(data) {\n            if (data.length>0) {\n              var parser = new OpenLayers.Format.WKT();\n              for (var i=0;i<data.length;i++)\n        {\n          if(data[i].centroid_geom){\n            " . self::readBoundaryJs('data[i].centroid_geom', $args['map_projection']) . "\n            feature.style = {label: data[i].name,\n\t\t\t\t\t\t     strokeColor: \"Green\",\n                             strokeWidth: 2,\n                             fillOpacity: 0};\n            centre = feature.geometry.getCentroid();\n            centrefeature = new OpenLayers.Feature.Vector(centre, {}, {label: data[i].name});\n            locationLayer.addFeatures([feature, centrefeature]);\n          }\n          if(data[i].boundary_geom){\n            " . self::readBoundaryJs('data[i].boundary_geom', $args['map_projection']) . "\n            feature.style = {strokeColor: \"Blue\", strokeWidth: 2};\n            locationLayer.addFeatures([feature]);\n          }\n          locationLayer.map.zoomToExtent(locationLayer.getDataExtent());\n        }\n      }\n    });\n     jQuery.getJSON(\"" . $svcUrl . "\" + \"/data/location\" +\n      \"?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . "&callback=?&parent_id=\"+obj.value, function(data) {\n            if (data.length>0) {\n              var parser = new OpenLayers.Format.WKT();\n              for (var i=0;i<data.length;i++)\n        {\n          if(data[i].centroid_geom){\n            " . self::readBoundaryJs('data[i].centroid_geom', $args['map_projection']) . "\n            locationLayer.addFeatures([feature]);\n          }\n          if(data[i].boundary_geom){\n            " . self::readBoundaryJs('data[i].boundary_geom', $args['map_projection']) . "\n            feature.style = {label: data[i].name,\n              labelAlign: \"cb\",\n              strokeColor: \"Blue\",\n                        strokeWidth: 2};\n            locationLayer.addFeatures([feature]);\n           }\n         }\n      }\n        });\n  }\n};\n// upload location initial value into map.\njQuery('#imp-location').each(function(){\n  locationChange(this);\n});\njQuery('#imp-location').unbind('change');\njQuery('#imp-location').change(function(){\n  locationChange(this);\n});\nvar selected = \$('#controls').tabs('option', 'selected');\n\n// Only leave the click control activated for edit/add occurrence tab.\nif(selected != 1){\n    locationLayer.map.editLayer.clickControl.deactivate();\n}\n\$('#controls').bind('tabsshow', function(event, ui) {\n        if(ui.index == 1)\n        {\n         locationLayer.map.editLayer.clickControl.activate();\n        }\n        else\n        {\n         locationLayer.map.editLayer.clickControl.deactivate();\n        }\n    }\n);\nactivateAddList = 1;\nthisOccID = " . $thisOccID . ";\naddListFeature = function(div, r, record, count) {\n  if(activateAddList == 0)\n    return;\n  if(r == count)\n    activateAddList = 0;\n    var parser = new OpenLayers.Format.WKT();\n    " . self::readBoundaryJs('record.geom', $args['map_projection']) . "\n    if(record.id != thisOccID || 1==" . ($surveyReadOnly ? 1 : 0) . " || 1==" . ($occReadOnly ? 1 : 0) . "){\n      feature.attributes.id = record.id;\n      feature.attributes.taxon = record.taxon;\n      feature.attributes.count = record.count;\n      occListLayer.addFeatures([feature]);\n      if(record.id == " . $thisOccID . "){\n        var bounds=feature.geometry.getBounds();\n        locationLayer.map.setCenter(bounds.getCenterLonLat());\n      }\n    } else {\n      locationLayer.map.editLayer.destroyFeatures();\n      locationLayer.map.editLayer.addFeatures([feature]);\n      var bounds=feature.geometry.getBounds()\n      var centre=bounds.getCenterLonLat();\n      locationLayer.map.setCenter(centre);\n    }\n};\nhighlight = function(id){\n  if(id == " . $thisOccID . "){\n    if(occListLayer.map.editLayer.features.length > 0){\n      var bounds=occListLayer.map.editLayer.features[0].geometry.getBounds()\n      var centre=bounds.getCenterLonLat();\n      occListLayer.map.setCenter(centre);\n      return;\n    }\n  }\n  for(var i = 0; i < occListLayer.features.length; i++){\n    if(occListLayer.features[i].attributes.id == id){\n      control.unselectAll();\n      var bounds=occListLayer.features[i].geometry.getBounds()\n      var centre=bounds.getCenterLonLat();\n      occListLayer.map.setCenter(centre);\n      control.select(occListLayer.features[i]);\n      return;\n    }\n  }\n}\n";
       if ($mode != 1) {
           data_entry_helper::$onload_javascript .= "\n\$('div#occ_grid').indiciaDataGrid('rpt:reports_for_prebuilt_forms/MNHNL/mnhnl_btw_list_occurrences', {\n    indiciaSvc: '" . $svcUrl . "',\n    dataColumns: ['taxon', 'territorial', 'count'],\n    reportColumnTitles: {taxon : '" . lang::get('LANG_Species') . "', territorial : '" . lang::get('LANG_Territorial') . "', count : '" . lang::get('LANG_Count') . "'},\n    actionColumns: {'" . lang::get('LANG_Show') . "' : \"" . url('node/' . $node->nid, array('query' => 'occurrence_id=£id£')) . "\",\n            '" . lang::get('LANG_Highlight') . "' : \"script:highlight(£id£);\"},\n    auth : { nonce : '" . $readAuth['nonce'] . "', auth_token : '" . $readAuth['auth_token'] . "'},\n    parameters : { survey_id : '" . $args['survey_id'] . "',\n            parent_id : '" . $parentSample['sample:id'] . "',\n            territorial_attr_id : '" . $occurrence_territorial_id . "',\n            count_attr_id : '" . $occurrence_count_id . "'},\n    itemsPerPage : 12,\n    callback : addListFeature ,\n    cssOdd : ''\n  });\n\n// activateAddList = 0;\n\n";
       }
       $r .= "</div><div><form><input id=\"return-to-main\" type=\"button\" value=\"" . lang::get('LANG_Return') . "\" onclick=\"window.location.href='" . url('node/' . $node->nid, array('query' => 'Main')) . "'\"></form></div></div>\n";
       if (method_exists(get_called_class(), 'getTrailerHTML')) {
           $r .= call_user_func(array(get_called_class(), 'getTrailerHTML'), $args);
       }
       return $r;
   }
 /**
  * Return the generated form output.
  * @return Form HTML.
  */
 public static function get_form($args)
 {
     global $user;
     $logged_in = $user->uid > 0;
     // Get authorisation tokens to update and read from the Warehouse.
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $readAuth = $auth['read'];
     // enable image viewing with FancyBox - only required if the file box is enabled
     //data_entry_helper::$javascript .= "jQuery(\"a.fancybox\").fancybox();\n";
     $r = "\n<form method=\"post\" id=\"entry_form\">\n";
     if (isset($_GET['taxa_taxon_list_id']) || isset($_GET['taxon_external_key'])) {
         if (isset($_GET['taxa_taxon_list_id'])) {
             $filter = array('id' => $_GET['taxa_taxon_list_id']);
         } else {
             $filter = array('external_key' => $_GET['taxon_external_key']);
         }
         $species = data_entry_helper::get_population_data(array('table' => 'taxa_taxon_list', 'extraParams' => $readAuth + $filter + array('taxon_list_id' => $args['list_id'], 'view' => 'detail', 'preferred' => 't')));
         // we need only one result, but there could be more than one picture, therefore multiple rows
         $uniqueMeaning = false;
         if (count($species) == 1) {
             $uniqueMeaning = $species[0]['taxon_meaning_id'];
         }
         if (count($species) > 1) {
             $uniqueMeaning = $species[0]['taxon_meaning_id'];
             foreach ($species as $item) {
                 if ($item['taxon_meaning_id'] != $uniqueMeaning) {
                     $uniqueMeaning = false;
                 }
             }
         }
         if ($uniqueMeaning) {
             // now we have the meaning_id, we need to fetch the actual species in the chosen common name
             $speciesCommon = data_entry_helper::get_population_data(array('table' => 'taxa_taxon_list', 'extraParams' => $readAuth + array('taxon_meaning_id' => $uniqueMeaning, 'language_iso' => iform_lang_iso_639_2($user->lang), 'view' => 'detail')));
             $r .= '<div class="ui-widget ui-widget-content ui-corner-all page-notice ui-helper-clearfix">';
             $nameString = ($species[0]['language_iso'] == 'lat' ? '<em>' : '') . $species[0]['taxon'] . ($species[0]['language_iso'] == 'lat' ? '</em>' : '');
             if (count($speciesCommon) >= 1) {
                 // use a common name if we have one
                 $nameString = $speciesCommon[0]['taxon'] . ' (' . $nameString . ')';
             }
             if (!empty($species[0]['description_in_list'])) {
                 $r .= '<div class="page-notice">' . lang::get('you are recording a', $nameString) . '</div>';
             }
             $taxa_taxon_list_id = $species[0]['id'];
             $images_path = data_entry_helper::$base_url . (isset(data_entry_helper::$indicia_upload_path) ? data_entry_helper::$indicia_upload_path : 'upload/');
             foreach ($species as $item) {
                 if (!empty($item['image_path'])) {
                     $r .= '<a class="fancybox left" href="' . $images_path . $item['image_path'] . '" style="margin: 0 1em 1em;">';
                     $r .= '<img width="100" src="' . $images_path . 'thumb-' . $item['image_path'] . '" />';
                     $r .= '</a>';
                 }
             }
             if (!empty($species[0]['description_in_list'])) {
                 $r .= '<p>' . $species[0]['description_in_list'] . "</p>";
             } else {
                 $r .= '<p>' . lang::get('you are recording a', $nameString) . '</p>';
             }
             $r .= "</div>\n";
         } else {
             $r .= "<p>The species not be identified uniquely from the URL parameters.</p>\n";
         }
     }
     // request automatic JS validation
     data_entry_helper::enable_validation('entry_form');
     $r .= "<div id=\"controls\">\n";
     if ($args['interface'] != 'one_page') {
         $r .= "<ul>\n";
         if (!$logged_in) {
             $r .= '  <li><a href="#about_you"><span>' . lang::get('about you') . "</span></a></li>\n";
         }
         if (!isset($taxa_taxon_list_id)) {
             $r .= '  <li><a href="#species"><span>' . lang::get('what did you see') . "</span></a></li>\n";
         }
         $r .= '  <li><a href="#place"><span>' . lang::get('where was it') . "</span></a></li>\n";
         $r .= '  <li><a href="#other"><span>' . lang::get('other information') . "</span></a></li>\n";
         $r .= "</ul>\n";
         data_entry_helper::enable_tabs(array('divId' => 'controls', 'style' => $args['interface']));
     }
     if ($user->uid == 0) {
         $r .= "<fieldset id=\"about_you\">\n";
         $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('about you tab instructions') . "</p>";
         $r .= data_entry_helper::text_input(array('label' => lang::get('first name'), 'fieldname' => 'smpAttr:' . $args['first_name_attr_id'], 'class' => 'control-width-4'));
         $r .= data_entry_helper::text_input(array('label' => lang::get('surname'), 'fieldname' => 'smpAttr:' . $args['surname_attr_id'], 'class' => 'control-width-4'));
         $r .= data_entry_helper::text_input(array('label' => lang::get('email'), 'fieldname' => 'smpAttr:' . $args['email_attr_id'], 'class' => 'control-width-4'));
         $r .= data_entry_helper::text_input(array('label' => lang::get('phone number'), 'fieldname' => 'smpAttr:' . $args['phone_attr_id'], 'class' => 'control-width-4'));
         if ($args['interface'] == 'wizard') {
             $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => 'first'));
         }
         $r .= "</fieldset>\n";
     }
     // the species tab is ommitted if the page is called with a taxon in the querystring parameters
     if (isset($taxa_taxon_list_id)) {
         $r .= "<input type=\"hidden\" name=\"occurrence:taxa_taxon_list_id\" value=\"{$taxa_taxon_list_id}\"/>\n";
     } else {
         $r .= "<fieldset id=\"species\">\n";
         $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('species tab instructions') . "</p>";
         $extraParams = $readAuth + array('taxon_list_id' => $args['list_id']);
         if ($args['preferred']) {
             $extraParams += array('preferred' => 't');
         }
         if ($args['restrict_species_to_users_lang']) {
             $extraParams += array('language_iso' => iform_lang_iso_639_2($user->lang));
         }
         $species_list_args = array('label' => lang::get('occurrence:taxa_taxon_list_id'), 'fieldname' => 'occurrence:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 2, 'view' => 'detail', 'parentField' => 'parent_id', 'extraParams' => $extraParams);
         if ($args['species_ctrl'] == 'tree_browser') {
             // change the node template to include images
             global $indicia_templates;
             $indicia_templates['tree_browser_node'] = '<div>' . '<img src="' . data_entry_helper::$base_url . '/upload/thumb-{image_path}" alt="Image of {caption}" width="80" /></div>' . '<span>{caption}</span>';
         }
         // Dynamically generate the species selection control required.
         $r .= call_user_func(array('data_entry_helper', $args['species_ctrl']), $species_list_args);
         if ($args['interface'] == 'wizard') {
             $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => $user->id == 0 ? 'first' : 'middle'));
         }
         $r .= "</fieldset>\n";
     }
     $r .= "<fieldset id=\"place\">\n";
     // Output all our hidden data here, because this tab is always present
     $r .= $auth['write'];
     if ($logged_in) {
         // If logged in, output some hidden data about the user
         $r .= iform_user_get_hidden_inputs($args);
     }
     // if the species being recorded is a fixed species defined in the URL, then output a hidden
     if (isset($taxa_taxon_list_id)) {
         $r .= "<input type=\"hidden\" name=\"occurrence:taxa_taxon_list_id'\" value=\"" . $taxa_taxon_list_id . "\" />\n";
     }
     $r .= "<input type=\"hidden\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" name=\"survey_id\" value=\"" . $args['survey_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" name=\"record_status\" value=\"" . $args['record_status'] . "\" />\n";
     $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('place tab instructions') . "</p>";
     // Build the array of spatial reference systems into a format Indicia can use.
     $systems = array();
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get($system);
     }
     $r .= data_entry_helper::georeference_lookup(iform_map_get_georef_options($args, $auth['read']));
     $r .= data_entry_helper::sref_and_system(array('label' => lang::get('sample:entered_sref'), 'systems' => $systems));
     // retrieve options for the IndiciaMapPanel, and optionally options for OpenLayers.
     $options = iform_map_get_map_options($args, $readAuth);
     $options['tabDiv'] = 'place';
     $olOptions = iform_map_get_ol_options($args);
     $options['scroll_wheel_zoom'] = false;
     $r .= data_entry_helper::map_panel($options, $olOptions);
     if ($args['interface'] == 'wizard') {
         $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => $user->id == 0 && isset($taxa_taxon_list_id) ? 'first' : 'middle'));
     }
     $r .= "</fieldset>\n";
     $r .= "<fieldset id=\"other\">\n";
     $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('other tab instructions') . "</p>";
     $r .= data_entry_helper::date_picker(array('label' => lang::get('Date'), 'fieldname' => 'sample:date'));
     $r .= data_entry_helper::file_box(array('caption' => 'Upload your photos', 'readAuth' => $readAuth, 'resizeWidth' => 1024, 'resizeHeight' => 768, 'table' => 'occurrence_image', 'tabDiv' => 'other', 'runtimes' => array('html5', 'html4')));
     // Dynamically create a control for the abundance, unless overridden for this species
     if (isset($species) && count($species) > 0 && trim($args['abundance_overrides']) !== '') {
         $overrides = explode("\n", $args['abundance_overrides']);
         foreach ($overrides as $override) {
             $tokens = explode(':', $override);
             if ($tokens[0] == $species[0]['taxon']) {
                 // remove the default abundance attribute behaviour
                 $args['abundance_attr_id'] = '';
                 if (trim($tokens[1]) !== '') {
                     $attrIds = explode(',', $tokens[1]);
                     $attributes = data_entry_helper::getAttributes(array('id' => null, 'valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => "occAttr", 'extraParams' => $readAuth + array('query' => urlencode(json_encode(array('in' => array('id', $attrIds))))), 'survey_id' => $args['survey_id']));
                     foreach ($attributes as $attribute) {
                         $r .= data_entry_helper::outputAttribute($attribute, array('language' => iform_lang_iso_639_2($user->lang), 'booleanCtrl' => 'checkbox'));
                     }
                 }
             }
         }
     }
     if (!empty($args['abundance_attr_id'])) {
         $abundance_args = array('label' => lang::get('abundance'), 'fieldname' => 'occAttr:' . $args['abundance_attr_id'], 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'id', 'extraParams' => $readAuth + array('termlist_id' => $args['abundance_termlist_id']), 'size' => 6, 'sep' => '<br/>');
         $r .= call_user_func(array('data_entry_helper', $args['abundance_ctrl']), $abundance_args);
     }
     $r .= data_entry_helper::textarea(array('label' => lang::get('sample:comment'), 'fieldname' => 'sample:comment', 'class' => 'wide'));
     $r .= '<div class="footer">' . data_entry_helper::checkbox(array('label' => lang::get('happy for contact'), 'labelClass' => 'auto', 'fieldname' => 'smpAttr:' . $args['contact_attr_id'])) . '</div>';
     if ($args['interface'] == 'wizard') {
         $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => 'last'));
     } else {
         $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"Save\" />\n";
     }
     $r .= "</fieldset>\n";
     $r .= "</div>\n";
     $r .= "</form>";
     return $r;
 }
Esempio 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 $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 $indicia_templates, $user;
     data_entry_helper::enable_validation('entry_form');
     $url = !empty($_SERVER['HTTPS']) ? "https://" . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'] : "http://" . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
     $r = data_entry_helper::loading_block_start();
     $r .= "<form method=\"post\" id=\"entry_form\" action=\"{$url}\">\n";
     $readAuth = data_entry_helper::get_read_auth($args['website_id'], $args['password']);
     $r .= "<div id=\"controls\">\n";
     if ($args['interface'] != 'one_page') {
         $r .= "<ul>\n";
         if ($user->uid == 0) {
             $r .= '  <li><a href="#about_you"><span>' . lang::get('about you') . "</span></a></li>\n";
         }
         $r .= '  <li><a href="#species"><span>' . lang::get('what did you see') . "</span></a></li>\n";
         $r .= '  <li><a href="#place"><span>' . lang::get('where was it') . "</span></a></li>\n";
         $r .= '  <li><a href="#other"><span>' . lang::get('other information') . "</span></a></li>\n";
         $r .= "</ul>\n";
         data_entry_helper::enable_tabs(array('divId' => 'controls', 'style' => $args['interface']));
     }
     if ($user->uid == 0) {
         $r .= "<fieldset id=\"about_you\">\n";
         if ($args['interface'] == 'one_page') {
             $r .= '<legend>' . lang::get('about you') . '</legend>';
         }
         $r .= data_entry_helper::text_input(array('label' => lang::get('first name'), 'fieldname' => 'smpAttr:' . $args['first_name_attr_id'], 'class' => 'control-width-4', 'validation' => array('required')));
         $r .= data_entry_helper::text_input(array('label' => lang::get('surname'), 'fieldname' => 'smpAttr:' . $args['surname_attr_id'], 'class' => 'control-width-4', 'validation' => array('required')));
         $r .= data_entry_helper::text_input(array('label' => lang::get('phone number'), 'fieldname' => 'smpAttr:' . $args['phone_attr_id'], 'class' => 'control-width-4'));
         $r .= data_entry_helper::text_input(array('label' => lang::get('email'), 'fieldname' => 'smpAttr:' . $args['email_attr_id'], 'class' => 'control-width-4 optional', 'validation' => array('email')));
         if ($args['interface'] == 'wizard') {
             $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => 'first'));
         }
         $r .= "</fieldset>\n";
     }
     // Species tab
     $r .= "<fieldset id=\"species\">\n";
     if ($args['interface'] == 'one_page') {
         $r .= '<legend>' . lang::get('what did you see') . '</legend>';
     }
     $species_list_args = array('label' => lang::get('Species'), 'fieldname' => 'occurrence:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'listId' => $args['species_list_id'], 'columns' => 1, 'parentField' => 'parent_id', 'checkboxCol' => false, 'occAttrs' => array($args['abundance_attr_id']), 'extraParams' => $readAuth + array('view' => 'detail', 'orderby' => 'taxonomic_sort_order'), 'survey_id' => $args['survey_id'], 'header' => false, 'view' => 'detail', 'PHPtaxonLabel' => true);
     // Build a nice template to show a picture of each species, with fancybox.
     data_entry_helper::add_resource('fancybox');
     data_entry_helper::$javascript .= "jQuery('a.fancybox').fancybox();\n";
     $indicia_templates['taxon_label'] = 'return \'<div class="taxon-cell">' . '<a href="' . data_entry_helper::$base_url . 'upload/{image_path}" class="fancybox" >' . '<img alt="{taxon}" src="' . data_entry_helper::$base_url . 'upload/med-{image_path}" width="250"/></a>' . '<div>{taxon}</div></div>' . '<div class="taxon-desc"><ul><li>\'.str_replace("\\n", "</li><li>","{description_in_list}").\'</li></ul>' . '<a href="http://www.marine-life.org.uk/northeastcetaceans/?q=\'.
     strtolower(str_replace(array(" ", "\\\'"), array("-", ""), "{taxon}")).
     \'" target="_blank" class="ui-state-default ui-corner-all indicia-button">' . lang::get('More Info') . '...</a></div>\';';
     // Template the taxon label cell
     $indicia_templates['taxon_label_cell'] = "\n<td class='scTaxonCell'>{content}</td>";
     // Also template the attribute controls to show the label in place.
     $indicia_templates['attribute_cell'] = "\n<td class='scOccAttrCell'><label>{label}:</label><br/>{content}</td>";
     $r .= data_entry_helper::species_checklist($species_list_args);
     if ($args['interface'] == 'wizard') {
         $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => $user->uid == 0 ? 'middle' : 'first'));
     }
     $r .= "</fieldset>";
     // --Place tab--
     $r .= "<fieldset id=\"place\">\n";
     if ($args['interface'] == 'one_page') {
         $r .= '<legend>' . lang::get('where was it') . '</legend>';
     }
     $r .= data_entry_helper::radio_group(array('label' => 'Where were you when you made the sighting?', 'fieldname' => 'smpAttr:' . $args['platform_attr_id'], 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'id', 'extraParams' => $readAuth + array('termlist_id' => $args['platform_termlist_id']), 'sep' => '<br />', 'labelClass' => 'auto', 'class' => 'inline sighting-platform', 'validation' => array('required')));
     $r .= '<div id="place_wrapper" class="hidden">';
     // Some instructions only visible when entering data from a boat
     $r .= '<p class="boat_mode page-notice ui-state-highlight ui-corner-all">' . lang::get('Instructions for when on boat') . '</p>';
     // Some instructions only visible when entering data from the shore
     $r .= '<p class="shore_mode page-notice ui-state-highlight ui-corner-all">' . lang::get('Instructions for clicking on map') . '</p>';
     $r .= '<div class="boat_mode">';
     // Add help examples to the lat and long boxes
     $indicia_templates['sref_textbox_latlong'] = '<label for="{idLat}">{labelLat}:</label>' . '<input type="text" id="{idLat}" name="{fieldnameLat}" {class} {disabled} value="{default}" /> <p class="helpText">e.g. 55:12.345N</p>' . '<label for="{idLong}">{labelLong}:</label>' . '<input type="text" id="{idLong}" name="{fieldnameLong}" {class} {disabled} value="{default}" /> <p class="helpText">e.g. 0:45.678W</p>' . '<input type="hidden" id="imp-geom" name="{table}:geom" value="{defaultGeom}" />' . '<input type="text" id="{id}" name="{fieldname}" style="display:none" value="{default}" />';
     $r .= data_entry_helper::sref_and_system(array('systems' => array(4326 => lang::get('Latitude, Longitude')), 'splitLatLong' => true, 'helpText' => lang::get('Instructions for latlong')));
     $r .= '</div>';
     // Initially, we hide the map. Only show it when the user selects the sighting was from the shore,
     // as a click on the map for boat recordings will not be accurate.
     $r .= '<div class="shore_mode">';
     $options = iform_map_get_map_options($args, $readAuth);
     $olOptions = iform_map_get_ol_options($args);
     $options['maxZoom'] = 9;
     // Switch to degrees and decimal minutes for lat long.
     $options['latLongFormat'] = 'DM';
     $r .= data_entry_helper::map_panel($options, $olOptions);
     // Now, add some JavaScript to show or hide the map. Show it for when the sighting was from the shore.
     // Hide it for boat based sightings as we want a GPS coordinate in this case. The JavaScript looks for the
     // checked radio button to see the value
     data_entry_helper::$javascript .= 'jQuery(".sighting-platform input").click(
   function() {
     var platformId = jQuery("input[name=smpAttr\\\\:' . $args['platform_attr_id'] . ']:checked").val();
     if (platformId == ' . $args['platform_mapped_term_id'] . ') {
       jQuery("#place_wrapper").removeClass("hidden");
       jQuery(".shore_mode").removeClass("hidden");
       jQuery(".boat_mode").addClass("hidden");
     } else {          
       jQuery("#place_wrapper").removeClass("hidden");
       jQuery(".shore_mode").addClass("hidden");
       jQuery(".boat_mode").removeClass("hidden");
     }
   }
 );' . "\n";
     // Force existing setting of the radio buttons to reload when showign page after validation failure
     data_entry_helper::$onload_javascript .= '
 jQuery("input[name=smpAttr\\\\:' . $args['platform_attr_id'] . ']:checked").trigger("click");
 ';
     $r .= '</div></div>';
     if ($args['interface'] == 'wizard') {
         $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls'));
     }
     $r .= '</fieldset>';
     // --Other information tab--
     $r .= "<fieldset id=\"other\">\n";
     // Get authorisation tokens to update and read from the Warehouse.
     $r .= data_entry_helper::get_auth($args['website_id'], $args['password']);
     $r .= "<input type=\"hidden\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" name=\"survey_id\" value=\"" . $args['survey_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" name=\"occurrence:record_status\" value=\"C\" />\n";
     if ($args['interface'] == 'one_page') {
         $r .= '<legend>' . lang::get('other information') . '</legend>';
     }
     $r .= data_entry_helper::date_picker(array('label' => lang::get('Sighting Date'), 'fieldname' => 'sample:date'));
     $indicia_templates['timeFormat'] = '<label>hh:mm</label><br/>';
     $r .= data_entry_helper::text_input(array('label' => lang::get('Sighting Time'), 'fieldname' => 'smpAttr:' . $args['sample_time_attr_id'], 'class' => 'control-width-1', 'suffixTemplate' => 'timeFormat'));
     $r .= data_entry_helper::textarea(array('label' => lang::get('Any other information'), 'fieldname' => 'sample:comment', 'class' => 'control-width-6', 'helpText' => lang::get('Instructions for any other info')));
     $r .= '<div class="footer">' . data_entry_helper::checkbox(array('label' => lang::get('happy for contact'), 'labelClass' => 'auto', 'fieldname' => 'smpAttr:' . $args['contact_attr_id'])) . '</div>';
     if ($args['interface'] == 'wizard') {
         $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => 'last'));
     } else {
         $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"Save\" />\n";
     }
     $r .= "</fieldset></div>";
     $r .= "</form>";
     $r .= data_entry_helper::loading_block_end();
     return $r;
 }
 /**
  * Return the generated form output.
  * @return Form HTML.
  */
 public static function get_form($args)
 {
     global $user;
     $logged_in = $user->uid > 0;
     $r = "\n<form method=\"post\" id=\"entry_form\">\n";
     // Get authorisation tokens to update and read from the Warehouse.
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $readAuth = $auth['read'];
     // request automatic JS validation
     data_entry_helper::enable_validation('entry_form');
     $r .= "<div id=\"controls\">\n";
     if ($args['interface'] != 'one_page') {
         $r .= "<ul>\n";
         if (!$logged_in) {
             $r .= '  <li><a href="#about_you"><span>' . lang::get('about you') . "</span></a></li>\n";
         }
         $r .= '  <li><a href="#species"><span>' . lang::get('what did you see') . "</span></a></li>\n";
         $r .= '  <li><a href="#place"><span>' . lang::get('where was it') . "</span></a></li>\n";
         $r .= '  <li><a href="#other"><span>' . lang::get('other information') . "</span></a></li>\n";
         $r .= "</ul>\n";
         data_entry_helper::enable_tabs(array('divId' => 'controls', 'style' => $args['interface']));
     }
     if ($user->uid == 0) {
         $r .= "<div id=\"about_you\">\n";
         $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('about you tab instructions') . "</p>";
         $r .= data_entry_helper::text_input(array('label' => lang::get('first name'), 'fieldname' => 'smpAttr:' . $args['first_name_attr_id'], 'class' => 'control-width-4'));
         $r .= data_entry_helper::text_input(array('label' => lang::get('surname'), 'fieldname' => 'smpAttr:' . $args['surname_attr_id'], 'class' => 'control-width-4'));
         $r .= data_entry_helper::text_input(array('label' => lang::get('email'), 'fieldname' => 'smpAttr:' . $args['email_attr_id'], 'class' => 'control-width-4'));
         $r .= data_entry_helper::text_input(array('label' => lang::get('phone number'), 'fieldname' => 'smpAttr:' . $args['phone_attr_id'], 'class' => 'control-width-4'));
         if ($args['interface'] == 'wizard') {
             $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => 'first'));
         }
         $r .= "</div>\n";
     }
     $r .= "<div id=\"species\">\n";
     // Output all our hidden data here
     $r .= $auth['write'];
     if ($logged_in) {
         // If logged in, output some hidden data about the user
         $r .= iform_user_get_hidden_inputs($args);
     }
     $r .= "<input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" id=\"survey_id\" name=\"survey_id\" value=\"" . $args['survey_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" id=\"record_status\" name=\"record_status\" value=\"C\" />\n";
     $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('species tab instructions') . "</p>";
     $extraParams = $readAuth + array('taxon_list_id' => $args['list_id']);
     if ($args['preferred']) {
         $extraParams += array('preferred' => 't');
     }
     if ($args['restrict_species_to_users_lang']) {
         $extraParams += array('language_iso' => iform_lang_iso_639_2($user->lang));
     }
     $species_list_args = array('label' => lang::get('occurrence:taxa_taxon_list_id'), 'fieldname' => 'occurrence:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 2, 'view' => 'detail', 'parentField' => 'parent_id', 'extraParams' => $extraParams);
     if ($args['species_ctrl'] == 'tree_browser') {
         // change the node template to include images
         global $indicia_templates;
         $indicia_templates['tree_browser_node'] = '<div>' . '<img src="' . data_entry_helper::$base_url . '/upload/thumb-{image_path}" alt="Image of {caption}" width="80" /></div>' . '<span>{caption}</span>';
     }
     // Dynamically generate the species selection control required.
     $r .= call_user_func(array('data_entry_helper', $args['species_ctrl']), $species_list_args);
     if ($args['interface'] == 'wizard') {
         $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => $user->id == 0 ? 'first' : 'middle'));
     }
     $r .= "</div>\n";
     $r .= "<div id=\"place\">\n";
     $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('place tab instructions') . "</p>";
     // Build the array of spatial reference systems into a format Indicia can use.
     $systems = array();
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get($system);
     }
     $r .= data_entry_helper::sref_and_system(array('label' => lang::get('sample:entered_sref'), 'systems' => $systems));
     $r .= data_entry_helper::georeference_lookup(array('label' => lang::get('search for place on map'), 'georefPreferredArea' => $args['georefPreferredArea'], 'georefCountry' => $args['georefCountry'], 'georefLang' => $args['language']));
     // retrieve options for the IndiciaMapPanel, and optionally options for OpenLayers.
     $options = iform_map_get_map_options($args, $readAuth);
     $olOptions = iform_map_get_ol_options($args);
     $r .= data_entry_helper::map_panel($options, $olOptions);
     if ($args['interface'] == 'wizard') {
         $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls'));
     }
     $r .= "</div>\n";
     $r .= "<div id=\"other\">\n";
     $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('other tab instructions') . "</p>";
     $r .= data_entry_helper::date_picker(array('label' => lang::get('Date'), 'fieldname' => 'sample:date'));
     $r .= data_entry_helper::file_box(array('caption' => 'Upload your photos', 'resizeWidth' => 1024, 'resizeHeight' => 768, 'table' => 'occurrence_image'));
     // Dynamically create a control for the abundance
     $abundance_args = array('label' => lang::get('abundance'), 'fieldname' => 'occAttr:' + $args['abundance_attr_id'], 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'id', 'extraParams' => $readAuth + array('termlist_id' => $args['abundance_termlist_id']), 'size' => 6, 'sep' => '<br/>');
     $r .= call_user_func(array('data_entry_helper', $args['abundance_ctrl']), $abundance_args);
     $r .= data_entry_helper::textarea(array('label' => lang::get('sample:comment'), 'fieldname' => 'sample:comment', 'class' => 'wide'));
     $r .= '<div class="footer">' . data_entry_helper::checkbox(array('label' => lang::get('happy for contact'), 'labelClass' => 'auto', 'fieldname' => 'smpAttr:' . $args['contact_attr_id'])) . '</div>';
     if ($args['interface'] == 'wizard') {
         $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => 'last'));
     } else {
         $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"Save\" />\n";
     }
     $r .= "</div>\n";
     $r .= "</div>\n";
     $r .= "</form>";
     return $r;
 }
$auth = data_entry_helper::get_read_write_auth($config['website_id'], $config['password']);
echo $auth['write'];
$readAuth = $auth['read'];
?>
<input type='hidden' name='website_id' value='<?php 
echo $config['website_id'];
?>
' />
<input type='hidden' name='survey_id' value='<?php 
echo $config['survey_id'];
?>
' />
<input type='hidden' name='occurrence:record_status' value='C' />
<?php 
echo data_entry_helper::date_picker(array('label' => 'Date', 'fieldname' => 'sample:date'));
echo data_entry_helper::sref_and_system(array('label' => 'Grid Ref', 'fieldname' => 'sample:entered_sref'));
?>
<div class="smaller">
<?php 
echo data_entry_helper::species_checklist(array('listId' => $config['species_checklist_taxon_list'], 'lookupListId' => $config['species_checklist_alt_list'], 'extraParams' => $readAuth, 'survey_id' => $config['survey_id']));
?>
</div>

<br />
<input type='submit' value='Save' />
</form>
</div>
</body>
<?php 
echo data_entry_helper::dump_javascript();
?>
 private static function get_site_tab($auth, $args, $settings)
 {
     $r = '<div id="site-details" class="ui-helper-clearfix">';
     $r .= '<form method="post" id="input-form">';
     $r .= $auth['write'];
     $r .= '<div id="cols" class="ui-helper-clearfix"><div class="left" style="width: 54%">';
     $r .= '<fieldset><legend>' . lang::get('Transect Details') . '</legend>';
     $r .= "<input type=\"hidden\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" name=\"survey_id\" value=\"" . $args['survey_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" name=\"location:location_type_id\" value=\"" . $settings['locationTypes'][0]['id'] . "\" />\n";
     if ($settings['locationId']) {
         $r .= '<input type="hidden" name="location:id" id="location:id" value="' . $settings['locationId'] . "\" />\n";
     }
     $r .= data_entry_helper::text_input(array('fieldname' => 'location:name', 'label' => lang::get('Transect Name'), 'class' => 'control-width-4 required', 'disabled' => $settings['canEditBody'] ? '' : ' disabled="disabled" '));
     if (!$settings['canEditBody']) {
         $r .= '<p>' . lang::get('This site cannot be edited because there are walks recorded on it. Please contact the site administrator if you think there are details which need changing.') . '</p>';
     } else {
         if (count($settings['walks']) > 0) {
             // can edit it
             $r .= '<p>' . lang::get('This site has walks recorded on it. Please do not change the site details without considering the impact on the existing data.') . '</p>';
         }
     }
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get($system);
     }
     $r .= data_entry_helper::sref_and_system(array('fieldname' => 'location:centroid_sref', 'geomFieldname' => 'location:centroid_geom', 'label' => 'Grid Ref.', 'systems' => $systems, 'class' => 'required', 'helpText' => lang::get('Click on the map to set the central grid reference.'), 'disabled' => $settings['canEditBody'] ? '' : ' disabled="disabled" '));
     if ($settings['locationId'] && data_entry_helper::$entity_to_load['location:code'] != '' && data_entry_helper::$entity_to_load['location:code'] != null) {
         $r .= data_entry_helper::text_input(array('fieldname' => 'location:code', 'label' => lang::get('Site Code'), 'class' => 'control-width-4', 'disabled' => ' readonly="readonly" '));
     } else {
         $r .= "<p>" . lang::get('The Site Code will be allocated by the Administrator.') . "</p>";
     }
     // setup the map options
     $options = iform_map_get_map_options($args, $auth['read']);
     // find the form blocks that need to go below the map.
     $bottom = '';
     $bottomBlocks = explode("\n", isset($args['bottom_blocks']) ? $args['bottom_blocks'] : '');
     foreach ($bottomBlocks as $block) {
         $bottom .= get_attribute_html($settings['attributes'], $args, array('extraParams' => $auth['read'], 'disabled' => $settings['canEditBody'] ? '' : ' disabled="disabled" '), $block);
     }
     // other blocks to go at the top, next to the map
     if (isset($args['site_help']) && $args['site_help'] != '') {
         $r .= '<p class="ui-state-highlight page-notice ui-corner-all">' . t($args['site_help']) . '</p>';
     }
     $r .= get_attribute_html($settings['attributes'], $args, array('extraParams' => $auth['read']));
     $r .= '</fieldset>';
     $r .= "</div>";
     // left
     $r .= '<div class="right" style="width: 44%">';
     if (!$settings['locationId']) {
         $help = t('Use the search box to find a nearby town or village, then drag the map to pan and click on the map to set the centre grid reference of the transect. ' . 'Alternatively if you know the grid reference you can enter it in the Grid Ref box on the left.');
         $r .= '<p class="ui-state-highlight page-notice ui-corner-all">' . $help . '</p>';
         $r .= data_entry_helper::georeference_lookup(array('label' => lang::get('Search for place'), 'driver' => $args['georefDriver'], 'georefPreferredArea' => $args['georefPreferredArea'], 'georefCountry' => $args['georefCountry'], 'georefLang' => $args['language'], 'readAuth' => $auth['read']));
     }
     if (isset($args['maxPrecision']) && $args['maxPrecision'] != '') {
         $options['clickedSrefPrecisionMax'] = $args['maxPrecision'];
     }
     if (isset($args['minPrecision']) && $args['minPrecision'] != '') {
         $options['clickedSrefPrecisionMin'] = $args['minPrecision'];
     }
     $olOptions = iform_map_get_ol_options($args);
     $options['clickForSpatialRef'] = $settings['canEditBody'];
     $r .= map_helper::map_panel($options, $olOptions);
     $r .= '</div></div>';
     // right
     if (!empty($bottom)) {
         $r .= $bottom;
     }
     if ($args['branch_assignment_permission'] != '') {
         if ($settings['canAllocBranch'] || $settings['locationId']) {
             $r .= self::get_branch_assignment_control($auth['read'], $settings['branchCmsUserAttr'], $args, $settings);
         }
     }
     if ($args['allow_user_assignment']) {
         if ($settings['canAllocUser']) {
             $r .= self::get_user_assignment_control($auth['read'], $settings['cmsUserAttr'], $args);
         } else {
             if (!$settings['locationId']) {
                 // for a new record, we need to link the current user to the location if they are not admin.
                 global $user;
                 $r .= '<input type="hidden" name="locAttr:' . self::$cmsUserAttrId . '" value="' . $user->uid . '">';
             }
         }
     }
     if ($settings['canEditBody']) {
         $r .= '<button type="submit" class="indicia-button right">' . lang::get('Save') . '</button>';
     }
     if ($settings['canEditBody'] && $settings['locationId']) {
         $r .= '<button type="button" class="indicia-button right" id="delete-transect">' . lang::get('Delete') . '</button>';
     }
     $r .= '</form>';
     $r .= '</div>';
     // site-details
     // This must go after the map panel, so it has created its toolbar
     data_entry_helper::$onload_javascript .= "\$('#current-section').change(selectSection);\n";
     if ($settings['canEditBody'] && $settings['locationId']) {
         $walkIDs = array();
         foreach ($settings['walks'] as $walk) {
             $walkIDs[] = $walk['id'];
         }
         $sectionIDs = array();
         foreach ($settings['sections'] as $code => $section) {
             $sectionIDs[] = $section['id'];
         }
         data_entry_helper::$javascript .= "\r\ndeleteSurvey = function(){\r\n  if(confirm(\"" . (count($settings['walks']) > 0 ? count($settings['walks']) . ' ' . lang::get('walks will also be deleted when you delete this location.') . ' ' : '') . lang::get('Are you sure you wish to delete this location?') . "\")){\r\n    deleteWalks([" . implode(',', $walkIDs) . "]);\r\n    deleteSections([" . implode(',', $sectionIDs) . "]);\r\n    \$('#delete-transect').html('Deleting Transect');\r\n    deleteLocation(" . $settings['locationId'] . ");\r\n    \$('#delete-transect').html('Done');\r\n    window.location='" . url($args['sites_list_path']) . "';\r\n  };\r\n};\r\n\$('#delete-transect').click(deleteSurvey);\r\n";
     }
     return $r;
 }
Esempio n. 7
0
 /** 
  * Get the spatial reference control.
  */
 private static function get_control_spatialreference($auth, $args, $tabalias, $options)
 {
     // Build the array of spatial reference systems into a format Indicia can use.
     $systems = array();
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get($system);
     }
     return data_entry_helper::sref_and_system(array_merge(array('label' => lang::get('LANG_SRef_Label'), 'systems' => $systems), $options));
 }
Esempio n. 8
0
<div id="details">
<?php 
echo $metadata;
?>
  <fieldset>
  <legend>Location details</legend>
  <input type="hidden" name="location:id" value="<?php 
echo html::initial_value($values, 'location:id');
?>
" />
  <?php 
echo data_entry_helper::text_input(array('label' => 'Name', 'fieldname' => 'location:name', 'default' => html::initial_value($values, 'location:name'), 'validation' => 'required', 'disabled' => $disabled));
echo data_entry_helper::text_input(array('label' => 'Code', 'fieldname' => 'location:code', 'default' => html::initial_value($values, 'location:code'), 'disabled' => $disabled));
echo data_entry_helper::select(array('label' => 'Type', 'fieldname' => 'location:location_type_id', 'default' => html::initial_value($values, 'location:location_type_id'), 'lookupValues' => $other_data['type_terms'], 'blankText' => '<Please select>', 'disabled' => $disabled));
echo data_entry_helper::textarea(array('label' => 'Comment', 'fieldname' => 'location:comment', 'default' => html::initial_value($values, 'location:comment'), 'disabled' => $disabled));
echo data_entry_helper::sref_and_system(array('label' => 'Spatial Ref', 'fieldname' => 'location:centroid_sref', 'geomFieldname' => 'location:centroid_geom', 'default' => html::initial_value($values, 'location:centroid_sref'), 'defaultGeom' => html::initial_value($values, 'location:centroid_geom'), 'systems' => spatial_ref::system_list(), 'defaultSystem' => html::initial_value($values, 'location:centroid_sref_system'), 'class' => 'control-width-3', 'validation' => 'required', 'disabled' => $disabled));
?>
  <input type="hidden" name="location:boundary_geom" id="imp-boundary-geom" value="<?php 
echo $boundary_geom;
?>
"/>
  <p class="instruct">Zoom the map in by double-clicking then single click on the location's centre to set the
  spatial reference. The more you zoom in, the more accurate the reference will be.</p>
  <?php 
$readAuth = data_entry_helper::get_read_auth(0 - $_SESSION['auth_user']->id, kohana::config('indicia.private_key'));
echo map_helper::map_panel(array('readAuth' => $readAuth, 'presetLayers' => array('osm'), 'editLayer' => true, 'layers' => array(), 'initial_lat' => 52, 'initial_long' => -2, 'initial_zoom' => 7, 'width' => 870, 'height' => 400, 'initialFeatureWkt' => $centroid_geom, 'standardControls' => $disabled_input === 'YES' ? array('layerSwitcher', 'panZoomBar') : array('layerSwitcher', 'panZoomBar', 'drawPolygon', 'drawLine', 'modifyFeature'), 'allowPolygonRecording' => true));
echo data_entry_helper::autocomplete(array('label' => 'Parent location', 'fieldname' => 'location:parent_id', 'table' => 'location', 'captionField' => 'name', 'valueField' => 'id', 'extraParams' => $readAuth, 'default' => html::initial_value($values, 'location:parent_id'), 'defaultCaption' => html::initial_value($values, 'parent:name'), 'disabled' => $disabled));
if ($this->auth->logged_in('CoreAdmin')) {
    //Only core admin can create public locations.
    echo data_entry_helper::checkbox(array('label' => 'Available to all websites', 'fieldname' => 'location:public', 'default' => html::initial_value($values, 'location:public'), 'disabled' => $disabled));
}
echo $base_url;
?>
/index.php/services/spatial/wkt_to_sref"+
    "?wkt=POINT(" + lonlat.lon + "  " + lonlat.lat + ")"+
    "&system=" + $('#imp-sref-system').val() +
    "&precision=" + precision +
    "&callback=?", function(data)
    {
      $('#imp-sref').attr('value', data.sref);
    }
  );
}
</script>
</head>
<body>
<div id="wrap">
<h1>Polygon Capture Map</h1>
<p>Click on the map to define a polygon. Double click to finish.</p>
<?php 
echo data_entry_helper::sref_and_system(array('label' => 'Spatial ref'));
echo data_entry_helper::map_panel(array('controls' => array('drawControl'), 'layers' => array('polygonLayer')));
echo data_entry_helper::dump_javascript();
?>
<script type='text/javascript'>
$(document).ready(function() {
  drawControl.activate();
});
</script>
</body>
</html>
Esempio n. 10
0
 private static function get_site_tab($auth, $args, $settings)
 {
     $r = '<div id="site-details" class="ui-helper-clearfix">';
     $r .= '<form method="post" id="input-form">';
     $r .= $auth['write'];
     $r .= '<fieldset><legend>' . lang::get('Site Details') . '</legend>';
     $r .= "<input type=\"hidden\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" name=\"survey_id\" value=\"" . $args['survey_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" name=\"location:location_type_id\" value=\"" . $settings['SiteLocationType'][0]['id'] . "\" />\n";
     if ($settings['locationId']) {
         $r .= '<input type="hidden" name="location:id" id="location:id" value="' . $settings['locationId'] . "\" />\n";
     }
     $r .= data_entry_helper::text_input(array('fieldname' => 'location:name', 'label' => lang::get('Site Name'), 'class' => 'control-width-4 required'));
     $r .= data_entry_helper::sref_and_system(array('fieldname' => 'location:centroid_sref', 'geomFieldname' => 'location:centroid_geom', 'label' => 'Site Central Grid Ref', 'systems' => array('4326' => '4326'), 'class' => 'required', 'disabled' => ' readonly="readonly" ', 'helpText' => lang::get('The following field is filled in automatically when the site is drawn on the map.')));
     $r .= '<input type="hidden" name="location:boundary_geom" id="imp-boundary-geom" value="' . data_entry_helper::$entity_to_load['location:boundary_geom'] . '"/>';
     // setup the map options
     $options = iform_map_get_map_options($args, $auth['read']);
     $r .= get_attribute_html($settings['attributes'], $args, array('extraParams' => $auth['read']));
     $r .= '</fieldset>';
     if (!$settings['locationId']) {
         $help = lang::get('Use the search box to find a nearby town or village, then drag the map to pan and zoom in or out to find your site.');
         $r .= '<p class="ui-state-highlight page-notice ui-corner-all">' . $help . '</p>';
         $r .= data_entry_helper::georeference_lookup(array('label' => lang::get('Search for place'), 'driver' => $args['georefDriver'], 'georefPreferredArea' => $args['georefPreferredArea'], 'georefCountry' => $args['georefCountry'], 'georefLang' => $args['language'], 'readAuth' => $auth['read']));
     }
     $help = '<p>' . lang::get('Draw your site by selecting the appropriate tool in the top right of the map') . ':</p>' . '<ol><li>' . lang::get('Navigation Tool. This allows you to navigate around the map by dragging.') . '</li>' . '<li>' . lang::get('Draw Site Tool. This tool allows you to draw your site on the map. Click on the map to start drawing, and click each time you wish to fix a point on the outline of your site.  <b>Double click the last fixed point to finish drawing</b>. Double clicking will replace any previously drawn site outline.') . '</li>' . '<li>' . lang::get('Modify Site Tool. This tool allows you to change the shape of a previously drawn site. Click on the existing site outline to add grab points (circles) along it. You can then click and drag these points to change the shape of the site. To remove a fixed point, hover your mouse over the point and press the "Delete" button on your keyboard.') . '</li></ol>';
     if ($args['allow_user_assignment']) {
         if ($settings['canAllocUser']) {
             $help .= '<p>' . lang::get('You, as a scheme administrator, have the option of changing who the site is assigned to, using control under the map. If you so wish, the site may be assigned to more than one person at a time.') . '</p>';
         }
     }
     $r .= '<div class="page-notice ui-state-highlight ui-corner-all">' . $help . '</div>';
     if (isset($args['maxPrecision']) && $args['maxPrecision'] != '') {
         $options['clickedSrefPrecisionMax'] = $args['maxPrecision'];
     }
     if (isset($args['minPrecision']) && $args['minPrecision'] != '') {
         $options['clickedSrefPrecisionMin'] = $args['minPrecision'];
     }
     $olOptions = iform_map_get_ol_options($args);
     $options['clickForSpatialRef'] = false;
     $options['allowPolygonRecording'] = true;
     $options['latLongFormat'] = 'DMS';
     $options['autoFillInCentroid'] = true;
     $options['initialFeatureWkt'] = false;
     $options['initialBoundaryWkt'] = data_entry_helper::$entity_to_load['location:boundary_geom'];
     $options['hintModifyFeature'] = lang::get('Modify Site Tool.');
     $options['hintDrawPolygonHint'] = lang::get('Draw Site Tool.');
     $options['hintNavigation'] = lang::get('Navigation Tool.');
     $options['searchDisplaysPoint'] = false;
     // with multiple maps can't use built in method on tabshow, so do here...
     $divId = preg_replace('/[^a-zA-Z0-9]/', '', 'site-details');
     $javascript = "var mapTabHandler = function(event, ui) { \n";
     $javascript .= "  panel = typeof ui.newPanel==='undefined' ? ui.panel : ui.newPanel[0];\n  if (panel.id=='site-details' && typeof indiciaData.mapdiv !== 'undefined') {\n    var map = jQuery('#map')[0].map;\n    map.updateSize();\n    var layerBounds = map.editLayer.getDataExtent().clone(); // use a clone\n    map.zoomToExtent(layerBounds);\n  }\n};\nindiciaFns.bindTabsActivate(jQuery(jQuery('#site-details').parent()), mapTabHandler);\n";
     // Insert this script at the beginning, because it must be done before the tabs are initialised or the
     // first tab cannot fire the event
     data_entry_helper::$javascript = $javascript . data_entry_helper::$javascript;
     $r .= map_helper::map_panel($options, $olOptions);
     if ($args['allow_user_assignment']) {
         if ($settings['canAllocUser']) {
             $r .= self::get_user_assignment_control($auth['read'], $settings['cmsUserAttr'], $args);
         } else {
             if (!$settings['locationId']) {
                 // for a new record, we need to link the current user to the location if they are not admin.
                 global $user;
                 self::get_user_assignment_control($auth['read'], $settings['cmsUserAttr'], $args);
                 // this will populate the recorder list.
                 $r .= '<input type="hidden" name="locAttr:' . self::$cmsUserAttrId . '" value="' . $user->uid . '">';
             }
         }
     }
     $r .= '<button type="submit" class="indicia-button right">' . lang::get('Save') . '</button>';
     if ($settings['locationId']) {
         $r .= '<button type="button" class="indicia-button right" id="delete-site">' . lang::get('Delete') . '</button>';
     }
     $r .= '</form>';
     $r .= '</div>';
     // site-details
     if ($settings['locationId']) {
         $treeIDs = array();
         foreach ($settings['trees'] as $id => $tree) {
             $treeIDs[] = $tree['id'];
         }
         data_entry_helper::$javascript .= "\ndeleteSite = function(){\n  if(confirm(\"" . lang::get('Are you sure you wish to delete this location?') . "\")){\n    deleteTrees([" . implode(',', $treeIDs) . "]);\n    \$('#delete-site').html('Deleting Site');\n    deleteLocation(" . $settings['locationId'] . ");\n    \$('#delete-site').html('Done');\n    window.location='" . url($args['sites_list_path']) . "';\n  };\n};\n\$('#delete-site').click(deleteSite);\n";
     }
     return $r;
 }
   /**
    * Return the generated form output.
    * @return Form HTML.
    */
   public static function get_form($args, $node, $response = null)
   {
       global $user;
       global $custom_terms;
       $logged_in = $user->uid > 0;
       $r = '';
       // Get authorisation tokens to update and read from the Warehouse.
       $writeAuth = data_entry_helper::get_auth($args['website_id'], $args['password']);
       $readAuth = data_entry_helper::get_read_auth($args['website_id'], $args['password']);
       $svcUrl = data_entry_helper::$base_url . '/index.php/services';
       $presetLayers = array();
       // read out the activated preset layers
       if (isset($args['preset_layers'])) {
           foreach ($args['preset_layers'] as $layer => $active) {
               if ($active !== 0) {
                   $presetLayers[] = $layer;
               }
           }
       }
       drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/jquery.form.js', 'module');
       data_entry_helper::link_default_stylesheet();
       data_entry_helper::add_resource('jquery_ui');
       if ($args['language'] != 'en') {
           data_entry_helper::add_resource('jquery_ui_' . $args['language']);
       }
       // If not logged in: Display an information message.
       // This form should only be called in POST mode when setting the location allocation.
       //  All other posting is now done via AJAX.
       // When invoked by GET there are the following modes:
       // No additional arguments: mode 0.
       // Additional argument - newSample: mode 1.
       // Additional argument - sample_id=<id>: mode 2.
       // Additional argument - occurrence_id=<id>: mode 3.
       $mode = 0;
       // default mode : output survey selector
       // mode 1: output the main Data Entry page: occurrence list or add/edit occurrence tabs hidden. "Survey" tab active
       // mode 2: output the main Data Entry page, display existing sample. Active tab determined by iform params. No occurence details filled in.
       // mode 3: output the main Data Entry page, display existing occurrence. "Edit Occurrence" tab active. Occurence details filled in.
       $surveyReadOnly = false;
       // On top of this, things can be flagged as readonly. RO mode 2+4 means no Add Occurrence tab.
       if (!$logged_in) {
           return lang::get('LANG_not_logged_in');
       }
       $parentSample = array();
       $parentLoadID = null;
       $childSample = array();
       $childLoadID = null;
       $thisOccID = -1;
       // IDs have to be >0, so this is outside the valid range
       if ($_POST) {
           if (!array_key_exists('website_id', $_POST)) {
               // non Indicia POST, in this case must be the location allocations. add check to ensure we don't corrept the data by accident
               if (iform_loctools_checkaccess($node, 'admin') && array_key_exists('mnhnlbtw', $_POST)) {
                   iform_loctools_deletelocations($node);
                   foreach ($_POST as $key => $value) {
                       $parts = explode(':', $key);
                       if ($parts[0] == 'location' && $value) {
                           iform_loctools_insertlocation($node, $value, $parts[1]);
                       }
                   }
               }
           }
       } else {
           if (array_key_exists('sample_id', $_GET)) {
               $mode = 2;
               $parentLoadID = $_GET['sample_id'];
           } else {
               if (array_key_exists('occurrence_id', $_GET)) {
                   $mode = 3;
                   $childLoadID = $_GET['occurrence_id'];
                   $thisOccID = $childLoadID;
               } else {
                   if (array_key_exists('newSample', $_GET)) {
                       $mode = 1;
                   }
               }
           }
           // else default to mode 0
       }
       // define language strings so they can be used for validation translation.
       data_entry_helper::$javascript .= "var translations = [\n";
       foreach ($custom_terms as $key => $value) {
           if (substr($key, 0, 4) != "LANG") {
               data_entry_helper::$javascript .= "  {key: \"" . $key . "\", translated: \"" . $value . "\"},\n";
           }
       }
       data_entry_helper::$javascript .= "];\n";
       // define layers for all maps.
       // each argument is a comma separated list eg:
       // "Name:Lux Outline,URL:http://localhost/geoserver/wms,LAYERS:indicia:nation2,SRS:EPSG:2169,FORMAT:image/png,minScale:0,maxScale:1000000,units:m";
       $optionArray_1 = array();
       $optionArray_2 = array();
       $optionArray_Location = array();
       $options = explode(',', $args['layer1']);
       foreach ($options as $option) {
           $parts = explode(':', $option);
           $optionName = $parts[0];
           unset($parts[0]);
           $optionsArray_1[$optionName] = implode(':', $parts);
       }
       $options = explode(',', $args['layer2']);
       foreach ($options as $option) {
           $parts = explode(':', $option);
           $optionName = $parts[0];
           unset($parts[0]);
           $optionsArray_2[$optionName] = implode(':', $parts);
       }
       $options = explode(',', $args['locationLayer']);
       foreach ($options as $option) {
           $parts = explode(':', $option);
           $optionName = $parts[0];
           unset($parts[0]);
           $optionsArray_Location[$optionName] = implode(':', $parts);
       }
       // Work out list of locations this user can see.
       $locations = iform_loctools_listlocations($node);
       if ($locations != 'all') {
           data_entry_helper::$javascript .= "locationList = [" . implode(',', $locations) . "];\n";
       }
       data_entry_helper::$javascript .= "\n// Create Layers.\n// Base Layers first.\nvar WMSoptions = {\n          LAYERS: '" . $optionsArray_1['LAYERS'] . "',\n          SERVICE: 'WMS',\n          VERSION: '1.1.0',\n          STYLES: '',\n          SRS: '" . $optionsArray_1['SRS'] . "',\n          FORMAT: '" . $optionsArray_1['FORMAT'] . "'\n    };\nbaseLayer_1 = new OpenLayers.Layer.WMS('" . $optionsArray_1['Name'] . "',\n        '" . iform_proxy_url($optionsArray_1['URL']) . "',\n        WMSoptions, {\n             minScale: " . $optionsArray_1['minScale'] . ",\n            maxScale: " . $optionsArray_1['maxScale'] . ",\n            units: '" . $optionsArray_1['units'] . "',\n            isBaseLayer: true,\n            singleTile: true\n        });\nWMSoptions = {\n          LAYERS: '" . $optionsArray_2['LAYERS'] . "',\n          SERVICE: 'WMS',\n          VERSION: '1.1.0',\n          STYLES: '',\n          SRS: '" . $optionsArray_2['SRS'] . "',\n          FORMAT: '" . $optionsArray_2['FORMAT'] . "'\n    };\nbaseLayer_2 = new OpenLayers.Layer.WMS('" . $optionsArray_2['Name'] . "',\n        '" . iform_proxy_url($optionsArray_2['URL']) . "',\n        WMSoptions, {\n             minScale: " . $optionsArray_2['minScale'] . ",\n            maxScale: " . $optionsArray_2['maxScale'] . ",\n            units: '" . $optionsArray_2['units'] . "',\n            isBaseLayer: true,\n            singleTile: true\n        });\nWMSoptions = {\n          SERVICE: 'WMS',\n          VERSION: '1.1.0',\n          STYLES: '',\n          SRS: '" . $optionsArray_Location['SRS'] . "',\n          FORMAT: '" . $optionsArray_Location['FORMAT'] . "',\n          TRANSPARENT: 'true', ";
       if ($locations != 'all') {
           // when given a restricted feature list we have to use the feature id to filter in order to not go over 2000 char limit on the URL
           // Can only generate the feature id if we access a table directly, not through a view. Go direct to the locations table.
           // don't need to worry about parent_id in this case as we know exactly which features we want.
           // need to use btw_transects view for unrestricted so we can filter by parent_id.
           $locFeatures = array();
           foreach ($locations as $location) {
               $locFeatures[] = "locations." . $location;
           }
           data_entry_helper::$javascript .= "\n        LAYERS: 'indicia:locations',\n        FEATUREID: '" . implode(',', $locFeatures) . "'";
       } else {
           data_entry_helper::$javascript .= "\n        LAYERS: '" . $optionsArray_Location['LAYERS'] . "'";
       }
       data_entry_helper::$javascript .= "\n    };\nlocationListLayer = new OpenLayers.Layer.WMS('" . $optionArray_Location['Name'] . "',\n        '" . iform_proxy_url($optionsArray_Location['URL']) . "',\n        WMSoptions, {\n             minScale: " . $optionsArray_Location['minScale'] . ",\n            maxScale: " . $optionsArray_Location['maxScale'] . ",\n            units: '" . $optionsArray_Location['units'] . "',\n            isBaseLayer: false,\n            singleTile: true\n        });\n// Create vector layers: one to display the location onto, and another for the occurrence list\n// the default edit layer is used for the occurrences themselves\nlocStyleMap = new OpenLayers.StyleMap({\n                \"default\": new OpenLayers.Style({\n                    fillColor: \"Green\",\n                    strokeColor: \"Black\",\n                    fillOpacity: 0.2,\n                    strokeWidth: 1\n                  })\n  });\nlocationLayer = new OpenLayers.Layer.Vector(\"" . lang::get("LANG_Location_Layer") . "\",\n                                    {styleMap: locStyleMap});\noccStyleMap = new OpenLayers.StyleMap({\n                \"default\": new OpenLayers.Style({\n                    pointRadius: 3,\n                    fillColor: \"Red\",\n                    fillOpacity: 0.3,\n                    strokeColor: \"Red\",\n                    strokeWidth: 1\n          }) });\noccListLayer = new OpenLayers.Layer.Vector(\"" . lang::get("LANG_Occurrence_List_Layer") . "\",\n                                    {styleMap: occStyleMap});\n";
       drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/hasharray.js', 'module');
       drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/jquery.datagrid.js', 'module');
       // Work out list of locations this user can see.
       $locations = iform_loctools_listlocations($node);
       ///////////////////////////////////////////////////////////////////
       // default mode 0 : display a page with tabs for survey selector,
       // locations allocator and reports (last two require permissions)
       ///////////////////////////////////////////////////////////////////
       if ($mode == 0) {
           // If the user has permissions, add tabs so can choose to see
           // locations allocator
           $tabs = array('#surveyList' => lang::get('LANG_Surveys'));
           if (iform_loctools_checkaccess($node, 'admin')) {
               $tabs['#setLocations'] = lang::get('LANG_Allocate_Locations');
           }
           if (iform_loctools_checkaccess($node, 'superuser')) {
               $tabs['#downloads'] = lang::get('LANG_Download');
           }
           if (count($tabs) > 1) {
               $r .= "<div id=\"controls\">" . data_entry_helper::enable_tabs(array('divId' => 'controls', 'active' => '#surveyList')) . "<div id=\"temp\"></div>";
               $r .= data_entry_helper::tab_header(array('tabs' => $tabs));
           }
           if ($locations == 'all') {
               $useloclist = 'NO';
               $loclist = '-1';
           } else {
               // an empty list will cause an sql error, lids must be > 0, so push a -1 to prevent the error.
               if (empty($locations)) {
                   $locations[] = -1;
               }
               $useloclist = 'YES';
               $loclist = implode(',', $locations);
           }
           // Create the Survey list datagrid for this user.
           drupal_add_js("jQuery(document).ready(function(){\n  \$('div#smp_grid').indiciaDataGrid('rpt:mnhnl_btw_list_samples', {\n    indiciaSvc: '" . $svcUrl . "',\n    dataColumns: ['location_name', 'date', 'num_visit', 'num_occurrences', 'num_taxa'],\n    reportColumnTitles: {location_name : '" . lang::get('LANG_Transect') . "', date : '" . lang::get('LANG_Date') . "', num_visit : '" . lang::get('LANG_Visit_No') . "', num_occurrences : '" . lang::get('LANG_Num_Occurrences') . "', num_taxa : '" . lang::get('LANG_Num_Species') . "'},\n    actionColumns: {" . lang::get('LANG_Show') . " : \"" . url('node/' . $node->nid, array('query' => 'sample_id=£id£')) . "\"},\n    auth : { nonce : '" . $readAuth['nonce'] . "', auth_token : '" . $readAuth['auth_token'] . "'},\n    parameters : { survey_id : '" . $args['survey_id'] . "', visit_attr_id : '" . $args['sample_visit_number_id'] . "', closed_attr_id : '" . $args['sample_closure_id'] . "', use_location_list : '" . $useloclist . "', locations : '" . $loclist . "'},\n    itemsPerPage : 12,\n    condCss : {field : 'closed', value : '0', css: 'mnhnl-btw-highlight'},\n    cssOdd : ''\n  });\n});\n      ", 'inline');
           $r .= '
 <div id="surveyList" class="mnhnl-btw-datapanel"><div id="smp_grid"></div>
   <form><input type="button" value="' . lang::get('LANG_Add_Survey') . '" onclick="window.location.href=\'' . url('node/' . $node->nid, array('query' => 'newSample')) . '\'"></form></div>';
           // Add the locations allocator if user has admin rights.
           if (iform_loctools_checkaccess($node, 'admin')) {
               $r .= '
 <div id="setLocations" class="mnhnl-btw-datapanel">
   <form method="post">
     <input type="hidden" id="mnhnlbtw" name="mnhnlbtw" value="mnhnlbtw" />\\n';
               $url = $svcUrl . '/data/location?mode=json&view=detail&auth_token=' . $readAuth['auth_token'] . "&nonce=" . $readAuth["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);
               if (!empty($entities)) {
                   foreach ($entities as $entity) {
                       if (!$entity["parent_id"]) {
                           // only assign parent locations.
                           $r .= "\n<label for=\"location:" . $entity["id"] . "\">" . $entity["name"] . ":</label><select id=\"location:" . $entity["id"] . "\" name=\"location:" . $entity["id"] . "\"><option value=\"\" >&lt;" . lang::get('LANG_Not_Allocated') . "&gt;</option>";
                           $defaultuserid = iform_loctools_getuser($node, $entity["id"]);
                           foreach ($userlist as $uid => $a_user) {
                               $r .= "<option value=\"" . $uid . "\" " . ($uid == $defaultuserid ? 'selected="selected" ' : '') . ">" . $a_user->name . "</option>";
                           }
                           $r .= "</select>";
                       }
                   }
               }
               $r .= "\n      <input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Save_Location_Allocations') . "\" />\n    </form>\n  </div>";
           }
           // Add the downloader if user has manager (superuser) rights.
           if (iform_loctools_checkaccess($node, 'superuser')) {
               $r .= '
 <div id="downloads" class="mnhnl-btw-datapanel">
   <form method="post" action="' . data_entry_helper::$base_url . '/index.php/services/report/requestReport?report=mnhnl_btw_transect_direction_report.xml&reportSource=local&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth['nonce'] . '&mode=csv">
     <p>' . lang::get('LANG_Direction_Report') . '</p>
     <input type="hidden" id="params" name="params" value=\'{"survey_id":' . $args['survey_id'] . ', "direction_attr_id":' . $args['sample_walk_direction_id'] . ', "closed_attr_id":' . $args['sample_closure_id'] . '}\' />
     <input type="submit" class="ui-state-default ui-corner-all" value="' . lang::get('LANG_Direction_Report_Button') . '">
   </form>
   <form method="post" action="' . data_entry_helper::$base_url . '/index.php/services/report/requestReport?report=mnhnl_btw_download_report.xml&reportSource=local&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth['nonce'] . '&mode=csv\\">
     <p>' . lang::get('LANG_Initial_Download') . '</p>
     <input type="hidden" id="params" name="params" value=\'{"survey_id":' . $args['survey_id'] . ', "closed_attr_id":' . $args['sample_closure_id'] . ', "download": "INITIAL"}\' />
     <input type="submit" class=\\"ui-state-default ui-corner-all" value="' . lang::get('LANG_Initial_Download_Button') . '">
   </form>
   <form method="post" action="' . data_entry_helper::$base_url . '/index.php/services/report/requestReport?report=mnhnl_btw_download_report.xml&reportSource=local&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth['nonce'] . '&mode=csv\\">
     <p>' . lang::get('LANG_Confirm_Download') . '</p>
     <input type="hidden" id="params" name="params" value=\'{"survey_id":' . $args['survey_id'] . ', "closed_attr_id":' . $args['sample_closure_id'] . ', "download": "CONFIRM"}\' />
     <input type="submit" class="ui-state-default ui-corner-all" value="' . lang::get('LANG_Confirm_Download_Button') . '">
   </form>
   <form method="post" action="' . data_entry_helper::$base_url . '/index.php/services/report/requestReport?report=mnhnl_btw_download_report.xml&reportSource=local&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth['nonce'] . '&mode=csv\\">
     <p>' . lang::get('LANG_Final_Download') . '</p>
     <input type="hidden" id="params" name="params" value=\'{"survey_id":' . $args['survey_id'] . ', "closed_attr_id":' . $args['sample_closure_id'] . ', "download": "FINAL"}\' />
     <input type="submit" class="ui-state-default ui-corner-all" value="' . lang::get('LANG_Final_Download_Button') . '">
   </form>
 </div>';
           }
           // Create Map
           $r .= "<div class=\"mnhnl-btw-mappanel\">\n" . data_entry_helper::map_panel(array('presetLayers' => $presetLayers, 'layers' => array('baseLayer_1', 'baseLayer_2', 'locationListLayer'), 'initialFeatureWkt' => null, 'width' => 'auto', 'height' => 490, 'editLayer' => false, 'initial_lat' => $args['map_centroid_lat'], 'initial_long' => $args['map_centroid_long'], 'initial_zoom' => (int) $args['map_zoom'], 'scroll_wheel_zoom' => false), array('projection' => $args['map_projection'])) . "</div>\n";
           data_entry_helper::$javascript .= "\n\$('#controls').bind('tabsshow', function(event, ui) {\n  var y = \$('.mnhnl-btw-datapanel:visible').outerHeight(true) + \$('.mnhnl-btw-datapanel:visible').position().top;\n  if(y < \$('.mnhnl-btw-mappanel').outerHeight(true)+ \$('.mnhnl-btw-mappanel').position().top){\n    y = \$('.mnhnl-btw-mappanel').outerHeight(true)+ \$('.mnhnl-btw-mappanel').position().top;\n  }\n  \$('#controls').height(y - \$('#controls').position().top);\n});\n";
           if (count($tabs) > 1) {
               // close tabs div if present
               $r .= "</div>";
           }
           return $r;
       }
       ///////////////////////////////////////////////////////////////////
       $occReadOnly = false;
       if ($childLoadID) {
           // load the occurrence and its associated sample (which holds the position)
           $url = $svcUrl . '/data/occurrence/' . $childLoadID;
           $url .= "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"];
           $session = curl_init($url);
           curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
           $entity = json_decode(curl_exec($session), true);
           $childSample = array();
           foreach ($entity[0] as $key => $value) {
               $childSample['occurrence:' . $key] = $value;
           }
           if ($entity[0]['downloaded_flag'] == 'F') {
               // Final download complete, now readonly
               $occReadOnly = true;
           }
           $url = $svcUrl . '/data/sample/' . $childSample['occurrence:sample_id'];
           $url .= "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"];
           $session = curl_init($url);
           curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
           $entity = json_decode(curl_exec($session), true);
           foreach ($entity[0] as $key => $value) {
               $childSample['sample:' . $key] = $value;
           }
           $childSample['sample:geom'] = '';
           // value received from db is not WKT, which is assumed by all the code.
           $thisOccID = $childLoadID;
           // this will be used to load the occurrence into the editlayer.
           $childSample['taxon'] = $childSample['occurrence:taxon'];
           $parentLoadID = $childSample['sample:parent_id'];
       }
       if ($parentLoadID) {
           // load the container master sample
           $url = $svcUrl . '/data/sample/' . $parentLoadID;
           $url .= "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"];
           $session = curl_init($url);
           curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
           $entity = json_decode(curl_exec($session), true);
           $parentSample = array();
           foreach ($entity[0] as $key => $value) {
               $parentSample['sample:' . $key] = $value;
           }
           if (is_array($locations) && !in_array($entity[0]["location_id"], $locations)) {
               return '<p>' . lang::get('LANG_No_Access_To_Location') . '</p>';
           }
           if ($entity[0]["parent_id"]) {
               return '<p>' . lang::get('LANG_No_Access_To_Sample') . '</p>';
           }
           $parentSample['sample:date'] = $parentSample['sample:date_start'];
           // bit of a bodge
           // default values for attributes from DB are picked up automatically.
       }
       $childSample['sample:date'] = $parentSample['sample:date'];
       // enforce a match between child and parent sample dates
       data_entry_helper::$entity_to_load = $parentSample;
       $attributes = data_entry_helper::getAttributes(array('id' => data_entry_helper::$entity_to_load['sample:id'], 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $readAuth));
       $closedFieldName = $attributes[$args['sample_closure_id']]['fieldname'];
       $closedFieldValue = data_entry_helper::check_default_value($closedFieldName, array_key_exists('default', $attributes[$args['sample_closure_id']]) ? $attributes[$args['sample_closure_id']]['default'] : '0');
       // default is not closed
       $adminPerm = 'IForm node ' . $node->nid . ' admin';
       if ($closedFieldValue == '1' && !user_access($adminPerm)) {
           // sample has been closed, no admin perms. Everything now set to read only.
           $surveyReadOnly = true;
           $disabledText = "disabled=\"disabled\"";
           $defAttrOptions = array('extraParams' => $readAuth, 'disabled' => $disabledText);
       } else {
           // sample open.
           $disabledText = "";
           $defAttrOptions = array('extraParams' => $readAuth);
       }
       // with the AJAX code, we deal with the validation semi manually: Form name is meant be invalid as we only want code included.
       data_entry_helper::enable_validation('DummyForm');
       $r .= "<div id=\"controls\">\n";
       $activeTab = 'survey';
       // mode 1 = new Sample, display sample.
       if ($mode == 2) {
           // have specified a sample ID
           if ($args["on_edit_survey_nav"] == "survey") {
               $activeTab = 'survey';
           } else {
               if ($surveyReadOnly || $args["on_edit_survey_nav"] == "list") {
                   $activeTab = 'occurrenceList';
               } else {
                   $activeTab = 'occurrence';
               }
           }
           if ($surveyReadOnly) {
               data_entry_helper::$javascript .= "jQuery('#occ-form').hide();";
           }
       } else {
           if ($mode == 3) {
               // have specified an occurrence ID
               $activeTab = 'occurrence';
           }
       }
       // Set Up form tabs.
       $r .= data_entry_helper::enable_tabs(array('divId' => 'controls', 'active' => $activeTab));
       $r .= "<div id=\"temp\"></div>";
       $r .= data_entry_helper::tab_header(array('tabs' => array('#survey' => lang::get('LANG_Survey'), '#occurrence' => lang::get($surveyReadOnly || $occReadOnly ? 'LANG_Show_Occurrence' : (isset($childSample['sample:id']) ? 'LANG_Edit_Occurrence' : 'LANG_Add_Occurrence')), '#occurrenceList' => lang::get('LANG_Occurrence_List'))));
       // Set up main Survey Form.
       $r .= "<div id=\"survey\" class=\"mnhnl-btw-datapanel\">\n  <p id=\"read-only-survey\"><strong>" . lang::get('LANG_Read_Only_Survey') . "</strong></p>\n  <form id=\"SurveyForm\" action=\"" . iform_ajaxproxy_url($node, 'sample') . "\" method=\"post\">\n    <input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n    <input type=\"hidden\" id=\"sample:survey_id\" name=\"sample:survey_id\" value=\"" . $args['survey_id'] . "\" />\n    " . iform_user_get_hidden_inputs($args);
       if (array_key_exists('sample:id', data_entry_helper::$entity_to_load)) {
           $r .= "<input type=\"hidden\" id=\"sample:id\" name=\"sample:id\" value=\"" . data_entry_helper::$entity_to_load['sample:id'] . "\" />\n";
       } else {
           $r .= "<input type=\"hidden\" id=\"sample:id\" name=\"sample:id\" value=\"\" disabled=\"disabled\" />\n";
       }
       $defAttrOptions['validation'] = array('required');
       $defAttrOptions['suffixTemplate'] = 'requiredsuffix';
       if ($locations == 'all') {
           $locOptions = array_merge(array('label' => lang::get('LANG_Transect')), $defAttrOptions);
           $locOptions['extraParams'] = array_merge(array('parent_id' => 'NULL', 'view' => 'detail', 'orderby' => 'name'), $locOptions['extraParams']);
           $r .= data_entry_helper::location_select($locOptions);
       } else {
           // can't use location select due to location filtering.
           $r .= "<label for=\"imp-location\">" . lang::get('LANG_Transect') . ":</label>\n<select id=\"imp-location\" name=\"sample:location_id\" " . $disabled_text . " class=\" \"  >";
           $url = $svcUrl . '/data/location?mode=json&view=detail&parent_id=NULL&orderby=name&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth["nonce"];
           $session = curl_init($url);
           curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
           $entities = json_decode(curl_exec($session), true);
           if (!empty($entities)) {
               foreach ($entities as $entity) {
                   if (in_array($entity["id"], $locations)) {
                       if ($entity["id"] == data_entry_helper::$entity_to_load['sample:location_id']) {
                           $selected = 'selected="selected"';
                       } else {
                           $selected = '';
                       }
                       $r .= "<option value=\"" . $entity["id"] . "\" " . $selected . ">" . $entity["name"] . "</option>";
                   }
               }
           }
           $r .= "</select><span class=\"deh-required\">*</span><br />";
       }
       $languageFilteredAttrOptions = $defAttrOptions + array('language' => iform_lang_iso_639_2($args['language']));
       $r .= data_entry_helper::outputAttribute($attributes[$args['sample_walk_direction_id']], $languageFilteredAttrOptions) . data_entry_helper::outputAttribute($attributes[$args['sample_reliability_id']], $languageFilteredAttrOptions) . data_entry_helper::outputAttribute($attributes[$args['sample_visit_number_id']], array_merge($languageFilteredAttrOptions, array('default' => 1, 'noBlankText' => true)));
       if ($surveyReadOnly) {
           $r .= data_entry_helper::text_input(array_merge($defAttrOptions, array('label' => lang::get('LANG_Date'), 'fieldname' => 'sample:date', 'disabled' => $disabledText)));
       } else {
           $r .= data_entry_helper::date_picker(array('label' => lang::get('LANG_Date'), 'fieldname' => 'sample:date', 'class' => 'vague-date-picker', 'suffixTemplate' => 'requiredsuffix'));
       }
       $r .= data_entry_helper::outputAttribute($attributes[$args['sample_wind_id']], $languageFilteredAttrOptions) . data_entry_helper::outputAttribute($attributes[$args['sample_precipitation_id']], $languageFilteredAttrOptions) . data_entry_helper::outputAttribute($attributes[$args['sample_temperature_id']], array_merge($defAttrOptions, array('suffixTemplate' => 'nosuffix'))) . " degC<span class=\"deh-required\">*</span><br />" . data_entry_helper::outputAttribute($attributes[$args['sample_cloud_id']], $defAttrOptions) . data_entry_helper::outputAttribute($attributes[$args['sample_start_time_id']], array_merge($defAttrOptions, array('suffixTemplate' => 'nosuffix'))) . " hh:mm<span class=\"deh-required\">*</span><br />" . data_entry_helper::outputAttribute($attributes[$args['sample_end_time_id']], array_merge($defAttrOptions, array('suffixTemplate' => 'nosuffix'))) . " hh:mm<span class=\"deh-required\">*</span><br />";
       unset($defAttrOptions['suffixTemplate']);
       unset($defAttrOptions['validation']);
       if (user_access($adminPerm)) {
           //  users with admin permissions can override the closing of the
           // sample by unchecking the checkbox.
           // Because this is attached to the sample, we have to include the sample required fields in the
           // the post. This means they can't be disabled, so we enable all fields in this case.
           // Normal users can only set this to closed, and they do this using a button/hidden field.
           $r .= data_entry_helper::outputAttribute($attributes[$args['sample_closure_id']], $defAttrOptions);
       } else {
           // hidden closed
           $r .= "<input type=\"hidden\" id=\"" . $closedFieldName . "\" name=\"" . $closedFieldName . "\" value=\"" . $closedFieldValue . "\" />\n";
       }
       $escaped_id = str_replace(':', '\\\\:', $closedFieldName);
       if (!$surveyReadOnly) {
           // NB that we don't even include the buttons when readonly.
           data_entry_helper::$javascript .= "\njQuery('#read-only-survey').hide();\njQuery('#ro-sur-occ-warn').hide();\n";
           $r .= "<input type=button id=\"close1\" class=\"ui-state-default ui-corner-all \" value=\"" . lang::get('LANG_Save_Survey_Details') . "\";\n        onclick=\"var result = \$('#SurveyForm input').valid();\n          var result2 = \$('#SurveyForm select').valid();\n          if (!result || !result2) {\n              return;\n            }\n            jQuery('#close1').addClass('loading-button');\n            jQuery('#SurveyForm').submit();\">\n";
           if (!user_access($adminPerm)) {
               if ($mode != 1) {
                   data_entry_helper::$javascript .= "jQuery('#close2').hide();\n";
               }
               $r .= "<input type=button id=\"close2\" class=\"ui-state-default ui-corner-all \" value=\"" . lang::get('LANG_Save_Survey_And_Close') . "\"\n        onclick=\"if(confirm('" . lang::get('LANG_Close_Survey_Confirm') . "')){\n          var result = \$('#SurveyForm input').valid();\n          var result2 = \$('#SurveyForm select').valid();\n          if (!result || !result2) {\n              return;\n            }\n            jQuery('#" . $escaped_id . "').val('1');\n            jQuery('#close2').addClass('loading-button');\n            jQuery('#SurveyForm').submit();\n          };\">\n";
           }
       }
       $r .= "</form></div>\n";
       data_entry_helper::$javascript .= "\nalertIndiciaError = function(data){\n\tvar errorString = \"" . lang::get('LANG_Indicia_Warehouse_Error') . "\";\n\tif(data.error){\terrorString = errorString + ' : ' + data.error;\t}\n\tif(data.errors){\n\t\tfor (var i in data.errors){\n\t\t\terrorString = errorString + ' : ' + data.errors[i];\n\t\t}\t\t\t\t\n\t}\n\talert(errorString);\n\t// the most likely cause is authentication failure - eg the read authentication has timed out.\n\t// prevent further use of the form:\n\t\$('.loading-panel').remove();\n\t\$('.loading-hide').removeClass('loading-hide');\n};\nerrorPos = null;\nclearErrors = function(formSel) {\n\tjQuery(formSel).find('.inline-error').remove();\n\terrorPos = null;\n};\nmyScrollTo = function(selector){\n\tjQuery(selector).filter(':visible').each(function(){\n\t\tif(errorPos == null || jQuery(this).offset().top < errorPos){\n\t\t\terrorPos = jQuery(this).offset().top;\n\t\t\twindow.scroll(0,errorPos);\n\t\t}\n\t});\n};\nmyScrollToError = function(){\n\tjQuery('.inline-error,.error').filter(':visible').prev().each(function(){\n\t\tif(errorPos == null || jQuery(this).offset().top < errorPos){\n\t\t\terrorPos = jQuery(this).offset().top;\n\t\t\twindow.scroll(0,errorPos);\n\t\t}\n\t});\n};\njQuery('#SurveyForm').ajaxForm({ \n\tasync: false,\n\tdataType:  'json', \n    beforeSubmit:   function(data, obj, options){\n    \tvar valid = true;\n    \tclearErrors('form#SurveyForm');\n    \tif (!jQuery('form#SurveyForm > input').valid()) {\n\t\t\tmyScrollToError();\n  \t\t\tjQuery('.loading-button').removeClass('loading-button');\n\t\t\treturn false;\n  \t\t};\n\t\treturn true;\n\t},\n    success:   function(data){\n       // this will leave all the fields populated.\n       \tif(data.success == 'multiple records' && data.outer_table == 'sample'){\n\t\t\twindow.scroll(0,0);\n            jQuery('#SurveyForm > input[name=sample\\:id]').removeAttr('disabled').val(data.outer_id);\n            jQuery('#occ-form > input[name=sample\\:parent_id]').val(data.outer_id);\n            jQuery('#occ-form > input[name=sample\\:date]').val(jQuery('#SurveyForm > input[name=sample\\:date]').val());\n            jQuery('#occ-form').show();\n            jQuery('#na-occ-warn').hide();";
       if (!user_access($adminPerm)) {
           data_entry_helper::$javascript .= "\n\t\t\tif(jQuery('#" . $escaped_id . "').val() == '1'){\n\t\t\t\tjQuery('#read-only-survey').show();\n\t\t\t\tjQuery('#close1').hide();\n\t\t\t\tjQuery('#close2').hide();\n\t\t\t};\n";
       }
       data_entry_helper::$javascript .= "\n\t\t\tswitch(\"" . $args["on_save_survey_nav"] . "\"){\n\t\t\t\tcase \"list\":\n\t\t\t\t\tvar a = \$('ul.ui-tabs-nav a')[2];\n\t\t\t\t\t\$(a).click();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"survey\":\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tvar a = \$('ul.ui-tabs-nav a')[1];\n\t\t\t\t\t\$(a).click();\n\t\t\t\t\tbreak;\n\t\t\t}\n        } else {\n\t\t\tif(data.error){\n\t\t\t\tvar lastIndex = data.error.lastIndexOf('Validation error'); \n    \t\t\tif (lastIndex != -1 && lastIndex  == (data.error.length - 16)){ \n\t\t\t\t\tif(data.errors){\n\t\t\t\t\t\t// TODO translation\n\t\t\t\t\t\tfor (i in data.errors){\n\t\t\t\t\t\t\tvar label = \$('<p/>')\n\t\t\t\t\t\t\t\t.addClass('inline-error')\n\t\t\t\t\t\t\t\t.html(data.errors[i]);\n\t\t\t\t\t\t\tlabel.insertAfter('[name='+i+']');\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmyScrollToError();\n\t\t\t\t\t\treturn;\n  \t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\talertIndiciaError(data);\n        }\n\t},\n    complete: function (){\n  \t\tjQuery('.loading-button').removeClass('loading-button');\n  \t}\n});";
       // Set up Occurrence List tab: don't include when creating a new sample as it will have no occurrences
       // Grid populated at a later point
       $r .= "<div id=\"occurrenceList\" class=\"mnhnl-btw-datapanel\"><div id=\"occ_grid\"></div>\n  <form method=\"post\" action=\"" . data_entry_helper::$base_url . "/index.php/services/report/requestReport?report=mnhnl_btw_occurrences_report.xml&reportSource=local&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth['nonce'] . "&mode=csv\">\n    <input type=\"hidden\" id=\"params\" name=\"params\" value='{\"survey_id\":" . $args['survey_id'] . ", \"sample_id\":" . data_entry_helper::$entity_to_load['sample:id'] . "}' />\n    <input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Download_Occurrences') . "\">\n  </form></div>";
       if ($occReadOnly) {
           // NB that we don't even include the buttons when readonly.
           data_entry_helper::$javascript .= "\njQuery('#ro-occ-occ-warn').show();\njQuery('#ro-sur-occ-warn').hide();\n";
       } else {
           data_entry_helper::$javascript .= "\njQuery('#ro-occ-occ-warn').hide();\n";
       }
       if ($mode == 1) {
           data_entry_helper::$javascript .= "jQuery('#occ-form').hide();";
       } else {
           data_entry_helper::$javascript .= "jQuery('#na-occ-warn').hide();";
       }
       // Set up Occurrence tab: don't allow entry of a new occurrence until after top level sample is saved.
       data_entry_helper::$entity_to_load = $childSample;
       $attributes = data_entry_helper::getAttributes(array('id' => data_entry_helper::$entity_to_load['occurrence:id'], 'valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => 'occAttr', 'extraParams' => $readAuth));
       $extraParams = $readAuth + array('taxon_list_id' => $args['list_id'], 'view' => 'detail', 'query' => urlencode(json_encode(array('in' => array('language_iso', array('lat', iform_lang_iso_639_2($args['language'])))))));
       if ($occReadOnly) {
           // if the occurrence has been downloaded, no one can modify it.
           $disabledText = "disabled=\"disabled\"";
           $defAttrOptions['disabled'] = $disabledText;
       }
       $species_ctrl_args = array('label' => lang::get('LANG_Species'), 'fieldname' => 'occurrence:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 2, 'extraParams' => $extraParams, 'suffixTemplate' => 'requiredsuffix', 'disabled' => $disabledText, 'defaultCaption' => data_entry_helper::$entity_to_load['occurrence:taxon']);
       $escaped_terr_id = str_replace(':', '\\\\:', $attributes[$args['occurrence_territorial_id']]['fieldname']);
       $r .= "  <div id=\"occurrence\" class=\"mnhnl-btw-datapanel\">\n    <p id=\"ro-occ-occ-warn\"><strong>" . lang::get('LANG_Read_Only_Occurrence') . "</strong></p>\n    <p id=\"ro-sur-occ-warn\"><strong>" . lang::get('LANG_Read_Only_Survey') . "</strong></p>\n    <p id=\"na-occ-warn\"><strong>" . lang::get('LANG_Page_Not_Available') . "</strong></p>\n    <form method=\"post\" id=\"occ-form\" action=\"" . iform_ajaxproxy_url($node, 'smp-occ') . "\" >\n    <input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n    <input type=\"hidden\" id=\"sample:survey_id\" name=\"sample:survey_id\" value=\"" . $args['survey_id'] . "\" />\n    <input type=\"hidden\" id=\"sample:parent_id\" name=\"sample:parent_id\" value=\"" . $parentSample['sample:id'] . "\" />\n    <input type=\"hidden\" id=\"sample:date\" name=\"sample:date\" value=\"" . data_entry_helper::$entity_to_load['sample:date'] . "\" />\n    <input type=\"hidden\" id=\"sample:id\" name=\"sample:id\" value=\"" . data_entry_helper::$entity_to_load['sample:id'] . "\" />\n    <input type=\"hidden\" id=\"occurrence:id\" name=\"occurrence:id\" value=\"" . data_entry_helper::$entity_to_load['occurrence:id'] . "\" />\n    <input type=\"hidden\" id=\"occurrence:record_status\" name=\"occurrence:record_status\" value=\"C\" />\n    <input type=\"hidden\" id=\"occurrence:downloaded_flag\" name=\"occurrence:downloaded_flag\" value=\"N\" />\n    " . data_entry_helper::autocomplete($species_ctrl_args) . "\n    " . data_entry_helper::outputAttribute($attributes[$args['occurrence_confidence_id']], array_merge($languageFilteredAttrOptions, array('noBlankText' => ''))) . "\n    " . data_entry_helper::sref_and_system(array('label' => lang::get('LANG_Spatial_ref'), 'systems' => array('2169' => 'Luref (Gauss Luxembourg)'), 'suffixTemplate' => 'requiredsuffix')) . "\n    <p>" . lang::get('LANG_Click_on_map') . "</p>\n    " . data_entry_helper::outputAttribute($attributes[$args['occurrence_count_id']], array_merge($defAttrOptions, array('default' => 1, 'suffixTemplate' => 'requiredsuffix'))) . "\n    " . data_entry_helper::outputAttribute($attributes[$args['occurrence_approximation_id']], $defAttrOptions) . "\n    " . data_entry_helper::outputAttribute($attributes[$args['occurrence_territorial_id']], array_merge($defAttrOptions, array('default' => 1))) . "\n    " . data_entry_helper::outputAttribute($attributes[$args['occurrence_atlas_code_id']], $languageFilteredAttrOptions) . "\n    " . data_entry_helper::outputAttribute($attributes[$args['occurrence_overflying_id']], $defAttrOptions) . "\n    " . data_entry_helper::textarea(array('label' => lang::get('LANG_Comment'), 'fieldname' => 'occurrence:comment', 'disabled' => $disabledText));
       if (!$surveyReadOnly && !$occReadOnly) {
           $r .= "<input type=\"submit\" id=\"occ-submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Save_Occurrence_Details') . "\" />";
       }
       $r .= "  </form>\n";
       data_entry_helper::$javascript .= "\n// because of ID tracking it is easier to rebuild entire list etc.\nretriggerGrid = function(){\n  \$('div#occ_grid').empty();\n  occListLayer.destroyFeatures();\n  activateAddList = 1;\n  thisOccID = -1;\n  \$('div#occ_grid').indiciaDataGrid('rpt:mnhnl_btw_list_occurrences', {\n    indiciaSvc: '" . $svcUrl . "',\n    dataColumns: ['taxon', 'territorial', 'count'],\n    reportColumnTitles: {taxon : '" . lang::get('LANG_Species') . "', territorial : '" . lang::get('LANG_Territorial') . "', count : '" . lang::get('LANG_Count') . "'},\n    actionColumns: {'" . lang::get('LANG_Show') . "' : \"" . url('node/' . $node->nid, array('query' => 'occurrence_id=£id£')) . "\",\n            '" . lang::get('LANG_Highlight') . "' : \"script:highlight(£id£);\"},\n    auth : { nonce : '" . $readAuth['nonce'] . "', auth_token : '" . $readAuth['auth_token'] . "'},\n    parameters : { survey_id : '" . $args['survey_id'] . "',\n            parent_id : jQuery('#SurveyForm [name=sample\\:id]').val(),\n            territorial_attr_id : '" . $args['occurrence_territorial_id'] . "',\n            count_attr_id : '" . $args['occurrence_count_id'] . "'},\n    itemsPerPage : 12,\n    callback : addListFeature ,\n    cssOdd : ''\n  });\n}\n\njQuery('#occ-form').ajaxForm({ \n\tasync: false,\n\tdataType:  'json', \n    beforeSubmit:   function(data, obj, options){\n    \tvar valid = true;\n    \tclearErrors('form#occ-form');\n    \tif (!jQuery('form#occ-form > input').valid()) { valid = false; }\n    \tif (!jQuery('form#occ-form > select').valid()) { valid = false; }\n    \tif(!valid) {\n\t\t\tmyScrollToError();\n\t\t\treturn false;\n\t\t};\n\t\tjQuery('#occ-submit').addClass('loading-button');\n\t\treturn true;\n\t},\n    success:   function(data){\n       // this will leave all the fields populated.\n       \tif(data.success == 'multiple records' && data.outer_table == 'sample'){\n\t\t\twindow.scroll(0,0);\n\t\t\t// cant use reset form, as returns it to original values: if this was called with occurrence_id =<x> then it would repopulate with original occurrence's values\n\t\t\t// website_id, survey_id, record_status, downloaded_flag, sample:entered_sref_system are constants and are left alone. parent_id, date are only set referring to parent sample.\n\t\t\tjQuery('form#occ-form').find('[name^=occAttr\\:]').each(function(){\n\t\t\t\tvar name = jQuery(this).attr('name').split(':');\n\t\t\t\tjQuery(this).attr('name', name[0]+':'+name[1]);\n\t\t\t});\n\t\t\tjQuery('form#occ-form').find('[name=occurrence\\:id],[name=sample\\:id]').val('').attr('disabled', 'disabled');\n\t\t\tjQuery('form#occ-form').find('[name=occurrence\\:taxa_taxon_list_id],[name=occurrence\\:taxa_taxon_list_id\\:taxon],[name=sample\\:entered_sref],[name=sample\\:geom],[name=occurrence\\:comment]').val('');\n\t\t\tjQuery('form#occ-form').find('[name=occAttr\\:" . $args['occurrence_confidence_id'] . "]').find('option').removeAttr('selected');\n\t\t\tjQuery('form#occ-form').find('[name=occAttr\\:" . $args['occurrence_count_id'] . "]').val('1');\n\t\t\tjQuery('form#occ-form').find('input[name=occAttr\\:" . $args['occurrence_approximation_id'] . "],input[name=occAttr\\:" . $args['occurrence_overflying_id'] . "]').filter('[value=0]').attr('checked','checked');\n\t\t\tjQuery('form#occ-form').find('input[name=occAttr\\:" . $args['occurrence_territorial_id'] . "]').filter('[value=1]').attr('checked','checked');\n\t\t\tjQuery('form#occ-form').find('select[name=occAttr\\:" . $args['occurrence_atlas_code_id'] . "]').val('');\n\t\t\tsetAtlasStatus();\n\t\t\tretriggerGrid();\n\t\t\tlocationLayer.map.editLayer.destroyFeatures();\n\t\t\tvar a = \$('ul.ui-tabs-nav a')[1];\n\t\t\t\$(a).empty().html('<span>" . lang::get('LANG_Add_Occurrence') . "</span>');\n\t\t\tswitch(\"" . $args["on_save_occurrence_nav"] . "\"){\n\t\t\t\tcase \"list\":\n\t\t\t\t\ta = \$('ul.ui-tabs-nav a')[2];\n\t\t\t\t\t\$(a).click();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"survey\":\n\t\t\t\t\ta = \$('ul.ui-tabs-nav a')[0];\n\t\t\t\t\t\$(a).click();\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n        } else {\n\t\t\tif(data.error){\n\t\t\t\tvar lastIndex = data.error.lastIndexOf('Validation error'); \n    \t\t\tif (lastIndex != -1 && lastIndex  == (data.error.length - 16)){ \n\t\t\t\t\tif(data.errors){\n\t\t\t\t\t\t// TODO translation\n\t\t\t\t\t\tfor (i in data.errors){\n\t\t\t\t\t\t\tvar label = \$('<p/>')\n\t\t\t\t\t\t\t\t.addClass('inline-error')\n\t\t\t\t\t\t\t\t.html(data.errors[i]);\n\t\t\t\t\t\t\tlabel.insertAfter('[name='+i+']');\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmyScrollToError();\n\t\t\t\t\t\treturn;\n  \t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\talertIndiciaError(data);\n        }\n\t},\n    complete: function (){\n  \t\tjQuery('.loading-button').removeClass('loading-button');\n  \t}\n});\nsetAtlasStatus = function() {\n  if (jQuery(\"input[name=occAttr\\:" . $args['occurrence_territorial_id'] . "]:checked,input[name^=occAttr\\:" . $args['occurrence_territorial_id'] . "\\:]:checked\").val() == '0') {\n      jQuery(\"select[name=occAttr\\:" . $args['occurrence_atlas_code_id'] . "],select[name^=occAttr\\:" . $args['occurrence_atlas_code_id'] . "\\:]\").val('');\n  } else {\n      if(jQuery(\"select[name=occAttr\\:" . $args['occurrence_atlas_code_id'] . "],select[name^=occAttr\\:" . $args['occurrence_atlas_code_id'] . "\\:]\").val() == '') {\n        // Find the BB02 option (depends on the language what val it has)\n        var bb02;\n        jQuery.each(jQuery(\"select[name=occAttr\\:" . $args['occurrence_atlas_code_id'] . "],select[name^=occAttr\\:" . $args['occurrence_atlas_code_id'] . "\\:]\").find('option'), function(index, option) {\n          if (option.text.substr(0,4)=='BB02') {\n            bb02 = option.value;\n            return; // just from the each loop\n          }\n        });\n        jQuery(\"select[name=occAttr\\:" . $args['occurrence_atlas_code_id'] . "],select[name^=occAttr\\:" . $args['occurrence_atlas_code_id'] . "\\:]\").val(bb02);\n      }\n  }\n};\njQuery(\"input[name='" . $escaped_terr_id . "']\").change(setAtlasStatus);\n";
       $r .= '</div>';
       // add map panel.
       $r .= "<div class=\"mnhnl-btw-mappanel\">\n";
       $r .= data_entry_helper::map_panel(array('presetLayers' => $presetLayers, 'layers' => array('baseLayer_1', 'baseLayer_2', 'locationLayer', 'occListLayer'), 'initialFeatureWkt' => null, 'width' => 'auto', 'height' => 490, 'initial_lat' => $args['map_centroid_lat'], 'initial_long' => $args['map_centroid_long'], 'initial_zoom' => (int) $args['map_zoom'], 'scroll_wheel_zoom' => false), array('projection' => $args['map_projection']));
       // for timing reasons, all the following has to be done after the map is loaded.
       // 1) feature selector for occurrence list must have the map present to attach the control
       // 2) location placer must have the location layer populated and the map present in
       //    order to zoom the map into the location.
       // 3) occurrence list feature adder must have map present in order to zoom into any
       //    current selection.
       data_entry_helper::$onload_javascript .= "\nvar control = new OpenLayers.Control.SelectFeature(occListLayer);\noccListLayer.map.addControl(control);\nfunction onPopupClose(evt) {\n    // 'this' is the popup.\n    control.unselect(this.feature);\n}\nfunction onFeatureSelect(evt) {\n    feature = evt.feature;\n    popup = new OpenLayers.Popup.FramedCloud(\"featurePopup\",\n               feature.geometry.getBounds().getCenterLonLat(),\n                             new OpenLayers.Size(100,100),\n                             feature.attributes.taxon + \" (\" + feature.attributes.count + \")\",\n                             null, true, onPopupClose);\n    feature.popup = popup;\n    popup.feature = feature;\n    feature.layer.map.addPopup(popup);\n}\nfunction onFeatureUnselect(evt) {\n    feature = evt.feature;\n    if (feature.popup) {\n        popup.feature = null;\n        feature.layer.map.removePopup(feature.popup);\n        feature.popup.destroy();\n        feature.popup = null;\n    }\n}\n\noccListLayer.events.on({\n    'featureselected': onFeatureSelect,\n    'featureunselected': onFeatureUnselect\n});\n\ncontrol.activate();\n\nlocationChange = function(obj){\n  locationLayer.destroyFeatures();\n  if(obj.value != ''){\n    jQuery.getJSON(\"" . $svcUrl . "\" + \"/data/location/\"+obj.value +\n      \"?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . "\" +\n      \"&callback=?\", function(data) {\n            if (data.length>0) {\n              var parser = new OpenLayers.Format.WKT();\n              for (var i=0;i<data.length;i++)\n        {\n          if(data[i].centroid_geom){\n            " . self::readBoundaryJs('data[i].centroid_geom', $args['map_projection']) . "\n            feature.style = {label: data[i].name,\n\t\t\t\t\t\t     strokeColor: \"Green\",\n                             strokeWidth: 2,\n                             fillOpacity: 0};\n            centre = feature.geometry.getCentroid();\n            centrefeature = new OpenLayers.Feature.Vector(centre, {}, {label: data[i].name});\n            locationLayer.addFeatures([feature, centrefeature]);\n          }\n          if(data[i].boundary_geom){\n            " . self::readBoundaryJs('data[i].boundary_geom', $args['map_projection']) . "\n            feature.style = {strokeColor: \"Blue\", strokeWidth: 2};\n            locationLayer.addFeatures([feature]);\n          }\n          locationLayer.map.zoomToExtent(locationLayer.getDataExtent());\n        }\n      }\n    });\n     jQuery.getJSON(\"" . $svcUrl . "\" + \"/data/location\" +\n      \"?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . "&callback=?&parent_id=\"+obj.value, function(data) {\n            if (data.length>0) {\n              var parser = new OpenLayers.Format.WKT();\n              for (var i=0;i<data.length;i++)\n        {\n          if(data[i].centroid_geom){\n            " . self::readBoundaryJs('data[i].centroid_geom', $args['map_projection']) . "\n            locationLayer.addFeatures([feature]);\n          }\n          if(data[i].boundary_geom){\n            " . self::readBoundaryJs('data[i].boundary_geom', $args['map_projection']) . "\n            feature.style = {label: data[i].name,\n              labelAlign: \"cb\",\n              strokeColor: \"Blue\",\n                        strokeWidth: 2};\n            locationLayer.addFeatures([feature]);\n           }\n         }\n      }\n        });\n  }\n};\n// upload location initial value into map.\njQuery('#imp-location').each(function(){\n  locationChange(this);\n});\njQuery('#imp-location').unbind('change');\njQuery('#imp-location').change(function(){\n  locationChange(this);\n});\nvar selected = \$('#controls').tabs('option', 'selected');\n\n// Only leave the click control activated for edit/add occurrence tab.\nif(selected != 1){\n    locationLayer.map.editLayer.clickControl.deactivate();\n}\n\$('#controls').bind('tabsshow', function(event, ui) {\n        if(ui.index == 1)\n        {\n         locationLayer.map.editLayer.clickControl.activate();\n        }\n        else\n        {\n         locationLayer.map.editLayer.clickControl.deactivate();\n        }\n    }\n);\n";
       if ($mode != 1) {
           data_entry_helper::$onload_javascript .= "\nactivateAddList = 1;\nthisOccID = " . $thisOccID . ";\n\naddListFeature = function(div, r, record, count) {\n  if(activateAddList == 0)\n    return;\n  if(r == count)\n    activateAddList = 0;\n    var parser = new OpenLayers.Format.WKT();\n    " . self::readBoundaryJs('record.geom', $args['map_projection']) . "\n    if(record.id != thisOccID || 1==" . ($surveyReadOnly ? 1 : 0) . " || 1==" . ($occReadOnly ? 1 : 0) . "){\n      feature.attributes.id = record.id;\n      feature.attributes.taxon = record.taxon;\n      feature.attributes.count = record.count;\n      occListLayer.addFeatures([feature]);\n      if(record.id == " . $thisOccID . "){\n        var bounds=feature.geometry.getBounds();\n        locationLayer.map.setCenter(bounds.getCenterLonLat());\n      }\n    } else {\n      locationLayer.map.editLayer.destroyFeatures();\n      locationLayer.map.editLayer.addFeatures([feature]);\n      var bounds=feature.geometry.getBounds()\n      var centre=bounds.getCenterLonLat();\n      locationLayer.map.setCenter(centre);\n    }\n};\nhighlight = function(id){\n  if(id == " . $thisOccID . "){\n    if(occListLayer.map.editLayer.features.length > 0){\n      var bounds=occListLayer.map.editLayer.features[0].geometry.getBounds()\n      var centre=bounds.getCenterLonLat();\n      occListLayer.map.setCenter(centre);\n      return;\n    }\n  }\n  for(var i = 0; i < occListLayer.features.length; i++){\n    if(occListLayer.features[i].attributes.id == id){\n      control.unselectAll();\n      var bounds=occListLayer.features[i].geometry.getBounds()\n      var centre=bounds.getCenterLonLat();\n      occListLayer.map.setCenter(centre);\n      control.select(occListLayer.features[i]);\n      return;\n    }\n  }\n}\n\$('div#occ_grid').indiciaDataGrid('rpt:mnhnl_btw_list_occurrences', {\n    indiciaSvc: '" . $svcUrl . "',\n    dataColumns: ['taxon', 'territorial', 'count'],\n    reportColumnTitles: {taxon : '" . lang::get('LANG_Species') . "', territorial : '" . lang::get('LANG_Territorial') . "', count : '" . lang::get('LANG_Count') . "'},\n    actionColumns: {'" . lang::get('LANG_Show') . "' : \"" . url('node/' . $node->nid, array('query' => 'occurrence_id=£id£')) . "\",\n            '" . lang::get('LANG_Highlight') . "' : \"script:highlight(£id£);\"},\n    auth : { nonce : '" . $readAuth['nonce'] . "', auth_token : '" . $readAuth['auth_token'] . "'},\n    parameters : { survey_id : '" . $args['survey_id'] . "',\n            parent_id : '" . $parentSample['sample:id'] . "',\n            territorial_attr_id : '" . $args['occurrence_territorial_id'] . "',\n            count_attr_id : '" . $args['occurrence_count_id'] . "'},\n    itemsPerPage : 12,\n    callback : addListFeature ,\n    cssOdd : ''\n  });\n\n// activateAddList = 0;\n\n";
       }
       $r .= "</div><div><form><input type=\"button\" value=\"" . lang::get('LANG_Return') . "\" onclick=\"window.location.href='" . url('node/' . $node->nid, array('query' => 'Main')) . "'\"></form></div></div>\n";
       return $r;
   }
 protected static function tab_your_square($args, $auth, $attrs)
 {
     $r = '<fieldset class="ui-corner-all" >';
     $r .= '<legend>Place on map</legend>';
     $r .= '<div class="two columns"><div class="column">';
     $r .= data_entry_helper::georeference_lookup(array('label' => 'Enter the nearest place name', 'labelClass' => 'control-width-5', 'helpText' => 'Enter the name of a nearby town or village then click Search to quickly find the correct region on the map. ' . 'Or if you know the grid reference, type it into the following box.'));
     $r .= data_entry_helper::sref_and_system(array('label' => 'Your 1km grid reference', 'labelClass' => 'control-width-5', 'fieldname' => 'sample:entered_sref', 'systems' => array('OSGB' => 'British National Grid', 'OSIE' => 'Irish Grid'), 'class' => 'ui-state-highlight'));
     $sq_error = data_entry_helper::check_errors('smpAttr:' . $args['attr_surveyed_square']);
     $r .= '<fieldset class="ui-state-highlight ui-corner-all' . ($sq_error ? ' ui-state-error' : '') . '">';
     $r .= "<legend>Please also select one of the 3 choices below</legend>\n";
     if ($sq_error) {
         $r .= "{$sq_error}<br/>\n";
     }
     // manual output of radio buttons since data_entry_helper::radio_group does not support splicing in the textarea.
     $whichSqrAttr = $attrs['smpAttr:' . $args['attr_surveyed_square']];
     $reasonAttr = $attrs['smpAttr:' . $args['attr_surveyed_other_square_reason']];
     $fieldname = $whichSqrAttr['fieldname'];
     $value = $whichSqrAttr['default'];
     $r .= '<label class="auto">';
     $r .= '<input ';
     if ($value == $args['term_surveyed_given_square']) {
         $r .= 'checked="checked" ';
     }
     $r .= 'type="radio" id="attr_surveyed_given_square" value="' . $args['term_surveyed_given_square'] . '" name="' . $whichSqrAttr['fieldname'] . '"/> ';
     $r .= "I have surveyed the random square that I was given</label><br/>\n";
     $r .= '<label class="auto">';
     $r .= '<input ';
     if ($value == $args['term_surveyed_other_square']) {
         $r .= 'checked="checked" ';
     }
     $r .= 'type="radio" id="attr_surveyed_other_square" value="' . $args['term_surveyed_other_square'] . '" name="' . $whichSqrAttr['fieldname'] . '"/> ';
     $r .= "I have not surveyed the random square because</label><br/>\n";
     $r .= data_entry_helper::textarea(array('fieldname' => $reasonAttr['fieldname'], 'class' => 'indented reason', 'default' => $reasonAttr['default'], 'cols' => 50));
     $r .= "\n<label class=\"auto\">";
     $r .= '<input ';
     if ($value == $args['term_surveyed_same_square']) {
         $r .= 'checked="checked" ';
     }
     $r .= 'type="radio" id="attr_surveyed_same_square" value="' . $args['term_surveyed_same_square'] . '" name="' . $whichSqrAttr['fieldname'] . '"/> ';
     $r .= "I have resurveyed the same square as before</label>\n";
     $r .= '</fieldset>';
     $r .= '</div><div class="column">';
     $r .= data_entry_helper::map_panel(array('presetLayers' => array('google_hybrid'), 'readAuth' => $auth, 'class' => 'ui-widget-content', 'clickedSrefPrecisionMin' => 4, 'clickedSrefPrecisionMax' => 4, 'initial_lat' => 54, 'initial_long' => -1, 'initial_zoom' => 5, 'width' => '100%', 'tabDiv' => 'your-square'));
     $r .= "</div></div></fieldset>\n";
     $r .= data_entry_helper::wizard_buttons(array('divId' => 'tabs', 'page' => 'middle'));
     return $r;
 }
Esempio n. 13
0
 /**
  * Define the HTML required for this filter's UI panel.
  * Options available:
  * * **personSiteAttrId** - a multi-value location attribute used to link users to their recording sites.
  * * **includeSitesCreatedByUser** - boolean which defines if sites that the user is the creator of are available. Default TRUE.
  * * **indexedLocationTypeIds** - array of location type IDs for types that are available and which are indexed in the spatial index builder
  * * **otherLocationTypeIds** - array of location type IDs for types that are available and which are indexed in the 
  */
 public function get_controls($readAuth, $options)
 {
     if (function_exists('iform_load_helpers')) {
         iform_load_helpers(array('map_helper'));
     } else {
         //When running on warehouse we don't have iform_load_helpers
         require_once DOCROOT . 'client_helpers/map_helper.php';
     }
     $options = array_merge(array('includeSitesCreatedByUser' => TRUE, 'indexedLocationTypeIds' => array(), 'otherLocationTypeIds' => array()), $options);
     data_entry_helper::$javascript .= "indiciaData.includeSitesCreatedByUser="******";\n";
     data_entry_helper::$javascript .= "indiciaData.personSiteAttrId=" . (empty($options['personSiteAttrId']) ? 'false' : $options['personSiteAttrId']) . ";\n";
     $r = '<fieldset class="inline"><legend>' . lang::get('Filter by site or place') . '</legend>';
     $r .= '<p>' . lang::get('Choose from the following place filtering options.') . '</p>' . '<div class="context-instruct messages warning">' . lang::get('Please note that your access permissions are limiting the areas you are able to include.') . '</div>';
     $r .= '<fieldset class="exclusive">';
     // top level of sites selection
     $sitesLevel1 = array();
     $this->addProfileLocation($readAuth, 'location', $sitesLevel1);
     $this->addProfileLocation($readAuth, 'location_expertise', $sitesLevel1);
     $this->addProfileLocation($readAuth, 'location_collation', $sitesLevel1);
     if (!empty($options['personSiteAttrId']) || $options['includeSitesCreatedByUser']) {
         $sitesLevel1['my'] = lang::get('My sites') . '...';
     }
     // The JS needs to know which location types are indexed so it can build the correct filter.
     data_entry_helper::$javascript .= "indiciaData.indexedLocationTypeIds=" . json_encode($options['indexedLocationTypeIds']) . ";\n";
     $locTypes = array_merge($options['indexedLocationTypeIds'], $options['otherLocationTypeIds']);
     $locTypes = data_entry_helper::get_population_data(array('table' => 'termlists_term', 'extraParams' => $readAuth + array('view' => 'cache', 'query' => json_encode(array('in' => array('id' => $locTypes))))));
     foreach ($locTypes as $locType) {
         $sitesLevel1[$locType['id']] = $locType['term'] . '...';
     }
     $r .= '<div id="ctrl-wrap-imp-location" class="form-row ctrl-wrap">';
     $r .= data_entry_helper::select(array('fieldname' => 'site-type', 'label' => lang::get('Choose an existing site or location'), 'lookupValues' => $sitesLevel1, 'blankText' => '<' . lang::get('Please select') . '>', 'controlWrapTemplate' => 'justControl'));
     $r .= data_entry_helper::select(array('fieldname' => 'imp-location', 'lookupValues' => array(), 'controlWrapTemplate' => 'justControl'));
     $r .= '</div></fieldset>';
     $r .= '<fieldset class="exclusive">';
     $r .= data_entry_helper::text_input(array('label' => lang::get('Or, search for site names containing'), 'fieldname' => 'location_name'));
     $r .= '</fieldset>';
     $r .= '<fieldset class="exclusive">';
     // Build the array of spatial reference systems into a format Indicia can use.
     $systems = array();
     $systemsConfig = '4326';
     // default
     if (!empty($options['sref_systems'])) {
         $systemsConfig = $options['sref_systems'];
     } elseif (function_exists('variable_get')) {
         $systemsConfig = variable_get('indicia_spatial_systems', '4326');
     }
     $list = explode(',', str_replace(' ', '', $systemsConfig));
     foreach ($list as $system) {
         $systems[$system] = lang::get("sref:{$system}");
     }
     $r .= data_entry_helper::sref_and_system(array('label' => lang::get('Or, find records in map reference'), 'fieldname' => 'sref', 'systems' => $systems));
     $r .= '</fieldset></fieldset>';
     $r .= '<fieldset><legend>' . lang::get('Or, select a drawing tool in the map toolbar then draw a boundary to find intersecting records') . '</legend>';
     if (empty($options['linkToMapDiv'])) {
         if (function_exists('variable_get')) {
             $initialLat = variable_get('indicia_map_centroid_lat', 55);
             $initialLong = variable_get('indicia_map_centroid_long', -1);
             $initialZoom = (int) variable_get('indicia_map_zoom', 5);
         } else {
             $initialLat = 55;
             $initialLong = -1;
             $initialZoom = 5;
         }
         // need our own map on the popup
         // The js wrapper around the map div does not help here, since it breaks fancybox and fancybox is js only anyway.
         global $indicia_templates;
         $oldwrap = $indicia_templates['jsWrap'];
         $indicia_templates['jsWrap'] = '{content}';
         $r .= map_helper::map_panel(array('divId' => 'filter-pane-map', 'presetLayers' => array('osm'), 'editLayer' => true, 'initial_lat' => $initialLat, 'initial_long' => $initialLong, 'initial_zoom' => $initialZoom, 'width' => '100%', 'height' => 400, 'standardControls' => array('layerSwitcher', 'panZoomBar', 'drawPolygon', 'drawLine', 'drawPoint', 'modifyFeature', 'clearEditLayer'), 'readAuth' => $readAuth, 'gridRefHint' => true));
         $indicia_templates['jsWrap'] = $oldwrap;
     } else {
         // We are going to use an existing map for drawing boundaries etc. So prepare a container.
         $r .= '<div id="filter-map-container"></div>';
         data_entry_helper::$javascript .= "indiciaData.linkToMapDiv='" . $options['linkToMapDiv'] . "';\n";
     }
     $r .= '</fieldset>';
     return $r;
 }
 /**
  * Get the location control as a select dropdown.
  * Default control ordering is by name.
  * reportProvidesOrderBy option should be set to true if the control is populated by a report that
  * provides its own Order By statement, if the reportProvidesOrderBy option is not set in this situation, then the report
  * will have two Order By statements and will fail.
  */
 protected static function get_control_treelocationselect($auth, $args, $tabAlias, $options)
 {
     global $indicia_templates;
     global $user;
     data_entry_helper::$helpTextPos = 'before';
     $indicia_templates['two-col-50'] = '<div class="two_columns"><div id="leftcol" class="column">{col-1}</div><div id="rightcol" class="column">{col-2}</div></div>';
     $r = "";
     if (!array_key_exists('location_type_id', $options)) {
         return "Control [tree location select] must be provided with a location_type_id.<br />";
     }
     if (!array_key_exists('tree_location_type_id', $options)) {
         return "Control [tree location select] must be provided with a tree_location_type_id.<br />";
     }
     $r .= '<span style="display:none;">' . print_r($_SERVER, true) . '</span>';
     if (isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER'] != '' && ($referer = self::getRefererPath()) !== false) {
         $r .= '<input name="referer" type="hidden" value="' . $referer . '" />';
     }
     $attrArgs = array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'fieldprefix' => 'smpAttr');
     $attrArgs['extraParams'] += array('query' => json_encode(array('in' => array('caption' => array('No Understorey Observed')))));
     $smpAttrs = data_entry_helper::getAttributes($attrArgs, false);
     if (!count($smpAttrs)) {
         throw new exception(lang::get('This form must be used with an "No Understorey Observed" sample attribute.'));
     }
     data_entry_helper::$javascript .= "\n// assume map projection is same as indicia internal\n// Create vector layers: one to display the Parent Site onto, and another for the tree locations list\n// the default edit layer is used for this sample\nvar labelRule = new OpenLayers.Rule({\n        symbolizer: {\n          label : \"\${name}\",\n          fontSize: \"16px\",\n          fontFamily: \"Verdana, Arial, Helvetica,sans-serif\",\n          fontWeight: \"bold\",\n          fontColor: \"#FF0000\",\n          labelAlign: \"cm\",\n          labelYOffset: \"-15\"\n        }\n      });\nvar defaultStyle = new OpenLayers.Style({pointRadius: 6,fillColor: \"Red\",fillOpacity: 0.3,strokeColor: \"Yellow\",strokeWidth: 1});\ndefaultStyle.addRules([labelRule]);\n\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\nTreeStyleMap = new OpenLayers.StyleMap({\"default\": defaultStyle});\nTreeListLayer = new OpenLayers.Layer.Vector('Trees',{styleMap: TreeStyleMap, displayInLayerSwitcher: false});\nvar _zoomToExtent = function(bounds, layer){\n  var dy = Math.max(10, (bounds.top-bounds.bottom) * layer.map.div.settings.maxZoomBuffer);\n  var dx = Math.max(10, (bounds.right-bounds.left) * layer.map.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 (layer.map.getZoomForExtent(bounds) > layer.map.div.settings.maxZoom) {\n    // if showing something small, don't zoom in too far\n    layer.map.setCenter(bounds.getCenterLonLat(), layer.map.div.settings.maxZoom);\n  } else {\n    // Set the default view to show something a bit larger than the size of the grid square\n    layer.map.zoomToExtent(bounds);\n  }\n};\n\$('.scPresence:checkbox').change(function(){\n  var cells = \$(this).closest('tr').find('.scOccAttrCell');\n  if(\$(this).attr('checked')){\n    cells.find('select').addClass('required').removeAttr('disabled');\n    cells.append('<span class=\"deh-required\">*</span>');\n  } else {\n    cells.find('select').removeClass('required').val('').attr('disabled',true);\n    cells.find('.deh-required').remove();\n    cells.find('label.error').remove();\n    cells.find('.error').removeClass('error');\n    cells.find('.inline-error').remove();\n    cells.find('.ui-state-error').removeClass('ui-state-error');\n  }\n});\n\$('.scPresence:checkbox').change();\nindiciaData.searchUpdatesSref=false;\n";
     data_entry_helper::$late_javascript .= "\njQuery('[name=" . str_replace(':', '\\\\:', $smpAttrs[0]['id']) . "],[name^=" . str_replace(':', '\\\\:', $smpAttrs[0]['id']) . "\\\\:]').filter(':checkbox').rules('add', {no_observation: true});\n\$.validator.addMethod('no_observation', function(arg1, arg2){\n  // ignore the hidden zeroing field asscoiated with the boolean\n  if(!\$(arg2).filter(':checkbox').length) return true;\n  var numRows = jQuery('.scPresence').filter(':checkbox').filter('[checked]').length;\n  var isChecked = jQuery(arg2).attr('checked') != false;\n  if(isChecked) return(numRows==0)\n  else if(numRows>0) return true;\n  return false;\n},\n  \"The <strong>" . lang::get('No Understorey Observed') . "</strong> checkbox must be selected if there are no species entered in the Flowering plant phenology grid, otherwise it must be unchecked.\");\n\n";
     self::$treeOccurrenceRecord = false;
     if (self::$loadedSampleId) {
         $location_id = data_entry_helper::$entity_to_load['sample:location_id'];
     } else {
         if (isset($_GET['location_id'])) {
             $location_id = $_GET['location_id'];
         } else {
             $location_id = false;
         }
     }
     $attrArgs = array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'fieldprefix' => 'locAttr', 'location_type_id' => $options['tree_location_type_id']);
     if ($location_id) {
         $attrArgs['id'] = $location_id;
     }
     $attrArgs['extraParams'] += array('query' => json_encode(array('in' => array('caption' => array('Recorder Name')))));
     $locAttrs = data_entry_helper::getAttributes($attrArgs, false);
     $attrArgs = array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'fieldprefix' => 'smpAttr', 'sample_method_id' => $args['sample_method_id']);
     $attrArgs['extraParams'] += array('query' => json_encode(array('in' => array('caption' => array('Recorder Name')))));
     $smpAttrs = data_entry_helper::getAttributes($attrArgs, false);
     if (!count($locAttrs)) {
         throw new exception(lang::get('This form must be used with a "Recorder Name" tree location attribute.'));
     }
     if (!count($smpAttrs)) {
         throw new exception(lang::get('This form must be used with a "Recorder Name" sample attribute.'));
     }
     data_entry_helper::$javascript .= "indiciaData.assignedRecorderAttrID='" . $locAttrs[0]['attributeId'] . "';\n";
     data_entry_helper::$javascript .= "indiciaData.recorderNameID='" . $smpAttrs[0]['id'] . "';\n";
     if ($location_id) {
         $r .= '<div class="page-notice ui-state-highlight ui-corner-all">This visit is registered against the tree highlighted on the map. All fields followed by a red asterisk (<span class="deh-required">*</span>) must be filled in. You can not modify any field that is greyed out.</div>';
         $locationRecord = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('id' => $location_id, "view" => "detail"), 'nocache' => true));
         if (count($locationRecord) != 1) {
             throw new exception(lang::get('Could not identify tree location : ID ') . $location_id);
         }
         if (count($locAttrs) && count($smpAttrs)) {
             data_entry_helper::$entity_to_load[$smpAttrs[0]['fieldname']] = $locAttrs[0]['default'];
         }
         $parentLocationRecord = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('id' => $locationRecord[0]['parent_id'], "view" => "detail"), 'nocache' => true));
         if (count($parentLocationRecord) != 1) {
             throw new exception(lang::get('Could not identify site location : ID ') . $locationRecord[0]['parent_id']);
         }
         // TODO make sure user is allocated this tree, or if sample already exists, that they created this sample, or they are admin
         $registrationSampleRecord = data_entry_helper::get_population_data(array('table' => 'sample', 'extraParams' => $auth['read'] + array('location_id' => $locationRecord[0]['id'], "view" => "detail", "sample_method_id" => $args['reg_sample_method_id']), 'nocache' => true));
         if (count($registrationSampleRecord) != 1) {
             throw new exception(lang::get('Could not identify registration sample for tree location ID ') . $locationRecord[0]['id']);
         }
         $registrationOccurrenceRecord = data_entry_helper::get_population_data(array('table' => 'occurrence', 'extraParams' => $auth['read'] + array('sample_id' => $registrationSampleRecord[0]['id'], "view" => "detail"), 'nocache' => true));
         if (count($registrationOccurrenceRecord) != 1) {
             throw new exception(lang::get('Could not identify registration occurrence for tree location ID ') . $locationRecord[0]['id']);
         }
         if (self::$loadedSampleId) {
             self::$treeOccurrenceRecord = data_entry_helper::get_population_data(array('table' => 'occurrence', 'extraParams' => $auth['read'] + array('sample_id' => self::$loadedSampleId, "view" => "detail", 'taxa_taxon_list_id' => $registrationOccurrenceRecord[0]['taxa_taxon_list_id']), 'nocache' => true));
         } else {
             // need to set sref & system to match tree.
             data_entry_helper::$javascript .= "\n\$('#imp-sref').val('" . $locationRecord[0]['centroid_sref'] . "');\n";
         }
         $r .= data_entry_helper::text_input(array('label' => lang::get('Site'), 'fieldname' => 'dummy:site_name', 'class' => 'control-width-4 tree-details-readonly', 'default' => $parentLocationRecord[0]["name"], 'disabled' => ' readonly="readonly"'));
         // don't need a hidden control.
         $r .= data_entry_helper::text_input(array('label' => lang::get('Tree'), 'fieldname' => 'dummy:tree_name', 'class' => 'control-width-4 tree-details-readonly', 'default' => $locationRecord[0]["name"], 'disabled' => ' readonly="readonly"'));
         $r .= '<input name="sample:location_id" type="hidden" value="' . $location_id . '" />';
         $r .= data_entry_helper::text_input(array('label' => lang::get('Tree Species'), 'fieldname' => 'dummy:tree_species', 'class' => 'control-width-4 tree-details-readonly', 'default' => $registrationOccurrenceRecord[0]["taxon"], 'disabled' => ' readonly="readonly"'));
         if (self::$treeOccurrenceRecord && count(self::$treeOccurrenceRecord)) {
             $r .= '<input name="sc:tree:' . self::$treeOccurrenceRecord[0]['id'] . ':present" type="hidden" value="' . self::$treeOccurrenceRecord[0]['taxa_taxon_list_id'] . '" />';
         } else {
             $r .= '<input name="sc:tree::present" type="hidden" value="' . $registrationOccurrenceRecord[0]['taxa_taxon_list_id'] . '" />';
         }
         if (self::$loadedSampleId) {
             $systems = array(data_entry_helper::$entity_to_load['sample:entered_sref_system'] => data_entry_helper::$entity_to_load['sample:entered_sref_system']);
         } else {
             $systems = array($locationRecord[0]['centroid_sref_system'] => $locationRecord[0]['centroid_sref_system']);
         }
         $r .= data_entry_helper::sref_and_system(array_merge(array('label' => lang::get('Tree Grid Ref'), 'systems' => $systems, 'disabled' => ' readonly="readonly"', 'validation' => '', 'class' => 'control-width-4 tree-details-readonly'), $options));
         data_entry_helper::$javascript .= "\nmapInitialisationHooks.push(function (div) {\n  'use strict';\n  \$.getJSON(ParentLocationLayer.map.div.settings.indiciaSvc + 'index.php/services/data/location/'+" . $locationRecord[0]['parent_id'] . " +\r\n            '?mode=json&view=detail' + ParentLocationLayer.map.div.settings.readAuth + '&callback=?', function(data) {\n    if (typeof data.error!=='undefined') {\n      alert(data.error);\n      return;\n    }\r\n    if (data.length>0) {\r\n      var geomwkt = data[0].boundary_geom || data[0].centroid_geom;\r\n      var parser = new OpenLayers.Format.WKT();\r\n      var feature = parser.read(geomwkt);\r\n      ParentLocationLayer.addFeatures([feature]);\n      // no zoom, but put in other trees at site - will add our name.\n      \$.getJSON(TreeListLayer.map.div.settings.indiciaSvc + 'index.php/services/data/location?parent_id='+data[0].id +\n            '&mode=json&view=detail' + TreeListLayer.map.div.settings.readAuth + '&callback=?', function(tdata) {\n        if (typeof tdata.error!=='undefined') {\n          alert(tdata.error);\n          return;\n        }\n        if (tdata.length>0) {\n          for(var i=0; i<tdata.length; i++){\n            var geomwkt = tdata[i].centroid_geom, feature;\n            var parser = new OpenLayers.Format.WKT();\n            var feature = parser.read(geomwkt);\n            feature.attributes.name = tdata[i].name;\n            TreeListLayer.addFeatures(feature);\n      }}});\r\n  }});\n  if(div.map.editLayer.features.length>0) {\n    var highlighter = new OpenLayers.Control.SelectFeature(div.map.editLayer, {highlightOnly: true});\n    div.map.addControl(highlighter);\n    highlighter.activate();\n    highlighter.highlight(div.map.editLayer.features[0]);\n  }\n});";
         if (self::$loadedSampleId) {
             data_entry_helper::$javascript .= "\n\$('[name=sample\\\\:date]').change(function(){ // sample exists so just check that no sample already taken on that date.\n  \$.getJSON(ParentLocationLayer.map.div.settings.indiciaSvc + 'index.php/services/data/sample?location_id='+" . $locationRecord[0]['id'] . " +\n      '&sample_method_id=" . $args['sample_method_id'] . "&mode=json&view=detail' + ParentLocationLayer.map.div.settings.readAuth + '&callback=?', function(data) {\n    if (typeof data.error!=='undefined') {\n      alert(data.error);\n      return;\n    }\n    var date = \$('[name=sample\\\\:date]').val();\n    date = date.split('/');\n    for(var i = 0; i < data.length; i++){\n      if(data[i][\"id\"] != " . self::$loadedSampleId . " && data[i][\"date_start\"] == date[2]+'-'+date[1]+'-'+date[0]){\n        alert(\"Warning: there is already a visit recorded for this tree on \"+data[i][\"date_start\"]);\n        return;\n    }}\n  });\n});\n";
         } else {
             data_entry_helper::$javascript .= "\n\$('[name=sample\\\\:date]').change(function(){\n  \$.getJSON(ParentLocationLayer.map.div.settings.indiciaSvc + 'index.php/services/data/sample?location_id='+" . $locationRecord[0]['id'] . " +\n  \t\t'&sample_method_id=" . $args['sample_method_id'] . "&mode=json&view=detail&orderby=date_start' + ParentLocationLayer.map.div.settings.readAuth + '&callback=?', function(data) {\n    if (typeof data.error!=='undefined') {\n      alert(data.error);\n      return;\n    }\n    var date = \$('[name=sample\\\\:date]').val();\n    date = date.split('/');\n    for(var i = 0; i < data.length; i++){\n      if(data[i][\"date_start\"] == date[2]+'-'+date[1]+'-'+date[0]) {\n        alert(\"Warning: there is already a visit recorded for this tree on \"+data[i][\"date_start\"]);\n        return;\n      }\n    }\n    for(var i = 0; i < data.length; i++){\n      sdate = data[i][\"date_start\"].split('-');\n      if(sdate[0] > date[2] || (sdate[0] == date[2] && (sdate[1] > date[1] || (sdate[1] == date[1] && sdate[2] >= date[0])))) {\n        alert(\"Warning: there is already a visit recorded for this tree after this date, on \"+data[i][\"date_start\"]);\n        break;\n      }\n    }\n    for(var i = data.length-1; i >=0; i--){\n      sdate = data[i][\"date_start\"].split('-');\n      if(sdate[0] < date[2] || (sdate[0] == date[2] && (sdate[1] < date[1] || (sdate[1] == date[1] && sdate[2] <= date[0])))) {\n        if(confirm(\"There was a previously recorded visit for this tree prior to this date, on \"+data[i][\"date_start\"]+'. Do you wish to use the data from this earlier visit as a starting point? (This will not affect any previously recorded observations - it will just fill in this form with the data from your previous visit, excluding the field diary. You can then update the data with any changes for this visit.)')){\n          // this is an initial save: all attributes have vanilla names.\n          \$('.scPresence').removeAttr('checked');\n          var cells = \$('.scOccAttrCell');\n          \$('#" . data_entry_helper::$validated_form_id . "').find('label.error').remove();\n          \$('#" . data_entry_helper::$validated_form_id . "').find('.error').removeClass('error');\n          \$('#" . data_entry_helper::$validated_form_id . "').find('.inline-error').remove();\n          \$('#" . data_entry_helper::$validated_form_id . "').find('.ui-state-error').removeClass('ui-state-error');\n          cells.find('select').removeClass('required').val('').attr('disabled',true);\n          cells.find('.deh-required').remove();\n          \$('[name^=sc\\\\:tree\\\\:\\\\:occAttr\\\\:]').val('');\n          \$.getJSON(ParentLocationLayer.map.div.settings.indiciaSvc + 'index.php/services/data/occurrence?sample_id='+data[i]['id'] +\n              '&mode=json&view=detail' + ParentLocationLayer.map.div.settings.readAuth + '&callback=?', function(odata) {\n            if (typeof odata.error!=='undefined') {\n              alert(odata.error);\n              return;\n            }\n            var occIDs = [];\n            if(odata.length>0){\n              for(var j = 0; j < odata.length; j++) {\n                occIDs.push(odata[j].id);\n                \$('.scPresence[value='+odata[j].taxa_taxon_list_id+']').each(function(idx, elem){\n                  var cells = \$(elem).attr('checked',true).closest('tr').find('.scOccAttrCell');\n                  cells.find('select').addClass('required').removeAttr('disabled');\n                  cells.append('<span class=\"deh-required\">*</span>');\n                });\n              }\n              \$.getJSON(ParentLocationLayer.map.div.settings.indiciaSvc + 'index.php/services/data/occurrence_attribute_value' +\n                  '?query={\"in\":{\"occurrence_id\":'+JSON.stringify(occIDs) +'}}' +\n                  '&mode=json&view=list' + ParentLocationLayer.map.div.settings.readAuth + '&callback=?', function(adata) {\n                if (typeof adata.error!=='undefined') {\n                  alert(adata.error);\n                  return;\n                }\n                var x = adata;\n                for(var k = 0; k < adata.length; k++){\n                  if(adata[k].id != null){\n                    for(var j = 0; j < odata.length; j++) {\n                      if(odata[j].id == adata[k].occurrence_id){\n                        \$('.scPresence[value='+odata[j].taxa_taxon_list_id+']').closest('tr').find('[name\$=\\\\:occAttr\\\\:'+adata[k]['occurrence_attribute_id']+']').val(adata[k]['raw_value']);\n                        \$('[name=sc\\\\:tree\\\\:\\\\:occAttr\\\\:'+adata[k]['occurrence_attribute_id']+']').val(adata[k]['raw_value']);\n                        break;\n              }}}}});\n          }});\n        }\n        break;\n  }}});\n});\n\n";
         }
         return $r;
     }
     $r .= '<div class="page-notice ui-state-highlight ui-corner-all">All fields followed by a red asterisk (<span class="deh-required">*</span>) must be filled in. You can not modify any field that is greyed out.</div>';
     self::$treeOccurrenceRecord = false;
     if (isset($options['extraParams'])) {
         foreach ($options['extraParams'] as $key => &$value) {
             $value = apply_user_replacements($value);
         }
         $options['extraParams'] = array_merge($auth['read'], $options['extraParams']);
     } else {
         $options['extraParams'] = array_merge($auth['read']);
     }
     if (empty($options['reportProvidesOrderBy']) || $options['reportProvidesOrderBy'] == 0) {
         $options['extraParams']['orderby'] = 'name';
     }
     // Get list of sites alocated to me, using CMS User ID.
     $site_attributes = data_entry_helper::getAttributes(array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'location_type_id' => $options['location_type_id'], 'fieldprefix' => 'locAttr'));
     if (false == ($cmsUserAttr = extract_cms_user_attr($site_attributes))) {
         return 'This form is designed to be used with the "CMS User ID" attribute setup for Site locations in the survey.';
     }
     $response = data_entry_helper::get_population_data(array('table' => 'location_attribute_value', 'extraParams' => $auth['read'] + array('view' => 'list', 'location_attribute_id' => $cmsUserAttr['attributeId'], 'raw_value' => $user->uid), 'nocache' => true));
     if (count($response) == 0) {
         throw new exception(lang::get('You have no sites, so you can not enter any phenology observations. Please create a site and some trees first.'));
     }
     $siteIDs = array();
     foreach ($response as $loc) {
         $siteIDs[] = $loc['location_id'];
     }
     $location_list_args = array_merge(array('label' => lang::get('Site'), 'view' => 'detail', 'fieldname' => 'location:parent_id', 'id' => 'imp-site-location', 'blankText' => lang::get('Please select a site.'), 'validation' => 'required', 'nocache' => true), $options);
     // $options already has the location_type_id set
     $location_list_args['extraParams']['id'] = $siteIDs;
     $r .= data_entry_helper::location_select($location_list_args);
     $location_list_args = array_merge(array('label' => lang::get('Tree'), 'view' => 'detail', 'blankText' => lang::get('Please select a tree.'), 'validation' => 'required', 'nocache' => true), $options);
     $location_list_args['extraParams']['id'] = $siteIDs;
     $location_list_args['location_type_id'] = $options['tree_location_type_id'];
     $r .= data_entry_helper::location_select($location_list_args);
     $r .= data_entry_helper::text_input(array('label' => lang::get('Tree Species'), 'fieldname' => 'dummy:tree_species', 'class' => 'control-width-4 tree-details-readonly', 'disabled' => ' readonly="readonly"', 'validation' => 'required', 'helpText' => lang::get('The following field is filled in automatically when you select a tree.')));
     $r .= '<input name="sc:tree::present" type="hidden" value="" />';
     $systems = array('4326' => lang::get("sref:4326"));
     // this will be overwriten when the tree is loaded.
     $r .= data_entry_helper::sref_and_system(array_merge(array('label' => lang::get('Tree Grid Ref'), 'systems' => $systems, 'disabled' => ' readonly="readonly"', 'validation' => '', 'class' => 'tree-details-readonly', 'helpText' => lang::get('The following field is filled in automatically when you select a tree.')), $options));
     data_entry_helper::$javascript .= "\r\n\$('#imp-site-location').change(function() {\n  \$('#" . data_entry_helper::$validated_form_id . "').find('label.error').remove();\n  \$('#" . data_entry_helper::$validated_form_id . "').find('.error').removeClass('error');\n  \$('#" . data_entry_helper::$validated_form_id . "').find('.inline-error').remove();\n  \$('#" . data_entry_helper::$validated_form_id . "').find('.ui-state-error').removeClass('ui-state-error');\n  ParentLocationLayer.destroyFeatures();\r\n  TreeListLayer.destroyFeatures();\n  var intValue = parseInt(\$(this).val());\r\n  if (!isNaN(intValue)) {\n    \$(this).find('option[value=]').attr('disabled',true);\n    // site list has been populated with correct location_type_ids.\r\n    \$.getJSON(ParentLocationLayer.map.div.settings.indiciaSvc + 'index.php/services/data/location/'+\$(this).val() +\r\n              '?mode=json&view=detail' + ParentLocationLayer.map.div.settings.readAuth + '&callback=?', function(data) {\r\n      if (typeof data.error!=='undefined') {\n        alert(data.error);\n        return;\n      }\n      if (data.length>0) {\r\n        var geomwkt = data[0].boundary_geom || data[0].centroid_geom;\n        // assume single geometry - not a collection, and default style\n        var parser = new OpenLayers.Format.WKT();\n        var feature = parser.read(geomwkt);\n        ParentLocationLayer.addFeatures([feature]);\n        _zoomToExtent(feature.geometry.getBounds(), ParentLocationLayer);\n        \$('#imp-location option[value!=]').not(':selected').remove();\n        \$.getJSON(TreeListLayer.map.div.settings.indiciaSvc + 'index.php/services/data/location?parent_id='+data[0].id +\n              '&mode=json&view=detail' + TreeListLayer.map.div.settings.readAuth + '&callback=?', function(tdata) {\n          if (typeof tdata.error!=='undefined') {\n            alert(tdata.error);\n            return;\n          }\n          if (tdata.length>0) {\n            var features = [], found=false;\n            var bounds = ParentLocationLayer.features[0].geometry.getBounds();\n            for(var i=0; i<tdata.length; i++){\n              var geomwkt = tdata[i].centroid_geom, feature;\n              var parser = new OpenLayers.Format.WKT();\n              var feature = parser.read(geomwkt);\n              feature.attributes.name = tdata[i].name;\n              features.push(feature);\n              bounds.extend(feature.geometry.getBounds());\n              if(\$('#imp-location option[value='+tdata[i].id+']').length == 0)\n                \$('#imp-location').append('<option value=\"'+tdata[i].id+'\">'+tdata[i].name+'</option>');\n              else found=true;\n            }\n            if(!found){ // currently selected tree no longer on this site. Deselect it.\n              \$(this).find('option[value=]').removeAttr('disabled');\n              \$('#imp-location option[value!=]:selected').remove();\n              \$('#imp-location,#imp-sref').val('');\n              TreeListLayer.map.editLayer.destroyFeatures();\n              \$('[name=dummy\\\\:tree_species]').val('');\n            }\n            TreeListLayer.addFeatures(features);\n            _zoomToExtent(bounds, ParentLocationLayer);\n        }});\r\n    }});\n}});\nmapLocationSelectedHooks.push(function(div, data){\n  \$('#" . data_entry_helper::$validated_form_id . "').find('label.error').remove();\n  \$('#" . data_entry_helper::$validated_form_id . "').find('.error').removeClass('error');\n  \$('#" . data_entry_helper::$validated_form_id . "').find('.inline-error').remove();\n  \$('#" . data_entry_helper::$validated_form_id . "').find('.ui-state-error').removeClass('ui-state-error');\n  if(\$('#imp-site-location').val() != data[0].parent_id) {\n    \$('#imp-site-location').val(data[0].parent_id).change();\n    \$('#imp-site-location option[value=]').attr('disabled',true);\n  }\n  if(data[0].parent_id != ''){\n    \$('#imp-location option[value=]').attr('disabled',true);\n  }\n  \$('#'+indiciaData.recorderNameID.replace(/:/g,'\\\\:')).val('');\n  \$.getJSON(ParentLocationLayer.map.div.settings.indiciaSvc + 'index.php/services/data/location_attribute_value?location_id='+data[0]['id'] +\n      '&mode=json&view=list' + ParentLocationLayer.map.div.settings.readAuth + '&callback=?', function(data) {\n    if(data instanceof Array && data.length>0){\n      for (var i=0;i<data.length;i++){\n        if (data[i]['location_attribute_id'] == indiciaData.assignedRecorderAttrID)\n          \$('#'+indiciaData.recorderNameID.replace(/:/g,'\\\\:')).val(data[i].raw_value);\n      }\n  }});\n  // get registration sample and occurrence and fill in species.\n  \$.getJSON(ParentLocationLayer.map.div.settings.indiciaSvc + 'index.php/services/data/sample?location_id='+data[0]['id'] +\n      '&sample_method_id=" . $args['reg_sample_method_id'] . "&mode=json&view=detail' + ParentLocationLayer.map.div.settings.readAuth + '&callback=?', function(data) {\n    if (typeof data.error!=='undefined') {\n      alert(data.error);\n      return;\n    }\n    if(data.length){\n      \$.getJSON(ParentLocationLayer.map.div.settings.indiciaSvc + 'index.php/services/data/occurrence?sample_id='+data[0]['id'] +\n          '&mode=json&view=detail' + ParentLocationLayer.map.div.settings.readAuth + '&callback=?', function(data) {\n        if (typeof data.error!=='undefined') {\n          alert(data.error);\n          return;\n        }\n        if(data.length){\n          \$('[name=dummy\\\\:tree_species]').val(data[0].taxon);\n          \$('[name=sc\\\\:tree\\\\:\\\\:present]').val(data[0].taxa_taxon_list_id);\n      }});\n  }});\n});\n\$('[name=sample\\\\:date]').change(function(){\n  if(\$('#imp-location').val()=='') return;\n  \$.getJSON(ParentLocationLayer.map.div.settings.indiciaSvc + 'index.php/services/data/sample?location_id='+\$('#imp-location').val() +\n  \t\t'&sample_method_id=" . $args['sample_method_id'] . "&mode=json&view=detail&orderby=date_start' + ParentLocationLayer.map.div.settings.readAuth + '&callback=?', function(data) {\n    if (typeof data.error!=='undefined') {\n      alert(data.error);\n      return;\n    }\n    var date = \$('[name=sample\\\\:date]').val();\n    date = date.split('/');\n    for(var i = 0; i < data.length; i++){\n      if(data[i][\"date_start\"] == date[2]+'-'+date[1]+'-'+date[0]) {\n        alert(\"Warning: there is already a visit recorded for this tree on \"+data[i][\"date_start\"]);\n        return;\n      }\n    }\n    for(var i = 0; i < data.length; i++){\n      sdate = data[i][\"date_start\"].split('-');\n      if(sdate[0] > date[2] || (sdate[0] == date[2] && (sdate[1] > date[1] || (sdate[1] == date[1] && sdate[2] >= date[0])))) {\n        alert(\"Warning: there is already a visit recorded for this tree after this date, on \"+data[i][\"date_start\"]);\n        break;\n      }\n    }\n    for(var i = data.length-1; i >=0; i--){\n      sdate = data[i][\"date_start\"].split('-');\n      if(sdate[0] < date[2] || (sdate[0] == date[2] && (sdate[1] < date[1] || (sdate[1] == date[1] && sdate[2] <= date[0])))) {\n        if(confirm(\"There was a previously recorded visit for this tree prior to this date, on \"+data[i][\"date_start\"]+'. Do you wish to use the data from this earlier visit as a starting point? (This will not affect any previously recorded observations - it will just fill in this form with the data from your previous visit, excluding the field diary. You can then update the data with any changes for this visit.)')){\n          // this is an initial save: all attributes have vanilla names.\n          // TODO sample attributes\n          \$('.scPresence').removeAttr('checked');\n          var cells = \$('.scOccAttrCell');\n          cells.find('select').removeClass('required').val('').attr('disabled',true);\n          cells.find('.deh-required').remove();\n          \$('#" . data_entry_helper::$validated_form_id . "').find('label.error').remove();\n          \$('#" . data_entry_helper::$validated_form_id . "').find('.error').removeClass('error');\n          \$('#" . data_entry_helper::$validated_form_id . "').find('.inline-error').remove();\n          \$('#" . data_entry_helper::$validated_form_id . "').find('.ui-state-error').removeClass('ui-state-error');\n          \$('[name^=sc\\\\:tree\\\\:\\\\:occAttr\\\\:]').val('');\n          \$.getJSON(ParentLocationLayer.map.div.settings.indiciaSvc + 'index.php/services/data/occurrence?sample_id='+data[i]['id'] +\n              '&mode=json&view=detail' + ParentLocationLayer.map.div.settings.readAuth + '&callback=?', function(odata) {\n            if (typeof odata.error!=='undefined') {\n              alert(odata.error);\n              return;\n            }\n            var occIDs = [];\n            if(odata.length>0){\n              for(var j = 0; j < odata.length; j++) {\n                occIDs.push(odata[j].id);\n                \$('.scPresence[value='+odata[j].taxa_taxon_list_id+']').each(function(idx, elem){\n                  var cells = \$(elem).attr('checked',true).closest('tr').find('.scOccAttrCell');\n                  cells.find('select').addClass('required').removeAttr('disabled');\n                  cells.append('<span class=\"deh-required\">*</span>');\n                });\n              }\n              \$.getJSON(ParentLocationLayer.map.div.settings.indiciaSvc + 'index.php/services/data/occurrence_attribute_value' +\n                  '?query={\"in\":{\"occurrence_id\":'+JSON.stringify(occIDs) +'}}' +\n                  '&mode=json&view=list' + ParentLocationLayer.map.div.settings.readAuth + '&callback=?', function(adata) {\n                if (typeof adata.error!=='undefined') {\n                  alert(adata.error);\n                  return;\n                }\n                var x = adata;\n                for(var k = 0; k < adata.length; k++){\n                  if(adata[k].id != null){\n                    for(var j = 0; j < odata.length; j++) {\n                      if(odata[j].id == adata[k].occurrence_id){\n                        \$('.scPresence[value='+odata[j].taxa_taxon_list_id+']').closest('tr').find('[name\$=\\\\:occAttr\\\\:'+adata[k]['occurrence_attribute_id']+']').val(adata[k]['raw_value']);\n                        \$('[name=sc\\\\:tree\\\\:\\\\:occAttr\\\\:'+adata[k]['occurrence_attribute_id']+']').val(adata[k]['raw_value']);\n                        break;\n              }}}}});\n          }});\n        }\n        break;\n  }}});\n});\n\n";
     return $r;
 }
 /**
  * Return the generated form output.
  * @return Form HTML.
  */
 public static function get_form($args, $node)
 {
     global $user;
     $logged_in = $user->uid > 0;
     $r = '';
     // Get authorisation tokens to update and read from the Warehouse.
     $writeAuth = data_entry_helper::get_auth($args['website_id'], $args['password']);
     $readAuth = data_entry_helper::get_read_auth($args['website_id'], $args['password']);
     $svcUrl = data_entry_helper::$base_url . '/index.php/services';
     $mode = 0;
     // default mode : display survey selector
     // mode 1: display new sample
     // mode 2: display existing sample
     $loadID = null;
     $displayThisOcc = true;
     // when populating from the DB rather than POST we have to be
     // careful with selection object, as geom in wrong format.
     if ($_POST) {
         if (!is_null(data_entry_helper::$entity_to_load)) {
             $mode = 2;
             // errors with new sample, entity poulated with post, so display this data.
         }
         // else valid save, so go back to gridview: default mode 0
     } else {
         if (array_key_exists('sample_id', $_GET)) {
             $mode = 2;
             $loadID = $_GET['sample_id'];
         } else {
             if (array_key_exists('newSample', $_GET)) {
                 $mode = 1;
                 data_entry_helper::$entity_to_load = array();
             }
         }
         // else default to mode 0
     }
     ///////////////////////////////////////////////////////////////////
     // default mode 0 : display survey selector
     ///////////////////////////////////////////////////////////////////
     if ($mode == 0) {
         // Create the Sample list datagrid for this user.
         drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/hasharray.js', 'module');
         drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/jquery.datagrid.js', 'module');
         drupal_add_js("jQuery(document).ready(function(){\n  \$('div#smp_grid').indiciaDataGrid('rpt:mnhnl_collab_list_samples', {\n    indiciaSvc: '" . $svcUrl . "',\n    dataColumns: ['location_name', 'entered_sref', 'date', 'num_occurrences', 'completed'],\n    reportColumnTitles: {location_name : '" . lang::get('LANG_Location') . "', entered_sref : '" . lang::get('LANG_Spatial_ref') . "', date : '" . lang::get('LANG_Date') . "', num_occurrences : '" . lang::get('LANG_Num_Occurrences') . "', completed : '" . lang::get('LANG_Completed') . "'},\n    actionColumns: {" . lang::get('LANG_Edit') . " : \"" . url('node/' . $node->nid, array('query' => 'sample_id=�id�')) . "\"},\n    auth : { nonce : '" . $readAuth['nonce'] . "', auth_token : '" . $readAuth['auth_token'] . "'},\n    parameters : {\n    \t\t\tsurvey_id : '" . $args['survey_id'] . "',\n    \t\t\tuserID_attr_id : '" . $args['uid_attr_id'] . "',\n    \t\t\tuserID : '" . $user->uid . "'\n    \t\t\t\t},\n    itemsPerPage : 12 \n  });\n});\n\n", 'inline');
         $r .= '<div id="sampleList" class="mnhnl-btw-datapanel"><div id="smp_grid"></div>';
         $r .= '<form><input type="button" value="' . lang::get('LANG_Add_Sample') . '" onclick="window.location.href=\'' . url('node/' . $node->nid, array('query' => 'newSample')) . '\'"></form></div>';
         $r .= "</div>\n";
         return $r;
     }
     ///////////////////////////////////////////////////////////////////
     data_entry_helper::$javascript .= "\n// Create vector layers: one to display the location onto, and another for the occurrence list\n// the default edit layer is used for the occurrences themselves\nlocStyleMap = new OpenLayers.StyleMap({\n                \"default\": new OpenLayers.Style({\n                    fillColor: \"Green\",\n                    strokeColor: \"Black\",\n                    fillOpacity: 0.3,\n                    strokeWidth: 1\n                  })\n  });\nlocationLayer = new OpenLayers.Layer.Vector(\"" . lang::get("LANG_Location_Layer") . "\",\n                                    {styleMap: locStyleMap});\n";
     if ($loadID) {
         // Can't cache these as data may have just changed
         data_entry_helper::$entity_to_load['occurrence:record_status'] = 'I';
         $url = $svcUrl . '/data/sample/' . $loadID;
         $url .= "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"];
         $session = curl_init($url);
         curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
         $entity = json_decode(curl_exec($session), true);
         // Attributes should be loaded by get_attributes.
         data_entry_helper::$entity_to_load = array();
         foreach ($entity[0] as $key => $value) {
             data_entry_helper::$entity_to_load['sample:' . $key] = $value;
         }
         $url = $svcUrl . '/data/occurrence';
         $url .= "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . "&sample_id=" . $loadID . "&deleted=FALSE";
         $session = curl_init($url);
         curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
         $entities = json_decode(curl_exec($session), true);
         foreach ($entities as $entity) {
             data_entry_helper::$entity_to_load['occurrence:record_status'] = $entity['record_status'];
             data_entry_helper::$entity_to_load['sc:' . $entity['taxa_taxon_list_id'] . ':' . $entity['id'] . ':present'] = true;
         }
         data_entry_helper::$entity_to_load['sample:geom'] = '';
         // value received from db is not WKT, which is assumed by all the code.
         data_entry_helper::$entity_to_load['sample:date'] = data_entry_helper::$entity_to_load['sample:date_start'];
         // bit of a bodge to get around vague dates.
     }
     $defAttrOptions = array('extraParams' => $readAuth);
     //    $r .= "<h1>MODE = ".$mode."</h1>";
     //    $r .= "<h2>readOnly = ".$readOnly."</h2>";
     $r = "<form method=\"post\" id=\"entry_form\">\n";
     // Get authorisation tokens to update and read from the Warehouse.
     $r .= $writeAuth;
     $r .= "<input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" id=\"sample:survey_id\" name=\"sample:survey_id\" value=\"" . $args['survey_id'] . "\" />\n";
     if (array_key_exists('sample:id', data_entry_helper::$entity_to_load)) {
         $r .= "<input type=\"hidden\" id=\"sample:id\" name=\"sample:id\" value=\"" . data_entry_helper::$entity_to_load['sample:id'] . "\" />\n";
     }
     // request automatic JS validation
     data_entry_helper::enable_validation('entry_form');
     $attributes = data_entry_helper::getAttributes(array('id' => data_entry_helper::$entity_to_load['sample:id'], 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $readAuth, 'survey_id' => $args['survey_id']));
     if ($logged_in) {
         // If logged in, output some hidden data about the user
         $uid = $user->uid;
         $email = $user->mail;
         $username = $user->name;
         $uid_attr_id = $args['uid_attr_id'];
         $email_attr_id = $args['email_attr_id'];
         $username_attr_id = $args['username_attr_id'];
         // This assumes that we have the following attributes : no built in error checking.
         $r .= "<input type=\"hidden\" name=\"" . $attributes[$uid_attr_id]['fieldname'] . "\" value=\"{$uid}\" />\n";
         $r .= "<input type=\"hidden\" name=\"" . $attributes[$email_attr_id]['fieldname'] . "\" value=\"{$email}\" />\n";
         $r .= "<input type=\"hidden\" name=\"" . $attributes[$username_attr_id]['fieldname'] . "\" value=\"{$username}\" />\n";
     }
     $r .= "<div id=\"controls\">\n";
     if ($args['interface'] != 'one_page') {
         $r .= "<ul>\n";
         if (!$logged_in) {
             $r .= '  <li><a href="#about_you"><span>' . lang::get('LANG_About_You_Tab') . "</span></a></li>\n";
         }
         $r .= '  <li><a href="#species"><span>' . lang::get('LANG_Species_Tab') . "</span></a></li>\n";
         $r .= '  <li><a href="#place"><span>' . lang::get('LANG_Place_Tab') . "</span></a></li>\n";
         $r .= '  <li><a href="#other"><span>' . lang::get('LANG_Other_Information_Tab') . "</span></a></li>\n";
         $r .= "</ul>\n";
         data_entry_helper::enable_tabs(array('divId' => 'controls', 'style' => $args['interface']));
     }
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////
     if (!$logged_in) {
         $r .= "<div id=\"about_you\">\n";
         $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('LANG_About_You_Tab_Instructions') . "</p>";
         $defAttrOptions['class'] = 'control-width-4';
         $r .= data_entry_helper::outputAttribute($attributes[$args['first_name_attr_id']], $defAttrOptions);
         $r .= data_entry_helper::outputAttribute($attributes[$args['surname_attr_id']], $defAttrOptions);
         $r .= data_entry_helper::outputAttribute($attributes[$args['email_attr_id']], $defAttrOptions);
         $r .= data_entry_helper::outputAttribute($attributes[$args['phone_attr_id']], $defAttrOptions);
         if ($args['interface'] == 'wizard') {
             $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => 'first'));
         }
         unset($defAttrOptions['class']);
         $r .= "</div>\n";
     }
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////
     global $indicia_templates;
     $indicia_templates['taxon_label'] = '<div class="biota"><span class="nobreak sci binomial"><em>{taxon}</em></span> {authority}</div>';
     $r .= "<div id=\"species\">\n";
     $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('LANG_Species_Tab_Instructions') . "</p>";
     $extraParams = $readAuth + array('taxon_list_id' => $args['list_id']);
     $species_list_args = array('label' => lang::get('occurrence:taxa_taxon_list_id'), 'fieldname' => 'occurrence:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 1, 'view' => 'detail', 'parentField' => 'parent_id', 'occAttrs' => explode(',', $args['checklist_attributes']), 'extraParams' => $extraParams, 'survey_id' => $args['survey_id']);
     $r .= data_entry_helper::species_checklist($species_list_args);
     $r .= "<label for=\"sample:comment\">" . lang::get('LANG_Sample_Comment_Label') . "</label><input type=\"text\" id=\"sample:comment\" name=\"sample:comment\" value=\"" . data_entry_helper::$entity_to_load['sample:comment'] . "\" />\n";
     if ($args['interface'] == 'wizard') {
         $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => $user->id == 0 ? 'first' : 'middle'));
     }
     $r .= "</div>\n";
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////
     $r .= "<div id=\"place\">\n";
     $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('LANG_Place_Tab_Instructions') . "</p>";
     // Build the array of spatial reference systems into a format Indicia can use.
     $systems = array();
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get($system);
     }
     $r .= data_entry_helper::sref_and_system(array('label' => lang::get('LANG_SRef_Label'), 'systems' => $systems));
     $location_list_args = array('label' => lang::get('LANG_Location_Label'), 'view' => 'detail', 'extraParams' => array_merge(array('view' => 'detail', 'orderby' => 'name'), $extraParams));
     $r .= call_user_func(array('data_entry_helper', $args['location_ctrl']), $location_list_args);
     $r .= data_entry_helper::georeference_lookup(array('label' => lang::get('LANG_Georef_Label'), 'georefPreferredArea' => $args['georefPreferredArea'], 'georefCountry' => $args['georefCountry'], 'georefLang' => $args['language']));
     $options = iform_map_get_map_options($args, $readAuth);
     $options['layers'][] = 'locationLayer';
     $olOptions = iform_map_get_ol_options($args);
     $r .= data_entry_helper::map_panel($options, $olOptions);
     if ($args['interface'] == 'wizard') {
         $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls'));
     }
     $r .= "</div>\n";
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////
     $r .= "<div id=\"other\">\n";
     $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('LANG_Other_Information_Tab_Instructions') . "</p>";
     $r .= data_entry_helper::date_picker(array('label' => lang::get('LANG_Date'), 'fieldname' => 'sample:date'));
     $r .= data_entry_helper::outputAttribute($attributes[$args['biotope_attr_id']], $defAttrOptions);
     $r .= data_entry_helper::outputAttribute($attributes[$args['voucher_attr_id']], $defAttrOptions);
     $values = array('I', 'C');
     // not initially doing V=Verified
     $r .= '<label for="occurrence:record_status">' . lang::get('LANG_Record_Status_Label') . '</label><select id="occurrence:record_status" name="occurrence:record_status">';
     foreach ($values as $value) {
         $r .= '<option value="' . $value . '"';
         if (isset(data_entry_helper::$entity_to_load['occurrence:record_status'])) {
             if (data_entry_helper::$entity_to_load['occurrence:record_status'] == $value) {
                 $r .= ' selected="selected"';
             }
         }
         $r .= '>' . lang::get('LANG_Record_Status_' . $value) . '</option>';
     }
     $r .= '</select>';
     //  TODO image upload - not sure how to do this as images are attached to occurrences, and occurrences
     //  are embedded in the species list.
     //    $r .= "<label for='occurrence:image'>".lang::get('LANG_Image_Label')."</label>\n".
     //        data_entry_helper::image_upload('occurrence:image');
     $r .= '<br/><br/>';
     if ($args['interface'] == 'wizard') {
         $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => 'last'));
     } else {
         $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Save') . "\" />\n";
     }
     $r .= "</div>\n";
     $r .= "</div>\n";
     if (!empty(data_entry_helper::$validation_errors)) {
         $r .= data_entry_helper::dump_remaining_errors();
     }
     $r .= "</form>";
     // may need to keep following code for location change functionality
     data_entry_helper::$onload_javascript .= "\n    \nlocationChange = function(obj){\n\tlocationLayer.destroyFeatures();\n\tif(obj.value != ''){\n\t\tjQuery.getJSON(\"" . $svcUrl . "\" + \"/data/location/\"+obj.value +\n\t\t\t\"?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . "\" +\n\t\t\t\"&callback=?\", function(data) {\n            if (data.length>0) {\n            \tvar parser = new OpenLayers.Format.WKT();\n            \tfor (var i=0;i<data.length;i++)\n\t\t\t\t{\n\t      \t\t\tif(data[i].centroid_geom){\n\t\t\t\t\t\tfeature = parser.read(data[i].centroid_geom);\n\t\t\t\t\t\tcentre = feature.geometry.getCentroid();\n\t\t\t\t\t\tcentrefeature = new OpenLayers.Feature.Vector(centre, {}, {label: data[i].name});\n\t\t\t\t\t\tlocationLayer.addFeatures([feature, centrefeature]); \n\t\t\t\t\t}\n\t\t\t\t\tif(data[i].boundary_geom){\n\t\t\t\t\t\tfeature = parser.read(data[i].boundary_geom);\n\t\t\t\t\t\tfeature.style = {strokeColor: \"Blue\",\n    \t                \tstrokeWidth: 2,\n  \t\t\t\t\t\t\tlabel: (data[i].centroid_geom ? \"\" : data[i].name)};\n\t\t\t\t\t\tlocationLayer.addFeatures([feature]);\n \t\t\t\t\t}\n    \t\t\t\tlocationLayer.map.zoomToExtent(locationLayer.getDataExtent());\n  \t\t\t\t}\n\t\t\t}\n\t\t});\n  }\n};\njQuery('#imp-location').unbind('change');\njQuery('#imp-location').change(function(){\n\tlocationChange(this);\n});\n// upload location & sref initial values into map.\njQuery('#imp-location').change();\njQuery('#imp-sref').change();\n\n";
     return $r;
 }
Esempio n. 16
0
<?php 
// Get authorisation tokens to update and read from the Warehouse.
$auth = data_entry_helper::get_read_write_auth($config['website_id'], $config['password']);
echo $auth['write'];
$readAuth = $auth['read'];
?>
<input type='hidden' id='website_id' name='website_id' value='<?php 
echo $config['website_id'];
?>
' />
<input type='hidden' id='record_status' name='record_status' value='C' />
<?php 
echo data_entry_helper::autocomplete(array('label' => 'Species', 'fieldname' => 'occurrence:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'extraParams' => $readAuth + array('taxon_list_id' => $config['species_checklist_taxon_list'])));
echo data_entry_helper::date_picker(array('label' => 'Date', 'fieldname' => 'sample:date'));
echo data_entry_helper::file_box(array('caption' => 'Upload your photos', 'resizeWidth' => 1024, 'resizeHeight' => 768, 'table' => 'occurrence_image', 'runtimes' => array('html4')));
echo data_entry_helper::sref_and_system(array('label' => 'Grid ref'));
echo data_entry_helper::select(array('label' => 'Survey', 'fieldname' => 'sample:survey_id', 'table' => 'survey', 'captionField' => 'title', 'valueField' => 'id', 'extraParams' => $readAuth));
echo data_entry_helper::textarea(array('label' => 'Comment', 'fieldname' => 'sample:comment', 'class' => 'wide'));
?>

<input type="submit" class="ui-state-default ui-corner-all" value="Save" />
</form>
<?php 
echo data_entry_helper::loading_block_end();
echo data_entry_helper::dump_remaining_errors();
echo data_entry_helper::dump_javascript();
?>
</div>
</body>
</html>
 private static function get_site_tab($auth, $args, $settings)
 {
     $r = '<div id="site-details" class="ui-helper-clearfix">';
     $r .= '<form method="post" id="input-form">';
     $r .= $auth['write'];
     $r .= '<div id="cols" class="ui-helper-clearfix"><div class="left" style="width: 54%">';
     $r .= '<fieldset><legend>' . lang::get('Site Details') . '</legend>';
     $r .= "<input type=\"hidden\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $typeTerms = array();
     if (!empty($args['main_type_term_1'])) {
         $typeTerms[] = $args['main_type_term_1'];
     }
     if (!empty($args['main_type_term_2'])) {
         $typeTerms[] = $args['main_type_term_2'];
     }
     if (!empty($args['main_type_term_3'])) {
         $typeTerms[] = $args['main_type_term_3'];
     }
     $typeTermIDs = helper_base::get_termlist_terms($auth, 'indicia:location_types', $typeTerms);
     $lookUpValues = array('' => '<' . lang::get('please select') . '>');
     foreach ($typeTermIDs as $termDetails) {
         $lookUpValues[$termDetails['id']] = $termDetails['term'];
     }
     // if location is predefined, can not change unless a 'managerPermission'
     $canEditType = !$settings['locationId'] || isset($args['managerPermission']) && $args['managerPermission'] != '' && function_exists('user_access') && user_access($args['managerPermission']);
     if ($canEditType) {
         $r .= data_entry_helper::select(array('label' => lang::get('Site Type'), 'id' => 'location_type_id', 'fieldname' => 'location:location_type_id', 'lookupValues' => $lookUpValues));
         data_entry_helper::$javascript .= "\$('#location_type_id').change(function(){\r\n  switch(\$(this).val()){\n";
         for ($i = 1; $i < 4; $i++) {
             if (!empty($args['main_type_term_' . $i])) {
                 $type = helper_base::get_termlist_terms($auth, 'indicia:location_types', array($args['main_type_term_' . $i]));
                 data_entry_helper::$javascript .= "    case \"" . $type[0]['id'] . "\":\n";
                 if (!isset($args['can_change_section_number_' . $i]) || !$args['can_change_section_number_' . $i]) {
                     if ($settings['locationId']) {
                         // not saved yet, so no sections yet created, hence no need to worry about existing value. make number attribute readonly. set value. min value will be 1.
                         data_entry_helper::$javascript .= "      var minValue = \$('[name=" . str_replace(':', '\\\\:', $settings['numSectionsAttr']) . "]').attr('min');\r\n      if(minValue > " . $args['section_number_' . $i] . ") { // existing value is greater than one we want to set\r\n        alert('You are reducing the number of sections below that already existing. Please use the Remove Section button on the Your Route tab to reduce the number of sections to " . $args['section_number_' . $i] . " before changing the Site type');\r\n        return false;\r\n      }\r\n      \$('[name=" . str_replace(':', '\\\\:', $settings['numSectionsAttr']) . "]').val(" . $args['section_number_' . $i] . ").attr('readonly','readonly').css('color','graytext');\n";
                     } else {
                         // not saved yet, so no sections yet created, hence no need to worry about existing value. make number attribute readonly. set value. min value will be 1.
                         data_entry_helper::$javascript .= "      \$('[name=" . str_replace(':', '\\\\:', $settings['numSectionsAttr']) . "]').val(" . $args['section_number_' . $i] . ").attr('readonly','readonly').css('color','graytext');\n";
                     }
                 } else {
                     // user modifiable number of sections. value of attribute is left alone: don't have to worry att his point whether existing data.
                     data_entry_helper::$javascript .= "      \$('[name=" . str_replace(':', '\\\\:', $settings['numSectionsAttr']) . "]').removeAttr('readonly').css('color','');\n";
                 }
                 data_entry_helper::$javascript .= "      break;\n";
             }
         }
         data_entry_helper::$javascript .= "    default: break;\r\n  };\r\n  return true;\r\n});\n";
     }
     if ($settings['locationId']) {
         $r .= '<input type="hidden" name="location:id" id="location:id" value="' . $settings['locationId'] . "\" />\n";
     }
     $r .= data_entry_helper::text_input(array('fieldname' => 'location:name', 'label' => lang::get('Site Name'), 'class' => 'control-width-4 required', 'disabled' => $settings['canEditBody'] ? '' : ' disabled="disabled" '));
     if (!$settings['canEditBody']) {
         $r .= '<p>' . lang::get('This site cannot be edited because there are walks recorded on it. Please contact the site administrator if you think there are details which need changing.') . '</p>';
     } else {
         if (count($settings['walks']) > 0) {
             // can edit it
             $r .= '<p>' . lang::get('This site has walks recorded on it. Please do not change the site details without considering the impact on the existing data.') . '</p>';
         }
     }
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get($system);
     }
     if (isset(data_entry_helper::$entity_to_load['location:centroid_sref_system']) && in_array(data_entry_helper::$entity_to_load['location:centroid_sref_system'], array('osgb', 'osie'))) {
         data_entry_helper::$entity_to_load['location:centroid_sref_system'] = strtoupper(data_entry_helper::$entity_to_load['location:centroid_sref_system']);
     }
     $r .= data_entry_helper::sref_and_system(array('fieldname' => 'location:centroid_sref', 'geomFieldname' => 'location:centroid_geom', 'label' => 'Grid Ref.', 'systems' => $systems, 'class' => 'required', 'helpText' => lang::get('Click on the map to set the central grid reference.'), 'disabled' => $settings['canEditBody'] ? '' : ' disabled="disabled" '));
     if ($settings['locationId'] && data_entry_helper::$entity_to_load['location:code'] != '' && data_entry_helper::$entity_to_load['location:code'] != null) {
         $r .= data_entry_helper::text_input(array('fieldname' => 'location:code', 'label' => lang::get('Site Code'), 'class' => 'control-width-4', 'disabled' => ' readonly="readonly" '));
     } else {
         $r .= "<p>" . lang::get('The Site Code will be allocated by the Administrator.') . "</p>";
     }
     // setup the map options
     $options = iform_map_get_map_options($args, $auth['read']);
     // find the form blocks that need to go below the map.
     $bottom = '';
     $bottomBlocks = explode("\n", isset($args['bottom_blocks']) ? $args['bottom_blocks'] : '');
     foreach ($bottomBlocks as $block) {
         $bottom .= get_attribute_html($settings['attributes'], $args, array('extraParams' => $auth['read'], 'disabled' => $settings['canEditBody'] ? '' : ' disabled="disabled" '), $block);
     }
     // other blocks to go at the top, next to the map
     if (isset($args['site_help']) && $args['site_help'] != '') {
         $r .= '<p class="ui-state-highlight page-notice ui-corner-all">' . t($args['site_help']) . '</p>';
     }
     $r .= get_attribute_html($settings['attributes'], $args, array('extraParams' => $auth['read']));
     $r .= '</fieldset>';
     $r .= "</div>";
     // left
     $r .= '<div class="right" style="width: 44%">';
     if (!$settings['locationId']) {
         $help = t('Use the search box to find a nearby town or village, then drag the map to pan and click on the map to set the centre grid reference of the transect. ' . 'Alternatively if you know the grid reference you can enter it in the Grid Ref box on the left.');
         $r .= '<p class="ui-state-highlight page-notice ui-corner-all">' . $help . '</p>';
         $r .= data_entry_helper::georeference_lookup(array('label' => lang::get('Search for place'), 'driver' => $args['georefDriver'], 'georefPreferredArea' => $args['georefPreferredArea'], 'georefCountry' => $args['georefCountry'], 'georefLang' => $args['language'], 'readAuth' => $auth['read']));
     }
     if (isset($args['maxPrecision']) && $args['maxPrecision'] != '') {
         $options['clickedSrefPrecisionMax'] = $args['maxPrecision'];
     }
     if (isset($args['minPrecision']) && $args['minPrecision'] != '') {
         $options['clickedSrefPrecisionMin'] = $args['minPrecision'];
     }
     $olOptions = iform_map_get_ol_options($args);
     $options['clickForSpatialRef'] = $settings['canEditBody'];
     $r .= map_helper::map_panel($options, $olOptions);
     $r .= '</div></div>';
     // right
     if (!empty($bottom)) {
         $r .= $bottom;
     }
     if ($args['branch_assignment_permission'] != '') {
         if ($settings['canAllocBranch'] || $settings['locationId']) {
             $r .= self::get_branch_assignment_control($auth['read'], $settings['branchCmsUserAttr'], $args, $settings);
         }
     }
     if ($args['allow_user_assignment']) {
         if ($settings['canAllocUser']) {
             $r .= self::get_user_assignment_control($auth['read'], $settings['cmsUserAttr'], $args);
         } else {
             if (!$settings['locationId']) {
                 // for a new record, we need to link the current user to the location if they are not admin.
                 global $user;
                 $r .= '<input type="hidden" name="locAttr:' . self::$cmsUserAttrId . '" value="' . $user->uid . '">';
             }
         }
     }
     if ($settings['canEditBody']) {
         $r .= '<button type="submit" class="indicia-button right">' . lang::get('Save') . '</button>';
     }
     if ($settings['canEditBody'] && $settings['locationId']) {
         $r .= '<button type="button" class="indicia-button right" id="delete-transect">' . lang::get('Delete') . '</button>';
     }
     $r .= '</form>';
     $r .= '</div>';
     // site-details
     // This must go after the map panel, so it has created its toolbar
     data_entry_helper::$onload_javascript .= "\$('#current-section').change(selectSection);\n";
     if ($settings['canEditBody'] && $settings['locationId']) {
         $walkIDs = array();
         foreach ($settings['walks'] as $walk) {
             $walkIDs[] = $walk['id'];
         }
         $sectionIDs = array();
         foreach ($settings['sections'] as $code => $section) {
             $sectionIDs[] = $section['id'];
         }
         data_entry_helper::$javascript .= "\r\ndeleteSurvey = function(){\r\n  if(confirm(\"" . (count($settings['walks']) > 0 ? count($settings['walks']) . ' ' . lang::get('walks will also be deleted when you delete this location.') . ' ' : '') . lang::get('Are you sure you wish to delete this location?') . "\")){\r\n    deleteWalks([" . implode(',', $walkIDs) . "]);\r\n    deleteSections([" . implode(',', $sectionIDs) . "]);\r\n    \$('#delete-transect').html('Deleting Site');\r\n    deleteLocation(" . $settings['locationId'] . ");\r\n    \$('#delete-transect').html('Done');\r\n    window.location='" . url($args['sites_list_path']) . "';\r\n  };\r\n};\r\n\$('#delete-transect').click(deleteSurvey);\r\n";
     }
     return $r;
 }
 /**
  * Return the generated form output.
  * @return Form HTML.
  */
 public static function get_form($args, $node, $response = null)
 {
     global $user;
     $logged_in = $user->uid > 0;
     $r = '';
     // Get authorisation tokens to update and read from the Warehouse.
     $writeAuth = data_entry_helper::get_auth($args['website_id'], $args['password']);
     $readAuth = data_entry_helper::get_read_auth($args['website_id'], $args['password']);
     $svcUrl = data_entry_helper::$base_url . '/index.php/services';
     $presetLayers = array();
     // read out the activated preset layers
     if (isset($args['preset_layers'])) {
         foreach ($args['preset_layers'] as $layer => $active) {
             if ($active !== 0) {
                 $presetLayers[] = $layer;
             }
         }
     }
     // When invoked by GET there are the following modes:
     // Not logged in: Display an information message.
     // No additional arguments: display the survey selector.
     // Additional argument - newSample: display the main page, no occurrence or occurrence list tabs. Survey tab active.
     // Additional argument - sample_id=<id>: display the main page, fill in the main sample details, "Add Occurrence" tab present, survey tab active.
     // Additional argument - occurrence_id=<id>: display the main page, fill in the main sample details, "Add Occurrence" tab active.
     $mode = 0;
     // default mode : display survey selector
     // mode 1: display new sample: no occurrence list or add occurrence tabs. Survey tab active
     // mode 2: display existing sample. Survey tab active. No occurence details filled in.
     // mode 3: display existing occurrence. Add Occurrence tab active. Occurence details filled in.
     // mode 4: NO LONGER USED. display Occurrence List. Occurrence List tab active. No occurence details filled in.
     $readOnly = false;
     // On top of this, things can be flagged as readonly. RO mode 2+4 means no Add Occurrence tab.
     if (!$logged_in) {
         return lang::get('LANG_not_logged_in');
     }
     $parentSample = array();
     $parentErrors = null;
     $parentLoadID = null;
     $childSample = array();
     $childErrors = null;
     $childLoadID = null;
     $saveErrors = data_entry_helper::$validation_errors;
     $thisOccID = -1;
     // IDs have to be >0, so this is outside the valid range
     $displayThisOcc = true;
     // when populating from the DB rather than POST we have to be
     // careful with selection object, as geom in wrong format.
     if ($_POST) {
         if (array_key_exists('website_id', $_POST)) {
             // Indicia POST, already handled.
             if (array_key_exists('newSample', $_GET)) {
                 if (!is_null(data_entry_helper::$entity_to_load)) {
                     $mode = 1;
                     // errors with new sample, entity populated with post, so display this data.
                     $parentSample = data_entry_helper::$entity_to_load;
                     $parentErrors = $saveErrors;
                 } else {
                     // else new sample just saved, so reload it ready to add occurrences
                     // OR, child sample/occurrence saved against new parent sample, in which case parent sample is in the post.
                     $mode = 2;
                     $parentLoadID = array_key_exists('sample:parent_id', $_POST) ? $_POST['sample:parent_id'] : $response['outer_id'];
                 }
             } else {
                 // could have saved parent sample or child sample/occurrence pair.
                 if (array_key_exists('sample:parent_id', $_POST)) {
                     // have saved child sample/occurrence pair
                     $parentLoadID = $_POST['sample:parent_id'];
                     // load the parent sample.
                     $mode = 3;
                     if (isset(data_entry_helper::$entity_to_load)) {
                         // errors so display Edit Occurrence page.
                         $childSample = data_entry_helper::$entity_to_load;
                         $childErrors = $saveErrors;
                         $displayThisOcc = false;
                         if ($childSample['occurrence:id']) {
                             $thisOccID = $childSample['occurrence:id'];
                         }
                     }
                 } else {
                     // saved parent record. display updated parent, no child.
                     $mode = 2;
                     // display parent sample details, whether errors or not.
                     if (isset(data_entry_helper::$entity_to_load)) {
                         // errors so use posted data.
                         $parentSample = data_entry_helper::$entity_to_load;
                         $parentErrors = $saveErrors;
                     } else {
                         $parentLoadID = $_POST['sample:id'];
                         // load the parent sample.
                     }
                 }
             }
         } else {
             // non Indicia POST, in this case must be the location allocations. add check to ensure we don't corrept the data by accident
             if (iform_loctools_checkaccess($node, 'admin') && array_key_exists('mnhnlbtw', $_POST)) {
                 iform_loctools_deletelocations($node);
                 foreach ($_POST as $key => $value) {
                     $parts = explode(':', $key);
                     if ($parts[0] == 'location' && $value) {
                         iform_loctools_insertlocation($node, $value, $parts[1]);
                     }
                 }
             }
         }
     } else {
         if (array_key_exists('sample_id', $_GET)) {
             $mode = 2;
             $parentLoadID = $_GET['sample_id'];
         } else {
             if (array_key_exists('occurrence_id', $_GET)) {
                 $mode = 3;
                 $childLoadID = $_GET['occurrence_id'];
                 $thisOccID = $childLoadID;
             } else {
                 if (array_key_exists('newSample', $_GET)) {
                     $mode = 1;
                 }
             }
         }
         // else default to mode 0
     }
     // define layers for all maps.
     // each argument is a comma separated list eg:
     // "Name:Lux Outline,URL:http://localhost/geoserver/wms,LAYERS:indicia:nation2,SRS:EPSG:2169,FORMAT:image/png,minScale:0,maxScale:1000000,units:m";
     $optionArray_1 = array();
     $optionArray_2 = array();
     $options = explode(',', $args['layer1']);
     foreach ($options as $option) {
         $parts = explode(':', $option);
         $optionName = $parts[0];
         unset($parts[0]);
         $optionsArray_1[$optionName] = implode(':', $parts);
     }
     $options = explode(',', $args['layer2']);
     foreach ($options as $option) {
         $parts = explode(':', $option);
         $optionName = $parts[0];
         unset($parts[0]);
         $optionsArray_2[$optionName] = implode(':', $parts);
     }
     data_entry_helper::$javascript .= "\n// Create Layers.\n// Base Layers first.\nvar WMSoptions = {\n          LAYERS: '" . $optionsArray_1['LAYERS'] . "',\n          SERVICE: 'WMS',\n          VERSION: '1.1.0',\n          STYLES: '',\n          SRS: '" . $optionsArray_1['SRS'] . "',\n          FORMAT: '" . $optionsArray_1['FORMAT'] . "'\n    };\nbaseLayer_1 = new OpenLayers.Layer.WMS('" . $optionsArray_1['Name'] . "',\n        '" . iform_proxy_url($optionsArray_1['URL']) . "',\n        WMSoptions, {\n             minScale: " . $optionsArray_1['minScale'] . ",\n            maxScale: " . $optionsArray_1['maxScale'] . ",\n            units: '" . $optionsArray_1['units'] . "',\n            isBaseLayer: true,\n            singleTile: true\n        });\nWMSoptions = {\n          LAYERS: '" . $optionsArray_2['LAYERS'] . "',\n          SERVICE: 'WMS',\n          VERSION: '1.1.0',\n          STYLES: '',\n          SRS: '" . $optionsArray_2['SRS'] . "',\n          FORMAT: '" . $optionsArray_2['FORMAT'] . "'\n    };\nbaseLayer_2 = new OpenLayers.Layer.WMS('" . $optionsArray_2['Name'] . "',\n        '" . iform_proxy_url($optionsArray_2['URL']) . "',\n        WMSoptions, {\n             minScale: " . $optionsArray_2['minScale'] . ",\n            maxScale: " . $optionsArray_2['maxScale'] . ",\n            units: '" . $optionsArray_2['units'] . "',\n            isBaseLayer: true,\n            singleTile: true\n        });\n// Create vector layers: one to display the location onto, and another for the occurrence list\n// the default edit layer is used for the occurrences themselves\nlocStyleMap = new OpenLayers.StyleMap({\n                \"default\": new OpenLayers.Style({\n                    fillColor: \"Green\",\n                    strokeColor: \"Black\",\n                    fillOpacity: 0.2,\n                    strokeWidth: 1\n                  })\n  });\nlocationLayer = new OpenLayers.Layer.Vector(\"" . lang::get("LANG_Location_Layer") . "\",\n                                    {styleMap: locStyleMap});\noccStyleMap = new OpenLayers.StyleMap({\n                \"default\": new OpenLayers.Style({\n                    pointRadius: 3,\n                    fillColor: \"Red\",\n                    fillOpacity: 0.3,\n                    strokeColor: \"Red\",\n                    strokeWidth: 1\n          }) });\noccListLayer = new OpenLayers.Layer.Vector(\"" . lang::get("LANG_Occurrence_List_Layer") . "\",\n                                    {styleMap: occStyleMap});\n";
     // Work out list of locations this user can see.
     $locations = iform_loctools_listlocations($node);
     ///////////////////////////////////////////////////////////////////
     // default mode 0 : display survey selector and locations allocator
     ///////////////////////////////////////////////////////////////////
     if ($mode == 0) {
         // If the user has permissions, add tabs so can choose to see
         // locations allocator
         $tabs = array('#surveyList' => lang::get('LANG_Surveys'));
         if (iform_loctools_checkaccess($node, 'admin')) {
             $tabs['#setLocations'] = lang::get('LANG_Allocate_Locations');
         }
         if (iform_loctools_checkaccess($node, 'superuser')) {
             $tabs['#downloads'] = lang::get('LANG_Download');
         }
         if (count($tabs) > 1) {
             $r .= "<div id=\"controls\">\n";
             $r .= data_entry_helper::enable_tabs(array('divId' => 'controls', 'active' => '#surveyList'));
             $r .= "<div id=\"temp\"></div>";
             $r .= data_entry_helper::tab_header(array('tabs' => $tabs));
         }
         if ($locations == 'all') {
             $useloclist = 'NO';
             $loclist = '-1';
         } else {
             // an empty list will cause an sql error, lids must be > 0, so push a -1 to prevent the error.
             if (empty($locations)) {
                 $locations[] = -1;
             }
             $useloclist = 'YES';
             $loclist = implode(',', $locations);
         }
         // Create the Survey list datagrid for this user.
         drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/hasharray.js', 'module');
         drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/jquery.datagrid.js', 'module');
         drupal_add_js("jQuery(document).ready(function(){\n  \$('div#smp_grid').indiciaDataGrid('rpt:mnhnl_btw_list_samples', {\n    indiciaSvc: '" . $svcUrl . "',\n    dataColumns: ['location_name', 'date', 'num_visit', 'num_occurrences', 'num_taxa'],\n    reportColumnTitles: {location_name : '" . lang::get('LANG_Transect') . "', date : '" . lang::get('LANG_Date') . "', num_visit : '" . lang::get('LANG_Visit_No') . "', num_occurrences : '" . lang::get('LANG_Num_Occurrences') . "', num_taxa : '" . lang::get('LANG_Num_Species') . "'},\n    actionColumns: {" . lang::get('LANG_Show') . " : \"" . url('node/' . $node->nid, array('query' => 'sample_id=£id£')) . "\"},\n    auth : { nonce : '" . $readAuth['nonce'] . "', auth_token : '" . $readAuth['auth_token'] . "'},\n    parameters : { survey_id : '" . $args['survey_id'] . "', visit_attr_id : '" . $args['sample_visit_number_id'] . "', closed_attr_id : '" . $args['sample_closure_id'] . "', use_location_list : '" . $useloclist . "', locations : '" . $loclist . "'},\n    itemsPerPage : 12,\n    condCss : {field : 'closed', value : '0', css: 'mnhnl-btw-highlight'},\n    cssOdd : ''\n  });\n});\n\n", 'inline');
         $r .= '<div id="surveyList" class="mnhnl-btw-datapanel"><div id="smp_grid"></div>';
         $r .= '<form><input type="button" value="' . lang::get('LANG_Add_Survey') . '" onclick="window.location.href=\'' . url('node/' . $node->nid, array('query' => 'newSample')) . '\'"></form></div>';
         // Add the locations allocator if user has admin rights.
         if (iform_loctools_checkaccess($node, 'admin')) {
             $r .= '<div id="setLocations" class="mnhnl-btw-datapanel"><form method="post">';
             $r .= "<input type=\"hidden\" id=\"mnhnlbtw\" name=\"mnhnlbtw\" value=\"mnhnlbtw\" />\n";
             $url = $svcUrl . '/data/location';
             $url .= "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["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);
             if (!empty($entities)) {
                 foreach ($entities as $entity) {
                     if (!$entity["parent_id"]) {
                         // only assign parent locations.
                         $r .= "\n<label for=\"location:" . $entity["id"] . "\">" . $entity["name"] . ":</label><select id=\"location:" . $entity["id"] . "\" name=\"location:" . $entity["id"] . "\">";
                         $r .= "<option value=\"\" >&lt;" . lang::get('LANG_Not_Allocated') . "&gt;</option>";
                         $defaultuserid = iform_loctools_getuser($node, $entity["id"]);
                         foreach ($userlist as $uid => $a_user) {
                             if ($uid == $defaultuserid) {
                                 $selected = 'selected="selected"';
                             } else {
                                 $selected = '';
                             }
                             $r .= "<option value=\"" . $uid . "\" " . $selected . ">" . $a_user->name . "</option>";
                         }
                         $r .= "</select>";
                     }
                 }
             }
             $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Save_Location_Allocations') . "\" />\n";
             $r .= "</form></div>";
         }
         // Add the downloader if user has manager (superuser) rights.
         if (iform_loctools_checkaccess($node, 'superuser')) {
             $r .= '<div id="downloads" class="mnhnl-btw-datapanel">';
             $r .= "<form method=\"post\" action=\"" . data_entry_helper::$base_url . "/index.php/services/report/requestReport?report=mnhnl_btw_transect_direction_report.xml&reportSource=local&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth['nonce'] . "&mode=csv\">";
             $r .= '<p>' . lang::get('LANG_Direction_Report') . '</p>';
             $r .= "<input type=\"hidden\" id=\"params\" name=\"params\" value='{\"survey_id\":" . $args['survey_id'] . ", \"direction_attr_id\":" . $args['sample_walk_direction_id'] . ", \"closed_attr_id\":" . $args['sample_closure_id'] . "}' />";
             $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Direction_Report_Button') . "\">";
             $r .= "</form>";
             $r .= "<form method=\"post\" action=\"" . data_entry_helper::$base_url . "/index.php/services/report/requestReport?report=mnhnl_btw_download_report.xml&reportSource=local&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth['nonce'] . "&mode=csv\">";
             $r .= '<p>' . lang::get('LANG_Initial_Download') . '</p>';
             $r .= "<input type=\"hidden\" id=\"params\" name=\"params\" value='{\"survey_id\":" . $args['survey_id'] . ", \"closed_attr_id\":" . $args['sample_closure_id'] . ", \"download\": \"INITIAL\"}' />";
             $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Initial_Download_Button') . "\">";
             $r .= "</form>";
             $r .= "<form method=\"post\" action=\"" . data_entry_helper::$base_url . "/index.php/services/report/requestReport?report=mnhnl_btw_download_report.xml&reportSource=local&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth['nonce'] . "&mode=csv\">";
             $r .= '<p>' . lang::get('LANG_Confirm_Download') . '</p>';
             $r .= "<input type=\"hidden\" id=\"params\" name=\"params\" value='{\"survey_id\":" . $args['survey_id'] . ", \"closed_attr_id\":" . $args['sample_closure_id'] . ", \"download\": \"CONFIRM\"}' />";
             $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Confirm_Download_Button') . "\">";
             $r .= "</form>";
             $r .= "<form method=\"post\" action=\"" . data_entry_helper::$base_url . "/index.php/services/report/requestReport?report=mnhnl_btw_download_report.xml&reportSource=local&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth['nonce'] . "&mode=csv\">";
             $r .= '<p>' . lang::get('LANG_Final_Download') . '</p>';
             $r .= "<input type=\"hidden\" id=\"params\" name=\"params\" value='{\"survey_id\":" . $args['survey_id'] . ", \"closed_attr_id\":" . $args['sample_closure_id'] . ", \"download\": \"FINAL\"}' />";
             $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Final_Download_Button') . "\">";
             $r .= "</form></div>";
         }
         // Create Map
         $r .= "<div class=\"mnhnl-btw-mappanel\">\n";
         $r .= data_entry_helper::map_panel(array('presetLayers' => $presetLayers, 'layers' => array('baseLayer_1', 'baseLayer_2', 'locationLayer'), 'initialFeatureWkt' => null, 'width' => 'auto', 'height' => 490, 'editLayer' => false, 'initial_lat' => $args['map_centroid_lat'], 'initial_long' => $args['map_centroid_long'], 'initial_zoom' => (int) $args['map_zoom'], 'scroll_wheel_zoom' => false), array('projection' => $args['map_projection']));
         // Add locations to the map on the locations layer.
         // Zoom in to area which contains the users locations.
         if ($locations != 'all') {
             data_entry_helper::$javascript .= "locationList = [" . implode(',', $locations) . "];\n";
         }
         data_entry_helper::$javascript .= "\n// upload locations into map.\n// Change the location control requests the location's geometry to place on the map.\n\$.getJSON(\"{$svcUrl}\" + \"/data/location\" +\n          \"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n          \"&parent_id=NULL&callback=?\", function(data) {\n    // store value in saved field?\n  locationLayer.destroyFeatures();\n    if (data.length>0) {\n      var newFeatures = [];\n      var feature;\n      var parser = new OpenLayers.Format.WKT();\n    for (var i=0;i<data.length;i++)\n    {\n";
         if ($locations != 'all') {
             // include restriction on locations if user does not have full access.
             data_entry_helper::$javascript .= "\n        for(var j=0; j<locationList.length; j++) {\n          if(locationList[j] == data[i].id || locationList[j] == data[i].parent_id) {";
         }
         data_entry_helper::$javascript .= "\n        if(data[i].boundary_geom){\n          " . self::readBoundaryJs('data[i].boundary_geom', $args['map_projection']) . "\n          feature.style = {label: data[i].name,\n                        strokeColor: \"Blue\",\n                      strokeWidth: 2};\n          newFeatures.push(feature);\n        }\n";
         if ($locations != 'all') {
             data_entry_helper::$javascript .= "\n          }\n        }\n";
         }
         data_entry_helper::$javascript .= "\n    }\n    locationLayer.addFeatures(newFeatures);\n    locationLayer.map.zoomToExtent(locationLayer.getDataExtent());\n    }\n});\n\$('#controls').bind('tabsshow', function(event, ui) {\n  var y = \$('.mnhnl-btw-datapanel:visible').outerHeight(true) + \$('.mnhnl-btw-datapanel:visible').position().top;\n  if(y < \$('.mnhnl-btw-mappanel').outerHeight(true)+ \$('.mnhnl-btw-mappanel').position().top){\n    y = \$('.mnhnl-btw-mappanel').outerHeight(true)+ \$('.mnhnl-btw-mappanel').position().top;\n  }\n  \$('#controls').height(y - \$('#controls').position().top);\n});\n";
         $r .= "</div>\n";
         if (count($tabs) > 1) {
             $r .= "</div>";
         }
         return $r;
     }
     ///////////////////////////////////////////////////////////////////
     $occReadOnly = false;
     if ($childLoadID) {
         $url = $svcUrl . '/data/occurrence/' . $childLoadID;
         $url .= "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"];
         $session = curl_init($url);
         curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
         $entity = json_decode(curl_exec($session), true);
         $childSample = array();
         foreach ($entity[0] as $key => $value) {
             $childSample['occurrence:' . $key] = $value;
         }
         if ($entity[0]['downloaded_flag'] == 'F') {
             // Final download complete, now readonly
             $occReadOnly = true;
         }
         $url = $svcUrl . '/data/sample/' . $childSample['occurrence:sample_id'];
         $url .= "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"];
         $session = curl_init($url);
         curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
         $entity = json_decode(curl_exec($session), true);
         foreach ($entity[0] as $key => $value) {
             $childSample['sample:' . $key] = $value;
         }
         $childSample['sample:geom'] = '';
         // value received from db is not WKT, which is assumed by all the code.
         $thisOccID = $childLoadID;
         // this will be used to load the occurrence into the editlayer.
         $childSample['taxon'] = $childSample['occurrence:taxon'];
         $parentLoadID = $childSample['sample:parent_id'];
     }
     if ($parentLoadID) {
         $url = $svcUrl . '/data/sample/' . $parentLoadID;
         $url .= "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"];
         $session = curl_init($url);
         curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
         $entity = json_decode(curl_exec($session), true);
         $parentSample = array();
         foreach ($entity[0] as $key => $value) {
             $parentSample['sample:' . $key] = $value;
         }
         if (is_array($locations) && !in_array($entity[0]["location_id"], $locations)) {
             return '<p>' . lang::get('LANG_No_Access_To_Location') . '</p>';
         }
         if ($entity[0]["parent_id"]) {
             return '<p>' . lang::get('LANG_No_Access_To_Sample') . '</p>';
         }
         $parentSample['sample:date'] = $parentSample['sample:date_start'];
         // bit of a bodge
         // default values for attributes from DB are picked up automatically.
     }
     $childSample['sample:date'] = $parentSample['sample:date'];
     // enforce a match between child and parent sample dates
     data_entry_helper::$entity_to_load = $parentSample;
     data_entry_helper::$validation_errors = $parentErrors;
     $attributes = data_entry_helper::getAttributes(array('id' => data_entry_helper::$entity_to_load['sample:id'], 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $readAuth));
     $closedFieldName = $attributes[$args['sample_closure_id']]['fieldname'];
     $closedFieldValue = data_entry_helper::check_default_value($closedFieldName, array_key_exists('default', $attributes[$args['sample_closure_id']]) ? $attributes[$args['sample_closure_id']]['default'] : '0');
     // default is not closed
     $adminPerm = 'IForm node ' . $node->nid . ' admin';
     if ($closedFieldValue == '1' && !user_access($adminPerm)) {
         // sample has been closed, no admin perms. Everything now set to read only.
         $readOnly = true;
         $disabledText = "disabled=\"disabled\"";
         $defAttrOptions = array('extraParams' => $readAuth, 'disabled' => $disabledText);
     } else {
         // sample open.
         $disabledText = "";
         $defAttrOptions = array('extraParams' => $readAuth);
     }
     data_entry_helper::enable_validation('SurveyForm');
     $r .= "<div id=\"controls\">\n";
     $activeTab = 'survey';
     if ($mode == 3 || $mode == 2) {
         $activeTab = 'occurrence';
     }
     // Set Up form tabs.
     if ($mode == 4) {
         $activeTab = 'occurrenceList';
     }
     $r .= data_entry_helper::enable_tabs(array('divId' => 'controls', 'active' => $activeTab));
     $r .= "<div id=\"temp\"></div>";
     $r .= data_entry_helper::tab_header(array('tabs' => array('#survey' => lang::get('LANG_Survey'), '#occurrence' => lang::get($readOnly || $occReadOnly ? 'LANG_Show_Occurrence' : (isset($childSample['sample:id']) ? 'LANG_Edit_Occurrence' : 'LANG_Add_Occurrence')), '#occurrenceList' => lang::get('LANG_Occurrence_List'))));
     // Set up main Survey Form.
     $r .= "<div id=\"survey\" class=\"mnhnl-btw-datapanel\">\n";
     if ($readOnly) {
         $r .= "<strong>" . lang::get('LANG_Read_Only_Survey') . "</strong>";
     }
     $r .= "<form id=\"SurveyForm\" method=\"post\">\n";
     $r .= $writeAuth;
     $r .= "<input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" id=\"sample:survey_id\" name=\"sample:survey_id\" value=\"" . $args['survey_id'] . "\" />\n";
     $r .= iform_user_get_hidden_inputs($args);
     if (array_key_exists('sample:id', data_entry_helper::$entity_to_load)) {
         $r .= "<input type=\"hidden\" id=\"sample:id\" name=\"sample:id\" value=\"" . data_entry_helper::$entity_to_load['sample:id'] . "\" />\n";
     }
     $defAttrOptions['validation'] = array('required');
     $defAttrOptions['suffixTemplate'] = 'requiredsuffix';
     if ($locations == 'all') {
         $locOptions = array_merge(array('label' => lang::get('LANG_Transect')), $defAttrOptions);
         $locOptions['extraParams'] = array_merge(array('parent_id' => 'NULL', 'view' => 'detail', 'orderby' => 'name'), $locOptions['extraParams']);
         $r .= data_entry_helper::location_select($locOptions);
     } else {
         // can't use location select due to location filtering.
         $r .= "<label for=\"imp-location\">" . lang::get('LANG_Transect') . ":</label>\n<select id=\"imp-location\" name=\"sample:location_id\" " . $disabled_text . " class=\" \"  >";
         $url = $svcUrl . '/data/location';
         $url .= "?mode=json&view=detail&parent_id=NULL&orderby=name&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"];
         $session = curl_init($url);
         curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
         $entities = json_decode(curl_exec($session), true);
         if (!empty($entities)) {
             foreach ($entities as $entity) {
                 if (in_array($entity["id"], $locations)) {
                     if ($entity["id"] == data_entry_helper::$entity_to_load['sample:location_id']) {
                         $selected = 'selected="selected"';
                     } else {
                         $selected = '';
                     }
                     $r .= "<option value=\"" . $entity["id"] . "\" " . $selected . ">" . $entity["name"] . "</option>";
                 }
             }
         }
         $r .= "</select><span class=\"deh-required\">*</span><br />";
     }
     $languageFilteredAttrOptions = $defAttrOptions + array('language' => iform_lang_iso_639_2($args['language']));
     $r .= data_entry_helper::outputAttribute($attributes[$args['sample_walk_direction_id']], $languageFilteredAttrOptions);
     $r .= data_entry_helper::outputAttribute($attributes[$args['sample_reliability_id']], $languageFilteredAttrOptions);
     $r .= data_entry_helper::outputAttribute($attributes[$args['sample_visit_number_id']], array_merge($languageFilteredAttrOptions, array('default' => 1, 'noBlankText' => true)));
     if ($readOnly) {
         $r .= data_entry_helper::text_input(array_merge($defAttrOptions, array('label' => lang::get('LANG_Date'), 'fieldname' => 'sample:date', 'disabled' => $disabledText)));
     } else {
         $r .= data_entry_helper::date_picker(array('label' => lang::get('LANG_Date'), 'fieldname' => 'sample:date', 'class' => 'vague-date-picker', 'suffixTemplate' => 'requiredsuffix'));
     }
     $r .= data_entry_helper::outputAttribute($attributes[$args['sample_wind_id']], $languageFilteredAttrOptions);
     $r .= data_entry_helper::outputAttribute($attributes[$args['sample_precipitation_id']], $languageFilteredAttrOptions);
     $r .= data_entry_helper::outputAttribute($attributes[$args['sample_temperature_id']], array_merge($defAttrOptions, array('suffixTemplate' => 'nosuffix')));
     $r .= " degC<span class=\"deh-required\">*</span><br />";
     $r .= data_entry_helper::outputAttribute($attributes[$args['sample_cloud_id']], $defAttrOptions);
     $r .= data_entry_helper::outputAttribute($attributes[$args['sample_start_time_id']], array_merge($defAttrOptions, array('suffixTemplate' => 'nosuffix')));
     $r .= " hh:mm<span class=\"deh-required\">*</span><br />";
     $r .= data_entry_helper::outputAttribute($attributes[$args['sample_end_time_id']], array_merge($defAttrOptions, array('suffixTemplate' => 'nosuffix')));
     $r .= " hh:mm<span class=\"deh-required\">*</span><br />";
     unset($defAttrOptions['suffixTemplate']);
     unset($defAttrOptions['validation']);
     if (user_access($adminPerm)) {
         //  users with admin permissions can override the closing of the
         // sample by unchecking the checkbox.
         // Because this is attached to the sample, we have to include the sample required fields in the
         // the post. This means they can't be disabled, so we enable all fields in this case.
         // Normal users can only set this to closed, and they do this using a button/hidden field.
         $r .= data_entry_helper::outputAttribute($attributes[$args['sample_closure_id']], $defAttrOptions);
     } else {
         // hidden closed
         $r .= "<input type=\"hidden\" id=\"" . $closedFieldName . "\" name=\"" . $closedFieldName . "\" value=\"" . $closedFieldValue . "\" />\n";
     }
     if (!empty(data_entry_helper::$validation_errors)) {
         $r .= data_entry_helper::dump_remaining_errors();
     }
     $escaped_id = str_replace(':', '\\\\:', $closedFieldName);
     if (!$readOnly) {
         $r .= "<input type=button id=\"close1\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Save_Survey_Details') . "\";\n        onclick=\"var result = \$('#SurveyForm input').valid();\n          var result2 = \$('#SurveyForm select').valid();\n          if (!result || !result2) {\n              return;\n            }\n            jQuery('#SurveyForm').submit();\">\n";
         if (!user_access($adminPerm) && $mode != 1) {
             $r .= "<input type=button id=\"close2\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Save_Survey_And_Close') . "\"\n        onclick=\"if(confirm('" . lang::get('LANG_Close_Survey_Confirm') . "')){\n          var result = \$('#SurveyForm input').valid();\n          var result2 = \$('#SurveyForm select').valid();\n          if (!result || !result2) {\n              return;\n            }\n          jQuery('#" . $escaped_id . "').val('1');\n            jQuery('#SurveyForm').submit();\n          };\">\n";
         }
     }
     $r .= "</form>";
     $r .= "</div>\n";
     // Set up Occurrence List tab: don't include when creating a new sample as it will have no occurrences
     // Grid populated at a later point
     $r .= "<div id=\"occurrenceList\" class=\"mnhnl-btw-datapanel\">\n";
     if ($mode != 1) {
         drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/hasharray.js', 'module');
         drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/jquery.datagrid.js', 'module');
         $r .= '<div id="occ_grid"></div>';
         $r .= "<form method=\"post\" action=\"" . data_entry_helper::$base_url . "/index.php/services/report/requestReport?report=mnhnl_btw_occurrences_report.xml&reportSource=local&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth['nonce'] . "&mode=csv\">";
         $r .= "<input type=\"hidden\" id=\"params\" name=\"params\" value='{\"survey_id\":" . $args['survey_id'] . ", \"sample_id\":" . data_entry_helper::$entity_to_load['sample:id'] . "}' />";
         $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Download_Occurrences') . "\">";
         $r .= "</FORM>";
     } else {
         $r .= '<p>' . lang::get('LANG_Page_Not_Available') . '</p>';
     }
     $r .= '</div>';
     // Set up Occurrence tab: don't allow entry of a new occurrence until after top level sample is saved.
     $r .= "<div id=\"occurrence\" class=\"mnhnl-btw-datapanel\">\n";
     if ($mode != 1 && ($mode != 2 && $mode != 4 || $readOnly == false)) {
         data_entry_helper::$entity_to_load = $childSample;
         data_entry_helper::$validation_errors = $childErrors;
         $attributes = data_entry_helper::getAttributes(array('id' => data_entry_helper::$entity_to_load['occurrence:id'], 'valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => 'occAttr', 'extraParams' => $readAuth));
         if ($occReadOnly) {
             $r .= "<strong>" . lang::get('LANG_Read_Only_Occurrence') . "</strong>";
             $disabledText = "disabled=\"disabled\"";
             $defAttrOptions['disabled'] = $disabledText;
         } else {
             if ($readOnly) {
                 $r .= "<strong>" . lang::get('LANG_Read_Only_Survey') . "</strong>";
             }
         }
         $r .= "<form method=\"post\">\n";
         $r .= $writeAuth;
         $r .= "<input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
         $r .= "<input type=\"hidden\" id=\"sample:survey_id\" name=\"sample:survey_id\" value=\"" . $args['survey_id'] . "\" />\n";
         $r .= "<input type=\"hidden\" id=\"sample:parent_id\" name=\"sample:parent_id\" value=\"" . $parentSample['sample:id'] . "\" />\n";
         $r .= "<input type=\"hidden\" id=\"sample:date\" name=\"sample:date\" value=\"" . data_entry_helper::$entity_to_load['sample:date'] . "\" />\n";
         if (array_key_exists('sample:id', data_entry_helper::$entity_to_load)) {
             $r .= "<input type=\"hidden\" id=\"sample:id\" name=\"sample:id\" value=\"" . data_entry_helper::$entity_to_load['sample:id'] . "\" />\n";
         }
         if (array_key_exists('occurrence:id', data_entry_helper::$entity_to_load)) {
             $r .= "<input type=\"hidden\" id=\"occurrence:id\" name=\"occurrence:id\" value=\"" . data_entry_helper::$entity_to_load['occurrence:id'] . "\" />\n";
         }
         $r .= "<input type=\"hidden\" id=\"occurrence:record_status\" name=\"occurrence:record_status\" value=\"C\" />\n";
         $r .= "<input type=\"hidden\" id=\"occurrence:downloaded_flag\" name=\"occurrence:downloaded_flag\" value=\"N\" />\n";
         $extraParams = $readAuth + array('taxon_list_id' => $args['list_id']);
         $species_ctrl_args = array('label' => lang::get('LANG_Species'), 'fieldname' => 'occurrence:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 2, 'extraParams' => $extraParams, 'suffixTemplate' => 'requiredsuffix', 'disabled' => $disabledText, 'defaultCaption' => data_entry_helper::$entity_to_load['occurrence:taxon']);
         $r .= data_entry_helper::autocomplete($species_ctrl_args);
         $r .= data_entry_helper::outputAttribute($attributes[$args['occurrence_confidence_id']], array_merge($languageFilteredAttrOptions, array('noBlankText' => '')));
         $r .= data_entry_helper::sref_and_system(array('label' => lang::get('LANG_Spatial_ref'), 'systems' => array('2169' => 'Luref (Gauss Luxembourg)'), 'suffixTemplate' => 'requiredsuffix'));
         $r .= "<p>" . lang::get('LANG_Click_on_map') . "</p>";
         $r .= data_entry_helper::outputAttribute($attributes[$args['occurrence_count_id']], array_merge($defAttrOptions, array('default' => 1, 'suffixTemplate' => 'requiredsuffix')));
         $r .= data_entry_helper::outputAttribute($attributes[$args['occurrence_approximation_id']], $defAttrOptions);
         $r .= data_entry_helper::outputAttribute($attributes[$args['occurrence_territorial_id']], array_merge($defAttrOptions, array('default' => 1)));
         $r .= data_entry_helper::outputAttribute($attributes[$args['occurrence_atlas_code_id']], $languageFilteredAttrOptions);
         $r .= data_entry_helper::outputAttribute($attributes[$args['occurrence_overflying_id']], $defAttrOptions);
         $r .= data_entry_helper::textarea(array('label' => lang::get('LANG_Comment'), 'fieldname' => 'occurrence:comment', 'disabled' => $disabledText));
         if (!empty(data_entry_helper::$validation_errors)) {
             $r .= data_entry_helper::dump_remaining_errors();
         }
         if (!$readOnly && !$occReadOnly) {
             $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Save_Occurrence_Details') . "\" />\n";
         }
         $r .= "</form>\n";
         $escaped_terr_id = str_replace(':', '\\\\:', $attributes[$args['occurrence_territorial_id']]['fieldname']);
         $escaped_atlas_id = str_replace(':', '\\\\:', $attributes[$args['occurrence_atlas_code_id']]['fieldname']);
         data_entry_helper::$javascript .= "\nsetAtlasStatus = function() {\n  if (jQuery(\"input[name='" . $escaped_terr_id . "']:checked\").val() == '0') {\n      jQuery('#" . $escaped_atlas_id . "').val('');\n  } else {\n      if(jQuery('#" . $escaped_atlas_id . "').val() == '') {\n        // Find the BB02 option (depends on the language what val it has)\n        var bb02;\n        jQuery.each(jQuery('#" . $escaped_atlas_id . " option'), function(index, option) {\n          if (option.text.substr(0,4)=='BB02') {\n            bb02 = option.value;\n            return; // just from the each loop\n          }\n        });\n        jQuery('#" . $escaped_atlas_id . "').val(bb02);\n      }\n  }\n};\nsetAtlasStatus();\njQuery(\"input[name='" . $escaped_terr_id . "']\").change(setAtlasStatus);\n";
     } else {
         $r .= '<p>' . lang::get('LANG_Page_Not_Available') . '</p>';
     }
     $r .= '</div>';
     // add map panel.
     $r .= "<div class=\"mnhnl-btw-mappanel\">\n";
     $r .= data_entry_helper::map_panel(array('presetLayers' => $presetLayers, 'layers' => array('baseLayer_1', 'baseLayer_2', 'locationLayer', 'occListLayer'), 'initialFeatureWkt' => null, 'width' => 'auto', 'height' => 490, 'initial_lat' => $args['map_centroid_lat'], 'initial_long' => $args['map_centroid_long'], 'initial_zoom' => (int) $args['map_zoom'], 'scroll_wheel_zoom' => false), array('projection' => $args['map_projection']));
     // for timing reasons, all the following has to be done after the map is loaded.
     // 1) feature selector for occurrence list must have the map present to attach the control
     // 2) location placer must have the location layer populated and the map present in
     //    order to zoom the map into the location.
     // 3) occurrence list feature adder must have map present in order to zoom into any
     //    current selection.
     data_entry_helper::$onload_javascript .= "\nvar control = new OpenLayers.Control.SelectFeature(occListLayer);\noccListLayer.map.addControl(control);\nfunction onPopupClose(evt) {\n    // 'this' is the popup.\n    control.unselect(this.feature);\n}\nfunction onFeatureSelect(evt) {\n    feature = evt.feature;\n    popup = new OpenLayers.Popup.FramedCloud(\"featurePopup\",\n               feature.geometry.getBounds().getCenterLonLat(),\n                             new OpenLayers.Size(100,100),\n                             feature.attributes.taxon + \" (\" + feature.attributes.count + \")\",\n                             null, true, onPopupClose);\n    feature.popup = popup;\n    popup.feature = feature;\n    feature.layer.map.addPopup(popup);\n}\nfunction onFeatureUnselect(evt) {\n    feature = evt.feature;\n    if (feature.popup) {\n        popup.feature = null;\n        feature.layer.map.removePopup(feature.popup);\n        feature.popup.destroy();\n        feature.popup = null;\n    }\n}\n\noccListLayer.events.on({\n    'featureselected': onFeatureSelect,\n    'featureunselected': onFeatureUnselect\n});\n\ncontrol.activate();\n\nlocationChange = function(obj){\n  locationLayer.destroyFeatures();\n  if(obj.value != ''){\n    jQuery.getJSON(\"" . $svcUrl . "\" + \"/data/location/\"+obj.value +\n      \"?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . "\" +\n      \"&callback=?\", function(data) {\n            if (data.length>0) {\n              var parser = new OpenLayers.Format.WKT();\n              for (var i=0;i<data.length;i++)\n        {\n          if(data[i].centroid_geom){\n            " . self::readBoundaryJs('data[i].centroid_geom', $args['map_projection']) . "\n            feature.style = {label: data[i].name,\n\t\t\t\t\t\t     strokeColor: \"Green\",\n                             strokeWidth: 2,\n                             fillOpacity: 0};\n            centre = feature.geometry.getCentroid();\n            centrefeature = new OpenLayers.Feature.Vector(centre, {}, {label: data[i].name});\n            locationLayer.addFeatures([feature, centrefeature]);\n          }\n          if(data[i].boundary_geom){\n            " . self::readBoundaryJs('data[i].boundary_geom', $args['map_projection']) . "\n            feature.style = {strokeColor: \"Blue\", strokeWidth: 2};\n            locationLayer.addFeatures([feature]);\n          }\n          locationLayer.map.zoomToExtent(locationLayer.getDataExtent());\n        }\n      }\n    });\n     jQuery.getJSON(\"" . $svcUrl . "\" + \"/data/location\" +\n      \"?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . "&callback=?&parent_id=\"+obj.value, function(data) {\n            if (data.length>0) {\n              var parser = new OpenLayers.Format.WKT();\n              for (var i=0;i<data.length;i++)\n        {\n          if(data[i].centroid_geom){\n            " . self::readBoundaryJs('data[i].centroid_geom', $args['map_projection']) . "\n            locationLayer.addFeatures([feature]);\n          }\n          if(data[i].boundary_geom){\n            " . self::readBoundaryJs('data[i].boundary_geom', $args['map_projection']) . "\n            feature.style = {label: data[i].name,\n              labelAlign: \"cb\",\n              strokeColor: \"Blue\",\n                        strokeWidth: 2};\n            locationLayer.addFeatures([feature]);\n           }\n         }\n      }\n        });\n  }\n};\n// upload location initial value into map.\njQuery('#imp-location').each(function(){\n  locationChange(this);\n});\njQuery('#imp-location').unbind('change');\njQuery('#imp-location').change(function(){\n  locationChange(this);\n});\nvar selected = \$('#controls').tabs('option', 'selected');\n\n// Only leave the click control activated for edit/add occurrence tab.\nif(selected != 1){\n    locationLayer.map.editLayer.clickControl.deactivate();\n}\n\$('#controls').bind('tabsshow', function(event, ui) {\n        if(ui.index == 1)\n        {\n         locationLayer.map.editLayer.clickControl.activate();\n        }\n        else\n        {\n         locationLayer.map.editLayer.clickControl.deactivate();\n        }\n    }\n);\n";
     if ($mode != 1) {
         data_entry_helper::$onload_javascript .= "\nactivateAddList = 1;\n\naddListFeature = function(div, r, record, count) {\n  if(activateAddList == 0)\n    return;\n  if(r == count)\n    activateAddList = 0;\n    var parser = new OpenLayers.Format.WKT();\n    " . self::readBoundaryJs('record.geom', $args['map_projection']) . "\n    if(record.id != " . $thisOccID . " || 1==" . ($readOnly ? 1 : 0) . " || 1==" . ($occReadOnly ? 1 : 0) . "){\n      feature.attributes.id = record.id;\n      feature.attributes.taxon = record.taxon;\n      feature.attributes.count = record.count;\n      occListLayer.addFeatures([feature]);\n      if(record.id == " . $thisOccID . "){\n        var bounds=feature.geometry.getBounds();\n        locationLayer.map.setCenter(bounds.getCenterLonLat());\n      }\n    } else {\n      if(" . ($displayThisOcc ? 1 : 0) . "){\n        locationLayer.map.editLayer.destroyFeatures();\n      locationLayer.map.editLayer.addFeatures([feature]);\n      var bounds=feature.geometry.getBounds()\n      var centre=bounds.getCenterLonLat();\n      locationLayer.map.setCenter(centre);\n    }\n    }\n};\nhighlight = function(id){\n  if(id == " . $thisOccID . "){\n    if(occListLayer.map.editLayer.features.length > 0){\n      var bounds=occListLayer.map.editLayer.features[0].geometry.getBounds()\n      var centre=bounds.getCenterLonLat();\n      occListLayer.map.setCenter(centre);\n      return;\n    }\n  }\n  for(var i = 0; i < occListLayer.features.length; i++){\n    if(occListLayer.features[i].attributes.id == id){\n      control.unselectAll();\n      var bounds=occListLayer.features[i].geometry.getBounds()\n      var centre=bounds.getCenterLonLat();\n      occListLayer.map.setCenter(centre);\n      control.select(occListLayer.features[i]);\n      return;\n    }\n  }\n}\n\$('div#occ_grid').indiciaDataGrid('rpt:mnhnl_btw_list_occurrences', {\n    indiciaSvc: '" . $svcUrl . "',\n    dataColumns: ['taxon', 'territorial', 'count'],\n    reportColumnTitles: {taxon : '" . lang::get('LANG_Species') . "', territorial : '" . lang::get('LANG_Territorial') . "', count : '" . lang::get('LANG_Count') . "'},\n    actionColumns: {'" . lang::get('LANG_Show') . "' : \"" . url('node/' . $node->nid, array('query' => 'occurrence_id=£id£')) . "\",\n            '" . lang::get('LANG_Highlight') . "' : \"script:highlight(£id£);\"},\n    auth : { nonce : '" . $readAuth['nonce'] . "', auth_token : '" . $readAuth['auth_token'] . "'},\n    parameters : { survey_id : '" . $args['survey_id'] . "',\n            parent_id : '" . $parentSample['sample:id'] . "',\n            territorial_attr_id : '" . $args['occurrence_territorial_id'] . "',\n            count_attr_id : '" . $args['occurrence_count_id'] . "'},\n    itemsPerPage : 12,\n    callback : addListFeature ,\n    cssOdd : ''\n  });\n\n// activateAddList = 0;\n\n";
     }
     $r .= "</div><div><form><input type=\"button\" value=\"" . lang::get('LANG_Return') . "\" onclick=\"window.location.href='" . url('node/' . $node->nid, array('query' => 'Main')) . "'\"></form></div></div>\n";
     return $r;
 }
 public static function get_sample_form($args, $node, $response)
 {
     global $user;
     if (!module_exists('iform_ajaxproxy')) {
         return 'This form must be used in Drupal with the Indicia AJAX Proxy module enabled.';
     }
     iform_load_helpers(array('map_helper'));
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $sampleId = isset($_GET['sample_id']) ? $_GET['sample_id'] : null;
     $locationId = null;
     if ($sampleId) {
         data_entry_helper::load_existing_record($auth['read'], 'sample', $sampleId, 'detail', false, true);
         $locationId = data_entry_helper::$entity_to_load['sample:location_id'];
     } else {
         // location ID also might be in the $_POST data after a validation save of a new record
         if (isset($_POST['sample:location_id'])) {
             $locationId = $_POST['sample:location_id'];
         }
     }
     $url = explode('?', $args['my_obs_page'], 2);
     $params = NULL;
     $fragment = NULL;
     // fragment is always at the end.
     if (count($url) > 1) {
         $params = explode('#', $url[1], 2);
         if (count($params) > 1) {
             $fragment = $params[1];
         }
         $params = $params[0];
     } else {
         $url = explode('#', $url[0], 2);
         if (count($url) > 1) {
             $fragment = $url[1];
         }
     }
     $args['my_obs_page'] = url($url[0], array('query' => $params, 'fragment' => $fragment, 'absolute' => TRUE));
     $r = '<form method="post" id="sample">';
     $r .= $auth['write'];
     $r .= '<input type="hidden" name="page" value="mainSample"/>';
     $r .= '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>';
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         $r .= '<input type="hidden" name="sample:id" value="' . data_entry_helper::$entity_to_load['sample:id'] . '"/>';
     }
     $r .= '<input type="hidden" name="sample:survey_id" value="' . $args['survey_id'] . '"/>';
     $r .= '<div id="cols" class="ui-helper-clearfix"><div class="left" style="width: ' . (98 - (isset($args['percent_width']) ? $args['percent_width'] : 50)) . '%">';
     // Output only the locations for this website and location type.
     $availableSites = data_entry_helper::get_population_data(array('report' => 'library/locations/locations_list', 'extraParams' => $auth['read'] + array('website_id' => $args['website_id'], 'location_type_id' => $args['locationType'], 'locattrs' => 'CMS User ID', 'attr_location_cms_user_id' => $user->uid), 'nocache' => true));
     // convert the report data to an array for the lookup, plus one to pass to the JS so it can keep the map updated
     $sitesLookup = array();
     $sitesIds = array();
     $sitesJs = array();
     foreach ($availableSites as $site) {
         $sitesLookup[$site['location_id']] = $site['name'];
         $sitesIds[] = $site['location_id'];
     }
     $sites = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('website_id' => $args['website_id'], 'id' => $sitesIds, 'view' => 'detail')));
     foreach ($sites as $site) {
         $sitesJs[$site['id']] = $site;
     }
     data_entry_helper::$javascript .= "indiciaData.sites = " . json_encode($sitesJs) . ";\n";
     if ($locationId) {
         $r .= '<input type="hidden" name="sample:location_id" id="sample_location_id" value="' . $locationId . '"/>';
         // for reload of existing, don't let the user switch the square as that could mess everything up.
         $r .= '<label>' . lang::get('1km square') . ':</label><span>' . $sitesJs[$locationId]['name'] . '</span><br/>' . lang::get('<p class="ui-state-highlight page-notice ui-corner-all">Please use the map to select a more precise location for your timed observation.</p>');
     } else {
         $options = array('label' => lang::get('Select 1km square'), 'validation' => array('required'), 'blankText' => lang::get('Please select'), 'lookupValues' => $sitesLookup, 'id' => "sample_location_id");
         // if ($locationId) $options['default'] = $locationId;
         $r .= data_entry_helper::location_select($options) . lang::get('<p class="ui-state-highlight page-notice ui-corner-all">After selecting the 1km square, use the map to select a more precise location for your timed observation.</p>');
     }
     // [spatial reference]
     $systems = array();
     foreach (explode(',', str_replace(' ', '', $args['spatial_systems'])) as $system) {
         $systems[$system] = lang::get("sref:{$system}");
     }
     $r .= data_entry_helper::sref_and_system(array('label' => lang::get('Grid Ref'), 'systems' => $systems));
     $r .= data_entry_helper::file_box(array('table' => 'sample_image', 'readAuth' => $auth['read'], 'caption' => lang::get('Upload photo(s) of timed search area')));
     $sampleMethods = helper_base::get_termlist_terms($auth, 'indicia:sample_methods', array('Field Observation'));
     $attributes = data_entry_helper::getAttributes(array('id' => $sampleId, 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'sample_method_id' => $sampleMethods[0]['id']));
     $r .= get_user_profile_hidden_inputs($attributes, $args, '', $auth['read']);
     if (isset($_GET['date'])) {
         $r .= '<input type="hidden" name="sample:date" value="' . $_GET['date'] . '"/>';
         $r .= '<label>' . lang::get('Date') . ':</label> <span class="value-label">' . $_GET['date'] . '</span><br/>';
     } else {
         if (isset(data_entry_helper::$entity_to_load['sample:date']) && preg_match('/^(\\d{4})/', data_entry_helper::$entity_to_load['sample:date'])) {
             // Date has 4 digit year first (ISO style) - convert date to expected output format
             // @todo The date format should be a global configurable option. It should also be applied to reloading of custom date attributes.
             $d = new DateTime(data_entry_helper::$entity_to_load['sample:date']);
             data_entry_helper::$entity_to_load['sample:date'] = $d->format('d/m/Y');
         }
         $r .= data_entry_helper::date_picker(array('label' => lang::get('Date'), 'fieldname' => 'sample:date'));
     }
     // are there any option overrides for the custom attributes?
     if (isset($args['custom_attribute_options']) && $args['custom_attribute_options']) {
         $blockOptions = get_attr_options_array_with_user_data($args['custom_attribute_options']);
     } else {
         $blockOptions = array();
     }
     $r .= get_attribute_html($attributes, $args, array('extraParams' => $auth['read']), null, $blockOptions);
     $r .= '<input type="hidden" name="sample:sample_method_id" value="' . $sampleMethods[0]['id'] . '" />';
     $r .= '<input type="submit" value="' . lang::get('Next') . '" />';
     $r .= '<a href="' . $args['my_obs_page'] . '" class="button">' . lang::get('Cancel') . '</a>';
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         $r .= '<button id="delete-button" type="button" class="ui-state-default ui-corner-all" />' . lang::get('Delete') . '</button>';
     }
     $r .= "</div>";
     // left
     $r .= '<div class="right" style="width: ' . (isset($args['percent_width']) ? $args['percent_width'] : 50) . '%">';
     // [place search]
     $georefOpts = iform_map_get_georef_options($args, $auth['read']);
     $georefOpts['label'] = lang::get('Search for Place on Map');
     // can't use place search without the driver API key
     if ($georefOpts['driver'] == 'geoplanet' && empty(helper_config::$geoplanet_api_key)) {
         $r .= '<span style="display: none;">The form structure includes a place search but needs a geoplanet api key.</span>';
     } else {
         $r .= data_entry_helper::georeference_lookup($georefOpts);
     }
     // [map]
     $options = iform_map_get_map_options($args, $auth['read']);
     if (!empty(data_entry_helper::$entity_to_load['sample:wkt'])) {
         $options['initialFeatureWkt'] = data_entry_helper::$entity_to_load['sample:wkt'];
     }
     $olOptions = iform_map_get_ol_options($args);
     if (!isset($options['standardControls'])) {
         $options['standardControls'] = array('layerSwitcher', 'panZoomBar');
     }
     $r .= map_helper::map_panel($options, $olOptions);
     data_entry_helper::$javascript .= "\nmapInitialisationHooks.push(function(mapdiv) {\n  var defaultStyle = new OpenLayers.Style({pointRadius: 6,fillOpacity: 0,strokeColor: \"Red\",strokeWidth: 1});\n  var SiteStyleMap = new OpenLayers.StyleMap({\"default\": defaultStyle});\n  indiciaData.SiteLayer = new OpenLayers.Layer.Vector('1km square',{styleMap: SiteStyleMap, displayInLayerSwitcher: true});\n  mapdiv.map.addLayer(indiciaData.SiteLayer);\n  if(jQuery('#sample_location_id').length > 0) {\n    if(jQuery('#sample_location_id').val() != ''){\n      var parser = new OpenLayers.Format.WKT();\n      var feature = parser.read(indiciaData.sites[jQuery('#sample_location_id').val()].geom);\n      indiciaData.SiteLayer.addFeatures([feature]);\n      // for existing data we zoom on the site, not this parent location\n    } \n    jQuery('#sample_location_id').change(function(){\n      indiciaData.SiteLayer.destroyFeatures();\n      if(jQuery('#sample_location_id').val() != ''){\n        var parser = new OpenLayers.Format.WKT();\n        var feature = parser.read(indiciaData.sites[jQuery('#sample_location_id').val()].geom);\n        indiciaData.SiteLayer.addFeatures([feature]);\n        var layerBounds = indiciaData.SiteLayer.getDataExtent().clone(); // use a clone\n        indiciaData.SiteLayer.map.zoomToExtent(layerBounds);\n      }\n    });\n  }\n});\n";
     $r .= "</div>";
     // right
     $r .= '</form>';
     // Recorder Name - assume Easy Login uid
     if (function_exists('module_exists') && module_exists('easy_login')) {
         $userId = hostsite_get_user_field('indicia_user_id');
         // For non easy login test only     $userId = 1;
         foreach ($attributes as $attrID => $attr) {
             if (strcasecmp('Recorder Name', $attr["untranslatedCaption"]) == 0 && !empty($userId)) {
                 // determining which you have used is difficult from a services based autocomplete, esp when the created_by_id is not available on the data.
                 data_entry_helper::add_resource('autocomplete');
                 data_entry_helper::$javascript .= "bindRecorderNameAutocomplete(" . $attrID . ", '" . $userId . "', '" . data_entry_helper::$base_url . "', '" . $args['survey_id'] . "', '" . $auth['read']['auth_token'] . "', '" . $auth['read']['nonce'] . "');\n";
             }
         }
     }
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         // allow deletes if sample id is present.
         data_entry_helper::$javascript .= "jQuery('#delete-button').click(function(){\n  if(confirm(\"" . lang::get('Are you sure you want to delete this walk?') . "\")){\n    jQuery('#delete-form').submit();\n  } // else do nothing.\n});\n";
         // note we only require bare minimum in order to flag a sample as deleted.
         $r .= '<form method="post" id="delete-form" style="display: none;">';
         $r .= $auth['write'];
         $r .= '<input type="hidden" name="page" value="delete"/>';
         $r .= '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>';
         $r .= '<input type="hidden" name="sample:id" value="' . data_entry_helper::$entity_to_load['sample:id'] . '"/>';
         $r .= '<input type="hidden" name="sample:deleted" value="t"/>';
         $r .= '</form>';
     }
     data_entry_helper::enable_validation('sample');
     return $r;
 }
Esempio n. 20
0
 protected static function get_control_locationspatialreference($auth, $args, $tabalias, $options)
 {
     global $indicia_templates;
     // have to override the name of the imp-geom to point to the location centroid_geometry
     $indicia_templates['sref_textbox_latlong'] = '<label for="{idLat}" style="width: auto; ">{labelLat}:</label>' . '<input type="text" id="{idLat}" name="{fieldnameLat}" {class} {disabled} value="{defaultLat}" />' . '<label for="{idLong}" style="width: auto; margin-left: 20px; ">{labelLong}:</label>' . '<input type="text" id="{idLong}" name="{fieldnameLong}" {class} {disabled} value="{defaultLong}" />' . '<input type="hidden" id="imp-geom" name="{geomFieldname}" value="{defaultGeom}" />' . '<input type="hidden" id="{id}" name="{fieldname}" value="{default}" />' . '<span style="margin-left: 20px; ">' . lang::get('LANG_LatLong_Bumpf') . '</span><br />' . '<input type="button" value="' . lang::get('Clear Position') . '" onclick="ClearPosition();">' . '<input type="button" value="' . lang::get('View All Luxembourg') . '" onclick="ViewAllLuxembourg();">';
     data_entry_helper::$javascript .= "\nViewAllLuxembourg = 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};\nClearPosition = function(){\n  jQuery('#imp-geom').val('');\n  jQuery('#imp-sref').val('');\n  jQuery('#imp-sref-lat').val('');\n  jQuery('#imp-sref-long').val('');\n  var div = jQuery('#map')[0];\n  div.map.editLayer.destroyFeatures();\n};";
     // Build the array of spatial reference systems into a format Indicia can use.
     $systems = array();
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get($system);
     }
     return data_entry_helper::sref_and_system(array_merge(array('splitLatLong' => true, 'fieldname' => 'location:centroid_sref', 'srefField' => 'location:centroid_sref', 'geomFieldname' => 'location:centroid_geom', 'systems' => $systems), $options));
 }
 /**
  * Return the generated output for the main sample tab.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  *                    This array always contains a value for language.
  * @param integer $nid The Drupal node object's ID.
  * @param object $auth The full read-write authorisation.
  * @return HTML.
  */
 private static function get_sample_tab($args, $nid, $auth, $attributes, &$packageAttr)
 {
     global $user;
     if (isset(data_entry_helper::$entity_to_load['sample:date']) && preg_match('/^(\\d{4})/', data_entry_helper::$entity_to_load['sample:date'])) {
         // Date has 4 digit year first (ISO style) - convert date to expected output format
         // @todo The date format should be a global configurable option. It should also be applied to reloading of custom date attributes.
         $d = new DateTime(data_entry_helper::$entity_to_load['sample:date']);
         data_entry_helper::$entity_to_load['sample:date'] = $d->format('d/m/Y');
     }
     // are there any option overrides for the custom attributes?
     if (isset($args['custom_attribute_options']) && $args['custom_attribute_options']) {
         $blockOptions = get_attr_options_array_with_user_data($args['custom_attribute_options']);
     } else {
         $blockOptions = array();
     }
     $systems = array();
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get("sref:{$system}");
     }
     $options = iform_map_get_map_options($args, $auth['read']);
     $olOptions = iform_map_get_ol_options($args);
     if (!empty(data_entry_helper::$entity_to_load['sample:wkt'])) {
         $options['initialFeatureWkt'] = data_entry_helper::$entity_to_load['sample:wkt'];
     }
     if (!isset($options['standardControls'])) {
         $options['standardControls'] = array('layerSwitcher', 'panZoomBar');
     }
     $options['tabDiv'] = 'sample';
     // we pass through the read auth. This makes it possible for the get_submission method to authorise against the warehouse
     // without an additional (expensive) warehouse call, so it can get subsample details.
     $r = '<div id="sample">' . '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>' . get_user_profile_hidden_inputs($attributes, $args, isset(data_entry_helper::$entity_to_load['sample:id']), $auth['read']) . data_entry_helper::text_input(array('label' => lang::get('Location Name'), 'fieldname' => 'sample:location_name', 'class' => 'control-width-5', 'validation' => array('required'))) . data_entry_helper::date_picker(array('label' => lang::get('Date'), 'fieldname' => 'sample:date')) . self::_build_package_control($args, $packageAttr) . get_attribute_html($attributes, $args, array('extraParams' => $auth['read']), null, $blockOptions) . data_entry_helper::textarea(array('fieldname' => 'sample:comment', 'label' => lang::get('Overall comment'))) . data_entry_helper::sref_and_system(array('label' => lang::get('Grid Reference'), 'systems' => $systems)) . '<p class="ui-state-highlight page-notice ui-corner-all">' . t('Use the search box to find a nearby town or village, then drag the map to pan and click on the map to set the centre grid reference of the transect. ' . 'Alternatively if you know the grid reference you can enter it in the Grid Ref box above: this will then be drawn automatically on the map.') . '</p>' . (isset(data_entry_helper::$entity_to_load['sample:id']) ? '' : data_entry_helper::georeference_lookup(array('label' => lang::get('Search for place'), 'driver' => $args['georefDriver'], 'georefPreferredArea' => $args['georefPreferredArea'], 'georefCountry' => $args['georefCountry'], 'georefLang' => $args['language'], 'readAuth' => $auth['read']))) . map_helper::map_panel($options, $olOptions) . (self::$readOnly ? '' : '<br/><input type="submit" value="' . lang::get('Save') . '" title="' . lang::get('Saves any data entered across all the tabs.') . '" />') . '</div>';
     return $r;
 }
 private static function get_site_tab($auth, $args, $settings)
 {
     $r = '<div id="sitedetails" class="ui-helper-clearfix">';
     $r .= '<div class="left" style="width: 44%">';
     $r .= '<fieldset><legend>' . lang::get('Transect Details') . '</legend>';
     $r .= "<input type=\"hidden\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" name=\"survey_id\" value=\"" . $args['survey_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" name=\"location:location_type_id\" value=\"" . $settings['locationTypes'][0]['id'] . "\" />\n";
     if ($settings['locationId']) {
         $r .= '<input type="hidden" name="location:id" value="' . $settings['locationId'] . "\" />\n";
     }
     $r .= data_entry_helper::text_input(array('fieldname' => 'location:name', 'label' => lang::get('Transect Name'), 'class' => 'control-width-4 required'));
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get($system);
     }
     $r .= data_entry_helper::sref_and_system(array('fieldname' => 'location:centroid_sref', 'geomFieldname' => 'location:centroid_geom', 'label' => 'Grid Ref.', 'systems' => $systems, 'class' => 'required', 'helpText' => lang::get('Click on the map to set the grid reference.')));
     // setup the map options
     $options = iform_map_get_map_options($args, $auth['read']);
     $options['toolbarDiv'] = 'top';
     if (!empty($settings['sections'])) {
         // if we have an existing site with sections, output a selector for the current section.
         $sectionArr = array('' => htmlspecialchars(lang::get('<select>')));
         for ($i = 1; $i <= count($settings['sections']); $i++) {
             $sectionArr[$i] = $i;
         }
         $options['toolbarPrefix'] = data_entry_helper::select(array('fieldname' => '', 'id' => 'current-section', 'label' => lang::get('Select section'), 'lookupValues' => $sectionArr, 'suffixTemplate' => 'nosuffix'));
         $options['toolbarPrefix'] .= '<a href="' . $args['section_edit_path'] . (strpos($args['section_edit_path'], '?') === false ? '?' : '&') . 'from=transect&transect_id=' . $settings['locationId'] . '&section_id=0" id="section-edit" style="display: none" class="ui-state-default ui-corner-all indicia-button">' . lang::get('Edit') . '</a>';
         // also let the user click on a feature to select it. The highlighter just makes it easier to select one.
         $options['standardControls'][] = 'selectFeature';
         $options['standardControls'][] = 'hoverFeatureHighlight';
     }
     if ($settings['locationId']) {
         $options['toolbarPrefix'] .= '<a href="' . $args['section_edit_path'] . (strpos($args['section_edit_path'], '?') === false ? '?' : '&') . 'from=transect&transect_id=' . $settings['locationId'] . '" class="ui-state-default ui-corner-all indicia-button">' . lang::get('Add Section') . '</a>';
     }
     $r .= get_attribute_html($settings['attributes'], $args, array('extraParams' => $auth['read']), 'Site Details');
     $r .= '</fieldset>';
     if (user_access('indicia data admin')) {
         $r .= self::get_user_assignment_control($auth['read'], $settings['cmsUserAttr'], $args);
     } elseif (!$settings['locationId']) {
         // for a new record, we need to link the current user to the location if they are not admin.
         global $user;
         $r .= '<input type="hidden" name="locAttr:' . self::$cmsUserAttrId . '" value="' . $user->uid . '">';
     }
     $r .= "</div>";
     $r .= '<div class="right" style="width: ' . $options['width'] . 'px;">';
     if ($settings['locationId']) {
         $help = lang::get('Use the Add Section button to create each section of your transect in turn.');
         if (count($settings['sections']) > 0) {
             $help .= ' ' . lang::get('For existing sections, select a section from the drop down list then click Edit to make changes. ' . 'You can also select a section using the query tool to click on the section lines, or reset the transect centroid grid reference ' . 'using the Click Grid Ref tool.');
         }
     } else {
         $help = t('Use the search box to find a nearby town or village, then drag the map to pan and click on the map to set the centre grid reference of the transect. ' . 'Alternatively if you know the grid reference you can enter it in the Grid Ref box on the left.');
     }
     $r .= '<p class="ui-state-highlight page-notice ui-corner-all">' . $help . '</p>';
     if (!$settings['locationId']) {
         $r .= data_entry_helper::georeference_lookup(array('label' => lang::get('Search for place'), 'driver' => $args['georefDriver'], 'georefPreferredArea' => $args['georefPreferredArea'], 'georefCountry' => $args['georefCountry'], 'georefLang' => $args['language']));
     }
     $olOptions = iform_map_get_ol_options($args);
     $r .= map_helper::map_panel($options, $olOptions);
     $r .= '</div>';
     // right
     $r .= '</div>';
     // site
     // This must go after the map panel, so it has created its toolbar
     data_entry_helper::$onload_javascript .= "\$('#current-section').change(selectSection);\n";
     return $r;
 }