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;
 }
 /**
  * Get the block of sample custom attributes for the recorder
  */
 private static function get_control_recorderdetails($auth, $args, $tabalias, $options)
 {
     // get the sample attributes
     $attrOpts = array('id' => data_entry_helper::$entity_to_load['sample:id'], 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']);
     // select only the custom attributes that are for this sample method or all sample methods, if this
     // form is for a specific sample method.
     if (!empty($args['sample_method_id'])) {
         $attrOpts['sample_method_id'] = $args['sample_method_id'];
     }
     $attributes = data_entry_helper::getAttributes($attrOpts, false);
     // load values from profile. This is Drupal specific code, so degrade gracefully.
     if (function_exists('profile_load_profile')) {
         global $user;
         profile_load_all_profile($user);
         foreach ($attributes as &$attribute) {
             if (!isset($attribute['default'])) {
                 $attrPropName = 'profile_' . strtolower(str_replace(' ', '_', $attribute['caption']));
                 if (isset($user->{$attrPropName})) {
                     $attribute['default'] = $user->{$attrPropName};
                 } elseif (strcasecmp($attribute['caption'], 'email') === 0 && isset($user->mail)) {
                     $attribute['default'] = $user->mail;
                 }
             }
         }
     }
     $defAttrOptions = array('extraParams' => $auth['read'], 'class' => "required");
     $attrHtml = '';
     // Drupal specific code
     if (!user_access('IForm n' . self::$node->nid . ' enter data by proxy')) {
         if (isset($options['lockable'])) {
             unset($options['lockable']);
         }
         $defAttrOptions += array('readonly' => 'readonly="readonly"');
         $attrHtml .= '<div class="readonlyFieldset">';
     }
     $defAttrOptions += $options;
     $blockOptions = array();
     $attrHtml .= get_attribute_html($attributes, $args, $defAttrOptions, 'Enter data by proxy', $blockOptions);
     if (!user_access('IForm n' . self::$node->nid . ' enter data by proxy')) {
         $attrHtml .= '</div>';
     }
     return $attrHtml;
 }
 protected static function get_section_details_tab($auth, $args, $settings)
 {
     $r = '<div id="section-details" class="ui-helper-clearfix">';
     $r .= '<form method="post" id="section-form" action="' . self::$ajaxFormUrl . '">';
     $r .= '<fieldset><legend>' . lang::get('Section Details') . '</legend>';
     // Output a selector for the current section.
     $r .= self::section_selector($settings, 'section-select') . "<br/>";
     if ($settings['canEditBody']) {
         $r .= "<input type=\"hidden\" name=\"location:id\" value=\"\" id=\"section-location-id\" />\n";
         $r .= '<input type="hidden" name="website_id" value="' . $args['website_id'] . "\" />\n";
     }
     // for the SRef, we want to be able to edit the sref, but just display the system. Do not want the Geometry.
     $r .= '<label for="imp-sref">Section Grid Ref.:</label><input type="text" value="" class="required" name="location:centroid_sref" id="section-location-sref"><span class="deh-required">*</span>';
     // for the system we need to translate the system: easiest way is to have a disabled select plus a hidden field.
     $systems = array();
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get($system);
     }
     $options = array('fieldname' => '', 'systems' => $systems, 'disabled' => ' disabled="disabled"', 'id' => 'section-location-system-select');
     // Output the hidden system control
     $r .= '<input type="hidden" id="section-location-system" name="location:centroid_sref_system" value="" />';
     $r .= data_entry_helper::sref_system_select($options);
     // force a blank centroid, so that the Warehouse will recalculate it from the boundary
     //$r .= "<input type=\"hidden\" name=\"location:centroid_geom\" value=\"\" />\n";
     $r .= get_attribute_html($settings['section_attributes'], $args, array('extraParams' => $auth['read'], 'disabled' => $settings['canEditBody'] ? '' : ' disabled="disabled" '));
     if ($settings['canEditBody']) {
         $r .= '<input type="submit" value="' . lang::get('Save') . '" class="form-button right" id="submit-section" />';
     }
     $r .= '</fieldset></form>';
     $r .= '</div>';
     return $r;
 }
 /**
  * Get the sensitivity control
  */
 protected static function get_control_sensitivity($auth, $args, $tabAlias, $options)
 {
     if ($args['multiple_occurrence_mode'] === 'single') {
         self::load_custom_occattrs($auth['read'], $args['survey_id']);
         $ctrlOptions = array('extraParams' => $auth['read']);
         $attrSpecificOptions = array();
         self::parseForAttrSpecificOptions($options, $ctrlOptions, $attrSpecificOptions);
         $sensitivity_controls = get_attribute_html(self::$occAttrs, $args, $ctrlOptions, 'sensitivity', $attrSpecificOptions);
         return data_entry_helper::sensitivity_input(array('additionalControls' => $sensitivity_controls));
     } else {
         return "[sensitivity] control cannot be included in form when in grid entry mode, since photos are automatically included in the grid.";
     }
 }
 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;
 }
 protected static function get_control_occurrenceattributes($auth, $args, $tabAlias, $options)
 {
     $attrArgs = array('valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']);
     if (self::$treeOccurrenceRecord) {
         // if we have a single occurrence Id to load, use it to get attribute values
         $attrArgs['id'] = self::$treeOccurrenceRecord[0]['id'];
         $attrArgs['fieldprefix'] = 'sc:tree:' . $attrArgs['id'] . ':occAttr';
     } else {
         $attrArgs['fieldprefix'] = 'sc:tree::occAttr';
     }
     if (!empty($options['attributeIds'])) {
         $attrArgs['extraParams'] += array('query' => json_encode(array('in' => array('id' => $options['attributeIds']))));
     }
     $occAttrs = data_entry_helper::getAttributes($attrArgs, false);
     $ctrlOptions = array('extraParams' => $auth['read']);
     $attrSpecificOptions = array();
     self::parseForAttrSpecificOptions($options, $ctrlOptions, $attrSpecificOptions);
     return get_attribute_html($occAttrs, $args, $ctrlOptions, '', $attrSpecificOptions);
 }
