protected static function get_control_species($auth, $args, $tabAlias, $options)
 {
     data_entry_helper::$onload_javascript .= "indiciaFns.bindTabsActivate(\$(\$('#{$tabAlias}').parent()), function(event, ui) {\r\n      panel = typeof ui.newPanel==='undefined' ? ui.panel : ui.newPanel[0];\r\n      if (panel.id==='{$tabAlias}') { setSectionDropDown(); }\r\n    });\n";
     // we need a place to store the subsites, to save loading from the db on submission
     $r = '<input type="hidden" name="subsites" id="subsites" value="" />';
     // plus hiddens to store the main sample's sref info
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'sample:entered_sref', 'id' => 'imp-sref'));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'sample:entered_sref_system', 'id' => 'imp-sref-system'));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'sample:geom', 'id' => 'imp-geom'));
     // plus the sample method ids
     $sampleMethods = helper_base::get_termlist_terms($auth, 'indicia:sample_methods', array('Transect', 'Transect Section'));
     $r .= '<input type="hidden" name="sample:sample_method_id" value="' . $sampleMethods[0]['id'] . '" />';
     $r .= '<input type="hidden" name="subsample:sample_method_id" value="' . $sampleMethods[1]['id'] . '" />';
     // This option forces the grid to load all child sample occurrences, though we will ignore the hidden SampleIDX column and instead
     // use the section column to bind to samples
     $options['speciesControlToUseSubSamples'] = true;
     $r .= parent::get_control_species($auth, $args, $tabAlias, $options);
     // build an array of existing sub sample IDs, keyed by subsite location Id.
     $subSampleIds = array();
     if (isset(data_entry_helper::$entity_to_load)) {
         foreach (data_entry_helper::$entity_to_load as $key => $value) {
             if (preg_match('/^sc:(\\d+):(\\d+):sample:id$/', $key, $matches)) {
                 $subSampleIds[data_entry_helper::$entity_to_load["sc:{$matches['1']}:{$matches['2']}:sample:location_id"]] = $value;
             }
         }
     }
     $r .= '<input type="hidden" name="subSampleIds" value="' . htmlspecialchars(json_encode($subSampleIds)) . '" />';
     return $r;
 }
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  * @todo: Implement this method 
  */
 public static function get_form($args, $node, $response = null)
 {
     require_once drupal_get_path('module', 'iform') . '/client_helpers/map_helper.php';
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $settings = array('locationTypes' => helper_base::get_termlist_terms($auth, 'indicia:location_types', array('Transect Section')), 'locationId' => isset($_GET['section_id']) ? $_GET['section_id'] : null, 'parentId' => isset($_GET['transect_id']) ? $_GET['transect_id'] : null);
     if ($settings['parentId']) {
         $parent = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('view' => 'detail', 'id' => $settings['parentId'], 'deleted' => 'f'), 'nocache' => true));
         $settings['parent'] = $parent[0];
     } else {
         return 'This form must be called with a parent transect_id parameter.';
     }
     $settings['sections'] = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('view' => 'detail', 'parent_id' => $settings['parentId'], 'deleted' => 'f'), 'nocache' => true));
     if ($settings['locationId']) {
         data_entry_helper::load_existing_record($auth['read'], 'location', $settings['locationId']);
     } else {
         data_entry_helper::$entity_to_load['location:code'] = 'S' . (count($settings['sections']) + 1);
     }
     $settings['attributes'] = data_entry_helper::getAttributes(array('id' => $settings['locationId'], 'valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'location_type_id' => $settings['locationTypes'][0]['id']));
     if (data_entry_helper::$entity_to_load['location:code']) {
         $r = '<form method="post" id="input-form">';
     }
     $r .= $auth['write'];
     $r .= '<div id="controls">';
     $customAttributeTabs = array_merge(array('Section' => array('[*]')), get_attribute_tabs($settings['attributes']));
     if (count($customAttributeTabs) > 1) {
         $headerOptions = array('tabs' => array());
         foreach ($customAttributeTabs as $tab => $content) {
             $alias = preg_replace('/[^a-zA-Z0-9]/', '', strtolower($tab));
             $headerOptions['tabs']['#' . $alias] = lang::get($tab);
         }
         $r .= data_entry_helper::tab_header($headerOptions);
         data_entry_helper::enable_tabs(array('divId' => 'controls', 'style' => $args['interface'], 'progressBar' => isset($args['tabProgress']) && $args['tabProgress'] == true));
     }
     foreach ($customAttributeTabs as $tab => $content) {
         if ($tab == 'Section') {
             $r .= self::get_section_tab($auth, $args, $settings);
         } else {
             $alias = preg_replace('/[^a-zA-Z0-9]/', '', strtolower($tab));
             $r .= "\n<div id=\"{$alias}\">\n";
             $r .= get_attribute_html($settings['attributes'], $args, array('extraParams' => $auth['read']), $tab);
             $r .= "</div>\n";
         }
     }
     $r .= '</div>';
     // controls
     $r .= '</form>';
     data_entry_helper::link_default_stylesheet();
     if (function_exists('drupal_set_breadcrumb')) {
         $breadcrumb = array();
         $breadcrumb[] = l('Home', '<front>');
         $breadcrumb[] = l('Sites', $args['sites_list_path']);
         $breadcrumb[] = l($settings['parent']['name'], $args['transect_edit_path'], array('query' => array('id' => $settings['parentId'])));
         $breadcrumb[] = $settings['locationId'] ? data_entry_helper::$entity_to_load['location:name'] : lang::get('new section');
         drupal_set_breadcrumb($breadcrumb);
     }
     return $r;
 }
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  * @todo: Implement this method 
  */
 public static function get_form($args, $node, $response = null)
 {
     global $user;
     $checks = self::check_prerequisites();
     $args = self::getArgDefaults($args);
     if ($checks !== true) {
         return $checks;
     }
     iform_load_helpers(array('map_helper'));
     data_entry_helper::add_resource('jquery_form');
     self::$ajaxFormUrl = iform_ajaxproxy_url($node, 'location');
     self::$ajaxFormSampleUrl = iform_ajaxproxy_url($node, 'sample');
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $typeTerms = array(empty($args['transect_type_term']) ? 'Transect' : $args['transect_type_term'], empty($args['section_type_term']) ? 'Section' : $args['section_type_term']);
     $settings = array('locationTypes' => helper_base::get_termlist_terms($auth, 'indicia:location_types', $typeTerms), 'locationId' => isset($_GET['id']) ? $_GET['id'] : null, 'canEditBody' => true, 'canEditSections' => true, 'canAllocBranch' => $args['managerPermission'] == "" || user_access($args['managerPermission']), 'canAllocUser' => $args['managerPermission'] == "" || user_access($args['managerPermission']));
     $settings['attributes'] = data_entry_helper::getAttributes(array('id' => $settings['locationId'], 'valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'location_type_id' => $settings['locationTypes'][0]['id'], 'multiValue' => true));
     $settings['section_attributes'] = data_entry_helper::getAttributes(array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'location_type_id' => $settings['locationTypes'][1]['id'], 'multiValue' => true));
     if ($args['allow_user_assignment']) {
         if (false == ($settings['cmsUserAttr'] = extract_cms_user_attr($settings['attributes']))) {
             return 'This form is designed to be used with the CMS User ID attribute setup for locations in the survey, or the "Allow users to be assigned to transects" option unticked.';
         }
         // keep a copy of the cms user ID attribute so we can use it later.
         self::$cmsUserAttrId = $settings['cmsUserAttr']['attributeId'];
     }
     // need to check if branch allocation is active.
     if ($args['branch_assignment_permission'] != '') {
         if (false == ($settings['branchCmsUserAttr'] = self::extract_attr($settings['attributes'], "Branch CMS User ID"))) {
             return '<br />This form is designed to be used with either<br />1) the Branch CMS User ID attribute setup for locations in the survey, or<br />2) the "Permission name for Branch Manager" option left blank.<br />';
         }
         // keep a copy of the branch cms user ID attribute so we can use it later.
         self::$branchCmsUserAttrId = $settings['branchCmsUserAttr']['attributeId'];
     }
     data_entry_helper::$javascript .= "indiciaData.sections = {};\n";
     $settings['sections'] = array();
     $settings['numSectionsAttr'] = "";
     $settings['maxSectionCount'] = $args['maxSectionCount'];
     $settings['autocalcSectionLengthAttrId'] = empty($args['autocalc_section_length_attr_id']) ? 0 : $args['autocalc_section_length_attr_id'];
     $settings['defaultSectionGridRef'] = empty($args['default_section_grid_ref']) ? 'parent' : $args['default_section_grid_ref'];
     if ($settings['locationId']) {
         data_entry_helper::load_existing_record($auth['read'], 'location', $settings['locationId']);
         $settings['walks'] = data_entry_helper::get_population_data(array('table' => 'sample', 'extraParams' => $auth['read'] + array('view' => 'detail', 'location_id' => $settings['locationId'], 'deleted' => 'f'), 'nocache' => true));
         // Work out permissions for this user: note that canAllocBranch setting effectively shows if a manager.
         if (!$settings['canAllocBranch']) {
             // Check whether I am a normal user and it is allocated to me, and also if I am a branch manager and it is allocated to me.
             $settings['canEditBody'] = false;
             $settings['canEditSections'] = false;
             if ($args['allow_user_assignment'] && count($settings['walks']) == 0 && isset($settings['cmsUserAttr']['default']) && !empty($settings['cmsUserAttr']['default'])) {
                 foreach ($settings['cmsUserAttr']['default'] as $value) {
                     // multi value
                     if ($value['default'] == $user->uid) {
                         // comparing string against int so no triple equals
                         $settings['canEditBody'] = true;
                         $settings['canEditSections'] = true;
                         break;
                     }
                 }
             }
             // If a Branch Manager and not a main manager, then can't edit the number of sections
             if ($args['branch_assignment_permission'] != '' && user_access($args['branch_assignment_permission']) && isset($settings['branchCmsUserAttr']['default']) && !empty($settings['branchCmsUserAttr']['default'])) {
                 foreach ($settings['branchCmsUserAttr']['default'] as $value) {
                     // now multi value
                     if ($value['default'] == $user->uid) {
                         // comparing string against int so no triple equals
                         $settings['canEditBody'] = true;
                         $settings['canAllocUser'] = true;
                         break;
                     }
                 }
             }
         }
         // for an admin user the defaults apply, which will be can do everything.
         // find the number of sections attribute.
         foreach ($settings['attributes'] as $attr) {
             if ($attr['caption'] === 'No. of sections') {
                 $settings['numSectionsAttr'] = $attr['fieldname'];
                 for ($i = 1; $i <= $attr['displayValue']; $i++) {
                     $settings['sections']["S{$i}"] = null;
                 }
                 $existingSectionCount = empty($attr['displayValue']) ? 1 : $attr['displayValue'];
                 data_entry_helper::$javascript .= "\$('#" . str_replace(':', '\\\\:', $attr['id']) . "').attr('min',{$existingSectionCount}).attr('max'," . $args['maxSectionCount'] . ");\n";
                 if (!$settings['canEditSections']) {
                     data_entry_helper::$javascript .= "\$('#" . str_replace(':', '\\\\:', $attr['id']) . "').attr('readonly','readonly').css('color','graytext');\n";
                 }
             }
         }
         $sections = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('view' => 'detail', 'parent_id' => $settings['locationId'], 'deleted' => 'f', 'orderby' => 'id'), 'nocache' => true));
         foreach ($sections as $section) {
             $code = $section['code'];
             data_entry_helper::$javascript .= "indiciaData.sections.{$code} = {'geom':'" . $section['boundary_geom'] . "','id':'" . $section['id'] . "','sref':'" . $section['centroid_sref'] . "','system':'" . $section['centroid_sref_system'] . "'};\n";
             $settings['sections'][$code] = $section;
         }
     } else {
         // not an existing site therefore no walks. On initial save, no section data is created.
         foreach ($settings['attributes'] as $attr) {
             if ($attr['caption'] === 'No. of sections') {
                 $settings['numSectionsAttr'] = $attr['fieldname'];
                 data_entry_helper::$javascript .= "\$('#" . str_replace(':', '\\\\:', $attr['id']) . "').attr('min',1).attr('max'," . $args['maxSectionCount'] . ");\n";
             }
         }
         $settings['walks'] = array();
     }
     if ($settings['numSectionsAttr'] === '') {
         for ($i = 1; $i <= $settings['maxSectionCount']; $i++) {
             $settings['sections']["S{$i}"] = null;
         }
     }
     $r = '<div id="controls">';
     $headerOptions = array('tabs' => array('#site-details' => lang::get('Site Details')));
     if ($settings['locationId']) {
         $headerOptions['tabs']['#your-route'] = lang::get('Your Route');
         if ($args['always_show_section_details'] || count($settings['section_attributes']) > 0) {
             $headerOptions['tabs']['#section-details'] = lang::get('Section Details');
         }
     }
     if (count($headerOptions['tabs'])) {
         $r .= data_entry_helper::tab_header($headerOptions);
         data_entry_helper::enable_tabs(array('divId' => 'controls', 'style' => 'Tabs', 'progressBar' => isset($args['tabProgress']) && $args['tabProgress'] == true));
     }
     $r .= self::get_site_tab($auth, $args, $settings);
     if ($settings['locationId']) {
         $r .= self::get_your_route_tab($auth, $args, $settings);
         if ($args['always_show_section_details'] || count($settings['section_attributes']) > 0) {
             $r .= self::get_section_details_tab($auth, $args, $settings);
         }
     }
     $r .= '</div>';
     // controls
     data_entry_helper::enable_validation('input-form');
     if (function_exists('drupal_set_breadcrumb')) {
         $breadcrumb = array();
         $breadcrumb[] = l(lang::get('Home'), '<front>');
         $breadcrumb[] = l(lang::get('Sites'), $args['sites_list_path']);
         if ($settings['locationId']) {
             $breadcrumb[] = data_entry_helper::$entity_to_load['location:name'];
         } else {
             $breadcrumb[] = lang::get('New Site');
         }
         drupal_set_breadcrumb($breadcrumb);
     }
     // Inform JS where to post data to for AJAX form saving
     data_entry_helper::$javascript .= 'indiciaData.ajaxFormPostUrl="' . self::$ajaxFormUrl . "\";\n";
     data_entry_helper::$javascript .= 'indiciaData.ajaxFormPostSampleUrl="' . self::$ajaxFormSampleUrl . "\";\n";
     data_entry_helper::$javascript .= 'indiciaData.website_id="' . $args['website_id'] . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.indiciaSvc = '" . data_entry_helper::$base_url . "';\n";
     data_entry_helper::$javascript .= "indiciaData.readAuth = {nonce: '" . $auth['read']['nonce'] . "', auth_token: '" . $auth['read']['auth_token'] . "'};\n";
     data_entry_helper::$javascript .= "indiciaData.currentSection = '';\n";
     data_entry_helper::$javascript .= "indiciaData.sectionTypeId = '" . $settings['locationTypes'][1]['id'] . "';\n";
     data_entry_helper::$javascript .= "indiciaData.sectionDeleteConfirm = \"" . lang::get('Are you sure you wish to delete section') . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.sectionInsertConfirm = \"" . lang::get('Are you sure you wish to insert a new section after section') . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.sectionChangeConfirm = \"" . lang::get('Do you wish to save the currently unsaved changes you have made to the Section Details?') . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.numSectionsAttrName = \"" . $settings['numSectionsAttr'] . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.maxSectionCount = \"" . $settings['maxSectionCount'] . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.autocalcSectionLengthAttrId = " . $settings['autocalcSectionLengthAttrId'] . ";\n";
     data_entry_helper::$javascript .= "indiciaData.defaultSectionGridRef = '" . $settings['defaultSectionGridRef'] . "';\n";
     if ($settings['locationId']) {
         data_entry_helper::$javascript .= "selectSection('S1', true);\n";
     }
     return $r;
 }
 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;
 }
Пример #5
0
 protected static function get_control_locationtype($auth, $args, $tabalias, $options)
 {
     // To limit the terms listed add a terms option to the Form Structure as a JSON array.
     // The terms must exist in the termlist that has external key indidia:location_types
     // e.g.
     // [location type]
     // @terms=["City","Town","Village"]
     // get the list of terms
     $filter = null;
     if (array_key_exists('terms', $options)) {
         $filter = $options['terms'];
     }
     $terms = helper_base::get_termlist_terms($auth, 'indicia:location_types', $filter);
     if (count($terms) == 1) {
         //only one location type so output as hidden control
         return '<input type="hidden" id="location:location_type_id" name="location:location_type_id" value="' . $terms[0]['id'] . '" />' . PHP_EOL;
     } elseif (count($terms) > 1) {
         // convert the $terms to an array of id => term
         $lookup = array();
         foreach ($terms as $term) {
             $lookup[$term['id']] = $term['term'];
         }
         return data_entry_helper::select(array_merge(array('label' => lang::get('LANG_Location_Type'), 'fieldname' => 'location:location_type_id', 'lookupValues' => $lookup, 'blankText' => lang::get('LANG_Blank_Text')), $options));
     }
 }
 public static function get_sorted_termlist_terms($auth, $key, $filter)
 {
     $terms = helper_base::get_termlist_terms($auth, $key, $filter);
     $retVal = array();
     foreach ($filter as $f) {
         foreach ($terms as $term) {
             if ($f == $term['term']) {
                 $retVal[] = $term;
             }
         }
     }
     return $retVal;
 }
Пример #7
0
function iform_mnhnl_getTermID($auth, $termListExtKey, $term)
{
    $termList = helper_base::get_termlist_terms($auth, $termListExtKey, array($term));
    return $termList[0]['id'];
}
Пример #8
0
 /**
  * Handles the construction of a submission array from a set of form values.
  * @param array $values Associative array of form data values.
  * @param array $args iform parameters.
  * @return array Submission structure.
  */
 public static function get_submission($values, $args)
 {
     $subsampleModels = array();
     $read = array('nonce' => $values['read_nonce'], 'auth_token' => $values['read_auth_token']);
     if (!isset($values['page']) || $values['page'] == 'site') {
         // submitting the first page, with top level sample details
         // keep the first count date on a subsample for use later.
         // only create if a new sample: if existing, then this will already exist.
         if (isset($values['C1:sample:date']) && !isset($values['sample:id'])) {
             $sampleMethods = helper_base::get_termlist_terms(array('read' => $read), 'indicia:sample_methods', array('Timed Count Count'));
             $smp = array('fkId' => 'parent_id', 'model' => array('id' => 'sample', 'fields' => array('survey_id' => array('value' => $values['sample:survey_id']), 'website_id' => array('value' => $values['website_id']), 'date' => array('value' => $values['C1:sample:date']), 'sample_method_id' => array('value' => $sampleMethods[0]['id']))), 'copyFields' => array('entered_sref' => 'entered_sref', 'entered_sref_system' => 'entered_sref_system'));
             //                   'copyFields' => array('date_start'=>'date_start','date_end'=>'date_end','date_type'=>'date_type'));
             $subsampleModels[] = $smp;
         }
     } else {
         if ($values['page'] == 'occurrences') {
             // at this point there is a parent supersample.
             // loop from 1 to numberOfCounts, or number of existing subsamples, whichever is bigger.
             $subSamples = data_entry_helper::get_population_data(array('table' => 'sample', 'extraParams' => $read + array('parent_id' => $values['sample:id']), 'nocache' => true));
             for ($i = 1; $i <= max(count($subSamples), $args['numberOfCounts']); $i++) {
                 if (isset($values['C' . $i . ':sample:id']) || isset($values['C' . $i . ':sample:date']) && $values['C' . $i . ':sample:date'] != '') {
                     $subSample = array('website_id' => $values['website_id'], 'survey_id' => $values['sample:survey_id']);
                     $occurrences = array();
                     $occModels = array();
                     foreach ($values as $field => $value) {
                         $parts = explode(':', $field, 2);
                         if ($parts[0] == 'C' . $i) {
                             $subSample[$parts[1]] = $value;
                         }
                         if ($parts[0] == 'O' . $i) {
                             $occurrences[$parts[1]] = $value;
                         }
                     }
                     ksort($occurrences);
                     foreach ($occurrences as $field => $value) {
                         // have take off O<i> do is now <j>:<ttlid>:<occid>:<attrid>:<attrvalid> - sorted in <j> order
                         $parts = explode(':', $field);
                         $occurrence = array('website_id' => $values['website_id']);
                         if ($parts[1] != '--ttlid--') {
                             $occurrence['taxa_taxon_list_id'] = $parts[1];
                         }
                         if ($parts[2] != '--occid--') {
                             $occurrence['id'] = $parts[2];
                         }
                         if ($value == '') {
                             $occurrence['deleted'] = 't';
                         } else {
                             if ($parts[4] == '--valid--') {
                                 $occurrence['occAttr:' . $parts[3]] = $value;
                             } else {
                                 $occurrence['occAttr:' . $parts[3] . ':' . $parts[4]] = $value;
                             }
                         }
                         if (array_key_exists('occurrence:determiner_id', $values)) {
                             $occurrence['determiner_id'] = $values['occurrence:determiner_id'];
                         }
                         if (array_key_exists('occurrence:record_status', $values)) {
                             $occurrence['record_status'] = $values['occurrence:record_status'];
                         }
                         if (isset($occurrence['id']) || !isset($occurrence['deleted'])) {
                             $occ = data_entry_helper::wrap($occurrence, 'occurrence');
                             $occModels[] = array('fkId' => 'sample_id', 'model' => $occ);
                         }
                     }
                     $smp = array('fkId' => 'parent_id', 'model' => data_entry_helper::wrap($subSample, 'sample'), 'copyFields' => array('entered_sref' => 'entered_sref', 'entered_sref_system' => 'entered_sref_system'));
                     // from parent->to child
                     if (!isset($subSample['sample:deleted']) && count($occModels) > 0) {
                         $smp['model']['subModels'] = $occModels;
                     }
                     $subsampleModels[] = $smp;
                 }
             }
         }
     }
     $sampleMod = submission_builder::build_submission($values, array('model' => 'sample'));
     if (count($subsampleModels) > 0) {
         $sampleMod['subModels'] = $subsampleModels;
     }
     return $sampleMod;
 }
Пример #9
0
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  */
 public static function get_form($args, $node, $response = null)
 {
     global $user;
     data_entry_helper::$helpTextPos = 'before';
     $checks = self::check_prerequisites();
     $args = self::getArgDefaults($args);
     if ($checks !== true) {
         return $checks;
     }
     iform_load_helpers(array('map_helper'));
     data_entry_helper::add_resource('jquery_form');
     self::$ajaxFormUrl = iform_ajaxproxy_url($node, 'loc-smp-occ');
     self::$ajaxFormLocationUrl = iform_ajaxproxy_url($node, 'location');
     self::$ajaxFormSampleUrl = iform_ajaxproxy_url($node, 'sample');
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $settings = array('SiteLocationType' => helper_base::get_termlist_terms($auth, 'indicia:location_types', array(empty($args['location_type_term']) ? 'TreeSite' : $args['location_type_term'])), 'TreeLocationType' => helper_base::get_termlist_terms($auth, 'indicia:location_types', array(empty($args['tree_type_term']) ? 'Tree' : $args['tree_type_term'])), 'locationId' => isset($_GET['id']) ? $_GET['id'] : null, 'canAllocUser' => $args['manager_permission'] == "" || user_access($args['manager_permission']));
     $settings['attributes'] = data_entry_helper::getAttributes(array('id' => $settings['locationId'], 'valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'location_type_id' => $settings['SiteLocationType'][0]['id'], 'multiValue' => true));
     $settings['tree_attributes'] = data_entry_helper::getAttributes(array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'location_type_id' => $settings['TreeLocationType'][0]['id'], 'multiValue' => true));
     if ($args['allow_user_assignment']) {
         if (false == ($settings['cmsUserAttr'] = extract_cms_user_attr($settings['attributes']))) {
             return 'This form is designed to be used with the "CMS User ID" attribute setup for Site locations in the survey, or the "Allow users to be assigned to locations" option unticked.';
         }
         // keep a copy of the cms user ID attribute so we can use it later.
         self::$cmsUserAttrId = $settings['cmsUserAttr']['attributeId'];
         $found = false;
         foreach ($settings['tree_attributes'] as $idx => $attr) {
             if (strcasecmp($attr['caption'], 'Recorder Name') === 0) {
                 data_entry_helper::$javascript .= "indiciaData.assignedRecorderID = " . $attr['attributeId'] . ";\n";
                 $found = true;
                 break;
             }
         }
         if (!$found) {
             return 'This form is designed to be used with the "Recorder Name" attribute setup for Tree locations in the survey, or the "Allow users to be assigned to locations" option unticked.';
         }
     }
     // TBD data drive
     $definitions = array(array("attr" => "111", "term" => "WD", "target" => "112", "required" => true, "title" => "You must pick the dominant species from this drop down list when the WD (Dominant Species) checkbox is set."), array("attr" => "111", "term" => "WP", "target" => "113", "required" => false, "title" => "If known, you may enter the year that the woodland was planted in when the WP (Planted Date) checkbox is set."));
     $common = "var check_attrs = function(){\n";
     data_entry_helper::$javascript .= "var checkbox_changed_base = function(changedSelector, targetSelector, required){\n  \$(changedSelector).closest('span').find('label.inline-error').remove();\n  \$(changedSelector).closest('span').find('.ui-state-error').removeClass('ui-state-error');\n  \$(changedSelector).closest('span').find('label.error').remove();\n  \$(changedSelector).closest('span').find('.error').removeClass('error');\n  if(\$(changedSelector).attr('checked'))\n    \$(targetSelector).addClass(required ? 'required' : 'notrequired').closest('span').show();\n  else {\n    \$(targetSelector).removeClass('required').val('').closest('span').hide();\n  }\n};\nvar check_attr_def = [];\ncheck_attrs = function(){\n  for(var i=0; i<check_attr_def.length; i++){\n    checkbox_changed_base(check_attr_def[i][0], check_attr_def[i][1], check_attr_def[i][2]);\n  }\n}\n";
     foreach ($definitions as $defn) {
         data_entry_helper::$javascript .= "\$('[id^=locAttr\\\\:" . $defn["attr"] . "\\\\:]:checkbox').each(function(idx,elem){\n  if(\$('label[for='+\$(elem).attr('id').replace(/:/g,'\\\\:')+']').html() == '" . $defn["term"] . "'){\n    var tgt = \$('#locAttr\\\\:" . $defn["target"] . "');\n    tgt.prev('label').remove();\n    tgt.next('br').remove();\n    var span = \$('<span/>');\n    \$(elem).closest('span').append(span);\n    span.append(tgt);" . ($defn["required"] ? "\n    span.append('<span class=\"deh-required\">*</span>');" : "") . "\n    tgt.attr('title','" . $defn["title"] . "');\n    \$(elem).change(function(e){checkbox_changed_base(e.target, '#locAttr\\\\:" . $defn["target"] . "', " . ($defn["required"] ? "true" : "false") . ");});\n    check_attr_def.push([elem, '#locAttr\\\\:" . $defn["target"] . "', " . ($defn["required"] ? "true" : "false") . "]);\n  }\n});\n";
     }
     data_entry_helper::$javascript .= "check_attrs();\nindiciaData.trees = {};\n";
     $settings['trees'] = array();
     if ($settings['locationId']) {
         data_entry_helper::load_existing_record($auth['read'], 'location', $settings['locationId']);
         // Work out permissions for this user
         $canEdit = $args['manager_permission'] == "" || user_access($args['manager_permission']);
         if ($args['allow_user_assignment'] && isset($settings['cmsUserAttr']['default']) && !empty($settings['cmsUserAttr']['default'])) {
             foreach ($settings['cmsUserAttr']['default'] as $value) {
                 // multi value
                 if ($value['default'] == $user->uid) {
                     // comparing string against int so no triple equals
                     $canEdit = true;
                     break;
                 }
             }
         }
         if (!$canEdit) {
             return 'You do not have access to this site.';
         }
         $trees = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('view' => 'detail', 'parent_id' => $settings['locationId'], 'deleted' => 'f', 'orderby' => 'name'), 'nocache' => true));
         foreach ($trees as $tree) {
             $id = $tree['id'];
             data_entry_helper::$javascript .= "indiciaData.trees[{$id}] = {'id':'" . $tree['id'] . "','name':'" . str_replace("'", "\\'", $tree['name']) . "','geom':'" . $tree['centroid_geom'] . "','sref':'" . $tree['centroid_sref'] . "','system':'" . $tree['centroid_sref_system'] . "'};\n";
             $settings['trees'][$id] = $tree;
         }
     }
     $r = '<div id="controls">';
     $headerOptions = array('tabs' => array('#site-details' => lang::get('Site Details')));
     $tabOptions = array('divId' => 'controls', 'style' => 'Tabs');
     if ($settings['locationId']) {
         $headerOptions['tabs']['#site-trees'] = lang::get('Tree Details');
         $tabOptions['active'] = '#site-trees';
     }
     $r .= data_entry_helper::tab_header($headerOptions);
     data_entry_helper::enable_tabs($tabOptions);
     $settings['treeSampleMethod'] = helper_base::get_termlist_terms($auth, 'indicia:sample_methods', array('TreeInitialRegistration'));
     // TODO put in error check, add in $arg driving of text value
     $settings['treeSampleMethod'] = $settings['treeSampleMethod'][0];
     $r .= self::get_site_tab($auth, $args, $settings);
     if ($settings['locationId']) {
         $r .= self::get_site_trees_tab($auth, $args, $settings);
         data_entry_helper::enable_validation('tree-form');
         data_entry_helper::setup_jquery_validation_js();
     }
     $r .= '</div>';
     // controls
     data_entry_helper::enable_validation('input-form');
     if (function_exists('drupal_set_breadcrumb')) {
         $breadcrumb = array();
         $breadcrumb[] = l(lang::get('Home'), '<front>');
         $breadcrumb[] = l(lang::get('Sites'), $args['sites_list_path']);
         if ($settings['locationId']) {
             $breadcrumb[] = data_entry_helper::$entity_to_load['location:name'];
         } else {
             $breadcrumb[] = lang::get('New Site');
         }
         drupal_set_breadcrumb($breadcrumb);
     }
     // Inform JS where to post data to for AJAX form saving
     data_entry_helper::$javascript .= 'indiciaData.ajaxFormPostUrl="' . self::$ajaxFormUrl . "\";\n";
     data_entry_helper::$javascript .= 'indiciaData.ajaxFormPostLocationUrl="' . self::$ajaxFormLocationUrl . "\";\n";
     data_entry_helper::$javascript .= 'indiciaData.ajaxFormPostSampleUrl="' . self::$ajaxFormSampleUrl . "\";\n";
     data_entry_helper::$javascript .= 'indiciaData.website_id="' . $args['website_id'] . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.indiciaSvc = '" . data_entry_helper::$base_url . "';\n";
     data_entry_helper::$javascript .= "indiciaData.readAuth = {nonce: '" . $auth['read']['nonce'] . "', auth_token: '" . $auth['read']['auth_token'] . "'};\n";
     data_entry_helper::$javascript .= "indiciaData.currentTree = '';\n";
     data_entry_helper::$javascript .= "indiciaData.treeTypeId = '" . $settings['TreeLocationType'][0]['id'] . "';\n";
     data_entry_helper::$javascript .= "indiciaData.treeDeleteConfirm = \"" . lang::get('Are you sure you wish to delete tree') . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.treeInsertConfirm = \"" . lang::get('Are you sure you wish to create a new tree (make sure you have saved any data)') . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.treeChangeConfirm = \"" . lang::get('Do you wish to save the currently unsaved changes you have made to the Tree Details?') . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.treeSampleMethodID = \"" . $settings['treeSampleMethod']['id'] . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.newVisitDialog = \"" . lang::get('You have just created a new tree. You can now create the first phenology observation data, or you can leave it until later. Do you wish to create the phenology observation data now? (This will open in a new window.)') . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.existingVisitDialog = \"" . lang::get('You have just modified an existing tree. Do you wish to create phenology observation data now? (This will open in a new window.)') . "\";\n";
     data_entry_helper::$javascript .= "indiciaData.visitURL = \"" . ($args['visit_path'] . (strpos($args['visit_path'], '?') === false ? '?' : '&') . "new=1&location_id=") . "\";\n";
     $r .= '<a id="visit_link" style="display:none;" href="" target="_blank" />';
     if ($settings['locationId']) {
         data_entry_helper::$onload_javascript .= "var first=true;\njQuery.each(indiciaData.trees, function(idx, tree) {\n  if(first) selectTree(tree.id, true);  \nfirst=false\n});\nif(first) insertTree();\n";
     }
     return $r;
 }