Example #7
0
 /**
  * Get the block of custom attributes at the species (occurrence) level
  */
 private static function get_control_speciesattributes($auth, $args, $tabalias, $options)
 {
     if (!call_user_func(array(get_called_class(), 'getGridMode'), $args)) {
         // Add any dynamically generated controls
         $attrArgs = array('valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => 'occAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']);
         if (count(self::$occurrenceIds) == 1) {
             // if we have a single occurrence Id to load, use it to get attribute values
             $attrArgs['id'] = self::$occurrenceIds[0];
         }
         $attributes = data_entry_helper::getAttributes($attrArgs, false);
         $defAttrOptions = array('extraParams' => $auth['read']);
         $r = get_attribute_html($attributes, $args, $defAttrOptions);
         if ($args['occurrence_comment']) {
             $r .= data_entry_helper::textarea(array('fieldname' => 'occurrence:comment', 'label' => lang::get('Record Comment')));
         }
         if ($args['occurrence_confidential']) {
             $r .= data_entry_helper::checkbox(array('fieldname' => 'occurrence:confidential', 'label' => lang::get('Record Confidental')));
         }
         if ($args['occurrence_images']) {
             $opts = array('table' => 'occurrence_image', 'label' => lang::get('Upload your photos'));
             if ($args['interface'] !== 'one_page') {
                 $opts['tabDiv'] = $tabalias;
             }
             $opts['resizeWidth'] = isset($options['resizeWidth']) ? $options['resizeWidth'] : 1600;
             $opts['resizeHeight'] = isset($options['resizeHeight']) ? $options['resizeHeight'] : 1600;
             $opts['caption'] = lang::get('Photos');
             $r .= data_entry_helper::file_box($opts);
         }
         return $r;
     } else {
         // in grid mode the attributes are embedded in the grid.
         return '';
     }
 }
 /**
  * Get the sensitivity control.
  * @param $auth
  * @param $args
  * @param $tabAlias
  * @param $options
  * @return string
  */
 protected static function get_control_sensitivity($auth, $args, $tabAlias, $options)
 {
     $ctrlOptions = array('extraParams' => $auth['read']);
     $attrSpecificOptions = array();
     self::parseForAttrSpecificOptions($options, $ctrlOptions, $attrSpecificOptions);
     $sensitivity_controls = get_attribute_html(self::$occAttrs, $args, $ctrlOptions, 'sensitivity', $attrSpecificOptions);
     return data_entry_helper::sensitivity_input(array('additionalControls' => $sensitivity_controls));
 }
 public static function get_sample_form($args, $node, $response)
 {
     global $user;
     iform_load_helpers(array('map_helper'));
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     // either looking at existing, creating a new one, or an error occurred: no successful posts...
     // first check some conditions are met
     $sampleMethods = helper_base::get_termlist_terms($auth, 'indicia:sample_methods', array('Timed Count'));
     if (count($sampleMethods) == 0) {
         return 'The sample method "Timed Count" must be defined in the termlist in order to use this form.';
     }
     $sampleId = isset($_GET['sample_id']) ? $_GET['sample_id'] : null;
     if ($sampleId && !isset(data_entry_helper::$validation_errors)) {
         data_entry_helper::load_existing_record($auth['read'], 'sample', $sampleId);
     }
     $isAdmin = isset($args['manager_permission']) && user_access($args['manager_permission']);
     // The following is butchered from mnhnl.
     data_entry_helper::$javascript .= "\r\n// the default edit layer is used for this sample\r\nvar editLayer = null;\r\n\r\nconvertGeom = function(geom, projection){\r\n  if (projection.projcode!='EPSG:900913' && projection.projcode!='EPSG:3857') {\r\n    var cloned = geom.clone();\r\n    return cloned.transform(new OpenLayers.Projection('EPSG:900913'), projection);\r\n  }\r\n  return geom;\r\n}\r\nreverseConvertGeom = function(geom, projection){\r\n  if (projection.projcode!='EPSG:900913' && projection.projcode!='EPSG:3857') {\r\n    var cloned = geom.clone();\r\n    return cloned.transform(projection, new OpenLayers.Projection('EPSG:900913'));\r\n  }\r\n  return geom;\r\n}\r\n\r\ngetwkt = function(geometry, incFront, incBrackets){\r\n  var retVal;\r\n  \t  retVal = '';\r\n  \t  switch(geometry.CLASS_NAME){\r\n  \t  case \"OpenLayers.Geometry.Point\":\r\n  \t  return((incFront!=false ? 'POINT' : '')+(incBrackets!=false ? '(' : '')+geometry.x+' '+geometry.y+(incBrackets!=false ? ')' : ''));\r\n  \t  break;\r\n  \t  case \"OpenLayers.Geometry.MultiPoint\":\r\n      retVal = 'MULTIPOINT(';\r\n      for(var i=0; i< geometry.components.length; i++)\r\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[i], false, true);\r\n      retVal += ')';\r\n      break;\r\n    case \"OpenLayers.Geometry.LineString\":\r\n      retVal = (incFront!=false ? 'LINESTRING' : '')+'(';\r\n      for(var i=0; i< geometry.components.length; i++)\r\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[i], false, false);\r\n      retVal += ')';\r\n      break;\r\n    case \"OpenLayers.Geometry.MultiLineString\":\r\n      retVal = 'MULTILINESTRING(';\r\n      for(var i=0; i< geometry.components.length; i++)\r\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[i], false, true);\r\n      retVal += ')';\r\n      break;\r\n    case \"OpenLayers.Geometry.Polygon\": // only do outer ring\r\n      retVal = (incFront!=false ? 'POLYGON' : '')+'((';\r\n      for(var i=0; i< geometry.components[0].components.length; i++)\r\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[0].components[i], false, false);\r\n      retVal += '))';\r\n      break;\r\n    case \"OpenLayers.Geometry.MultiPolygon\":\r\n      retVal = 'MULTIPOLYGON(';\r\n      for(var i=0; i< geometry.components.length; i++)\r\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[i], false, true);\r\n      retVal += ')';\r\n      break;\r\n    case \"OpenLayers.Geometry.Collection\":\r\n      retVal = 'GEOMETRYCOLLECTION(';\r\n      for(var i=0; i< geometry.components.length; i++)\r\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[i], true, true);\r\n      retVal += ')';\r\n      break;\r\n  }\r\n  return retVal;\r\n}\r\nsetSref = function(geometry){\r\n  var centre = getCentroid(geometry);\r\n  centre = reverseConvertGeom(centre, editLayer.map.projection); // convert to indicia internal projection\r\n  var system = \$('#imp-sref-system').val();\t\t\t\t\r\n  jQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/spatial/wkt_to_sref?wkt=POINT(' + centre.x + '  ' + centre.y + ')&system=' + system + '&precision=" . (isset($args['precision']) && $args['precision'] != '' ? $args['precision'] : '8') . "&callback=?',\r\n      function(data){\r\n        if(typeof data.error != 'undefined')\r\n          alert(data.error);\r\n        else\r\n          \$('#imp-sref').val(data.sref);\r\n       });\r\n};\r\nhook_setGeomFields = [];\r\nsetGeomFields = function(){\r\n  var geomstack = [];\r\n  var completeGeom;\r\n  for(var i=0; i<editLayer.features.length; i++)\r\n    if(editLayer.features[i].attributes.highlighted == true)\r\n      geomstack.push(editLayer.features[i].geometry.clone()); // needs to be a clone as we don't want to transform the original geoms.\r\n  if(geomstack.length == 0){\r\n    jQuery('#imp-geom').val('');\r\n    jQuery('#imp-sref').val('');\r\n    return;\r\n  } else if (geomstack.length == 1)\r\n    completeGeom = geomstack[0];\r\n  else\r\n    completeGeom = new OpenLayers.Geometry.Collection(geomstack);\r\n  // the geometry is in the map projection: if this doesn't match indicia's internal one, then must convert.\r\n  if (editLayer.map.projection.projcode!='EPSG:900913' && editLayer.map.projection.projcode!='EPSG:3857') \r\n    completeGeom.transform(editLayer.map.projection,  new OpenLayers.Projection('EPSG:900913'));\r\n  jQuery('#imp-geom').val(getwkt(completeGeom, true, true));\r\n  setSref(getCentroid(completeGeom));\r\n  if(hook_setGeomFields.length > 0)\r\n    for(i=0; i< hook_setGeomFields.length; i++)\r\n  \t  (hook_setGeomFields[i])(completeGeom);\r\n}\r\nremoveDrawnGeom = function(){\r\n  var highlighted=gethighlight();\r\n  if(highlighted.length > 0) {\r\n    unhighlightAll();\r\n  }\r\n  for(var i=editLayer.features.length-1; i>=0; i--)\r\n    editLayer.destroyFeatures([editLayer.features[i]]);\r\n}\r\nreplaceGeom = function(feature, layer, modControl, geom, highlight, setFields){\r\n  if(modControl.feature)\r\n    modControl.unselectFeature(modControl.feature);\r\n  var newfeature = new OpenLayers.Feature.Vector(geom, {});\r\n  newfeature.attributes = feature.attributes;\r\n  layer.destroyFeatures([feature]);\r\n  layer.addFeatures([newfeature]);\r\n  modControl.selectFeature(newfeature);\r\n  selectFeature.highlight(newfeature);\r\n  newfeature.attributes.highlighted=true;\r\n  if(setFields) setGeomFields();\r\n}\r\naddAndSelectNewGeom = function(layer, modControl, geom, highlight){\r\n  var feature = new OpenLayers.Feature.Vector(geom, {highlighted: false, ours: true});\r\n  layer.addFeatures([feature]);\r\n  modControl.selectFeature(feature);\r\n  feature.attributes.highlighted=true;\r\n  selectFeature.highlight(feature);\r\n  setGeomFields();\r\n  return feature;\r\n}\r\naddToExistingFeatureSet = function(existingFeatures, layer, modControl, geom, highlight){\r\n  var feature = new OpenLayers.Feature.Vector(geom, {});\r\n  feature.attributes = existingFeatures[0].attributes;\r\n  layer.addFeatures([feature]);\r\n  modControl.selectFeature(feature);\r\n  selectFeature.highlight(feature);\r\n  feature.attributes.highlighted=true;\r\n  setGeomFields();\r\n}\r\nunhighlightAll = function(){\r\n  if(modAreaFeature.feature) modAreaFeature.unselectFeature(modAreaFeature.feature);\r\n  var highlighted = gethighlight();\r\n  for(var i=0; i<highlighted.length; i++) {\r\n    highlighted[i].attributes.highlighted = false;\r\n    selectFeature.unhighlight(highlighted[i]);\r\n  }\r\n}\r\ngethighlight = function(){\r\n  var features=[];\r\n  for(var i=0; i<editLayer.features.length; i++){\r\n    if(editLayer.features[i].attributes.highlighted==true){\r\n      features.push(editLayer.features[i]);\r\n    }}\r\n  return features;\r\n}\r\n\r\naddDrawnPolygonToSelection = function(geometry) {\r\n  var points = geometry.components[0].getVertices();\r\n  if(points.length < 3){\r\n    alert(\"" . lang::get('LANG_TooFewPoints') . "\");\r\n    return false;\r\n  }\r\n  var highlightedFeatures = gethighlight();\r\n  if(highlightedFeatures.length == 0){\r\n    // No currently selected feature. Create a new one.\r\n    feature = addAndSelectNewGeom(editLayer, modAreaFeature, geometry, true);\r\n  \treturn true;\r\n  }\r\n  var selectedFeature = false;\r\n  for(var i=0; i<highlightedFeatures.length; i++){\r\n    if(highlightedFeatures[i].geometry.CLASS_NAME == \"OpenLayers.Geometry.Polygon\" ||\r\n        highlightedFeatures[i].geometry.CLASS_NAME == \"OpenLayers.Geometry.MultiPolygon\") {\r\n      selectedFeature = highlightedFeatures[i];\r\n  \t        \t\tbreak;\r\n    }}\r\n  // a site is already selected so the Drawn/Specified state stays unaltered\r\n  if(!selectedFeature) {\r\n      addToExistingFeatureSet(highlightedFeatures, editLayer, modAreaFeature, geometry, true);\r\n      return true;\r\n  }\r\n  if(selectedFeature.geometry.CLASS_NAME == \"OpenLayers.Geometry.MultiPolygon\") {\r\n    if(modAreaFeature.feature)\r\n\t    modAreaFeature.unselectFeature(selectedFeature);\r\n    selectedFeature.geometry.addComponents([geometry]);\r\n    modAreaFeature.selectFeature(selectedFeature);\r\n    selectFeature.highlight(selectedFeature);\r\n    selectedFeature.attributes.highlighted = true;\r\n    setGeomFields();\r\n  } else { // is OpenLayers.Geometry.Polygon\r\n    var CompoundGeom = new OpenLayers.Geometry.MultiPolygon([selectedFeature.geometry, geometry]);\r\n    replaceGeom(selectedFeature, editLayer, modAreaFeature, CompoundGeom, true, true);\r\n  }\r\n  return true;\r\n}\r\nonFeatureModified = function(evt) {\r\n  var feature = evt.feature;\r\n  switch(feature.geometry.CLASS_NAME){\r\n    case \"OpenLayers.Geometry.Polygon\": // only do outer ring\r\n      points = feature.geometry.components[0].getVertices();\r\n      if(points.length < 3){\r\n        alert(\"" . lang::get('There are now too few vertices to make a polygon: it will now be completely removed.') . "\");\r\n        modAreaFeature.unselectFeature(feature);\r\n        editLayer.destroyFeatures([feature]);\r\n      }\r\n      break;\r\n    case \"OpenLayers.Geometry.MultiPolygon\":\r\n  \t  for(i=feature.geometry.components.length-1; i>=0; i--) {\r\n        points = feature.geometry.components[i].components[0].getVertices();\r\n        if(points.length < 3){\r\n          alert(\"" . lang::get('There are now too few vertices to make a polygon: it will now be completely removed.') . "\");\r\n  \t      var selectedFeature = modAreaFeature.feature;\r\n          modAreaFeature.unselectFeature(selectedFeature);\r\n          selectFeature.unhighlight(selectedFeature);\r\n          editLayer.removeFeatures([selectedFeature]);\r\n          selectedFeature.geometry.removeComponents([feature.geometry.components[i]]);\r\n  \t      editLayer.addFeatures([selectedFeature]);\r\n          modAreaFeature.selectFeature(selectedFeature);\r\n          selectFeature.highlight(selectedFeature);\r\n          selectedFeature.attributes.highlighted = true;\r\n        }\r\n      }\r\n      if(feature.geometry.components.length == 0){\r\n        modAreaFeature.unselectFeature(feature);\r\n        editLayer.destroyFeatures([feature]);\r\n      }\r\n      break;\r\n  }\r\n  setGeomFields();\r\n}\r\n/********************************/\r\n/* Define Map Control callbacks */\r\n/********************************/\r\nUndoSketchPoint = function(layer){\r\n  for(var i = editControl.controls.length-1; i>=0; i--)\r\n    if(editControl.controls[i].CLASS_NAME == \"OpenLayers.Control.DrawFeature\" && editControl.controls[i].active)\r\n      editControl.controls[i].undo();\r\n};\r\nRemoveNewSite = function(){\r\n  highlighted = gethighlight();\r\n  removeDrawnGeom(highlighted[0].attributes.SiteNum);\r\n  setGeomFields();\r\n};\r\nZoomToFeature = function(feature){\r\n  var div = jQuery('#map')[0];\r\n  var bounds=feature.geometry.bounds.clone();\r\n  // extend the boundary to include a buffer, so the map does not zoom too tight.\r\n  var dy = (bounds.top-bounds.bottom) * div.settings.maxZoomBuffer;\r\n  var dx = (bounds.right-bounds.left) * div.settings.maxZoomBuffer;\r\n  bounds.top = bounds.top + dy;\r\n  bounds.bottom = bounds.bottom - dy;\r\n  bounds.right = bounds.right + dx;\r\n  bounds.left = bounds.left - dx;\r\n  if (div.map.getZoomForExtent(bounds) > div.settings.maxZoom) {\r\n    // if showing something small, don't zoom in too far\r\n    div.map.setCenter(bounds.getCenterLonLat(), div.settings.maxZoom);\r\n  } else {\r\n    // Set the default view to show something triple the size of the grid square\r\n    // Assume this is within the map extent\r\n    div.map.zoomToExtent(bounds);\r\n  }\r\n};\r\n/***********************************/\r\n/* Define Controls for use on Map. */\r\n/***********************************/\r\npolygonDrawActivate = function(){\r\n  selectFeature.deactivate();\r\n  modAreaFeature.activate();\r\n  highlighted = gethighlight();\r\n  if(highlighted.length == 0)\r\n    return true;\r\n  for(var i=0; i<editLayer.features.length; i++)\r\n      if(editLayer.features[i].attributes.highlighted == true)\r\n        modAreaFeature.selectFeature(editLayer.features[i]);\r\n  return true;\r\n};\r\n\t\t         \t\t \t\t\r\nmodAreaFeature = null;\r\nselectFeature = null;\r\npolygonDraw = null;\r\neditControl = null;\r\n\r\nmapInitialisationHooks.push(function(mapdiv) {\r\n\t\$('#imp-sref').unbind('change');\r\n\teditLayer=mapdiv.map.editLayer;\r\n    var nav=new OpenLayers.Control.Navigation({displayClass: \"olControlNavigation\", \"title\":mapdiv.settings.hintNavigation+((!mapdiv.settings.scroll_wheel_zoom || mapdiv.settings.scroll_wheel_zoom===\"false\")?'': mapdiv.settings.hintScrollWheel)});\t\r\n\teditControl = new OpenLayers.Control.Panel({allowDepress: false, 'displayClass':'olControlEditingToolbar'});\r\n\tmapdiv.map.addControl(editControl);\r\n" . ($isAdmin || $sampleId == null ? "  \tmodAreaFeature = new OpenLayers.Control.ModifyFeature(editLayer,{standalone: true});\r\n\tselectFeature = new OpenLayers.Control.SelectFeature([editLayer],{standalone: true});\r\n\tpolygonDraw = new OpenLayers.Control.DrawFeature(editLayer,OpenLayers.Handler.Polygon,{'displayClass':'olControlDrawFeaturePolygon', drawFeature: addDrawnPolygonToSelection, title: '" . lang::get('Select this tool to draw a polygon, clicking on the map to place the vertices of the shape, and double clicking on the final vertex to finish. You may drag and drop vertices (circles) to move them, and draw more than one polygon, i.e. input a discontinuous site.') . "'});\r\n\tpolygonDraw.events.on({'activate': polygonDrawActivate});\r\n\teditControl.addControls([polygonDraw\r\n\t\t\t\t         ,new OpenLayers.Control.Button({displayClass: \"olControlClearLayer\", trigger: RemoveNewSite, title: '" . lang::get('Press this button to completely remove the currently drawn site.') . "'})\r\n    \t\t\t\t\t ,nav\t\r\n\t\t\t\t         ,new OpenLayers.Control.Button({displayClass: \"olControlUndo\", trigger: UndoSketchPoint, title: '" . lang::get('If you have not completed a polygon, press this button to clear the last vertex. If you have completed a polygon but wish to remove a vertex, place the mouse over the vertex and press the Delete button: this only works for the corner vertices, not the dummy ones half way down each side.') . "'})\r\n    ]);\r\n\tmapdiv.map.addControl(modAreaFeature);\r\n\tmodAreaFeature.deactivate();\r\n\tfor(var i=0; i<mapdiv.map.controls.length; i++)\r\n      mapdiv.map.controls[i].deactivate();\r\n\teditControl.activate();\r\n\tnav.activate();\r\n\t// any existing features come from the existing sites geometry: convert to ours\r\n    // will have been zoomed as well.\r\n\tfor(var i=0; i<editLayer.features.length; i++) {\r\n\t  editLayer.features[i].attributes.highlighted = true;\r\n\t  editLayer.features[i].attributes.type = 'ours';\r\n\t  editLayer.features[i].attributes.ours = true;\r\n\t  selectFeature.highlight(editLayer.features[i]);\r\n\t}\t\t\t\t         \t\t\r\n\teditLayer.events.on({\r\n\t\t'featuremodified': onFeatureModified\r\n\t});\r\n" : "\teditControl.addControls([nav]);\r\n\tfor(var i=0; i<mapdiv.map.controls.length; i++)\r\n      mapdiv.map.controls[i].deactivate();\r\n\teditControl.activate();\r\n\tnav.activate();\r\n") . "\tmapdiv.map.events.triggerEvent('zoomend');\r\n});\r\n";
     $r = '<form method="post" id="sample">' . $auth['write'];
     // we pass through the read auth. This makes it possible for the get_submission method to authorise against the warehouse
     // without an additional (expensive) warehouse call, so it can get location details.
     $r .= '<input type="hidden" name="read_nonce" value="' . $auth['read']['nonce'] . '"/>';
     $r .= '<input type="hidden" name="read_auth_token" value="' . $auth['read']['auth_token'] . '"/>';
     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'] . '"/>';
     }
     // pass a param that sets the next page to display
     $r .= "<input type=\"hidden\" name=\"website_id\" value=\"" . $args['website_id'] . "\"/>\r\n<input type=\"hidden\" name=\"sample:survey_id\" value=\"" . $args['survey_id'] . "\"/>\r\n<input type=\"hidden\" name=\"page\" value=\"site\"/>";
     $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, isset(data_entry_helper::$entity_to_load['sample:id']), $auth['read']) . data_entry_helper::text_input(array('label' => lang::get('Site Name'), 'fieldname' => 'sample:location_name', 'validation' => array('required')));
     $help = lang::get('The Year field is read-only, and is calculated automatically from the date(s) of the Counts.');
     $r .= '<p class="ui-state-highlight page-notice ui-corner-all">' . $help . '</p>';
     if ($sampleId == null) {
         if (isset($_GET['date'])) {
             data_entry_helper::$entity_to_load['C1:sample:date'] = $_GET['date'];
         }
         $r .= data_entry_helper::date_picker(array('label' => lang::get('Date of first count'), 'fieldname' => 'C1:sample:date', 'validation' => array('required', 'date')));
         data_entry_helper::$javascript .= "jQuery('#C1\\\\:sample\\\\:date').change(function(){\r\n  jQuery('#sample\\\\:date').val(jQuery(this).val() == '' ? '' : jQuery(this).datepicker('getDate').getFullYear());\r\n});\r\nif(jQuery('#C1\\\\:sample\\\\:date').val() != '') jQuery('#sample\\\\:date').val(jQuery('#C1\\\\:sample\\\\:date').datepicker('getDate').getFullYear());\n";
     }
     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) - only interested in Year.
         $d = new DateTime(data_entry_helper::$entity_to_load['sample:date']);
         data_entry_helper::$entity_to_load['sample:date'] = $d->format('Y');
     }
     unset(data_entry_helper::$default_validation_rules['sample:date']);
     $r .= data_entry_helper::text_input(array('label' => lang::get('Year'), 'fieldname' => 'sample:date', 'readonly' => ' readonly="readonly" '));
     // 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);
     foreach ($blockOptions as $attr => $block) {
         foreach ($block as $item => $value) {
             switch ($item) {
                 case 'suffix':
                     data_entry_helper::$javascript .= "\$('#" . str_replace(':', '\\\\:', $attr) . "').after(' <label style=\"width:auto\">" . $value . "</label>');\n";
                     break;
                 case 'setArea':
                     $parts = explode(',', $value);
                     // 0=factor,1=number decimal places
                     data_entry_helper::$javascript .= "\$('#" . str_replace(':', '\\\\:', $attr) . "').attr('readonly','readonly');\nhook_setGeomFields.push(function(geom){\n\$('#" . str_replace(':', '\\\\:', $attr) . "').val(\n(geom.getArea()/" . $parts[0] . ").toFixed(" . $parts[1] . "));\n});\n";
                     break;
             }
         }
     }
     $r .= '<input type="hidden" name="sample:sample_method_id" value="' . $sampleMethods[0]['id'] . '" />';
     $help = lang::get('Now draw the flight area for the timed count on the map below. The Grid Reference is filled in automatically when the site is drawn.');
     $r .= '<p class="ui-state-highlight page-notice ui-corner-all">' . $help . '</p>';
     $options = iform_map_get_map_options($args, $auth['read']);
     $options['clickForSpatialRef'] = false;
     $olOptions = iform_map_get_ol_options($args);
     $systems = array();
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get($system);
     }
     $r .= "<label for=\"imp-sref\">" . lang::get('Grid Reference') . ":</label> <input type=\"text\" id=\"imp-sref\" name=\"sample:entered_sref\" value=\"" . data_entry_helper::$entity_to_load['sample:entered_sref'] . "\" readonly=\"readonly\" class=\"required\" />";
     $r .= "<input type=\"hidden\" id=\"imp-geom\" name=\"sample:geom\" value=\"" . data_entry_helper::$entity_to_load['sample:geom'] . "\" />";
     if (count($systems) == 1) {
         // Hidden field for the system
         $keys = array_keys($systems);
         $r .= "<input type=\"hidden\" id=\"imp-sref-system\" name=\"sample:entered_sref_system\" value=\"" . $keys[0] . "\" />\n";
     } else {
         $r .= self::sref_system_select(array('fieldname' => 'sample:entered_sref_system'));
     }
     $r .= '<br />' . data_entry_helper::georeference_lookup(iform_map_get_georef_options($args, $auth['read']));
     $r .= data_entry_helper::map_panel($options, $olOptions);
     $r .= data_entry_helper::textarea(array('label' => 'Comment', 'fieldname' => 'sample:comment', 'class' => 'wide'));
     $r .= '<input type="submit" value="' . lang::get('Next') . '" />';
     $r .= '<a href="' . $args['summary_page'] . '"><button type="button" class="ui-state-default ui-corner-all" />' . lang::get('Cancel') . '</button></a>';
     // allow deletes if sample id is present: i.e. existing sample.
     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>';
         // note we only require bare minimum in order to flag a sample as deleted.
         $r .= '</form><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"/>';
         data_entry_helper::$javascript .= "jQuery('#delete-button').click(function(){\r\n  if(confirm(\"" . lang::get('Are you sure you want to delete this timed count?') . "\"))\r\n    jQuery('#delete-form').submit();\r\n});\n";
     }
     $r .= '</form>';
     data_entry_helper::enable_validation('sample');
     return $r;
 }