Пример #10
0
 /**
  * Insert any custom JS for this form: this may be related to attributes, which are included
  * as part of inherited generic code.
  * Does not include any HTML.
  */
 protected static function get_control_customJS($auth, $args, $tabalias, $options)
 {
     if (lang::get('validation_required') != 'validation_required') {
         data_entry_helper::$late_javascript .= "\n\$.validator.messages.required = \"" . lang::get('validation_required') . "\";";
     }
     if (lang::get('validation_max') != 'validation_max') {
         data_entry_helper::$late_javascript .= "\n\$.validator.messages.max = \$.validator.format(\"" . lang::get('validation_max') . "\");";
     }
     if (lang::get('validation_min') != 'validation_min') {
         data_entry_helper::$late_javascript .= "\n\$.validator.messages.min = \$.validator.format(\"" . lang::get('validation_min') . "\");";
     }
     if (lang::get('validation_number') != 'validation_number') {
         data_entry_helper::$late_javascript .= "\n\$.validator.messages.number = \$.validator.format(\"" . lang::get('validation_number') . "\");";
     }
     if (lang::get('validation_digits') != 'validation_digits') {
         data_entry_helper::$late_javascript .= "\n\$.validator.messages.digits = \$.validator.format(\"" . lang::get('validation_digits') . "\");";
     }
     if (lang::get('validation_integer') != 'validation_integer') {
         data_entry_helper::$late_javascript .= "\n\$.validator.messages.integer = \$.validator.format(\"" . lang::get('validation_integer') . "\");";
     }
     iform_mnhnl_addCancelButton($args['interface']);
     $r .= self::getSiteTypeJS(parent::$auth, $args);
     data_entry_helper::$javascript .= "\nif(\$.browser.msie && \$.browser.version < 9)\n  \$('input[type=radio],[type=checkbox]').live('click', function(){\n    this.blur();\n    this.focus();\n});\n";
     // Move the date after the Institution
     $institutionAttrID = iform_mnhnl_getAttrID($auth, $args, 'sample', 'Institution');
     if ($institutionAttrID) {
         data_entry_helper::$javascript .= "\nvar institutionAttr = jQuery('[name=smpAttr\\:" . $institutionAttrID . "],[name^=smpAttr\\:" . $institutionAttrID . "\\:],[name^=smpAttr\\:" . $institutionAttrID . "\\[\\]]').not(':hidden').eq(0).closest('.control-box').next();\nvar recorderField = jQuery('#sample\\\\:recorder_names');\nvar recorderLabel = recorderField.prev().filter('label');\nvar recorderRequired = recorderField.next();\nrecorderRequired.next().filter('br').remove();\nvar recorderText = recorderRequired.next();\nrecorderText.next().filter('br').remove();\nrecorderText.next().filter('br').remove();\ninstitutionAttr.after('<br/>');\ninstitutionAttr.after('<br/>');\ninstitutionAttr.after(recorderText);\ninstitutionAttr.after('<br/>');\ninstitutionAttr.after(recorderRequired);\ninstitutionAttr.after(recorderField);\ninstitutionAttr.after(recorderLabel);\nvar dateField = jQuery('#sample\\\\:date');\nvar dateLabel = dateField.prev().filter('label');\nvar dateRequired = dateField.next();\ndateRequired.next().filter('br').remove();\ninstitutionAttr.after('<br/>');\ninstitutionAttr.after(dateRequired);\ninstitutionAttr.after(dateField);\ninstitutionAttr.after(dateLabel);\n";
     }
     // Break up the Disturbances: makes assumptions on format, and assumes that we are doing a checkbox list
     if (!empty($args['addBreaks'])) {
         $addBreakSpecs = explode(';', $args['addBreaks']);
         foreach ($addBreakSpecs as $addBreakSpec) {
             $addBreakDetail = explode(',', $addBreakSpec);
             $addBreakDetail[0] = str_replace(':', '\\:', $addBreakDetail[0]);
             data_entry_helper::$javascript .= "jQuery('[name^=" . $addBreakDetail[0] . "\\:],[name^=" . $addBreakDetail[0] . "\\[\\]]').filter('[value=" . $addBreakDetail[1] . "],[value^=" . $addBreakDetail[1] . "\\:]').parent().before('<br/>');\n";
         }
     }
     $disturbOtherAttrID = iform_mnhnl_getAttrID($auth, $args, 'sample', 'Disturbances other comment');
     if (!$disturbOtherAttrID) {
         return lang::get('This form must be used with a survey that has the Disturbances other comment attribute associated with it.');
     }
     $disturb2AttrID = iform_mnhnl_getAttrID($auth, $args, 'sample', 'Disturbances2');
     if (!$disturb2AttrID) {
         return lang::get('This form must be used with a survey that has the Disturbances2 attribute associated with it.');
     }
     $disturb2OtherTerm = helper_base::get_termlist_terms($auth, 'bats2:disturbances', array('Other'));
     $disturb2PlannedTerm = helper_base::get_termlist_terms($auth, 'bats2:disturbances', array('Planned renovations'));
     $disturb2InProgTerm = helper_base::get_termlist_terms($auth, 'bats2:disturbances', array('Renovations in progress'));
     $disturb2RecentTerm = helper_base::get_termlist_terms($auth, 'bats2:disturbances', array('Renovations recently completed'));
     data_entry_helper::$javascript .= "\njQuery('[name=smpAttr\\:" . $disturb2AttrID . "\\[\\]],[name^=smpAttr\\:" . $disturb2AttrID . "\\:]').filter('[value=" . $disturb2PlannedTerm[0]['meaning_id'] . "],[value^=" . $disturb2PlannedTerm[0]['meaning_id'] . "\\:]').change(function(){\n  if(this.checked)\n    jQuery('[name=smpAttr\\:" . $disturb2AttrID . "\\[\\]],[name^=smpAttr\\:" . $disturb2AttrID . "\\:]').filter('[value=" . $disturb2InProgTerm[0]['meaning_id'] . "],[value^=" . $disturb2InProgTerm[0]['meaning_id'] . "\\:],[value=" . $disturb2RecentTerm[0]['meaning_id'] . "],[value^=" . $disturb2RecentTerm[0]['meaning_id'] . "\\:]').removeAttr('checked');\n});\njQuery('[name=smpAttr\\:" . $disturb2AttrID . "\\[\\]],[name^=smpAttr\\:" . $disturb2AttrID . "\\:]').filter('[value=" . $disturb2InProgTerm[0]['meaning_id'] . "],[value^=" . $disturb2InProgTerm[0]['meaning_id'] . "\\:]').change(function(){\n  if(this.checked)\n    jQuery('[name=smpAttr\\:" . $disturb2AttrID . "\\[\\]],[name^=smpAttr\\:" . $disturb2AttrID . "\\:]').filter('[value=" . $disturb2PlannedTerm[0]['meaning_id'] . "],[value^=" . $disturb2PlannedTerm[0]['meaning_id'] . "\\:],[value=" . $disturb2RecentTerm[0]['meaning_id'] . "],[value^=" . $disturb2RecentTerm[0]['meaning_id'] . "\\:]').removeAttr('checked');\n});\njQuery('[name=smpAttr\\:" . $disturb2AttrID . "\\[\\]],[name^=smpAttr\\:" . $disturb2AttrID . "\\:]').filter('[value=" . $disturb2RecentTerm[0]['meaning_id'] . "],[value^=" . $disturb2RecentTerm[0]['meaning_id'] . "\\:]').change(function(){\n  if(this.checked)\n    jQuery('[name=smpAttr\\:" . $disturb2AttrID . "\\[\\]],[name^=smpAttr\\:" . $disturb2AttrID . "\\:]').filter('[value=" . $disturb2InProgTerm[0]['meaning_id'] . "],[value^=" . $disturb2InProgTerm[0]['meaning_id'] . "\\:],[value=" . $disturb2PlannedTerm[0]['meaning_id'] . "],[value^=" . $disturb2PlannedTerm[0]['meaning_id'] . "\\:]').removeAttr('checked');\n});\nvar myTerm = jQuery('[name=smpAttr\\:" . $disturb2AttrID . "\\[\\]],[name^=smpAttr\\:" . $disturb2AttrID . "\\:]').filter('[value=" . $disturb2OtherTerm[0]['meaning_id'] . "],[value^=" . $disturb2OtherTerm[0]['meaning_id'] . "\\:]');\nmyTerm.change(function(){\n    if(this.checked)\n      jQuery('[name=smpAttr\\:" . $disturbOtherAttrID . "],[name^=smpAttr\\:" . $disturbOtherAttrID . "\\:]').addClass('required').removeAttr('readonly');\n    else\n      jQuery('[name=smpAttr\\:" . $disturbOtherAttrID . "],[name^=smpAttr\\:" . $disturbOtherAttrID . "\\:]').removeClass('required').val('').attr('readonly',true);\n  });\nvar other = jQuery('[name=smpAttr\\:" . $disturbOtherAttrID . "],[name^=smpAttr\\:" . $disturbOtherAttrID . "\\:]');\nother.next().remove(); // remove break\nother.prev().remove(); // remove legend\nother.removeClass('wide').remove(); // remove Other field, then bolt in after the other radio button.\nmyTerm.parent().append(other);\nmyTerm.change();\njQuery('span').filter('.control-box').each(function(idex, elem){\n  if(jQuery(elem).find(':checkbox').length){\n    jQuery(elem).prev().filter('label').addClass('auto-width');\n    jQuery(elem).prev().after('<br/>');\n  }\n});\n";
     if (!empty($args['attributeValidation'])) {
         $rules = array();
         $argRules = explode(';', $args['attributeValidation']);
         foreach ($argRules as $rule) {
             $rules[] = explode(',', $rule);
         }
         foreach ($rules as $rule) {
             // But only do if a parameter given as rule:param - eg min:-40
             for ($i = 1; $i < count($rule); $i++) {
                 if (strpos($rule[$i], ':') !== false) {
                     $details = explode(':', $rule[$i]);
                     data_entry_helper::$late_javascript .= "\njQuery('[name=" . str_replace(':', '\\:', $rule[0]) . "],[name^=" . str_replace(':', '\\:', $rule[0]) . "\\:]').attr('" . $details[0] . "'," . $details[1] . ");";
                 } else {
                     if ($rule[$i] == 'no_record') {
                         data_entry_helper::$late_javascript .= "\nnoRecCheckbox = jQuery('[name=" . str_replace(':', '\\:', $rule[0]) . "],[name^=" . str_replace(':', '\\:', $rule[0]) . "\\:]').filter(':checkbox');\nnumRows = jQuery('.scPresence').filter('[value=1]').length;\nif(numRows>0)\n  noRecCheckbox.addClass('no_record').removeAttr('checked').attr('disabled','disabled');\nelse\n  noRecCheckbox.addClass('no_record').removeAttr('disabled');\n";
                     } else {
                         if (substr($rule[0], 3, 4) != 'Attr') {
                             // have to add for non attribute case.
                             data_entry_helper::$late_javascript .= "\njQuery('[name=" . str_replace(':', '\\:', $rule[0]) . "],[name^=" . str_replace(':', '\\:', $rule[0]) . "\\:]').addClass('" . $rule[$i] . "');";
                         }
                     }
                 }
             }
         }
     }
     data_entry_helper::$late_javascript .= "// JS for survey methods grid control.\n\$.validator.addMethod('method-presence', function(value, element){\n    var valid = jQuery('.method-presence').filter('[checked]').length > 0;\n\tif(valid){\n\t  jQuery('.method-presence').removeClass('ui-state-error').next('p.inline-error').remove();\n\t}\n\treturn valid;\n},\n  \"" . lang::get('validation_method-presence') . "\");\n\$.validator.addMethod('scNumDead', function(value, element){\n  var assocNumAlive = jQuery(element).closest('tr').find('.scNumAlive');\n  var valid = true;\n  if(jQuery(element).val()!='' || assocNumAlive.val()!='') {\n    valid = ((jQuery(element).val()=='' ? 0 : jQuery(element).val()) + (assocNumAlive.val()=='' ? 0 : assocNumAlive.val()) > 0);\n  }\n  if(valid){\n    assocNumAlive.removeClass('ui-state-error')\n  } else {\n    assocNumAlive.addClass('ui-state-error')\n  }\n  return valid;\n},\n  \"" . lang::get('validation_scNumDead') . "\");\njQuery('.scNumAlive').live('change', function(){\n  var assocNumDead = jQuery(this).closest('tr').find('.scNumDead');\n  assocNumDead.valid();\n});\n\$.validator.addMethod('no_record', function(value, element){\n  var numRows = jQuery('.scPresence').filter('[value=1]').length;\n  var isChecked = jQuery(element).filter('[checked]').length>0;\n  if(isChecked) return(numRows==0)\n  else  return(numRows>0);\n},\n  \"" . lang::get('validation_no_record') . "\");\n\$.validator.addMethod('scCheckTaxon', function(value, element){\n  var retVal = false;\n  var row = jQuery(element).closest('tr');\n  var classList = row.attr('class').split(/\\s+/);\n  \$.each( classList, function(index, item){\n    if (item.split(/-/)[0] === 'scMeaning') {\n      if(jQuery('.'+item).find(':checkbox').filter('[checked]').length>0) retVal=true;\n      if(jQuery('.'+item).find(':text').not('[value=]').length>0) retVal=true;\n    }});\n    // this is called at two points: when a value is entered and when the save button is called.\n  // If this fails then fine, there is no data entered for this species.\n  // If it passes then look up all the error paragraphs.\n  if(retVal){\n    \$.each( classList, function(index, item){\n      if (item.split(/-/)[0] === 'scMeaning') {\n        jQuery('.'+item).find('p.inline-error').each(function(index, item){\n          if(item.innerHTML == \"" . lang::get('validation_taxon_data') . "\")\n            jQuery(item).prev('.ui-state-error').removeClass('ui-state-error');\n            jQuery(item).remove();\n        });\n      }});\n  }\n  var inputs = row.find('input');\n  if(inputs.eq(inputs.length-1)[0] != element) return true; // nb jQuery 1.3, we are only interested in displaying the error for the last entry in the row.\n  return retVal;\n},\n  \"" . lang::get('validation_taxon_data') . "\");\njQuery('.scCheckTaxon:checkbox').live('change', function(value, element){\n  if(jQuery(this).filter('[checked]').length > 0){\n    var row = jQuery(this).closest('tr');\n    var classList = row.attr('class').split(/\\s+/);\n    \$.each( classList, function(index, item){\n      if (item.split(/-/)[0] === 'scMeaning') {\n        jQuery('.'+item).find('p.inline-error').each(function(index, item){\n          if(item.innerHTML == \"" . lang::get('validation_taxon_data') . "\")\n            jQuery(item).prev('.ui-state-error').removeClass('ui-state-error');\n            jQuery(item).remove();\n        });\n      }});\n  }\n});\n";
     return '';
 }
 /**
  * Handles the construction of a submission array from a set of form values.
  * @param array $values Associative array of form data values.
  * @param array $args iform parameters.
  * @return array Submission structure.
  * @todo: Implement this method
  */
 public static function get_submission($values, $args)
 {
     $subsampleModels = array();
     if (isset($values['page']) && $values['page'] == 'speciesmap') {
         $submission = data_entry_helper::build_sample_subsamples_occurrences_submission($values);
     } else {
         if (!isset($values['page']) || $values['page'] == 'mainSample') {
             // submitting the first page, with top level sample details
             $read = array('nonce' => $values['read_nonce'], 'auth_token' => $values['read_auth_token']);
             if (!isset($values['sample:entered_sref'])) {
                 // the sample does not have sref data, as the user has just picked a transect site at this point. Copy the
                 // site's centroid across to the sample. Should this be cached?
                 $site = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $read + array('view' => 'detail', 'id' => $values['sample:location_id'], 'deleted' => 'f')));
                 $site = $site[0];
                 $values['sample:entered_sref'] = $site['centroid_sref'];
                 $values['sample:entered_sref_system'] = $site['centroid_sref_system'];
             }
             // Build the subsamples
             $sections = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $read + array('view' => 'detail', 'parent_id' => $values['sample:location_id'], 'deleted' => 'f'), 'nocache' => true));
             if (isset($values['sample:id'])) {
                 $existingSubSamples = data_entry_helper::get_population_data(array('table' => 'sample', 'extraParams' => $read + array('view' => 'detail', 'parent_id' => $values['sample:id'], 'deleted' => 'f'), 'nocache' => true));
             } else {
                 $existingSubSamples = array();
             }
             $sampleMethods = helper_base::get_termlist_terms(array('read' => $read), 'indicia:sample_methods', array('Transect Section'));
             $attributes = data_entry_helper::getAttributes(array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $read, 'survey_id' => $values['sample:survey_id'], 'sample_method_id' => $sampleMethods[0]['id'], 'multiValue' => false));
             $smpDate = self::parseSingleDate($values['sample:date']);
             foreach ($sections as $section) {
                 $smp = false;
                 $exists = false;
                 foreach ($existingSubSamples as $existingSubSample) {
                     if ($existingSubSample['location_id'] == $section['id']) {
                         $exists = $existingSubSample;
                         break;
                     }
                 }
                 if (!$exists) {
                     $smp = array('fkId' => 'parent_id', 'model' => array('id' => 'sample', 'fields' => array('survey_id' => array('value' => $values['sample:survey_id']), 'website_id' => array('value' => $values['website_id']), 'date' => array('value' => $values['sample:date']), 'location_id' => array('value' => $section['id']), 'entered_sref' => array('value' => $section['centroid_sref']), 'entered_sref_system' => array('value' => $section['centroid_sref_system']), 'sample_method_id' => array('value' => $sampleMethods[0]['id']))), 'copyFields' => array('date_start' => 'date_start', 'date_end' => 'date_end', 'date_type' => 'date_type'));
                     foreach ($attributes as $attr) {
                         foreach ($values as $key => $value) {
                             $parts = explode(':', $key);
                             if (count($parts) > 1 && $parts[0] == 'smpAttr' && $parts[1] == $attr['attributeId']) {
                                 $smp['model']['fields']['smpAttr:' . $attr['attributeId']] = array('value' => $value);
                             }
                         }
                     }
                 } else {
                     // need to ensure any date change is propagated: only do if date has changed for performance reasons.
                     $subSmpDate = self::parseSingleDate($exists['date_start']);
                     if (strcmp($smpDate, $subSmpDate)) {
                         $smp = array('fkId' => 'parent_id', 'model' => array('id' => 'sample', 'fields' => array('survey_id' => array('value' => $values['sample:survey_id']), 'website_id' => array('value' => $values['website_id']), 'id' => array('value' => $exists['id']), 'date' => array('value' => $values['sample:date']), 'location_id' => array('value' => $exists['location_id']))), 'copyFields' => array('date_start' => 'date_start', 'date_end' => 'date_end', 'date_type' => 'date_type'));
                     }
                 }
                 if ($smp) {
                     $subsampleModels[] = $smp;
                 }
             }
         }
         $submission = submission_builder::build_submission($values, array('model' => 'sample'));
         if (count($subsampleModels) > 0) {
             $submission['subModels'] = $subsampleModels;
         }
     }
     return $submission;
 }
 private static function user_control($args, $readAuth, $node, &$options)
 {
     // we don't use the userID option as the user_id can be blank, and will force the parameter request if left as a blank
     global $user;
     if (!isset($args['includeUserFilter']) || !$args['includeUserFilter']) {
         return '';
     }
     // if the user is changed then we must reset the location
     $siteUrlParams = self::get_site_url_params();
     var_dump($siteUrlParams);
     $options['extraParams']['user_id'] = $siteUrlParams[self::$userKey]['value'] == "branch" ? '' : $siteUrlParams[self::$userKey]['value'];
     $userList = array();
     if (function_exists('module_exists') && module_exists('easy_login') && function_exists('hostsite_get_user_field')) {
         $options['my_user_id'] = hostsite_get_user_field('indicia_user_id');
     } else {
         $options['my_user_id'] = $user->uid;
     }
     if (!isset($args['managerPermission']) || $args['managerPermission'] == "" || !user_access($args['managerPermission'])) {
         // user is a normal user
         $userList[$user->uid] = $user;
         // just me
     } else {
         // user is manager, so need to load the list of users they can choose to report against
         if (!($userList = self::_fetchDBCache($user->uid))) {
             $userList = array();
             if (!isset($args['userLookUp']) || !$args['userLookUp']) {
                 // look up all users, not just those that have entered data.
                 $results = db_query('SELECT uid, name FROM {users}');
                 if (version_compare(VERSION, '7', '<')) {
                     while ($result = db_fetch_object($results)) {
                         if ($result->uid) {
                             // ignore unauthorised user, uid zero
                             $account = user_load($result->uid);
                             $userList[$account->uid] = $account;
                         }
                     }
                 } else {
                     foreach ($results as $result) {
                         // DB handling is different in 7
                         if ($result->uid) {
                             // ignore unauthorised user, uid zero
                             $account = user_load($result->uid);
                             $userList[$account->uid] = $account;
                         }
                     }
                 }
             } else {
                 // need to scan param_presets for survey_id.
                 $presets = get_options_array_with_user_data($args['param_presets']);
                 if (!isset($presets['survey_id']) || $presets['survey_id'] == '') {
                     return lang::get('User control: survey_id missing from presets.');
                 }
                 if (function_exists('module_exists') && module_exists('easy_login')) {
                     $sampleArgs = array('extraParams' => array_merge(array('view' => 'detail', 'website_id' => $args['website_id'], 'survey_id' => $presets['survey_id']), $readAuth), 'table' => 'sample', 'columns' => 'created_by_id');
                     $sampleList = data_entry_helper::get_population_data($sampleArgs);
                     if (isset($sampleList['error'])) {
                         return $sampleList['error'];
                     }
                     $uList = array();
                     foreach ($sampleList as $sample) {
                         $uList[intval($sample['created_by_id'])] = true;
                     }
                     // This next bit is DRUPAL specific, but we are using the Easy Login module.
                     if (count($uList) > 0) {
                         if (version_compare(VERSION, '7', '<')) {
                             $results = db_query("SELECT DISTINCT pv.uid, u.name FROM {users} u " . "JOIN {profile_values} pv ON pv.uid=u.uid " . "JOIN {profile_fields} pf ON pf.fid=pv.fid AND pf.name='profile_indicia_user_id' " . "AND pv.value IN (" . implode(',', array_keys($uList)) . ")");
                             while ($result = db_fetch_object($results)) {
                                 if ($result->uid) {
                                     $userList[$result->uid] = $result;
                                 }
                             }
                         } else {
                             // @todo: This needs optimising as in the Drupal 6 version - don't want to load ALL users
                             $results = db_query('SELECT uid, name FROM {users}');
                             foreach ($results as $result) {
                                 // DB processing is different in 7
                                 if ($result->uid) {
                                     $account = user_load($result->uid);
                                     /* this loads the field_ fields, so no need for profile_load_profile */
                                     if (isset($account->profile_indicia_user_id) && isset($uList[$account->profile_indicia_user_id]) && $uList[$account->profile_indicia_user_id]) {
                                         $userList[$account->uid] = $account;
                                     }
                                 }
                             }
                         }
                     }
                 } else {
                     // not easy login so use the CMS User ID attribute hanging off the to find which users have entered data.
                     $attrArgs = array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $readAuth, 'survey_id' => $presets['survey_id']);
                     if (isset($args['userLookUpSampleMethod']) && $args['userLookUpSampleMethod'] != "") {
                         $sampleMethods = helper_base::get_termlist_terms(array('read' => $readAuth), 'indicia:sample_methods', array(trim($args['userLookUpSampleMethod'])));
                         $attrArgs['sample_method_id'] = $sampleMethods[0]['id'];
                     }
                     $sampleAttributes = data_entry_helper::getAttributes($attrArgs, false);
                     if (false == ($cmsAttr = extract_cms_user_attr($sampleAttributes))) {
                         return lang::get('User control: CMS User ID sample attribute missing.');
                     }
                     $attrListArgs = array('extraParams' => array_merge(array('view' => 'list', 'website_id' => $args['website_id'], 'sample_attribute_id' => $cmsAttr['attributeId']), $readAuth), 'table' => 'sample_attribute_value');
                     $attrList = data_entry_helper::get_population_data($attrListArgs);
                     if (isset($attrList['error'])) {
                         return $attrList['error'];
                     }
                     foreach ($attrList as $attr) {
                         if ($attr['id'] != null) {
                             $userList[intval($attr['raw_value'])] = true;
                         }
                     }
                     // This next bit is DRUPAL specific
                     $results = db_query('SELECT uid, name FROM {users}');
                     if (version_compare(VERSION, '7', '<')) {
                         while ($result = db_fetch_object($results)) {
                             if ($result->uid && isset($userList[$result->uid]) && $userList[$result->uid]) {
                                 $userList[$account->uid] = user_load($result->uid);
                             }
                         }
                     } else {
                         foreach ($results as $result) {
                             // DB handling is different in 7
                             if ($result->uid && isset($userList[$result->uid]) && $userList[$result->uid]) {
                                 $userList[$account->uid] = user_load($result->uid);
                             }
                         }
                     }
                 }
             }
             self::_cacheResponse($user->uid, $userList);
         }
     }
     $ctrlid = 'calendar-user-select-' . $node->nid;
     $ctrl = '<label for="' . $ctrlid . '" class="user-select-label">' . lang::get('Filter by recorder') . ': </label><select id="' . $ctrlid . '" class="user-select">' . '<option value=' . $user->uid . ' class="user-select-option" ' . ($siteUrlParams[self::$userKey]['value'] == $user->uid ? 'selected="selected" ' : '') . '>' . lang::get('My data') . '</option>' . (isset($args['branchManagerPermission']) && $args['branchManagerPermission'] != "" && user_access($args['branchManagerPermission']) ? '<option value="branch" class="user-select-option" ' . ($siteUrlParams[self::$userKey]['value'] == "branch" ? 'selected="selected" ' : '') . '>' . lang::get('Branch data') . '</option>' : '') . '<option value="all" class="user-select-option" ' . ($siteUrlParams[self::$userKey]['value'] == '' ? 'selected="selected" ' : '') . '>' . lang::get('All recorders') . '</option>';
     $found = $siteUrlParams[self::$userKey]['value'] == $user->uid || isset($args['branchManagerPermission']) && $args['branchManagerPermission'] != "" && user_access($args['branchManagerPermission']) && $siteUrlParams[self::$userKey]['value'] == "branch" || $siteUrlParams[self::$userKey]['value'] == '';
     $userListArr = array();
     foreach ($userList as $id => $account) {
         // if account comes from cache, then it is an array, if from drupal an object.
         if (!is_array($account)) {
             $account = get_object_vars($account);
         }
         if ($account !== true && $id != $user->uid) {
             $userListArr[$id] = $account['name'];
         }
     }
     natcasesort($userListArr);
     foreach ($userListArr as $id => $name) {
         $ctrl .= '<option value=' . $id . ' class="user-select-option" ' . ($siteUrlParams[self::$userKey]['value'] == $id ? 'selected="selected" ' : '') . '>' . $name . '</option>';
         $found = $found || $siteUrlParams[self::$userKey]['value'] == $id;
     }
     // masquerading may produce some odd results when flipping between accounts.
     switch ($siteUrlParams[self::$userKey]['value']) {
         case '':
             $options['downloadFilePrefix'] .= lang::get('AllRecorders') . '_';
             break;
         case $user->uid:
             $options['downloadFilePrefix'] .= lang::get('MyData') . '_';
             break;
         case "branch":
             $options['downloadFilePrefix'] .= lang::get('MyBranch') . '_';
             break;
         default:
             // if account comes from cache, then it is an array, if from drupal an object.
             $account = is_array($userList[$siteUrlParams[self::$userKey]['value']]) ? $userList[$siteUrlParams[self::$userKey]['value']] : get_object_vars($userList[$siteUrlParams[self::$userKey]['value']]);
             $options['downloadFilePrefix'] .= preg_replace('/[^A-Za-z0-9]/i', '', $account['name']) . '_';
             break;
     }
     // Haven't found the selected user on the list: this means select defaults to top option which is the user themselves.
     if (!$found) {
         $siteUrlParams[self::$userKey]['value'] = $user->uid;
     }
     $ctrl .= '</select>';
     self::set_up_control_change($ctrlid, self::$userKey, array('locationID'));
     return $ctrl;
 }
Пример #13
0
 protected static function getSiteTypeJS($auth, $args)
 {
     $siteTypeAttr = iform_mnhnl_getAttr($auth, $args, 'location', $args['siteTypeAttr']);
     if (!$siteTypeAttr) {
         return lang::get('This form must be used with a survey that has the ' . $args['siteTypeAttr'] . ' attribute associated with it.');
     }
     $siteTypeAttrID = $siteTypeAttr['attributeId'];
     $siteTypeTermList = helper_base::get_termlist_terms($auth, intval($siteTypeAttr['termlist_id']), array('Other'));
     $siteTypeOtherAttrID = iform_mnhnl_getAttrID($auth, $args, 'location', 'site type other');
     if (!$siteTypeOtherAttrID) {
         return lang::get("This form must be used with a survey that has the 'site type other' location attribute associated with it.");
     }
     // this needs to handle site type as radio (bats1) or checkbox (bats2)
     // type-required is only used for checkboxes - radio ones can use required as per normal.
     data_entry_helper::$javascript .= "\nvar myTerms = jQuery('[name=locAttr\\:" . $siteTypeAttrID . "],[name=locAttr\\:" . $siteTypeAttrID . "\\[\\]],[name^=locAttr\\:" . $siteTypeAttrID . "\\:]').not(':hidden');\nmyTerms_change = function(){\n  if(jQuery('.type-required').filter('[checked]').length > 0)\n    jQuery('.type-required').removeClass('ui-state-error').next('p.inline-error').remove();\n  // for a radio button the change is fired on the newly checked button\n  // for a checkbox button the change is fired on the button itself\n  var attrs = jQuery('[name=locAttr\\:" . $siteTypeAttrID . "],[name=locAttr\\:" . $siteTypeAttrID . "\\[\\]],[name^=locAttr\\:" . $siteTypeAttrID . "\\:]').filter('[value=" . $siteTypeTermList[0]['meaning_id'] . "],[value^=" . $siteTypeTermList[0]['meaning_id'] . "\\:]').filter('[checked]');\n  if(attrs.length>0)\n    jQuery('[name=locAttr\\:" . $siteTypeOtherAttrID . "],[name^=locAttr\\:" . $siteTypeOtherAttrID . "\\:]').addClass('required').removeAttr('readonly');\n  else\n    jQuery('[name=locAttr\\:" . $siteTypeOtherAttrID . "],[name^=locAttr\\:" . $siteTypeOtherAttrID . "\\:]').removeClass('required').val('').attr('readonly',true);\n};\nvar other = jQuery('[name=locAttr\\:" . $siteTypeOtherAttrID . "],[name^=locAttr\\:" . $siteTypeOtherAttrID . "\\:]');\nother.next('br').remove();\nother.prev('label').remove();\nother.removeClass('wide').remove(); // remove Other field, then bolt in after the 'other' selection.\nmyTerms.change(myTerms_change).filter('[value=" . $siteTypeTermList[0]['meaning_id'] . "],[value^=" . $siteTypeTermList[0]['meaning_id'] . "\\:]').parent().append(other);\nif(myTerms.filter(':checkbox').length>0){\n  myTerms.addClass('type-required');\n  other.after('<span class=\"deh-required\">*</span>');\n  \$.validator.addMethod('type-required', function(value, element){\n    var valid = jQuery('.type-required').filter('[checked]').length > 0 || element != jQuery('.type-required').eq(0)[0];\n    if(valid){\n      jQuery('.type-required').removeClass('ui-state-error').next('p.inline-error').remove();\n    }\n    return valid;\n  }, \"" . lang::get('At least one site type entry must be selected.') . "\");\n}\nmyTerms_change();\n";
     return '';
 }