Example #10
0
 public static function get_sample_form($args, $node, $response)
 {
     global $user;
     iform_load_helpers(array('map_helper'));
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     // either looking at existing, creating a new one, or an error occurred: no successful posts...
     // first check some conditions are met
     $sampleMethods = helper_base::get_termlist_terms($auth, 'indicia:sample_methods', array('Timed Count'));
     if (count($sampleMethods) == 0) {
         return 'The sample method "Timed Count" must be defined in the termlist in order to use this form.';
     }
     $sampleId = isset($_GET['sample_id']) ? $_GET['sample_id'] : null;
     if ($sampleId && !isset(data_entry_helper::$validation_errors)) {
         data_entry_helper::load_existing_record($auth['read'], 'sample', $sampleId);
     }
     $r = '<form method="post" id="sample">' . $auth['write'];
     // we pass through the read auth. This makes it possible for the get_submission method to authorise against the warehouse
     // without an additional (expensive) warehouse call, so it can get location details.
     $r .= '<input type="hidden" name="read_nonce" value="' . $auth['read']['nonce'] . '"/>';
     $r .= '<input type="hidden" name="read_auth_token" value="' . $auth['read']['auth_token'] . '"/>';
     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'] . '"/>';
     }
     // pass a param that sets the next page to display
     $r .= "<input type=\"hidden\" name=\"website_id\" value=\"" . $args['website_id'] . "\"/>\n<input type=\"hidden\" name=\"sample:survey_id\" value=\"" . $args['survey_id'] . "\"/>\n<input type=\"hidden\" name=\"page\" value=\"site\"/>";
     $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']) . data_entry_helper::text_input(array('label' => lang::get('Site Name'), 'fieldname' => 'sample:location_name', 'validation' => array('required')));
     $help = lang::get('The Year field is read-only, and is calculated automatically from the date(s) of the Counts.');
     $r .= '<p class="ui-state-highlight page-notice ui-corner-all">' . $help . '</p>';
     if ($sampleId == null) {
         if (isset($_GET['date'])) {
             data_entry_helper::$entity_to_load['C1:sample:date'] = $_GET['date'];
         }
         $r .= data_entry_helper::date_picker(array('label' => lang::get('Date of first count'), 'fieldname' => 'C1:sample:date', 'validation' => array('required', 'date')));
         data_entry_helper::$javascript .= "jQuery('#C1\\\\:sample\\\\:date').change(function(){\n  jQuery('#sample\\\\:date').val(jQuery(this).val() == '' ? '' : jQuery(this).datepicker('getDate').getFullYear());\n});\nif(jQuery('#C1\\\\:sample\\\\:date').val() != '') jQuery('#sample\\\\:date').val(jQuery('#C1\\\\:sample\\\\:date').datepicker('getDate').getFullYear());\n";
     }
     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) - only interested in Year.
         $d = new DateTime(data_entry_helper::$entity_to_load['sample:date']);
         data_entry_helper::$entity_to_load['sample:date'] = $d->format('Y');
     }
     unset(data_entry_helper::$default_validation_rules['sample:date']);
     $r .= data_entry_helper::text_input(array('label' => lang::get('Year'), 'fieldname' => 'sample:date', 'readonly' => ' readonly="readonly" '));
     // 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'] . '" />';
     $help = lang::get('Now draw the flight area for the timed count on the map below. The Grid Reference is filled in automatically when the site is drawn.');
     $r .= '<p class="ui-state-highlight page-notice ui-corner-all">' . $help . '</p>';
     $options = iform_map_get_map_options($args, $auth['read']);
     $options['allowPolygonRecording'] = true;
     $options['clickForSpatialRef'] = false;
     if (isset($args['precision']) && $args['precision'] != '') {
         $options['clickedSrefPrecisionMin'] = $args['precision'];
         $options['clickedSrefPrecisionMax'] = $args['precision'];
     }
     $olOptions = iform_map_get_ol_options($args);
     if (!in_array('drawPolygon', $options['standardControls'])) {
         $options['standardControls'][] = 'drawPolygon';
     }
     if (!in_array('modifyFeature', $options['standardControls'])) {
         $options['standardControls'][] = 'modifyFeature';
     }
     $systems = array();
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get($system);
     }
     $r .= "<label for=\"imp-sref\">" . lang::get('Grid Reference') . ":</label> <input type=\"text\" id=\"imp-sref\" name=\"sample:entered_sref\" value=\"" . data_entry_helper::$entity_to_load['sample:entered_sref'] . "\" readonly=\"readonly\" class=\"required\" />";
     $r .= "<input type=\"hidden\" id=\"imp-geom\" name=\"sample:geom\" value=\"" . data_entry_helper::$entity_to_load['sample:geom'] . "\" />";
     if (count($systems) == 1) {
         // Hidden field for the system
         $keys = array_keys($systems);
         $r .= "<input type=\"hidden\" id=\"imp-sref-system\" name=\"sample:entered_sref_system\" value=\"" . $keys[0] . "\" />\n";
     } else {
         $r .= self::sref_system_select(array('fieldname' => 'sample:entered_sref_system'));
     }
     $r .= '<br />' . data_entry_helper::georeference_lookup(iform_map_get_georef_options($args, $auth['read']));
     $r .= data_entry_helper::map_panel($options, $olOptions);
     // switch off the sref functionality.
     data_entry_helper::$javascript .= "mapInitialisationHooks.push(function(div){\n  \$('#imp-sref').unbind('change');\n  // Programatic activation does not rippleout, so deactivate Nav first, which is actibve by default.\n  for(var i=0; i<div.map.controls.length; i++)\n    if(div.map.controls[i].CLASS_NAME == \"OpenLayers.Control.Navigation\")\n      div.map.controls[i].deactivate();\n  activeCtrl = false;\n  for(var i=0; i<div.map.controls.length; i++){\n    if(div.map.controls[i].CLASS_NAME == \"" . (isset(data_entry_helper::$entity_to_load['sample:id']) ? "OpenLayers.Control.ModifyFeature" : "OpenLayers.Control.DrawFeature") . "\"){\n      div.map.controls[i].activate();\n      activeCtrl = div.map.controls[i];\n      break;\n    }}\n" . (isset(data_entry_helper::$entity_to_load['sample:id']) ? "  if(activeCtrl && div.map.editLayer.features.length>0) activeCtrl.selectFeature(div.map.editLayer.features[0]);\n" : "") . "});\n";
     $r .= data_entry_helper::textarea(array('label' => 'Comment', 'fieldname' => 'sample:comment', 'class' => 'wide'));
     $r .= '<input type="submit" value="' . lang::get('Next') . '" />';
     $r .= '<a href="' . $args['summary_page'] . '"><button type="button" class="ui-state-default ui-corner-all" />' . lang::get('Cancel') . '</button></a>';
     // allow deletes if sample id is present: i.e. existing sample.
     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>';
         // note we only require bare minimum in order to flag a sample as deleted.
         $r .= '</form><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"/>';
         data_entry_helper::$javascript .= "jQuery('#delete-button').click(function(){\n  if(confirm(\"" . lang::get('Are you sure you want to delete this timed count?') . "\"))\n    jQuery('#delete-form').submit();\n});\n";
     }
     $r .= '</form>';
     data_entry_helper::enable_validation('sample');
     return $r;
 }
 public static function get_sample_form($args, $node, $response)
 {
     global $user;
     if (!module_exists('iform_ajaxproxy')) {
         return 'This form must be used in Drupal with the Indicia AJAX Proxy module enabled.';
     }
     iform_load_helpers(array('map_helper'));
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $sampleId = isset($_GET['sample_id']) ? $_GET['sample_id'] : null;
     if ($sampleId) {
         data_entry_helper::load_existing_record($auth['read'], 'sample', $sampleId);
         $locationId = data_entry_helper::$entity_to_load['sample:location_id'];
     } else {
         $locationId = isset($_GET['site']) ? $_GET['site'] : null;
         // location ID also might be in the $_POST data after a validation save of a new record
         if (!$locationId && isset($_POST['sample:location_id'])) {
             $locationId = $_POST['sample:location_id'];
         }
     }
     $url = explode('?', $args['my_walks_page'], 2);
     $params = NULL;
     $fragment = NULL;
     // fragment is always at the end.
     if (count($url) > 1) {
         $params = explode('#', $url[1], 2);
         if (count($params) > 1) {
             $fragment = $params[1];
         }
         $params = $params[0];
     } else {
         $url = explode('#', $url[0], 2);
         if (count($url) > 1) {
             $fragment = $url[1];
         }
     }
     $args['my_walks_page'] = url($url[0], array('query' => $params, 'fragment' => $fragment, 'absolute' => TRUE));
     $r = '<form method="post" id="sample">';
     $r .= $auth['write'];
     // we pass through the read auth. This makes it possible for the get_submission method to authorise against the warehouse
     // without an additional (expensive) warehouse call, so it can get location details.
     $r .= '<input type="hidden" name="page" value="mainSample"/>';
     $r .= '<input type="hidden" name="read_nonce" value="' . $auth['read']['nonce'] . '"/>';
     $r .= '<input type="hidden" name="read_auth_token" value="' . $auth['read']['auth_token'] . '"/>';
     $r .= '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>';
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         $r .= '<input type="hidden" name="sample:id" value="' . data_entry_helper::$entity_to_load['sample:id'] . '"/>';
     }
     $r .= '<input type="hidden" name="sample:survey_id" value="' . $args['survey_id'] . '"/>';
     if (isset($args['include_map_samples_form']) && $args['include_map_samples_form']) {
         $r .= '<div id="cols" class="ui-helper-clearfix"><div class="left" style="width: ' . (98 - (isset($args['percent_width']) ? $args['percent_width'] : 50)) . '%">';
     }
     if ($locationId) {
         $site = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('view' => 'detail', 'id' => $locationId, 'deleted' => 'f')));
         $site = $site[0];
         $r .= '<input type="hidden" name="sample:location_id" value="' . $locationId . '"/>';
         $r .= '<input type="hidden" name="sample:entered_sref" value="' . $site['centroid_sref'] . '"/>';
         $r .= '<input type="hidden" name="sample:entered_sref_system" value="' . $site['centroid_sref_system'] . '"/>';
     }
     if ($locationId && (isset(data_entry_helper::$entity_to_load['sample:id']) || isset($_GET['site']))) {
         // for reload of existing or the the site is specified in the URL, don't let the user switch the transect as that would mess everything up.
         $r .= '<label>' . lang::get('Transect') . ':</label> <span class="value-label">' . $site['name'] . '</span><br/>';
     } else {
         // Output only the locations for this website and transect type. Note we load both transects and sections, just so that
         // we always use the same warehouse call and therefore it uses the cache.
         $typeTerms = array(empty($args['transect_type_term']) ? 'Transect' : $args['transect_type_term'], empty($args['section_type_term']) ? 'Section' : $args['section_type_term']);
         $locationTypes = helper_base::get_termlist_terms($auth, 'indicia:location_types', $typeTerms);
         $siteParams = $auth['read'] + array('website_id' => $args['website_id'], 'location_type_id' => $locationTypes[0]['id']);
         if ((!isset($args['user_locations_filter']) || $args['user_locations_filter']) && (!isset($args['managerPermission']) || !user_access($args['managerPermission']))) {
             $siteParams += array('locattrs' => 'CMS User ID', 'attr_location_cms_user_id' => $user->uid);
         } else {
             $siteParams += array('locattrs' => '');
         }
         $availableSites = data_entry_helper::get_population_data(array('report' => 'library/locations/locations_list', 'extraParams' => $siteParams, 'nocache' => true));
         // convert the report data to an array for the lookup, plus one to pass to the JS so it can keep the hidden sref fields updated
         $sitesLookup = array();
         $sitesJs = array();
         foreach ($availableSites as $site) {
             $sitesLookup[$site['location_id']] = $site['name'];
             $sitesJs[$site['location_id']] = $site;
         }
         // bolt in branch locations. Don't assume that branch list is superset of normal sites list.
         // Only need to do if not a manager - they have already fetched the full list anyway.
         if (isset($args['branch_assignment_permission']) && user_access($args['branch_assignment_permission']) && $siteParams['locattrs'] != '') {
             $siteParams['locattrs'] = 'Branch CMS User ID';
             $siteParams['attr_location_branch_cms_user_id'] = $user->uid;
             unset($siteParams['attr_location_cms_user_id']);
             $availableSites = data_entry_helper::get_population_data(array('report' => 'library/locations/locations_list', 'extraParams' => $siteParams, 'nocache' => true));
             foreach ($availableSites as $site) {
                 $sitesLookup[$site['location_id']] = $site['name'];
                 $sitesJs[$site['location_id']] = $site;
             }
             natcasesort($sitesLookup);
             // merge into original list in alphabetic order.
         }
         data_entry_helper::$javascript .= "indiciaData.sites = " . json_encode($sitesJs) . ";\n";
         $options = array('label' => lang::get('Select Transect'), 'validation' => array('required'), 'blankText' => lang::get('please select'), 'lookupValues' => $sitesLookup);
         if ($locationId) {
             $options['default'] = $locationId;
         }
         $r .= data_entry_helper::location_select($options);
     }
     if (!$locationId) {
         $r .= '<input type="hidden" name="sample:entered_sref" value="" id="entered_sref"/>';
         $r .= '<input type="hidden" name="sample:entered_sref_system" value="" id="entered_sref_system"/>';
         // sref values for the sample will be populated automatically when the submission is built.
     }
     $sampleMethods = helper_base::get_termlist_terms($auth, 'indicia:sample_methods', array('Transect'));
     $attributes = data_entry_helper::getAttributes(array('id' => $sampleId, 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'sample_method_id' => $sampleMethods[0]['id']));
     $r .= get_user_profile_hidden_inputs($attributes, $args, '', $auth['read']);
     if (isset($_GET['date'])) {
         $r .= '<input type="hidden" name="sample:date" value="' . $_GET['date'] . '"/>';
         $r .= '<label>' . lang::get('Date') . ':</label> <span class="value-label">' . $_GET['date'] . '</span><br/>';
     } else {
         if (isset(data_entry_helper::$entity_to_load['sample:date']) && preg_match('/^(\\d{4})/', data_entry_helper::$entity_to_load['sample:date'])) {
             // Date has 4 digit year first (ISO style) - convert date to expected output format
             // @todo The date format should be a global configurable option. It should also be applied to reloading of custom date attributes.
             $d = new DateTime(data_entry_helper::$entity_to_load['sample:date']);
             data_entry_helper::$entity_to_load['sample:date'] = $d->format('d/m/Y');
         }
         $r .= data_entry_helper::date_picker(array('label' => lang::get('Date'), 'fieldname' => 'sample:date'));
     }
     // are there any option overrides for the custom attributes?
     if (isset($args['custom_attribute_options']) && $args['custom_attribute_options']) {
         $blockOptions = get_attr_options_array_with_user_data($args['custom_attribute_options']);
     } else {
         $blockOptions = array();
     }
     $r .= get_attribute_html($attributes, $args, array('extraParams' => $auth['read']), null, $blockOptions);
     $r .= '<input type="hidden" name="sample:sample_method_id" value="' . $sampleMethods[0]['id'] . '" />';
     $r .= '<input type="submit" value="' . lang::get('Next') . '" />';
     $r .= '<a href="' . $args['my_walks_page'] . '" class="button">' . lang::get('Cancel') . '</a>';
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         $r .= '<button id="delete-button" type="button" class="ui-state-default ui-corner-all" />' . lang::get('Delete') . '</button>';
     }
     if (isset($args['include_map_samples_form']) && $args['include_map_samples_form']) {
         $r .= "</div>" . '<div class="right" style="width: ' . (isset($args['percent_width']) ? $args['percent_width'] : 50) . '%">';
         // no place search: [map]
         $options = iform_map_get_map_options($args, $auth['read']);
         if (!empty(data_entry_helper::$entity_to_load['sample:wkt'])) {
             $options['initialFeatureWkt'] = data_entry_helper::$entity_to_load['sample:wkt'];
         }
         $olOptions = iform_map_get_ol_options($args);
         if (!isset($options['standardControls'])) {
             $options['standardControls'] = array('layerSwitcher', 'panZoomBar');
         }
         $r .= map_helper::map_panel($options, $olOptions);
         $r .= "</div>";
         // right
     }
     $r .= '</form>';
     // Recorder Name - assume Easy Login uid
     if (function_exists('module_exists') && module_exists('easy_login')) {
         $userId = hostsite_get_user_field('indicia_user_id');
         // For non easy login test only     $userId = 1;
         foreach ($attributes as $attrID => $attr) {
             if (strcasecmp('Recorder Name', $attr["untranslatedCaption"]) == 0 && !empty($userId)) {
                 // determining which you have used is difficult from a services based autocomplete, esp when the created_by_id is not available on the data.
                 data_entry_helper::add_resource('autocomplete');
                 data_entry_helper::$javascript .= "bindRecorderNameAutocomplete(" . $attrID . ", '" . $userId . "', '" . data_entry_helper::$base_url . "', '" . $args['survey_id'] . "', '" . $auth['read']['auth_token'] . "', '" . $auth['read']['nonce'] . "');\n";
             }
         }
     }
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         // allow deletes if sample id is present.
         data_entry_helper::$javascript .= "jQuery('#delete-button').click(function(){\n  if(confirm(\"" . lang::get('Are you sure you want to delete this walk?') . "\")){\n    jQuery('#delete-form').submit();\n  } // else do nothing.\n});\n";
         // note we only require bare minimum in order to flag a sample as deleted.
         $r .= '<form method="post" id="delete-form" style="display: none;">';
         $r .= $auth['write'];
         $r .= '<input type="hidden" name="page" value="delete"/>';
         $r .= '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>';
         $r .= '<input type="hidden" name="sample:id" value="' . data_entry_helper::$entity_to_load['sample:id'] . '"/>';
         $r .= '<input type="hidden" name="sample:deleted" value="t"/>';
         $r .= '</form>';
     }
     data_entry_helper::enable_validation('sample');
     return $r;
 }
 protected static function initial_habitat_html_setup($existingHabitatSubSamples, $args, $auth, &$NextHabitatNum, $attrOptions, &$existingHabitatSubSamplesIds)
 {
     $habitatSmpAttrIds = explode(',', $args['habitat_smpAttr_cluster_ids']);
     $r = '';
     //Cycle through each existing habitat
     foreach ($existingHabitatSubSamples as $habitat) {
         $existingHabitatSubSamplesIds[] = $habitat['id'];
         //Get the attributes associated with the habitat subsample
         $habitatAttrs = self::getAttributesForSample($args, $auth, $habitat['id']);
         //enclose the attributes in a numbered div
         $r .= "<div id=\"habitat-panel-{$NextHabitatNum}\">";
         //Cycle through the attributes for the habitat
         foreach ($habitatSmpAttrIds as $habitatSmpAttrId) {
             //Only get sample attributes and then store them in an array so they can be passed to the existing function that builds the html
             $attrbuteArray = array();
             foreach ($habitatAttrs as $habitatAttr) {
                 if (!empty($habitatAttr['sample_attribute_id'])) {
                     if ($habitatSmpAttrId == $habitatAttr['sample_attribute_id']) {
                         $attrbuteArray[] = $habitatAttr;
                     }
                 }
             }
             $r .= get_attribute_html($attrbuteArray, $args, array('extraParams' => $auth['read']), null, $attrOptions);
         }
         //When dealng with existing habitats, we need to supply the existing id to the submission in a hidden field
         $r .= '<input id="sample:id" name="sample:id" type="hidden" value="' . $habitat['id'] . '">';
         $NextHabitatNum++;
         $r .= '</div><hr width="50%">';
     }
     return $r;
 }
 private function get_section_tab($auth, $args, $settings)
 {
     $r = '<div id="section" class="ui-helper-clearfix">';
     if ($settings['locationId']) {
         $r .= '<input type="hidden" name="location:id" value="' . $settings['locationId'] . "\" />\n";
     }
     $r .= "<input type=\"hidden\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" name=\"location:location_type_id\" value=\"" . $settings['locationTypes'][0]['id'] . "\" />\n";
     $r .= '<input type="hidden" name="location:parent_id" value="' . $settings['parentId'] . "\" />\n";
     // force a blank centroid, so that the Warehouse will recalculate it from the boundary
     $r .= "<input type=\"hidden\" name=\"location:centroid_geom\" value=\"\" />\n";
     $r .= '<div class="left" style="width: 45%"><fieldset><legend>' . lang::get('Section Details') . '</legend>';
     $sectionName = lang::get('{1} - section {2}', $settings['parent']['name'], str_replace('S', '', data_entry_helper::$entity_to_load['location:code']));
     $r .= "<input type=\"hidden\" name=\"location:name\" value=\"{$sectionName}\" />\n";
     $r .= "<input type=\"hidden\" name=\"location:code\" id=\"location_code\" value=\"" . data_entry_helper::$entity_to_load['location:code'] . "\" />\n";
     // if the from (calling) page is defined in the url, store this for use after the post
     if (!empty($_GET['from'])) {
         $r .= "<input type=\"hidden\" name=\"from\" value=\"" . $_GET['from'] . "\" />\n";
     }
     $r .= '<h2>' . $sectionName . '</h2>';
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     // output a hidden to contain the parent Geom, so we have something to zoom to if nothing else
     $r .= '<input type="hidden" id="parent-geom" value="' . $settings['parent']['centroid_geom'] . '" />';
     $r .= '<div id="section-geoms">';
     foreach ($settings['sections'] as $section) {
         $code = $section['code'];
         $r .= '<input type="hidden" id="' . $code . '" name="' . $code . '" value="' . $section['boundary_geom'] . '"/>';
     }
     $r .= '</div>';
     // add an input for the boundary geom of the one we are editing
     $r .= '<input type="hidden" id="boundary_geom" name="location: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']);
     $options['standardControls'][] = 'drawLine';
     $options['standardControls'][] = 'modifyFeature';
     $options['clickForSpatialRef'] = false;
     $options['toolbarDiv'] = 'top';
     $r .= get_attribute_html($settings['attributes'], $args, array('extraParams' => $auth['read']), 'Section');
     $olOptions = iform_map_get_ol_options($args);
     $r .= '<input type="submit" value="' . lang::get('Save') . '" class="ui-state-default ui-corner-all" />';
     $r .= '</fieldset></div>';
     $r .= '<div class="right" style="width: ' . $options['width'] . 'px;">';
     $help = lang::get('Use the Draw Lines tool to draw the section by clicking on the map. Double click to finish the line. You can edit an ' . 'existing line by selecting the Modify Feature tool then dragging the markers to change the line shape.');
     $r .= '<p class="ui-state-highlight page-notice ui-corner-all">' . $help . '</p>';
     $r .= map_helper::map_panel($options, $olOptions);
     $r .= '</div></div>';
     return $r;
 }
 private static function get_site_trees_tab($auth, $args, $settings)
 {
     global $indicia_templates;
     $r = '<div id="site-trees" class="ui-helper-clearfix">';
     $r .= '<form method="post" id="tree-form" action="' . self::$ajaxFormUrl . '">';
     $help = '<p>' . lang::get('To add a tree, click on the "Add Tree" button. You can then use the map\'s Location Tool to select the approximate location of your tree on the map. A new tree will then appear on the map.') . '</p>' . '<p>' . lang::get('To select a tree from the existing list of trees at this site you can either:') . '</p>' . '<ol><li>' . lang::get('Click on the button for the tree you wish to view, or') . '</li>' . '<li>' . lang::get('Use the map\'s Query Tool to click on the tree you wish to view on the map.') . '</li></ol>' . '<p>' . lang::get('To remove a tree, first select the tree you wish to remove, then click on the "Remove Tree" button. It will remove the current tree you are viewing completely.') . '</p>';
     $r .= '<div class="ui-state-highlight page-notice ui-corner-all">' . $help . '</div>';
     $r .= self::tree_selector($settings);
     $r .= '<input type="button" value="' . lang::get('Remove Tree') . '" class="remove-tree form-button right" title="' . lang::get('Completely remove the highlighted tree. The total number of tree will be reduced by one. The form will be reloaded after the tree is deleted.') . '">';
     $r .= '<input type="button" value="' . lang::get('Add Tree') . '" class="insert-tree form-button right" title="' . lang::get('This inserts an extra tree.') . '">';
     $r .= '<div id="cols" class="ui-helper-clearfix"><div class="left" style="width: ' . (98 - (isset($args['percent_width']) ? $args['percent_width'] : 50)) . '%">';
     $r .= '<fieldset><legend>' . lang::get('Tree Details') . '</legend>';
     $r .= '<input type="hidden" name="location:id" value="" id="tree-location-id" />';
     $r .= '<input type="hidden" name="locations_website:website_id" value="' . $args['website_id'] . '" id="locations-website-website-id" />';
     $r .= '<input type="hidden" name="location:parent_id" value="' . $settings['locationId'] . '" />';
     $r .= '<input type="hidden" name="location:location_type_id" value="' . $settings['TreeLocationType'][0]['id'] . '" />';
     $r .= '<input type="hidden" name="website_id" value="' . $args['website_id'] . "\" />\n";
     $r .= data_entry_helper::text_input(array('fieldname' => 'location:name', 'label' => lang::get('Tree ID'), 'class' => 'control-width-4 required'));
     $systems = array();
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get($system);
     }
     $srefOptions = array('id' => 'imp-sref-tree', 'fieldname' => 'location:centroid_sref', 'geomid' => 'imp-geom-tree', 'geomFieldname' => 'location:centroid_geom', 'label' => 'Grid Ref', 'labelClass' => 'auto', 'class' => 'required', 'helpText' => lang::get('You can also click on the map to set the grid reference. If directly entering the coordinates from a GPS device, set the format to "Lat/Long" first. To enter an OS Grid square, choose the "OSGB" or "OSIE" formats.'));
     data_entry_helper::$javascript .= "\n\$('#imp-sref-tree').attr('title',\n    '" . lang::get("When directly entering coordinates as a GPS Lat/Long reading, there should be no spaces between the numbers and the letter. " . "The degrees, minutes and seconds must all be separated by a colon (:). The direction letter can be placed at the start or the end of the number (e.g. N56.532 or 56.532N). " . "The figures may be entered as decimal degrees (e.g. 56.532), degrees and decimal minutes (e.g. 56:31.92), or degrees, minutes and decimal seconds (e.g. 56:31:55.2). " . "You can mix the formats of the Latitude and Longitude, provided they each follow the previous guidelines and a space separates them (e.g. N56.532 2:30W).") . "  " . lang::get("When directly entering an OS map reference, there should be no spaces between any of the characters. " . "An OSGB reference should comprise of 2 letters followed by an even number of digits (e.g. NT274628). " . "An OSIE reference should comprise of of 1 letter followed by an even number of digits (e.g. J081880).") . "');\n";
     // Output the sref control
     $r .= data_entry_helper::sref_textbox($srefOptions);
     $srefOptions = array('id' => 'imp-sref-system-tree', 'fieldname' => 'location:centroid_sref_system', 'class' => 'required', 'systems' => $systems);
     // Output the system control
     if (count($systems) < 2) {
         // Hidden field for the system
         $keys = array_keys($options['systems']);
         $r .= "<input type=\"hidden\" id=\"imp-sref-system-tree\" name=\"" . $options['fieldname'] . "\" value=\"" . $keys[0] . "\" />\n";
         // TODO    	self::include_sref_handler_js($options['systems']);
     } else {
         $r .= data_entry_helper::sref_system_select($srefOptions);
     }
     $r .= '<input type="hidden" name="survey_id" value="' . $args['survey_id'] . '" />';
     $r .= '<input type="hidden" name="sample:survey_id" value="' . $args['survey_id'] . '" />';
     $r .= '<input type="hidden" name="sample:id" value="" />';
     // this sample will reference the location id.
     if (isset(data_entry_helper::$entity_to_load['sample:date']) && preg_match('/^(\\d{4})/', data_entry_helper::$entity_to_load['sample:date'])) {
         // Date has 4 digit year first (ISO style) - convert date to expected output format
         // @todo The date format should be a global configurable option. It should also be applied to reloading of custom date attributes.
         $d = new DateTime(data_entry_helper::$entity_to_load['sample:date']);
         data_entry_helper::$entity_to_load['sample:date'] = $d->format('d/m/Y');
     }
     $r .= data_entry_helper::date_picker(array('label' => lang::get('Date Tree Selected'), 'fieldname' => 'sample:date', 'class' => 'control-width-2 required'));
     $r .= '<input type="hidden" id="sample:sample_method_id" value="' . $settings['treeSampleMethod']['id'] . '" name="sample:sample_method_id">';
     $r .= '<input type="hidden" id="sample:location_name" value="" name="sample:location_name">';
     $r .= '<input type="hidden" name="occurrence:id" value="" id="occurrence:id" />';
     $r .= '<input type="hidden" name="occurrence:record_status" value="C" id="occurrence:record_status" />';
     $extraParams = $auth['read'];
     $extraParams['taxon_list_id'] = $args['taxon_list_id'];
     $options = array('speciesNameFilterMode' => $args['speciesNameFilterMode']);
     $ctrl = $args['species_ctrl'];
     $species_ctrl_opts = array_merge(array('fieldname' => 'occurrence:taxa_taxon_list_id', 'label' => lang::get('Tree Species'), 'columns' => 1, 'parentField' => 'parent_id', 'blankText' => lang::get('Please select'), 'cacheLookup' => false), $options);
     if (isset($species_ctrl_opts['extraParams'])) {
         $species_ctrl_opts['extraParams'] = array_merge($extraParams, $species_ctrl_opts['extraParams']);
     } else {
         $species_ctrl_opts['extraParams'] = $extraParams;
     }
     if (!empty($args['taxon_filter'])) {
         $species_ctrl_opts['taxonFilterField'] = $args['taxon_filter_field'];
         // applies to autocompletes
         $species_ctrl_opts['taxonFilter'] = helper_base::explode_lines($args['taxon_filter']);
         // applies to autocompletes
     }
     // obtain table to query and hence fields to use
     $db = data_entry_helper::get_species_lookup_db_definition(false);
     // get local vars for the array
     extract($db);
     if ($ctrl !== 'species_autocomplete') {
         // The species autocomplete has built in support for the species name filter.
         // For other controls we need to apply the species name filter to the params used for population
         if (!empty($species_ctrl_opts['taxonFilter']) || $options['speciesNameFilterMode']) {
             $species_ctrl_opts['extraParams'] = array_merge($species_ctrl_opts['extraParams'], data_entry_helper::get_species_names_filter($species_ctrl_opts));
         }
         // for controls which don't know how to do the lookup, we need to tell them
         $species_ctrl_opts = array_merge(array('table' => $tblTaxon, 'captionField' => $colTaxon, 'valueField' => $colId), $species_ctrl_opts);
     }
     // if using something other than an autocomplete, then set the caption template to include the appropriate names. Autocompletes
     // use a JS function instead.
     if ($ctrl !== 'autocomplete' && isset($args['species_include_both_names']) && $args['species_include_both_names']) {
         if ($args['speciesNameFilterMode'] === 'all') {
             $indicia_templates['species_caption'] = "{{$colTaxon}}";
         } elseif ($args['speciesNameFilterMode'] === 'language') {
             $indicia_templates['species_caption'] = "{{$colTaxon}} - {{$colPreferred}}";
         } else {
             $indicia_templates['species_caption'] = "{{$colTaxon}} - {{$colCommon}}";
         }
         $species_ctrl_opts['captionTemplate'] = 'species_caption';
     }
     if ($ctrl == 'tree_browser') {
         // change the node template to include images
         $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', $ctrl), $species_ctrl_opts);
     $ctrlOptions = array('extraParams' => $auth['read']);
     $attrSpecificOptions = array();
     $options = helper_base::explode_lines_key_value_pairs($args['attrOptions']);
     self::parseForAttrSpecificOptions($options, $ctrlOptions, $attrSpecificOptions);
     $r .= get_attribute_html($settings['tree_attributes'], $args, $ctrlOptions, '', $attrSpecificOptions);
     $r .= '</fieldset>';
     $r .= "</div>" . '<div class="right" style="width: ' . (isset($args['percent_width']) ? $args['percent_width'] : 50) . '%">';
     $olOptions = iform_map_get_ol_options($args);
     $options = iform_map_get_map_options($args, $auth['read']);
     $options['divId'] = 'trees-map';
     $options['toolbarDiv'] = 'top';
     $options['tabDiv'] = 'site-trees';
     $options['gridRefHint'] = true;
     $options['latLongFormat'] = 'DMS';
     // TODO drive from args or user.
     if (array_key_exists('standard_controls_trees', $args) && $args['standard_controls_trees']) {
         $standard_controls_trees = str_replace("\r\n", "\n", $args['standard_controls_trees']);
         $options['standardControls'] = explode("\n", $standard_controls_trees);
         // If drawing controls are enabled, then allow polygon recording.
         if (in_array('drawPolygon', $options['standardControls']) || in_array('drawLine', $options['standardControls'])) {
             $options['allowPolygonRecording'] = true;
         }
     }
     // also let the user click on a feature to select it. The highlighter just makes it easier to select one.
     // these controls are not present in read-only mode: all you can do is look at the map.
     $options['switchOffSrefRetrigger'] = true;
     $options['clickForSpatialRef'] = true;
     // override the opacity so the parent square does not appear filled in.
     $options['fillOpacity'] = 0;
     // override the map height and buffer size, which are specific to this map.
     $options['height'] = $args['tree_map_height'];
     $options['maxZoomBuffer'] = $args['tree_map_buffer'];
     $options['srefId'] = 'imp-sref-tree';
     $options['geomId'] = 'imp-geom-tree';
     $options['srefSystemId'] = 'imp-sref-system-tree';
     $help = '<p>' . lang::get('Add your trees using the appropriate tools in the top right of the map') . ':</p>' . '<ol><li>' . lang::get('Navigation Tool.') . '</li>' . '<li>' . lang::get('Query Tool. This tool allows you to click on a tree on the map to view its tree details.') . '</li>' . '<li>' . lang::get('Location Tool. This tool allows you to select the approximate location of a new tree on your site map. You can also reposition existing trees by first clicking on the tree and then clicking on its new location on the map.') . '</li></ol>';
     $r .= '<div class="ui-state-highlight page-notice ui-corner-all">' . $help . '</div>';
     $r .= map_helper::map_panel($options, $olOptions);
     $r .= data_entry_helper::file_box(array('table' => 'location_medium', 'readAuth' => $auth['read'], 'caption' => lang::get('Photos of Tree'), 'readAuth' => $auth['read']));
     $r .= "</div>";
     // right
     $r .= '<div class="follow_on_block" style="clear:both;">';
     $r .= get_attribute_html($settings['tree_attributes'], $args, $ctrlOptions, 'Lower Block', $attrSpecificOptions);
     data_entry_helper::$javascript .= "\n\$('#fieldset-optional-external-sc').prepend(\"" . lang::get('If you choose to record this tree for one of the citizen science projects below, please submit the tree ID used for that scheme.') . "\");\n";
     $r .= data_entry_helper::textarea(array('id' => 'location-comment', 'fieldname' => 'location:comment', 'label' => lang::get("Additional information"), 'labelClass' => 'autowidth')) . "<br />";
     $r .= '<input type="submit" value="' . lang::get('Save') . '" class="form-button right" id="submit-tree" />';
     $r .= '</div></form></div>';
     data_entry_helper::$onload_javascript .= "\$('#current-tree').change(selectTree);\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.';
     }
     require_once dirname(dirname(__FILE__)) . '/map_helper.php';
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $sampleId = isset($_GET['sample_id']) ? $_GET['sample_id'] : null;
     if ($sampleId) {
         data_entry_helper::load_existing_record($auth['read'], 'sample', $sampleId);
         $locationId = data_entry_helper::$entity_to_load['sample:location_id'];
     } else {
         $locationId = isset($_GET['site']) ? $_GET['site'] : null;
         // location ID also might be in the $_POST data after a validation save of a new record
         if (!$locationId && isset($_POST['sample:location_id'])) {
             $locationId = $_POST['sample:location_id'];
         }
     }
     $r .= '<form method="post" id="sample">';
     $r .= $auth['write'];
     // we pass through the read auth. This makes it possible for the get_submission method to authorise against the warehouse
     // without an additional (expensive) warehouse call, so it can get location details.
     $r .= '<input type="hidden" name="read_nonce" value="' . $auth['read']['nonce'] . '"/>';
     $r .= '<input type="hidden" name="read_auth_token" value="' . $auth['read']['auth_  token'] . '"/>';
     $r .= '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>';
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         $r .= '<input type="hidden" name="sample:id" value="' . data_entry_helper::$entity_to_load['sample:id'] . '"/>';
     }
     $r .= '<input type="hidden" name="sample:survey_id" value="' . $args['survey_id'] . '"/>';
     // pass a param that sets the next page to display
     $r .= '<input type="hidden" name="page" value="grid"/>';
     if ($locationId) {
         $site = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('view' => 'detail', 'id' => $locationId, 'deleted' => 'f')));
         $site = $site[0];
         $r .= '<input type="hidden" name="sample:location_id" value="' . $locationId . '"/>';
         $r .= '<input type="hidden" name="sample:entered_sref" value="' . $site['centroid_sref'] . '"/>';
         $r .= '<input type="hidden" name="sample:entered_sref_system" value="' . $site['centroid_sref_system'] . '"/>';
     }
     if ($locationId && isset(data_entry_helper::$entity_to_load['sample:id'])) {
         // for reload of existing, don't let the user switch the transect as that would mess everything up.
         $r .= '<label>' . lang::get('Transect') . ':</label><span>' . $site['name'] . '</span><br/>';
     } else {
         // Output only the locations for this website and transect type. Note we load both transects and sections, just so that
         // we always use the same warehouse call and therefore it uses the cache.
         $locationTypes = helper_base::get_termlist_terms($auth, 'indicia:location_types', array('Transect', 'Transect Section'));
         $availableSites = data_entry_helper::get_population_data(array('report' => 'library/locations/locations_list', 'extraParams' => $auth['read'] + array('website_id' => $args['website_id'], 'location_type_id' => $locationTypes[0]['id'], 'locattrs' => 'CMS User ID', 'attr_location_cms_user_id' => $user->uid), 'nocache' => true));
         // convert the report data to an array for the lookup, plus one to pass to the JS so it can keep the hidden sref fields updated
         $sitesLookup = array();
         $sitesJs = array();
         foreach ($availableSites as $site) {
             $sitesLookup[$site['location_id']] = $site['name'];
             $sitesJs[$site['location_id']] = $site;
         }
         data_entry_helper::$javascript .= "indiciaData.sites = " . json_encode($sitesJs) . ";\n";
         $options = array('label' => lang::get('Select Transect'), 'validation' => array('required'), 'blankText' => lang::get('please select'), 'lookupValues' => $sitesLookup);
         if ($locationId) {
             $options['default'] = $locationId;
         }
         $r .= data_entry_helper::location_select($options);
     }
     if (!$locationId) {
         $r .= '<input type="hidden" name="sample:entered_sref" value="" id="entered_sref"/>';
         $r .= '<input type="hidden" name="sample:entered_sref_system" value="" id="entered_sref_system"/>';
         // sref values for the sample will be populated automatically when the submission is built.
     }
     $r .= data_entry_helper::date_picker(array('label' => lang::get('Date'), 'fieldname' => 'sample:date'));
     $sampleMethods = helper_base::get_termlist_terms($auth, 'indicia:sample_methods', array('Transect'));
     $attributes = data_entry_helper::getAttributes(array('id' => $sampleId, 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'sample_method_id' => $sampleMethods[0]['id']));
     $r .= get_attribute_html($attributes, $args, array('extraParams' => $auth['read']));
     $r .= '<input type="hidden" name="sample:sample_method_id" value="' . $sampleMethods[0]['id'] . '" />';
     $r .= '<input type="submit" value="' . lang::get('Next') . '" class="ui-state-default ui-corner-all" />';
     $r .= '</form>';
     data_entry_helper::enable_validation('sample');
     return $r;
 }