Пример #14
0
 public static function species_checklist($options)
 {
     global $indicia_templates;
     //    $options = data_entry_helper::check_arguments(func_get_args(), array('speciesListID', 'occAttrs', 'readAuth', 'extraParams'));
     $options = self::get_species_checklist_options($options);
     data_entry_helper::add_resource('json');
     data_entry_helper::add_resource('autocomplete');
     $occAttrControls = array();
     $occAttrCaptions = array();
     $occAttrs = array();
     // Load any existing sample's occurrence data into $entity_to_load
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         self::preload_species_checklist_occurrences(data_entry_helper::$entity_to_load['sample:id'], $options['readAuth'], $options);
     }
     // at this point we are only dealing with occurrence attributes.
     $attributes = data_entry_helper::getAttributes(array('valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => "{fieldname}", 'extraParams' => $options['readAuth'], 'survey_id' => array_key_exists('survey_id', $options) ? $options['survey_id'] : null));
     $numRows = 0;
     $maxCellsPerRow = $i = 1;
     do {
         $foundRows = false;
         $attrsPerRow = 0;
         foreach ($attributes as $attribute) {
             if ($attribute["inner_structure_block"] == "Row" . $i) {
                 $numRows = $i;
                 $foundRows = true;
                 $attrsPerRow++;
             }
         }
         $i++;
         $maxCellsPerRow = max($maxCellsPerRow, $attrsPerRow);
     } while ($foundRows);
     if ($numRows) {
         $foundRows = true;
     } else {
         $numRows = 1;
         $maxCellsPerRow = count($attributes);
     }
     $options['extraParams']['view'] = 'detail';
     $options['numRows'] = 1 + ($options['includeSubSample'] ? 1 : 0) + $numRows * ($options['useCaptionsInPreRow'] ? 2 : 1) + ($options['includeOccurrenceComment'] ? 1 : 0);
     $recordList = self::get_species_checklist_record_list($options);
     $grid = "";
     $precision = false;
     if ($options['includeSubSample']) {
         $grid .= "<input type='hidden' name='includeSubSample' id='includeSubSample' value='true' >";
         $smpattributes = data_entry_helper::getAttributes(array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => "smpAttr", 'extraParams' => $options['readAuth'] + array("untranslatedCaption" => "Precision"), 'survey_id' => array_key_exists('survey_id', $options) ? $options['survey_id'] : null, 'sample_method_id' => $options['subsample_method_id']), false);
         $precision = count($smpattributes) > 0 ? $smpattributes[0] : false;
         $maxCellsPerRow = max($maxCellsPerRow, 2 + ($options['displaySampleDate'] ? 1 : 0) + ($precision ? 1 : 0));
     }
     // If we managed to read the species list data we can proceed
     if (!array_key_exists('error', $recordList)) {
         // Get the attribute and control information required to build the custom occurrence attribute columns
         self::species_checklist_prepare_attributes($options, $attributes, $occAttrControls, $occAttrCaptions, $occAttrs);
         $grid .= self::get_species_checklist_clonable_row($options, $occAttrControls, $occAttrCaptions, $attributes, $precision);
         $grid .= '<table class="ui-widget ui-widget-content mnhnl-species-grid ' . $options['class'] . '" id="' . $options['id'] . '">';
         $grid .= self::get_species_checklist_header($options, $occAttrs);
         $rows = array();
         $rowIdx = 1;
         /*
          * fieldnames: SC:<RowGroup>:<sampleID>:<ttlID>:<occurrenceID>:[present|sample:[date|etc]|occAttr:<attrID>[:<valueID>]]
          */
         foreach ($recordList as $rec) {
             $ttlid = $rec['taxon']['id'];
             $occ_existing_record_id = $rec['occurrence']['id'];
             $smp_existing_record_id = $options['includeSubSample'] ? $rec['sample']['id'] : '';
             $firstCell = data_entry_helper::mergeParamsIntoTemplate($rec['taxon'], 'taxon_label', false, true);
             $prefix = "sc:{$rowIdx}:{$smp_existing_record_id}:{$ttlid}:{$occ_existing_record_id}";
             if ($options['PHPtaxonLabel']) {
                 $firstCell = eval($firstCell);
             }
             $colspan = ' colspan="' . $maxCellsPerRow . '"';
             // assume always removeable and presence is hidden.
             $row = "<td class='ui-state-default remove-row' rowspan='" . $options['numRows'] . "' >X</td>";
             $row .= str_replace('{content}', $firstCell, str_replace('{colspan}', $colspan, $indicia_templates['taxon_label_cell']));
             $row .= "<td class='scPresenceCell' style='display:none'><input type='hidden' class='scPresence' name='{$prefix}:present' value='true'/></td>";
             $rows[] = '<tr class="scMeaning-' . $rec['taxon']['taxon_meaning_id'] . ' first scOcc-' . $occ_existing_record_id . '">' . $row . '</tr>';
             if ($options['includeSubSample']) {
                 $row = '<tr class="scMeaning-' . $rec['taxon']['taxon_meaning_id'] . ' scDataRow">';
                 if ($options['displaySampleDate']) {
                     $ctrlID = $ctrlName = $prefix . ":sample:date";
                     self::_getCtrlNames($ctrlName, $oldCtrlName, false);
                     // TBD need to attach a date control
                     $row .= "<td class='ui-widget-content'><label class='auto-width' for='{$ctrlID}'>" . lang::get('LANG_Date') . ":</label> <input type='text' id='{$ctrlID}' class='date' name='{$ctrlName}' value='" . data_entry_helper::$entity_to_load[$oldCtrlName] . "' /></td>";
                 }
                 $ctrlName = $prefix . ":sample:geom";
                 self::_getCtrlNames($ctrlName, $oldCtrlName, false);
                 $row .= "<td class='ui-widget-content'><input type='hidden' id='{$prefix}:imp-geom' name='{$ctrlName}' value='" . data_entry_helper::$entity_to_load[$oldCtrlName] . "' />";
                 $ctrlName = $prefix . ":sample:entered_sref";
                 self::_getCtrlNames($ctrlName, $oldCtrlName, false);
                 $row .= "<input type='hidden' id='{$prefix}:imp-sref' name='{$ctrlName}' value='" . data_entry_helper::$entity_to_load[$oldCtrlName] . "' />";
                 if (isset(data_entry_helper::$entity_to_load[$oldCtrlName]) && data_entry_helper::$entity_to_load[$oldCtrlName] != "") {
                     $parts = explode(' ', data_entry_helper::$entity_to_load[$oldCtrlName]);
                     $parts[0] = explode(',', $parts[0]);
                     $parts[0] = $parts[0][0];
                 } else {
                     $parts = array('', '');
                 }
                 // for existing samples, don't need to specify sample_method, as it won't change.
                 $row .= "<label class='auto-width' for='{$prefix}:imp-srefX'>" . lang::get('LANG_Species_X_Label') . ":</label> <input type='text' id='{$prefix}:imp-srefX' class='imp-srefX required integer' name='dummy:srefX' value='{$parts['0']}' /><span class='deh-required'>*</span></td>\n<td class='ui-widget-content'><label class='auto-width' for='{$prefix}:imp-srefY'>" . lang::get('LANG_Species_Y_Label') . ":</label> <input type='text' id='{$prefix}:imp-srefY' class='imp-srefY required integer' name='dummy:srefY' value='{$parts['1']}'/><span class='deh-required'>*</span>\n</td>";
                 if ($precision) {
                     //  'sc::'.$smp.':'.$occurrence['taxa_taxon_list_id'].':'.$occurrence['id'].':'.$sampleAttr['fieldname']] = $sampleAttr['default'];
                     // sc:<rowIdx>:<smp_id>:<ttlid>:<occ_id>:[field]";
                     $ctrlId = $ctrlName = $prefix . ":smpAttr:" . $precision['attributeId'];
                     self::_getCtrlNames($ctrlName, $oldCtrlName, true);
                     $existing_value = isset(data_entry_helper::$entity_to_load[$oldCtrlName]) ? data_entry_helper::$entity_to_load[$oldCtrlName] : (array_key_exists('default', $precision) ? $precision['default'] : '');
                     $ctrlOptions = array('class' => 'scPrecision ' . (isset($precision['class']) ? ' ' . $precision['class'] : ''), 'extraParams' => $options['readAuth'], 'language' => $options['language']);
                     if (isset($options['lookUpKey'])) {
                         $ctrlOptions['lookUpKey'] = $options['lookUpKey'];
                     }
                     // if($options['useCaptionsInHeader'] || $options['useCaptionsInPreRow']) unset($attrDef['caption']);
                     $precision['fieldname'] = $ctrlName;
                     $precision['id'] = $ctrlId;
                     $precision['default'] = $existing_value;
                     //$headerPreRow .= '<td class="ui-widget-content" ><label class="auto-width">'.$occAttrCaptions[$attrId].':</label></td>';
                     $row .= '<td class="ui-widget-content scSmpAttrCell">' . data_entry_helper::outputAttribute($precision, $ctrlOptions) . '</td>';
                 }
                 if ($maxCellsPerRow > 2 + ($options['displaySampleDate'] ? 1 : 0) + ($precision ? 1 : 0)) {
                     $row .= "<td class='ui-widget-content' colspan=" . ($maxCellsPerRow - (2 + ($options['displaySampleDate'] ? 1 : 0) + ($precision ? 1 : 0))) . "></td>";
                 }
                 $rows[] = $row . "</tr>";
             }
             for ($i = 1; $i <= $numRows; $i++) {
                 $row = "";
                 $headerPreRow = "";
                 $numCtrls = 0;
                 foreach ($attributes as $attrId => $attribute) {
                     if ($foundRows && $attribute["inner_structure_block"] != "Row" . $i) {
                         continue;
                     }
                     $ctrlId = $ctrlName = $prefix . ":occAttr:{$attrId}";
                     // the control prebuild method fails for multiple value checkboxes, as each checkbox can be attached to a different attribute value record.
                     if ($attribute["control_type"] == 'checkbox_group') {
                         // implies multi_value
                         $attrDef = array_merge($attribute);
                         // sc:<rowIdx>:<smp_id>:<ttlid>:<occ_id>:[field]";
                         $ctrlArr = explode(':', $ctrlName, 6);
                         $default = array();
                         if ($ctrlArr[4] != "") {
                             $search = preg_grep("/^sc:" . '[0-9]*' . ":{$ctrlArr['2']}:{$ctrlArr['3']}:{$ctrlArr['4']}:{$ctrlArr['5']}" . ':[0-9]*$/', array_keys(data_entry_helper::$entity_to_load));
                             if (count($search) > 0) {
                                 foreach ($search as $existingField) {
                                     $ctrlNameX = explode(':', $existingField);
                                     $ctrlNameX[1] = $ctrlArr[1];
                                     // copy row index across.
                                     $ctrlNameX = implode(':', $ctrlNameX);
                                     $default[] = array('fieldname' => $ctrlNameX, 'default' => data_entry_helper::$entity_to_load[$existingField]);
                                 }
                             }
                         }
                         // Get the control class if available. If the class array is too short, the last entry gets reused for all remaining.
                         $ctrlOptions = array('class' => self::species_checklist_occ_attr_class($options, $idx, $attrDef['untranslatedCaption']) . (isset($attrDef['class']) ? ' ' . $attrDef['class'] : ''), 'extraParams' => $options['readAuth'], 'language' => $options['language']);
                         if (isset($options['lookUpKey'])) {
                             $ctrlOptions['lookUpKey'] = $options['lookUpKey'];
                         }
                         if ($options['useCaptionsInHeader'] || $options['useCaptionsInPreRow']) {
                             unset($attrDef['caption']);
                         }
                         $attrDef['fieldname'] = $ctrlName;
                         $attrDef['id'] = $ctrlId;
                         if (count($default) > 0) {
                             $attrDef['default'] = $default;
                         }
                         $oc = data_entry_helper::outputAttribute($attrDef, $ctrlOptions);
                     } else {
                         // use prebuilt attribute list
                         $control = $occAttrControls[$attrId];
                         self::_getCtrlNames($ctrlName, $oldCtrlName, true);
                         if (isset(data_entry_helper::$entity_to_load[$oldCtrlName])) {
                             $existing_value = data_entry_helper::$entity_to_load[$oldCtrlName];
                         } elseif (array_key_exists('default', $attributes[$attrId])) {
                             $existing_value = $attributes[$attrId]['default'];
                         } else {
                             $existing_value = '';
                         }
                         $oc = str_replace('{fieldname}', $ctrlName, $control);
                         if (!empty($existing_value)) {
                             // For select controls, specify which option is selected from the existing value
                             if (strpos($oc, '<select') !== false) {
                                 $oc = str_replace('value="' . $existing_value . '"', 'value="' . $existing_value . '" selected="selected"', $oc);
                             } else {
                                 if (strpos($oc, 'radio') !== false) {
                                     $oc = str_replace('value="' . $existing_value . '"', 'value="' . $existing_value . '" checked="checked"', $oc);
                                 } else {
                                     if (strpos($oc, 'checkbox') !== false) {
                                         if ($existing_value == "1") {
                                             $oc = str_replace('type="checkbox"', 'type="checkbox" checked="checked"', $oc);
                                         }
                                     } else {
                                         $oc = str_replace('value=""', 'value="' . $existing_value . '"', $oc);
                                     }
                                 }
                             }
                             // assume all error handling/validation done client side
                         }
                     }
                     $numCtrls++;
                     $row .= str_replace(array('{label}', '{content}'), array($attributes[$attrId]['caption'], $oc), $indicia_templates[$options['attrCellTemplate']]);
                     $headerPreRow .= '<td class="ui-widget-content" ><label class="auto-width">' . $occAttrCaptions[$attrId] . ':</label></td>';
                 }
                 if ($maxCellsPerRow > $numCtrls) {
                     $row .= "<td class='ui-widget-content sg-filler' colspan=" . ($maxCellsPerRow - $numCtrls) . "></td>";
                     $headerPreRow .= "<td class='ui-widget-content sg-filler' colspan=" . ($maxCellsPerRow - $numCtrls) . "></td>";
                 }
                 if ($options['useCaptionsInPreRow']) {
                     $rows[] = '<tr class="scMeaning-' . $rec['taxon']['taxon_meaning_id'] . ' scDataRow">' . $headerPreRow . '</tr>';
                 }
                 // no images.
                 $rows[] = '<tr class="scMeaning-' . $rec['taxon']['taxon_meaning_id'] . ' scDataRow' . ($i == $numRows && !$options['includeOccurrenceComment'] ? ' last' : '') . '">' . $row . '</tr>';
                 // no images.
             }
             if ($options['includeOccurrenceComment']) {
                 $ctrlId = $ctrlName = $prefix . ":occurrence:comment";
                 self::_getCtrlNames($ctrlName, $oldCtrlName, false);
                 if (isset(data_entry_helper::$entity_to_load[$oldCtrlName])) {
                     $existing_value = data_entry_helper::$entity_to_load[$oldCtrlName];
                 } else {
                     $existing_value = '';
                 }
                 $rows[] = "<tr class='scMeaning-" . $rec['taxon']['taxon_meaning_id'] . " scDataRow last'>\n<td class='ui-widget-content scCommentCell' {$colspan}>\n  <label for='{$ctrlId}' class='auto-width'>" . lang::get("Comment") . ":</label>\n  <input type='text' class='scComment' name='{$ctrlName}' id='{$ctrlId}' value=\"" . htmlspecialchars($existing_value) . "\">\n</td></tr>";
             }
             $rowIdx++;
         }
         $grid .= "\n<tbody>\n";
         if (count($rows) > 0) {
             $grid .= implode("\n", $rows) . "\n";
         } else {
             $grid .= "<tr style=\"display: none\"><td></td></tr>\n";
         }
         $grid .= "</tbody>\n</table>\n";
         // Javascript to add further rows to the grid
         data_entry_helper::$javascript .= "scRow=" . $rowIdx . ";\n\$('.sg-filler').each(function(idx,elem){\n  var colSpan = elem.colSpan;\n  var prev = \$(elem).prev();\n  prev[0].colSpan=colSpan+1;\n  \$(elem).remove();\n});\nvar formatter = function(rowData,taxonCell) {\n  taxonCell.html(\"" . lang::get('loading') . "\");\n  jQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/data/taxa_taxon_list/' + rowData.id +\n            '?mode=json&view=detail&auth_token=" . $options['readAuth']['auth_token'] . "&nonce=" . $options['readAuth']["nonce"] . "&callback=?', function(mdata) {\n    if(mdata instanceof Array && mdata.length>0){\n      jQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/data/taxa_taxon_list' +\n            '?mode=json&view=detail&auth_token=" . $options['readAuth']['auth_token'] . "&nonce=" . $options['readAuth']["nonce"] . "&taxon_meaning_id='+mdata[0].taxon_meaning_id+'&taxon_list_id=" . $options["speciesListID"] . "&callback=?', function(data) {\n        var taxaList = '';\n         if(data instanceof Array && data.length>0){\n          for (var i=0;i<data.length;i++){\n            if(data[i].preferred == 'f')\n              taxaList += (taxaList == '' ? '' : ', ')+data[i].taxon;\n            else\n              taxaList = '<em>'+data[i].taxon+'</em>'+(taxaList == '' ? '' : ', '+taxaList);\n            }\n          }\n          taxonCell.html(taxaList).removeClass('extraCommonNames');\n        });\n    }})\n};\nbindSpeciesOptions = {selectorID: \"addTaxonControl\",\n              url: \"" . data_entry_helper::$base_url . "index.php/services/data\",\n              gridId: \"" . $options['id'] . "\",\n              lookupListId: \"" . $options['speciesListID'] . "\",\n              auth_token : \"" . $options['readAuth']['auth_token'] . "\",\n              nonce : \"" . $options['readAuth']['nonce'] . "\",\n              formatter: formatter,\n              max: " . (isset($options['max_species_ids']) ? $options['max_species_ids'] : 25) . "};\n";
         if (isset($options['unitSpeciesMeaning'])) {
             data_entry_helper::$javascript .= "bindSpeciesOptions.unitSpeciesMeaning=\"" . $options['unitSpeciesMeaning'] . "\";\n";
         }
         if (isset($options['rowControl'])) {
             $rowControls = explode(';', $options['rowControl']);
             $controlArr = array();
             for ($i = 2; $i < count($rowControls); $i++) {
                 $parts = explode(',', $rowControls[$i], 2);
                 $termList = helper_base::get_termlist_terms(parent::$auth, $rowControls[1], array($parts[0]));
                 $controlArr[] = '{meaning_id: "' . $termList[0]['meaning_id'] . '" , rows: [' . $parts[1] . ']}';
             }
             data_entry_helper::$javascript .= "bindSpeciesOptions.rowControl = {selector: 'sc" . str_replace(' ', '', ucWords($rowControls[0])) . "',\n  controls: [" . implode(',', $controlArr) . "]};\n";
         }
         if (isset($options['singleSpeciesID'])) {
             $fetchOpts = array('table' => 'taxa_taxon_list', 'extraParams' => array('auth_token' => $options['readAuth']['auth_token'], 'nonce' => $options['readAuth']['nonce'], 'id' => $options['singleSpeciesID'], 'view' => 'detail', 'taxon_list_id' => $options['speciesListID']));
             $speciesRecord = data_entry_helper::get_population_data($fetchOpts);
             $grid .= "<input id='addTaxonControl' type='button' value='" . lang::get('Add another record') . "'>";
             data_entry_helper::$javascript .= "\nbindSpeciesOptions.speciesData = {id : \"" . $options['singleSpeciesID'] . "\", taxon_meaning_id: \"" . $speciesRecord[0]['taxon_meaning_id'] . "\"},\nbindSpeciesButton(bindSpeciesOptions);\n";
         } else {
             $grid .= "<label for='addTaxonControl' class='auto-width'>" . lang::get('Add species to list') . ":</label> <input id='addTaxonControl' name='addTaxonControl' >";
             data_entry_helper::$javascript .= "bindSpeciesAutocomplete(bindSpeciesOptions);\n";
         }
         // No help text
         if ($options['includeSubSample']) {
             $mapOptions = iform_map_get_map_options($options['args'], $options['readAuth']);
             $olOptions = iform_map_get_ol_options($options['args']);
             $mapOptions['tabDiv'] = 'tab-species';
             $mapOptions['divId'] = 'map2';
             $mapOptions['width'] = isset($options['map2Width']) ? $options['map2Width'] : "250px";
             $mapOptions['height'] = isset($options['map2Height']) ? $options['map2Height'] : "250px";
             $mapOptions['layers'] = array("superSampleLocationLayer", "occurrencePointLayer");
             $mapOptions['editLayer'] = true;
             $mapOptions['maxZoomBuffer'] = 0.3;
             $mapOptions['initialFeatureWkt'] = false;
             $mapOptions['srefId'] = 'sg-imp-sref';
             $mapOptions['srefLatId'] = 'sg-imp-srefX';
             $mapOptions['srefLongId'] = 'sg-imp-srefY';
             $mapOptions['standardControls'] = array('layerSwitcher', 'panZoomBar');
             $mapOptions['fillColor'] = $mapOptions['strokeColor'] = 'Fuchsia';
             $mapOptions['fillOpacity'] = 0.3;
             $mapOptions['strokeWidth'] = 1;
             $mapOptions['pointRadius'] = 6;
             //      $mapOptions['maxZoom']=$args['zoomLevel'];
         }
         $r = "<div><p>" . lang::get('LANG_SpeciesInstructions') . "</p>\n";
         if ($options['includeSubSample'] && $options['mapPosition'] == 'top') {
             $r .= '<div class="topMap-container">' . data_entry_helper::map_panel($mapOptions, $olOptions) . '</div>';
         }
         $r .= '<div class="grid-container">' . $grid . '</div>';
         if ($options['includeSubSample'] && $options['mapPosition'] != 'top') {
             $r .= '<div class="sideMap-container">' . data_entry_helper::map_panel($mapOptions, $olOptions) . '</div>';
         }
         if ($options['includeSubSample']) {
             data_entry_helper::$javascript .= "var speciesMapTabHandler = function(event, ui) {\n  panel = typeof ui.newPanel==='undefined' ? ui.panel : ui.newPanel[0];\n  if (panel.id==='" . $mapOptions['tabDiv'] . "') {\n    \$('.mnhnl-species-grid').find('tr').removeClass('highlight');\n    var div=\$('#" . $mapOptions['divId'] . "')[0];\n    div.map.editLayer.destroyFeatures();\n    // show the geometry currently held in the main locations part as the parent\n    var initialFeatureWkt = \$('#imp-boundary-geom').val();\n    if(initialFeatureWkt=='') initialFeatureWkt = \$('#imp-geom').val();\n    var parser = new OpenLayers.Format.WKT();\n    var feature = parser.read(initialFeatureWkt);\n    feature=convertFeature(feature, div.map.projection);\n    superSampleLocationLayer.destroyFeatures();\n    superSampleLocationLayer.addFeatures((typeof(feature)=='object'&&(feature instanceof Array) ? feature : [feature]));\n    var bounds=superSampleLocationLayer.getDataExtent();\n    occurrencePointLayer.removeAllFeatures();\n\t\$('.mnhnl-species-grid').find('.first').each(function(idx, elem){\n\t\tif(jQuery(elem).data('feature')!=null){\n\t\t\tjQuery(elem).data('feature').style=null;\n\t\t\toccurrencePointLayer.addFeatures([jQuery(elem).data('feature')]);\n\t\t}\n\t});\n    bounds.extend(occurrencePointLayer.getDataExtent());\n    // extend the boundary to include a buffer, so the map does not zoom too tight.\n    bounds.scale(1.2);\n    if (div.map.getZoomForExtent(bounds) > div.settings.maxZoom) {\n      // if showing something small, don't zoom in too far\n      div.map.setCenter(bounds.getCenterLonLat(), div.settings.maxZoom);\n    } else {\n      // Set the default view to show something triple the size of the grid square\n      // assume this is within the map extent.\n      div.map.zoomToExtent(bounds);\n    }\n  }\n};\nindiciaFns.bindTabsActivate(jQuery(jQuery('#" . $mapOptions['tabDiv'] . "').parent()), speciesMapTabHandler);\n";
         }
         // move the cloneable table outside the form, so allowing the validation to ignore it.
         data_entry_helper::$javascript .= "var cloneableDiv = \$('<div style=\"display: none;\">');\ncloneableDiv.append(\$('#" . $options['id'] . "-scClonable'));\n\$('#entry_form').before(cloneableDiv);\n";
         return $r . '</div>';
     } else {
         return $taxalist['error'];
     }
 }
 public static function get_occurrences_form($args, $node, $response)
 {
     global $user;
     if (!module_exists('iform_ajaxproxy')) {
         return 'This form must be used in Drupal with the Indicia AJAX Proxy module enabled.';
     }
     drupal_add_js('misc/tableheader.js');
     // for sticky heading
     data_entry_helper::add_resource('jquery_form');
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     // did the parent sample previously exist? Default is no.
     $existing = false;
     $url = explode('?', $args['my_obs_page'], 2);
     $params = NULL;
     $fragment = NULL;
     // fragment is always at the end.
     if (count($url) > 1) {
         $params = explode('#', $url[1], 2);
         if (count($params) > 1) {
             $fragment = $params[1];
         }
         $params = $params[0];
     } else {
         $url = explode('#', $url[0], 2);
         if (count($url) > 1) {
             $fragment = $url[1];
         }
     }
     $args['my_obs_page'] = url($url[0], array('query' => $params, 'fragment' => $fragment, 'absolute' => TRUE));
     if (isset($_POST['sample:id'])) {
         // have just posted an edit to the existing sample
         $sampleId = $_POST['sample:id'];
         $existing = true;
         data_entry_helper::load_existing_record($auth['read'], 'sample', $sampleId);
     } else {
         if (isset($response['outer_id'])) {
             // have just posted a new sample.
             $sampleId = $response['outer_id'];
         } else {
             $sampleId = $_GET['sample_id'];
             $existing = true;
         }
     }
     $sample = data_entry_helper::get_population_data(array('table' => 'sample', 'extraParams' => $auth['read'] + array('view' => 'detail', 'id' => $sampleId, 'deleted' => 'f')));
     $sample = $sample[0];
     $date = $sample['date_start'];
     if (!function_exists('module_exists') || !module_exists('easy_login')) {
         // work out the CMS User sample ID.
         $sampleMethods = helper_base::get_termlist_terms($auth, 'indicia:sample_methods', array('Field Observation'));
         $attributes = data_entry_helper::getAttributes(array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'sample_method_id' => $sampleMethods[0]['id']));
         if (false == ($cmsUserAttr = extract_cms_user_attr($attributes))) {
             return 'Easy Login not active: This form is designed to be used with the CMS User ID attribute setup for samples in the survey.';
         }
     }
     $allTaxonMeaningIdsAtSample = array();
     if ($existing) {
         // Only need to load the occurrences for a pre-existing sample
         $o = data_entry_helper::get_population_data(array('report' => 'reports_for_prebuilt_forms/UKBMS/ukbms_occurrences_list_for_sample', 'extraParams' => $auth['read'] + array('view' => 'detail', 'sample_id' => $sampleId, 'survey_id' => $args['survey_id'], 'date_from' => '', 'date_to' => '', 'taxon_group_id' => '', 'smpattrs' => '', 'occattrs' => $args['occurrence_attribute_ids']), 'nocache' => true));
         // build an array keyed for easy lookup
         $occurrences = array();
         $attrs = explode(',', $args['occurrence_attribute_ids']);
         if (!isset($o['error'])) {
             foreach ($o as $occurrence) {
                 if (!in_array($occurrence['taxon_meaning_id'], $allTaxonMeaningIdsAtSample)) {
                     $allTaxonMeaningIdsAtSample[] = $occurrence['taxon_meaning_id'];
                 }
                 $occurrences[$occurrence['taxon_meaning_id']] = array('ttl_id' => $occurrence['taxa_taxon_list_id'], 'ttl_id' => $occurrence['taxa_taxon_list_id'], 'preferred_ttl_id' => $occurrence['preferred_ttl_id'], 'o_id' => $occurrence['occurrence_id'], 'processed' => false);
                 foreach ($attrs as $attr) {
                     $occurrences[$occurrence['taxon_meaning_id']]['value_' . $attr] = $occurrence['attr_occurrence_' . $attr];
                     $occurrences[$occurrence['taxon_meaning_id']]['a_id_' . $attr] = $occurrence['attr_id_occurrence_' . $attr];
                 }
             }
         }
         // store it in data for JS to read when populating the grid
         data_entry_helper::$javascript .= "indiciaData.existingOccurrences = " . json_encode($occurrences) . ";\n";
     } else {
         data_entry_helper::$javascript .= "indiciaData.existingOccurrences = {};\n";
     }
     $occ_attributes = data_entry_helper::getAttributes(array('valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => 'occAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'multiValue' => false));
     data_entry_helper::$javascript .= "indiciaData.occurrence_totals = [];\n";
     data_entry_helper::$javascript .= "indiciaData.occurrence_attribute = [];\n";
     data_entry_helper::$javascript .= "indiciaData.occurrence_attribute_ctrl = [];\n";
     $defAttrOptions = array('extraParams' => $auth['read'] + array('orderby' => 'id'), 'suffixTemplate' => 'nosuffix');
     $occ_attributes_captions = array();
     foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
         $occ_attributes_captions[$idx] = $occ_attributes[$attr]['caption'];
         unset($occ_attributes[$attr]['caption']);
         $ctrl = data_entry_helper::outputAttribute($occ_attributes[$attr], $defAttrOptions);
         data_entry_helper::$javascript .= "indiciaData.occurrence_totals[" . $idx . "] = [];\n";
         data_entry_helper::$javascript .= "indiciaData.occurrence_attribute[" . $idx . "] = {$attr};\n";
         data_entry_helper::$javascript .= "indiciaData.occurrence_attribute_ctrl[" . $idx . "] = jQuery('" . str_replace("\n", "", $ctrl) . "');\n";
     }
     //    $r = "<h2>".$location[0]['name']." on ".$date."</h2>\n";
     $r = '<div id="tabs">';
     $tabs = array('#grid1' => t($args['species_tab_1']));
     // tab 1 is required.
     if (isset($args['taxon_list_id_2']) && $args['taxon_list_id_2'] != '') {
         $tabs['#grid2'] = t(isset($args['species_tab_2']) && $args['species_tab_2'] != '' ? $args['species_tab_2'] : 'Species Tab 2');
     }
     if (isset($args['taxon_list_id_3']) && $args['taxon_list_id_3'] != '') {
         $tabs['#grid3'] = t(isset($args['species_tab_3']) && $args['species_tab_3'] != '' ? $args['species_tab_3'] : 'Species Tab 3');
     }
     if (isset($args['taxon_list_id_4']) && $args['taxon_list_id_4'] != '') {
         $tabs['#grid4'] = t(isset($args['species_tab_4']) && $args['species_tab_4'] != '' ? $args['species_tab_4'] : 'Species Tab 4');
     }
     $tabs['#notes'] = lang::get('Notes');
     $r .= data_entry_helper::tab_header(array('tabs' => $tabs));
     data_entry_helper::enable_tabs(array('divId' => 'tabs', 'style' => 'Tabs'));
     // will assume that first table is based on abundance count, so do totals
     $r .= '<div id="grid1"><table id="observation-input1" class="ui-widget species-grid"><thead class="table-header"><tr><th class="ui-widget-header"></th>';
     foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
         $r .= '<th class="ui-widget-header col-' . ($idx + 1) . '">' . $occ_attributes_captions[$idx] . '</th>';
     }
     $r .= '<th class="ui-widget-header">' . lang::get('Total') . '</th></tr></thead>';
     $r .= '<tbody class="ui-widget-content occs-body"></tbody><tfoot><tr><td>Total</td>';
     foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
         $r .= '<td class="col-' . ($idx + 1) . ' ' . ($idx % 5 == 0 ? 'first' : '') . ' col-total"></td>';
     }
     $r .= '<td class="ui-state-disabled first"></td></tr></tfoot></table><br /><a href="' . $args['my_obs_page'] . '" class="button">' . lang::get('Finish') . '</a></div>';
     $extraParams = array_merge($auth['read'], array('taxon_list_id' => $args['taxon_list_id_1'], 'preferred' => 't', 'allow_data_entry' => 't', 'view' => 'cache', 'orderby' => 'taxonomic_sort_order'));
     if (!empty($args['taxon_filter_field_1']) && !empty($args['taxon_filter_1'])) {
         $extraParams[$args['taxon_filter_field_1']] = helper_base::explode_lines($args['taxon_filter_1']);
     }
     $taxa = data_entry_helper::get_population_data(array('table' => 'taxa_taxon_list', 'extraParams' => $extraParams));
     data_entry_helper::$javascript .= "indiciaData.speciesList1List = [";
     $first = true;
     foreach ($taxa as $taxon) {
         data_entry_helper::$javascript .= ($first ? "\n" : ",\n") . "{'id':" . $taxon['id'] . ",'taxon_meaning_id':" . $taxon['taxon_meaning_id'] . ",'preferred_language_iso':'" . $taxon["preferred_language_iso"] . "','default_common_name':'" . str_replace("'", "\\'", $taxon["default_common_name"]) . "'}";
         $first = false;
     }
     data_entry_helper::$javascript .= "];\n";
     data_entry_helper::$javascript .= "indiciaData.allTaxonMeaningIdsAtSample = [" . implode(',', $allTaxonMeaningIdsAtSample) . "];\n";
     if (isset($args['taxon_list_id_2']) && $args['taxon_list_id_2'] != '') {
         $r .= '<div id="grid2"><p id="grid2-loading">' . lang::get('Loading - Please Wait') . '</p><table id="observation-input2" class="ui-widget species-grid"><thead class="table-header"><tr><th class="ui-widget-header"></th>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<th class="ui-widget-header col-' . ($idx + 1) . '">' . $occ_attributes_captions[$idx] . '</th>';
         }
         $r .= '<th class="ui-widget-header">' . lang::get('Total') . '</th></tr></thead><tbody class="ui-widget-content occs-body"></tbody><tfoot><tr><td>Total</td>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<td class="col-' . ($idx + 1) . ' ' . ($idx % 5 == 0 ? 'first' : '') . ' col-total"></td>';
         }
         $r .= '<td class="ui-state-disabled first"></td></tr></tfoot></table><br /><a href="' . $args['my_obs_page'] . '" class="button">' . lang::get('Finish') . '</a></div>';
     }
     if (isset($args['taxon_list_id_3']) && $args['taxon_list_id_3'] != '') {
         $r .= '<div id="grid3"><p id="grid3-loading">' . lang::get('Loading - Please Wait') . '</p><table id="observation-input3" class="ui-widget species-grid"><thead class="table-header"><tr><th class="ui-widget-header"></th>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<th class="ui-widget-header col-' . ($idx + 1) . '">' . $occ_attributes_captions[$idx] . '</th>';
         }
         $r .= '<th class="ui-widget-header">' . lang::get('Total') . '</th></tr></thead><tbody class="ui-widget-content occs-body"></tbody><tfoot><tr><td>Total</td>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<td class="col-' . ($idx + 1) . ' ' . ($idx % 5 == 0 ? 'first' : '') . ' col-total"></td>';
         }
         $r .= '<td class="ui-state-disabled first"></td></tr></tfoot></table><br /><a href="' . $args['my_obs_page'] . '" class="button">' . lang::get('Finish') . '</a></div>';
     }
     if (isset($args['taxon_list_id_4']) && $args['taxon_list_id_4'] != '') {
         $r .= '<div id="grid4"><p id="grid4-loading">' . lang::get('Loading - Please Wait') . '</p><table id="observation-input4" class="ui-widget species-grid"><thead class="table-header"><tr><th class="ui-widget-header"></th>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<th class="ui-widget-header col-' . ($idx + 1) . '">' . $occ_attributes_captions[$idx] . '</th>';
         }
         $r .= '<th class="ui-widget-header">' . lang::get('Total') . '</th></tr></thead><tbody class="ui-widget-content occs-body"></tbody><tfoot><tr><td>Total</td>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<td class="col-' . ($idx + 1) . ' ' . ($idx % 5 == 0 ? 'first' : '') . ' col-total"></td>';
         }
         $r .= '<td class="ui-state-disabled first"></td></tr></tfoot></table>';
         $r .= '<label for="taxonLookupControl4" class="auto-width">' . lang::get('Add species to list') . ':</label> <input id="taxonLookupControl4" name="taxonLookupControl4" >';
         $r .= '<br /><a href="' . $args['my_obs_page'] . '" class="button">' . lang::get('Finish') . '</a></div>';
     }
     // for the comment form, we want to ensure that if there is a timeout error that it reloads the
     // data as stored in the DB.
     $reload = data_entry_helper::get_reload_link_parts();
     $reload['params']['sample_id'] = $parentSampleId;
     unset($reload['params']['new']);
     $reloadPath = $reload['path'];
     if (count($reload['params'])) {
         // decode params prior to encoding to prevent double encoding.
         foreach ($reload['params'] as $key => $param) {
             $reload['params'][$key] = urldecode($param);
         }
         $reloadPath .= '?' . http_build_query($reload['params']);
     }
     // fragment is always at the end. discard this.
     $reloadPath = explode('#', $reloadPath, 2);
     $reloadPath = $reloadPath[0];
     $r .= "<div id=\"notes\"><form method=\"post\" id=\"notes_form\" action=\"" . $reloadPath . "#notes\">\n";
     $r .= $auth['write'];
     $r .= '<input type="hidden" name="sample:id" value="' . $sampleId . '" />' . '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>' . '<input type="hidden" name="survey_id" value="' . $args['survey_id'] . '"/>' . '<input type="hidden" name="page" value="notes"/>';
     $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('When using this page, please remember that the data is not saved to the database as you go (which is the case for the previous tabs). In order to save the data entered in this page you must click on the Submit button at the bottom of the page.') . '</p>';
     $r .= data_entry_helper::textarea(array('fieldname' => 'sample:comment', 'label' => lang::get('Notes'), 'helpText' => "Use this space to input comments about this week's walk."));
     $r .= '<input type="submit" value="' . lang::get('Submit') . '" id="save-button"/></form>';
     $r .= '<br /><a href="' . $args['my_walks_page'] . '" class="button">' . lang::get('Finish') . '</a></div></div>';
     // enable validation on the comments form in order to include the simplified ajax queuing for the autocomplete.
     data_entry_helper::enable_validation('notes_form');
     // A stub form for AJAX posting when we need to create an occurrence
     $r .= '<form style="display: none" id="occ-form" method="post" action="' . iform_ajaxproxy_url($node, 'occurrence') . '">';
     $r .= '<input name="website_id" value="' . $args['website_id'] . '"/>';
     $r .= '<input name="occurrence:id" id="occid" />';
     $r .= '<input name="occurrence:taxa_taxon_list_id" id="ttlid" />';
     $r .= '<input name="occurrence:sample_id" value="' . $sampleId . '"/>';
     $r .= '<input name="occAttr:" id="occattr"/>';
     $r .= '<input name="transaction_id" id="transaction_id"/>';
     $r .= '<input name="user_id" value="' . hostsite_get_user_field('user_id', 1) . '"/>';
     $r .= '</form>';
     // tell the Javascript where to get species from.
     data_entry_helper::add_resource('jquery_ui');
     data_entry_helper::add_resource('json');
     data_entry_helper::add_resource('autocomplete');
     data_entry_helper::$javascript .= "indiciaData.speciesList1 = " . $args['taxon_list_id_1'] . ";\n";
     if (!empty($args['taxon_filter_field_1']) && !empty($args['taxon_filter_1'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesList1FilterField = '" . $args['taxon_filter_field_1'] . "';\n";
         $filterLines = helper_base::explode_lines($args['taxon_filter_1']);
         data_entry_helper::$javascript .= "indiciaData.speciesList1FilterValues = '" . json_encode($filterLines) . "';\n";
     }
     data_entry_helper::$javascript .= "indiciaData.speciesList2 = " . (isset($args['taxon_list_id_2']) && $args['taxon_list_id_2'] != "" ? $args['taxon_list_id_2'] : "-1") . ";\n";
     if (!empty($args['taxon_filter_field_2']) && !empty($args['taxon_filter_2'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesList2FilterField = '" . $args['taxon_filter_field_2'] . "';\n";
         $filterLines = helper_base::explode_lines($args['taxon_filter_2']);
         data_entry_helper::$javascript .= "indiciaData.speciesList2FilterValues = " . json_encode($filterLines) . ";\n";
     }
     data_entry_helper::$javascript .= "indiciaData.speciesList3 = " . (isset($args['taxon_list_id_3']) && $args['taxon_list_id_3'] != "" ? $args['taxon_list_id_3'] : "-1") . ";\n";
     if (!empty($args['taxon_filter_field_3']) && !empty($args['taxon_filter_3'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesList3FilterField = '" . $args['taxon_filter_field_3'] . "';\n";
         $filterLines = helper_base::explode_lines($args['taxon_filter_3']);
         data_entry_helper::$javascript .= "indiciaData.speciesList3FilterValues = " . json_encode($filterLines) . ";\n";
     }
     data_entry_helper::$javascript .= "indiciaData.speciesList4 = " . (isset($args['taxon_list_id_4']) && $args['taxon_list_id_4'] != "" ? $args['taxon_list_id_4'] : "-1") . ";\n";
     if (!empty($args['taxon_filter_field_4']) && !empty($args['taxon_filter_4'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesList4FilterField = '" . $args['taxon_filter_field_4'] . "';\n";
         $filterLines = helper_base::explode_lines($args['taxon_filter_4']);
         data_entry_helper::$javascript .= "indiciaData.speciesList4FilterValues = " . json_encode($filterLines) . ";\n";
     }
     // allow js to do AJAX by passing in the information it needs to post forms
     data_entry_helper::$javascript .= "bindSpeciesAutocomplete(\"taxonLookupControl4\",\"table#observation-input4\",\"" . data_entry_helper::$base_url . "index.php/services/data\", indiciaData.speciesList4,\n  indiciaData.speciesList4FilterField, indiciaData.speciesList4FilterValues, {\"auth_token\" : \"" . $auth['read']['auth_token'] . "\", \"nonce\" : \"" . $auth['read']['nonce'] . "\"},\n  \"" . lang::get('LANG_Duplicate_Taxon') . "\", 25, 4);\n\n";
     data_entry_helper::$javascript .= "indiciaData.indiciaSvc = '" . data_entry_helper::$base_url . "';\n";
     data_entry_helper::$javascript .= "indiciaData.readAuth = {nonce: '" . $auth['read']['nonce'] . "', auth_token: '" . $auth['read']['auth_token'] . "'};\n";
     data_entry_helper::$javascript .= "indiciaData.sample = " . $sampleId . ";\n";
     if (function_exists('module_exists') && module_exists('easy_login')) {
         data_entry_helper::$javascript .= "indiciaData.easyLogin = true;\n";
         $userId = hostsite_get_user_field('indicia_user_id');
         if (!empty($userId)) {
             data_entry_helper::$javascript .= "indiciaData.UserID = " . $userId . ";\n";
         } else {
             return '<p>Easy Login active but could not identify user</p>';
         }
         // something is wrong
     } else {
         data_entry_helper::$javascript .= "indiciaData.easyLogin = false;\n";
         data_entry_helper::$javascript .= "indiciaData.CMSUserAttrID = " . $cmsUserAttr['attributeId'] . ";\n";
         data_entry_helper::$javascript .= "indiciaData.CMSUserID = " . $user->uid . ";\n";
     }
     // Do an AJAX population of the grid rows.
     data_entry_helper::$javascript .= "loadSpeciesList();\njQuery('#tabs').bind('tabsshow', function(event, ui) {\n    var target = ui.panel;\n    // first get rid of any previous tables\n    jQuery('table.sticky-header').remove();\n    jQuery('table.sticky-enabled thead.tableHeader-processed').removeClass('tableHeader-processed');\n    jQuery('table.sticky-enabled.tableheader-processed').removeClass('tableheader-processed');\n    jQuery('table.species-grid.sticky-enabled').removeClass('sticky-enabled');\n    var table = jQuery('#'+target.id+' table.species-grid');\n    if(table.length > 0) {\n        table.addClass('sticky-enabled');\n        if(typeof Drupal.behaviors.tableHeader == 'object') // Drupal 7\n          Drupal.behaviors.tableHeader.attach(table.parent());\n        else // Drupal6 : it is a function\n          Drupal.behaviors.tableHeader(target);\n    }\n    // remove any hanging autocomplete select list.\n    jQuery('.ac_results').hide();\n});";
     return $r;
 }
 public static function get_occurrences_form($args, $node, $response)
 {
     if (!module_exists('iform_ajaxproxy')) {
         return 'This form must be used in Drupal with the Indicia AJAX Proxy module enabled.';
     }
     data_entry_helper::add_resource('jquery_form');
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     // did the parent sample previously exist? Default is no.
     $existing = false;
     if (isset($_POST['sample:id'])) {
         // have just posted an edit to the existing parent sample, so can use it to get the parent location id.
         $parentSampleId = $_POST['sample:id'];
         $parentLocId = $_POST['sample:location_id'];
         $date = $_POST['sample:date'];
         $existing = true;
     } else {
         if (isset($response['outer_id'])) {
             // have just posted a new parent sample, so can use it to get the parent location id.
             $parentSampleId = $response['outer_id'];
         } else {
             $parentSampleId = $_GET['sample_id'];
             $existing = true;
         }
         $sample = data_entry_helper::get_population_data(array('table' => 'sample', 'extraParams' => $auth['read'] + array('view' => 'detail', 'id' => $parentSampleId, 'deleted' => 'f')));
         $sample = $sample[0];
         $parentLocId = $sample['location_id'];
         $date = $sample['date_start'];
     }
     // find any attributes that apply to transect section samples.
     $sampleMethods = helper_base::get_termlist_terms($auth, 'indicia:sample_methods', array('Transect Section'));
     $attributes = data_entry_helper::getAttributes(array('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'], 'multiValue' => false));
     if ($existing) {
         // as the parent sample exists, we need to load the sub-samples and occurrences
         $subSamples = data_entry_helper::get_population_data(array('report' => 'library/samples/samples_list_for_parent_sample', 'extraParams' => $auth['read'] + array('sample_id' => $parentSampleId, 'date_from' => '', 'date_to' => '', 'sample_method_id' => '', 'smpattrs' => implode(',', array_keys($attributes))), 'nocache' => true));
         // transcribe the response array into a couple of forms that are useful elsewhere - one for outputting JSON so the JS knows about
         // the samples, and another for lookup of sample data by code later.
         $subSampleJson = array();
         $subSamplesByCode = array();
         foreach ($subSamples as $subSample) {
             $subSampleJson[] = '"' . $subSample['code'] . '": ' . $subSample['sample_id'];
             $subSamplesByCode[$subSample['code']] = $subSample;
         }
         data_entry_helper::$javascript .= "indiciaData.samples = { " . implode(', ', $subSampleJson) . "};\n";
         $o = data_entry_helper::get_population_data(array('report' => 'library/occurrences/occurrences_list_for_parent_sample', 'extraParams' => $auth['read'] + array('view' => 'detail', 'sample_id' => $parentSampleId, 'survey_id' => '', 'date_from' => '', 'date_to' => '', 'taxon_group_id' => '', 'smpattrs' => '', 'occattrs' => $args['occurrence_attribute_id']), 'nocache' => true));
         // build an array keyed for easy lookup
         $occurrences = array();
         foreach ($o as $occurrence) {
             $occurrences[$occurrence['sample_id'] . ':' . $occurrence['taxa_taxon_list_id']] = array('value' => $occurrence['attr_occurrence_' . $args['occurrence_attribute_id']], 'o_id' => $occurrence['occurrence_id'], 'a_id' => $occurrence['attr_id_occurrence_' . $args['occurrence_attribute_id']]);
         }
         // store it in data for JS to read when populating the grid
         data_entry_helper::$javascript .= "indiciaData.existingOccurrences = " . json_encode($occurrences) . ";\n";
     } else {
         data_entry_helper::$javascript .= "indiciaData.samples = {};\n";
         data_entry_helper::$javascript .= "indiciaData.existingOccurrences = {};\n";
     }
     $sections = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('view' => 'detail', 'parent_id' => $parentLocId, 'deleted' => 'f', 'orderby' => 'code')));
     $r = "<form method=\"post\"><div id=\"tabs\">\n";
     $r .= '<input type="hidden" name="sample:id" value="' . $parentSampleId . '" />';
     $r .= '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>';
     $r .= '<input type="hidden" name="survey_id" value="' . $args['survey_id'] . '"/>';
     $r .= '<input type="hidden" name="page" value="grid"/>';
     $r .= data_entry_helper::tab_header(array('tabs' => array('#grid' => lang::get('Enter Transect Data'), '#notes' => lang::get('Notes'))));
     data_entry_helper::enable_tabs(array('divId' => 'tabs', 'style' => $args['interface']));
     $r .= "<div id=\"grid\">\n";
     $r .= '<table id="transect-input" class="ui-widget"><thead>';
     $r .= '<tr><th class="ui-widget-header">' . lang::get('Sections') . '</th>';
     foreach ($sections as $section) {
         $r .= '<th class="ui-widget-header">' . $section['code'] . '</th>';
     }
     $r .= '</tr></thead>';
     $r .= '<tbody class="ui-widget-content">';
     // output rows at the top for any transect section level sample attributes
     $rowClass = '';
     foreach ($attributes as $attr) {
         $r .= '<tr ' . $rowClass . '><td>' . $attr['caption'] . '</td>';
         $rowClass = $rowClass == '' ? 'class="alt-row"' : '';
         unset($attr['caption']);
         foreach ($sections as $section) {
             // output a cell with the attribute - tag it with a class & id to make it easy to find from JS.
             $attrOpts = array('class' => 'smp-input smpAttr-' . $section['code'], 'id' => $attr['fieldname'] . ':' . $section['code'], 'extraParams' => $auth['read']);
             // if there is an existing value, set it and also ensure the attribute name reflects the attribute value id.
             if (isset($subSamplesByCode[$section['code']])) {
                 $attrOpts['fieldname'] = $attr['fieldname'] . ':' . $subSamplesByCode[$section['code']]['attr_id_sample_' . $attr['attributeId']];
                 $attr['default'] = $subSamplesByCode[$section['code']]['attr_sample_' . $attr['attributeId']];
             } else {
                 $attr['default'] = isset($_POST[$attr['fieldname']]) ? $_POST[$attr['fieldname']] : '';
             }
             $r .= '<td>' . data_entry_helper::outputAttribute($attr, $attrOpts) . '</td>';
         }
         $r .= '</tr>';
     }
     $r .= '</tbody>';
     $r .= '<tbody class="ui-widget-content" id="occs-body"></tbody>';
     $r .= '</table>';
     $r .= '</div>';
     $r .= "<div id=\"notes\">\n";
     $r .= data_entry_helper::textarea(array('fieldname' => 'sample:comment', 'label' => lang::get('Notes'), 'helpText' => "Use this space to input comments about this week's walk."));
     $r .= '<input type="submit" value="' . lang::get('Save') . '"/>';
     $r .= '</div></div></form>';
     // A stub form for AJAX posting when we need to create an occurrence
     $r .= '<form style="display: none" id="occ-form" method="post" action="' . iform_ajaxproxy_url($node, 'occurrence') . '">';
     $r .= '<input name="website_id" value="' . $args['website_id'] . '"/>';
     $r .= '<input name="occurrence:id" id="occid" />';
     $r .= '<input name="occurrence:taxa_taxon_list_id" id="ttlid" />';
     $r .= '<input name="occurrence:sample_id" id="occ_sampleid"/>';
     $r .= '<input name="occAttr:' . $args['occurrence_attribute_id'] . '" id="occattr"/>';
     $r .= '<input name="transaction_id" id="transaction_id"/>';
     $r .= '</form>';
     // A stub form for AJAX posting when we need to create a sample
     $r .= '<form style="display: none" id="smp-form" method="post" action="' . iform_ajaxproxy_url($node, 'sample') . '">';
     $r .= '<input name="website_id" value="' . $args['website_id'] . '"/>';
     $r .= '<input name="sample:id" id="smpid" />';
     $r .= '<input name="sample:parent_id" value="' . $parentSampleId . '" />';
     $r .= '<input name="sample:survey_id" value="' . $args['survey_id'] . '" />';
     $r .= '<input name="sample:sample_method_id" value="' . $sampleMethods[0]['id'] . '" />';
     $r .= '<input name="sample:entered_sref" id="smpsref" />';
     $r .= '<input name="sample:entered_sref_system" id="smpsref_system" />';
     $r .= '<input name="sample:location_id" id="smploc" />';
     $r .= '<input name="sample:date" value="' . $date . '" />';
     // include a stub input for each transect section sample attribute
     foreach ($attributes as $attr) {
         $r .= '<input id="' . $attr['fieldname'] . '" />';
     }
     $r .= '</form>';
     // tell the Javascript where to get species from.
     // @todo handle diff species lists.
     data_entry_helper::$javascript .= "indiciaData.initSpeciesList = " . $args['taxon_list_id'] . ";\n";
     // allow js to do AJAX by passing in the information it needs to post forms
     data_entry_helper::$javascript .= "indiciaData.indiciaSvc = '" . data_entry_helper::$base_url . "';\n";
     data_entry_helper::$javascript .= "indiciaData.readAuth = {nonce: '" . $auth['read']['nonce'] . "', auth_token: '" . $auth['read']['auth_token'] . "'};\n";
     data_entry_helper::$javascript .= "indiciaData.transect = " . $parentLocId . ";\n";
     data_entry_helper::$javascript .= "indiciaData.parentSample = " . $parentSampleId . ";\n";
     data_entry_helper::$javascript .= "indiciaData.sections = " . json_encode($sections) . ";\n";
     data_entry_helper::$javascript .= "indiciaData.occAttrId = " . $args['occurrence_attribute_id'] . ";\n";
     // Do an AJAX population of the grid rows.
     data_entry_helper::$javascript .= "loadSpeciesList();\n";
     data_entry_helper::add_resource('jquery_ui');
     return $r;
 }
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  * @todo: Implement this method 
  */
 public static function get_form($args, $node, $response = null)
 {
     require_once drupal_get_path('module', 'iform') . '/client_helpers/map_helper.php';
     if (function_exists('url')) {
         $args['section_edit_path'] = url($args['section_edit_path']);
     }
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $settings = array('locationTypes' => helper_base::get_termlist_terms($auth, 'indicia:location_types', array('Transect', 'Transect Section')), 'locationId' => isset($_GET['id']) ? $_GET['id'] : null);
     data_entry_helper::$javascript .= "indiciaData.sections = {};\n";
     if ($settings['locationId']) {
         data_entry_helper::load_existing_record($auth['read'], 'location', $settings['locationId']);
         $settings['sections'] = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('view' => 'detail', 'parent_id' => $settings['locationId'], 'deleted' => 'f'), 'nocache' => true));
         foreach ($settings['sections'] as $section) {
             $code = strtolower($section['code']);
             data_entry_helper::$javascript .= "indiciaData.sections.{$code} = {'geom':'" . $section['boundary_geom'] . "','id':'" . $section['id'] . "'};\n";
         }
     } else {
         $settings['sections'] = array();
     }
     $settings['attributes'] = data_entry_helper::getAttributes(array('id' => $settings['locationId'], 'valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'location_type_id' => $settings['locationTypes'][0]['id'], 'multiValue' => true));
     if (false == ($settings['cmsUserAttr'] = extract_cms_user_attr($settings['attributes']))) {
         return 'This form is designed to be used with the CMS User ID attribute setup for locations in the survey.';
     }
     // keep a copy of the location_attribute_id so we can use it later.
     self::$cmsUserAttrId = $settings['cmsUserAttr']['attributeId'];
     $r = '<form method="post" id="input-form">';
     $r .= $auth['write'];
     $r .= '<div id="controls">';
     $customAttributeTabs = array_merge(array('Site Details' => array('[*]')), get_attribute_tabs($settings['attributes']));
     if (count($customAttributeTabs) > 1) {
         $headerOptions = array('tabs' => array());
         foreach ($customAttributeTabs as $tab => $content) {
             $alias = preg_replace('/[^a-zA-Z0-9]/', '', strtolower($tab));
             $headerOptions['tabs']['#' . $alias] = lang::get($tab);
         }
         $r .= data_entry_helper::tab_header($headerOptions);
         data_entry_helper::enable_tabs(array('divId' => 'controls', 'style' => $args['interface'], 'progressBar' => isset($args['tabProgress']) && $args['tabProgress'] == true));
     }
     foreach ($customAttributeTabs as $tab => $content) {
         if ($tab == 'Site Details') {
             $r .= self::get_site_tab($auth, $args, $settings);
         } else {
             $alias = preg_replace('/[^a-zA-Z0-9]/', '', strtolower($tab));
             $r .= "\n<div id=\"{$alias}\">\n";
             $r .= get_attribute_html($settings['attributes'], $args, array('extraParams' => $auth['read']), $tab);
             $r .= "</div>\n";
         }
     }
     $r .= '</div>';
     // controls
     $r .= '<input type="submit" value="' . lang::get('Save') . '" class="ui-state-default ui-corner-all" />';
     $r .= '</form>';
     data_entry_helper::enable_validation('input-form');
     if (function_exists('drupal_set_breadcrumb')) {
         $breadcrumb = array();
         $breadcrumb[] = l(lang::get('Home'), '<front>');
         $breadcrumb[] = l(lang::get('Sites'), $args['sites_list_path']);
         if ($settings['locationId']) {
             $breadcrumb[] = data_entry_helper::$entity_to_load['location:name'];
         } else {
             $breadcrumb[] = lang::get('New Site');
         }
         drupal_set_breadcrumb($breadcrumb);
     }
     return $r;
 }