Example #16
0
 protected static function get_tab_content($auth, $args, $tab, $tabContent, $tabalias, &$attributes, &$hasControls)
 {
     // cols array used if we find | splitters
     $cols = array();
     $defAttrOptions = array('extraParams' => $auth['read']);
     if (isset($args['attribute_termlist_language_filter']) && $args['attribute_termlist_language_filter']) {
         $defAttrOptions['language'] = iform_lang_iso_639_2($args['language']);
     }
     //create array of attribute field names to test against later
     $attribNames = array();
     foreach ($attributes as $key => $attrib) {
         $attribNames[$key] = $attrib['id'];
     }
     $html = '';
     // Now output the content of the tab. Use a for loop, not each, so we can treat several rows as one object
     for ($i = 0; $i < count($tabContent); $i++) {
         $component = trim($tabContent[$i]);
         if (preg_match('/\\A\\?[^�]*\\?\\z/', $component) === 1) {
             // Component surrounded by ? so represents a help text
             $helpText = substr($component, 1, -1);
             $html .= '<div class="page-notice ui-state-highlight ui-corner-all">' . lang::get($helpText) . "</div>";
         } elseif (preg_match('/\\A\\[[^�]*\\]\\z/', $component) === 1) {
             // Component surrounded by [] so represents a control or control block
             // Anything following the component that starts with @ is an option to pass to the control
             $options = array();
             while ($i < count($tabContent) - 1 && substr($tabContent[$i + 1], 0, 1) == '@' || trim($tabContent[$i]) === '') {
                 $i++;
                 // ignore empty lines
                 if (trim($tabContent[$i]) !== '') {
                     $option = explode('=', substr($tabContent[$i], 1), 2);
                     if (!isset($option[1]) || $option[1] === 'false') {
                         $options[$option[0]] = FALSE;
                     } else {
                         $options[$option[0]] = json_decode($option[1], TRUE);
                         // if not json then need to use option value as it is
                         if ($options[$option[0]] == '') {
                             $options[$option[0]] = $option[1];
                         }
                     }
                     // urlParam is special as it loads the control's default value from $_GET
                     if ($option[0] === 'urlParam' && isset($_GET[$option[1]])) {
                         $options['default'] = $_GET[$option[1]];
                     }
                 }
             }
             // if @permission specified as an option, then check that the user has access to this control
             if (!empty($options['permission']) && !user_access($options['permission'])) {
                 continue;
             }
             $parts = explode('.', str_replace(array('[', ']'), '', $component));
             $method = 'get_control_' . preg_replace('/[^a-zA-Z0-9]/', '', strtolower($component));
             if (!empty($args['high_volume']) && $args['high_volume']) {
                 // enable control level report caching when in high_volume mode
                 $options['caching'] = empty($options['caching']) ? true : $options['caching'];
                 $options['cachetimeout'] = empty($options['cachetimeout']) ? HIGH_VOLUME_CONTROL_CACHE_TIMEOUT : $options['cachetimeout'];
             }
             // allow user settings to override the control - see iform_user_ui_options.module
             if (isset(data_entry_helper::$data['structureControlOverrides']) && !empty(data_entry_helper::$data['structureControlOverrides'][$component])) {
                 $options = array_merge($options, data_entry_helper::$data['structureControlOverrides'][$component]);
             }
             if (count($parts) === 1 && method_exists(self::$called_class, $method)) {
                 //outputs a control for which a specific output function has been written.
                 $html .= call_user_func(array(self::$called_class, $method), $auth, $args, $tabalias, $options);
                 $hasControls = true;
             } elseif (count($parts) === 2) {
                 require_once dirname($_SERVER['SCRIPT_FILENAME']) . '/' . data_entry_helper::relative_client_helper_path() . '/prebuilt_forms/extensions/' . $parts[0] . '.php';
                 if (method_exists('extension_' . $parts[0], $parts[1])) {
                     //outputs a control for which a specific extension function has been written.
                     $path = call_user_func(array(self::$called_class, 'getReloadPath'));
                     //pass the classname of the form through to the extension control method to allow access to calling class functions and variables
                     $args["calling_class"] = 'iform_' . self::$node->iform;
                     $html .= call_user_func(array('extension_' . $parts[0], $parts[1]), $auth, $args, $tabalias, $options, $path, $attributes);
                     $hasControls = true;
                     // auto-add JavaScript for the extension
                     if (file_exists(iform_client_helpers_path() . 'prebuilt_forms/extensions/' . $parts[0] . '.js')) {
                         drupal_add_js(iform_client_helpers_path() . 'prebuilt_forms/extensions/' . $parts[0] . '.js', array('preprocess' => FALSE));
                     }
                     if (file_exists(iform_client_helpers_path() . 'prebuilt_forms/extensions/' . $parts[0] . '.css')) {
                         drupal_add_css(iform_client_helpers_path() . 'prebuilt_forms/extensions/' . $parts[0] . '.css', array('preprocess' => FALSE));
                     }
                 } else {
                     $html .= lang::get("The {$component} extension cannot be found.");
                 }
             } elseif (($attribKey = array_search(substr($component, 1, -1), $attribNames)) !== false || preg_match('/^\\[[a-zA-Z]+:(?P<ctrlId>[0-9]+)\\]/', $component, $matches)) {
                 // control is a smpAttr or other attr control.
                 if (empty($options['extraParams'])) {
                     $options['extraParams'] = array_merge($defAttrOptions['extraParams']);
                 } else {
                     $options['extraParams'] = array_merge($defAttrOptions['extraParams'], (array) $options['extraParams']);
                 }
                 //merge extraParams first so we don't loose authentication
                 $options = array_merge($defAttrOptions, $options);
                 foreach ($options as $key => &$value) {
                     $value = apply_user_replacements($value);
                 }
                 if ($attribKey !== false) {
                     // a smpAttr control
                     $html .= data_entry_helper::outputAttribute($attributes[$attribKey], $options);
                     $attributes[$attribKey]['handled'] = true;
                 } else {
                     // if the control name of form name:id, then we will call get_control_name passing the id as a parameter
                     $method = 'get_control_' . preg_replace('/[^a-zA-Z]/', '', strtolower($component));
                     if (method_exists(self::$called_class, $method)) {
                         $options['ctrlId'] = $matches['ctrlId'];
                         $html .= call_user_func(array(self::$called_class, $method), $auth, $args, $tabalias, $options);
                     } else {
                         $html .= "Unsupported control {$component}<br/>";
                     }
                 }
                 $hasControls = true;
             } elseif ($component === '[*]') {
                 // this outputs any custom attributes that remain for this tab. The custom attributes can be configured in the
                 // settings text using something like @smpAttr:4|label=My label. The next bit of code parses these out into an
                 // array used when building the html.
                 // Alternatively, a setting like @option=value is applied to all the attributes.
                 $attrSpecificOptions = array();
                 foreach ($options as $option => $value) {
                     // split the id of the option into the control name and option name.
                     $optionId = explode('|', $option);
                     if (count($optionId) > 1) {
                         // Found an option like @smpAttr:4|label=My label
                         if (!isset($attrSpecificOptions[$optionId[0]])) {
                             $attrSpecificOptions[$optionId[0]] = array();
                         }
                         $attrSpecificOptions[$optionId[0]][$optionId[1]] = apply_user_replacements($value);
                     } else {
                         // Found an option like @option=value
                         $defAttrOptions = array_merge($defAttrOptions, array($option => $value));
                     }
                 }
                 $attrHtml = get_attribute_html($attributes, $args, $defAttrOptions, $tab, $attrSpecificOptions);
                 if (!empty($attrHtml)) {
                     $hasControls = true;
                 }
                 $html .= $attrHtml;
             } else {
                 $html .= "The form structure includes a control called {$component} which is not recognised.<br/>";
                 //ensure $hasControls is true so that the error message is shown
                 $hasControls = true;
             }
         } elseif ($component === '|') {
             // column splitter. So, store the col html and start on the next column.
             $cols[] = $html;
             $html = '';
         } else {
             // output anything else as is. This allow us to add html to the form structure.
             $html .= $component;
         }
     }
     if (count($cols) > 0) {
         $cols[] = $html;
         // a splitter in the structure so put the stuff so far in a 50% width left float div, and the stuff that follows in a 50% width right float div.
         global $indicia_templates;
         $html = str_replace(array('{col-1}', '{col-2}'), $cols, $indicia_templates['two-col-50']);
         if (count($cols) > 2) {
             unset($cols[1]);
             unset($cols[0]);
             $html .= '<div class="follow_on_block" style="clear:both;">' . implode('', $cols) . '</div>';
         } else {
             $html .= '<div class="follow_on_block" style="clear:both;"></div>';
         }
         // needed so any tab div is stretched around them
     }
     return $html;
 }
 /**
  * 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;
 }