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;
 }
Esempio n. 2
0
 /**
  * Return the Indicia form code
  * @param array $args Input parameters.
  * @param array $node Drupal node object
  * @param array $response Response from Indicia services after posting.
  * @return HTML string
  */
 public static function get_form($args, $node, $response)
 {
     iform_load_helpers(array('report_helper', 'map_helper'));
     $auth = report_helper::get_read_auth($args['website_id'], $args['password']);
     $reportOptions = iform_report_get_report_options($args, $auth);
     $r = '<div class="ui-helper-clearfix">';
     $reportOptions['geoserverLayer'] = $args['geoserver_layer'];
     $reportOptions['geoserverLayerStyle'] = $args['geoserver_layer_style'];
     $reportOptions['cqlTemplate'] = $args['cql_template'];
     $reportOptions['clickable'] = $args['click_on_map_mode'] != 'none';
     $reportOptions['clickableLayersOutputDiv'] = $args['click_on_map_div'];
     if (!empty($args['click_on_map_columns'])) {
         $reportOptions['clickableLayersOutputColumns'] = helper_base::explode_lines_key_value_pairs($args['click_on_map_columns']);
     }
     if ($args['click_on_map_mode'] != 'none') {
         $reportOptions['clickableLayersOutputMode'] = $args['click_on_map_mode'];
     }
     // Use the proxy module if enabled, to get round limitations in URL length for
     // filtered WMS requests.
     if (defined('DRUPAL_BOOTSTRAP_CONFIGURATION') && module_exists('iform_proxy')) {
         global $base_url;
         $reportOptions['proxy'] = $base_url . '/?q=' . variable_get('iform_proxy_path', 'proxy') . '&url=';
     }
     $r .= '<br/>' . report_helper::report_map($reportOptions);
     $options = iform_map_get_map_options($args, $readAuth);
     $olOptions = iform_map_get_ol_options($args);
     // This is used for drawing, so need an editlayer, but not used for input
     $options['editLayer'] = true;
     $options['editLayerInSwitcher'] = true;
     $options['clickForSpatialRef'] = false;
     if ($args['layer_picker'] != 'none') {
         $picker = array('id' => 'map-layer-picker', 'includeIcons' => false, 'includeSwitchers' => true, 'includeHiddenLayers' => true);
         if ($args['layer_picker'] == 'before') {
             $r .= map_helper::layer_list($picker);
         }
         // as we have a layer picker, we can drop the layerSwitcher from the OL map.
         if (array_search('layerSwitcher', $options['standardControls']) !== false) {
             unset($options['standardControls'][array_search('layerSwitcher', $options['standardControls'])]);
         }
     }
     if ($args['legend'] != 'none') {
         $legend = array('id' => 'map-legend', 'includeIcons' => true, 'includeSwitchers' => false, 'includeHiddenLayers' => false);
         if ($args['legend'] == 'before') {
             $r .= map_helper::layer_list($legend);
         }
     }
     if (isset($args['map_toolbar_pos'])) {
         $options['toolbarDiv'] = $args['map_toolbar_pos'];
     }
     $r .= map_helper::map_panel($options, $olOptions);
     if ($args['layer_picker'] == 'after') {
         $r .= map_helper::layer_list($picker);
     }
     if ($args['legend'] == 'after') {
         $r .= map_helper::layer_list($legend);
     }
     $r .= '</div>';
     return $r;
 }
Esempio n. 3
0
/**
 * Retreives the options array required to set up a report according to the default
 * report parameters.
 * @global <type> $indicia_templates
 * @param string $args
 * @param <type> $readAuth
 * @return string
 */
function iform_report_get_report_options($args, $readAuth)
{
    // handle auto_params_form for backwards compatibility
    if (empty($args['output']) && !empty($args['auto_params_form'])) {
        if (!$args['auto_params_form']) {
            $args['output'] = 'output';
        }
    }
    if (isset($args['map_toolbar_pos']) && $args['map_toolbar_pos'] == 'map') {
        // report params cannot go in the map toolbar if displayed as overlay on map
        $args['params_in_map_toolbar'] = false;
    }
    $r = '';
    require_once 'user.php';
    $presets = get_options_array_with_user_data($args['param_presets']);
    $defaults = get_options_array_with_user_data($args['param_defaults']);
    $ignores = isset($args['param_ignores']) ? helper_base::explode_lines($args['param_ignores']) : array();
    // default columns behaviour is to just include anything returned by the report
    $columns = array();
    // this can be overridden
    if (isset($args['columns_config']) && !empty($args['columns_config'])) {
        $columns = json_decode($args['columns_config'], true);
    }
    $reportOptions = array('id' => 'report-grid', 'reportGroup' => isset($args['report_group']) ? $args['report_group'] : '', 'rememberParamsReportGroup' => isset($args['remember_params_report_group']) ? $args['remember_params_report_group'] : '', 'dataSource' => $args['report_name'], 'mode' => 'report', 'readAuth' => $readAuth, 'columns' => $columns, 'itemsPerPage' => empty($args['items_per_page']) ? 20 : $args['items_per_page'], 'extraParams' => $presets, 'paramDefaults' => $defaults, 'ignoreParams' => $ignores, 'galleryColCount' => isset($args['gallery_col_count']) ? $args['gallery_col_count'] : 1, 'headers' => isset($args['gallery_col_count']) && $args['gallery_col_count'] > 1 ? false : true, 'paramsInMapToolbar' => isset($args['params_in_map_toolbar']) ? $args['params_in_map_toolbar'] : false);
    // put each param control in a div, which makes it easier to layout with CSS
    if (!isset($args['params_in_map_toolbar']) || !$args['params_in_map_toolbar']) {
        $reportOptions['paramPrefix'] = '<div id="container-{fieldname}" class="param-container">';
        $reportOptions['paramSuffix'] = '</div>';
    }
    // If in Drupal, allow the params panel to collapse.
    if (function_exists('drupal_add_js')) {
        if (function_exists('hostsite_add_library') && (!defined('DRUPAL_CORE_COMPATIBILITY') || DRUPAL_CORE_COMPATIBILITY !== '7.x')) {
            hostsite_add_library('collapse');
            $reportOptions['fieldsetClass'] = 'collapsible';
        }
    }
    if (empty($args['output']) || $args['output'] == 'default') {
        $reportOptions['autoParamsForm'] = true;
    } elseif ($args['output'] == 'form') {
        $reportOptions['autoParamsForm'] = true;
        $reportOptions['paramsOnly'] = true;
    } else {
        $reportOptions['autoParamsForm'] = false;
    }
    if (!empty($args['row_class'])) {
        $reportOptions['rowClass'] = $args['row_class'];
    }
    // Set up a page refresh for dynamic update of the report at set intervals
    if (isset($args['refresh_timer']) && $args['refresh_timer'] !== 0 && is_numeric($args['refresh_timer'])) {
        // is_numeric prevents injection
        if (isset($args['load_on_refresh']) && !empty($args['load_on_refresh'])) {
            report_helper::$javascript .= "setTimeout('window.location=\"" . $args['load_on_refresh'] . "\";', " . $args['refresh_timer'] . "*1000 );\n";
        } else {
            report_helper::$javascript .= "setTimeout('window.location.reload( false );', " . $args['refresh_timer'] . "*1000 );\n";
        }
    }
    return $reportOptions;
}
 /**
  * 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;
 }
Esempio n. 5
0
/**
 * Method to read a parameter from the arguments of a form that contains a list of key=value pairs on separate lines. 
 * Each value is checked for references to the user's data (either {user_id}, {username}, {email} or {profile_*})
 * and if found these substitutions are replaced.
 * @param string $listData Form argument data, with each key value pair on a separate line.
 * @return array Associative array.
 */
function get_options_array_with_user_data($listData)
{
    global $user;
    $r = array();
    if ($listData != '') {
        $params = helper_base::explode_lines($listData);
        foreach ($params as $param) {
            if (!empty($param)) {
                $tokens = explode('=', $param, 2);
                if (count($tokens) == 2) {
                    $tokens[1] = apply_user_replacements($tokens[1]);
                } else {
                    throw new Exception('Some of the preset or default parameters defined for this page are not of the form param=value.');
                }
                $r[$tokens[0]] = $tokens[1];
            }
        }
    }
    return $r;
}
 /**
  * Returns a control for picking a single species
  * @global type $indicia_templates
  * @param array $auth Read authorisation tokens
  * @param array $args Form configuration
  * @param array $extraParams Extra parameters pre-configured with taxon and taxon name type filters.
  * @param array $options additional options for the control, e.g. those configured in the form structure.
  * @return string HTML for the control.
  */
 protected static function get_control_species_single($auth, $args, $extraParams, $options)
 {
     $r = '';
     if ($args['extra_list_id'] === '' && $args['list_id'] !== '') {
         $extraParams['taxon_list_id'] = $args['list_id'];
     } elseif ($args['extra_list_id'] !== '' && $args['list_id'] === '') {
         $extraParams['taxon_list_id'] = $args['extra_list_id'];
     } elseif ($args['extra_list_id'] !== '' && $args['list_id'] !== '') {
         $extraParams['query'] = json_encode(array('in' => array('taxon_list_id' => array($args['list_id'], $args['extra_list_id']))));
     }
     if (isset($options['taxonGroupSelect']) && $options['taxonGroupSelect']) {
         $label = isset($options['taxonGroupSelectLabel']) ? $options['taxonGroupSelectLabel'] : 'Species Group';
         $helpText = isset($options['taxonGroupSelectHelpText']) ? $options['taxonGroupSelectHelpText'] : 'Choose which species group you want to pick a species from.';
         $default = '';
         if (!empty(data_entry_helper::$entity_to_load['occurrence:taxa_taxon_list_id'])) {
             // need to find the default value
             $species = data_entry_helper::get_population_data(array('table' => 'cache_taxa_taxon_list', 'extraParams' => $auth['read'] + array('id' => data_entry_helper::$entity_to_load['occurrence:taxa_taxon_list_id'])));
             data_entry_helper::$entity_to_load['taxon_group_id'] = $species[0]['taxon_group_id'];
         }
         $r .= data_entry_helper::select(array('fieldname' => 'taxon_group_id', 'id' => 'taxon_group_id', 'label' => lang::get($label), 'helpText' => lang::get($helpText), 'report' => 'library/taxon_groups/taxon_groups_used_in_checklist', 'valueField' => 'id', 'captionField' => 'title', 'extraParams' => $auth['read'] + array('taxon_list_id' => $extraParams['taxon_list_id'])));
         // update the select box to link to the species group picker. It must be a select box!
         $args['species_ctrl'] = 'select';
         $options['parentControlId'] = 'taxon_group_id';
         $options['parentControlLabel'] = lang::get($label);
         $options['filterField'] = 'taxon_group_id';
     }
     $options['speciesNameFilterMode'] = self::getSpeciesNameFilterMode($args);
     global $indicia_templates;
     $ctrl = $args['species_ctrl'] === 'autocomplete' ? 'species_autocomplete' : $args['species_ctrl'];
     $species_ctrl_opts = array_merge(array('fieldname' => 'occurrence:taxa_taxon_list_id', 'label' => lang::get('occurrence:taxa_taxon_list_id'), 'columns' => 2, 'parentField' => 'parent_id', 'blankText' => lang::get('Please select'), 'cacheLookup' => $args['cache_lookup']), $options);
     if (isset($species_ctrl_opts['extraParams'])) {
         $species_ctrl_opts['extraParams'] = array_merge($extraParams, $species_ctrl_opts['extraParams']);
     } else {
         $species_ctrl_opts['extraParams'] = $extraParams;
     }
     if (!empty($args['taxon_filter'])) {
         $species_ctrl_opts['taxonFilterField'] = $args['taxon_filter_field'];
         // applies to autocompletes
         $species_ctrl_opts['taxonFilter'] = helper_base::explode_lines($args['taxon_filter']);
         // applies to autocompletes
     }
     // obtain table to query and hence fields to use
     $db = data_entry_helper::get_species_lookup_db_definition($args['cache_lookup']);
     // get local vars for the array
     extract($db);
     if ($ctrl !== 'species_autocomplete') {
         // The species autocomplete has built in support for the species name filter.
         // For other controls we need to apply the species name filter to the params used for population
         if (!empty($species_ctrl_opts['taxonFilter']) || $options['speciesNameFilterMode']) {
             $species_ctrl_opts['extraParams'] = array_merge($species_ctrl_opts['extraParams'], data_entry_helper::get_species_names_filter($species_ctrl_opts));
         }
         // for controls which don't know how to do the lookup, we need to tell them
         $species_ctrl_opts = array_merge(array('table' => $tblTaxon, 'captionField' => $colTaxon, 'valueField' => $colId), $species_ctrl_opts);
     }
     // if using something other than an autocomplete, then set the caption template to include the appropriate names. Autocompletes
     // use a JS function instead.
     if ($ctrl !== 'autocomplete' && isset($args['species_include_both_names']) && $args['species_include_both_names']) {
         if ($args['species_names_filter'] === 'all') {
             $indicia_templates['species_caption'] = "{{$colTaxon}}";
         } elseif ($args['species_names_filter'] === 'language') {
             $indicia_templates['species_caption'] = "{{$colTaxon}} - {{$colPreferred}}";
         } else {
             $indicia_templates['species_caption'] = "{{$colTaxon}} - {{$colCommon}}";
         }
         $species_ctrl_opts['captionTemplate'] = 'species_caption';
     }
     if ($ctrl == 'tree_browser') {
         // change the node template to include images
         $indicia_templates['tree_browser_node'] = '<div>' . '<img src="' . data_entry_helper::$base_url . '/upload/thumb-{image_path}" alt="Image of {caption}" width="80" /></div>' . '<span>{caption}</span>';
     }
     // Dynamically generate the species selection control required.
     $r .= call_user_func(array('data_entry_helper', $ctrl), $species_ctrl_opts);
     return $r;
 }
 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_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;
 }
 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;
 }
 /**
  * Draw Record Details section of the page.
  * @return string The output freeform report.
  * 
  * @package    Client
  * @subpackage PrebuiltForms
  */
 protected static function get_control_recorddetails($auth, $args, $tabalias, $options)
 {
     iform_load_helpers(array('report_helper'));
     $options = array_merge(array('dataSource' => 'reports_for_prebuilt_forms/record_details_2/record_data_attributes_with_hiddens'), $options);
     $fields = helper_base::explode_lines($args['fields']);
     $fieldsLower = helper_base::explode_lines(strtolower($args['fields']));
     //Draw the Record Details, but only if they aren't requested as hidden by the administrator
     $detailstemplateHtml = '';
     $attrsTemplate = '<div class="field ui-helper-clearfix"><span>{caption}:</span><span>{value}</span></div>';
     $test = $args['operator'] === 'in';
     $availableFields = array('occurrence_id' => 'Record ID', 'taxon' => 'Species', 'preferred_taxon' => 'Preferred species name', 'taxonomy' => 'Taxonomy', 'survey_title' => 'Survey', 'recorder' => 'Recorder', 'inputter' => 'Input by', 'record_status' => 'Record status', 'verifier' => 'Verified by', 'date' => 'Date', 'entered_sref' => 'Grid ref', 'occurrence_comment' => 'Record comment', 'location_name' => 'Site name', 'sample_comment' => 'Sample comment');
     self::load_record($auth);
     $details_report = '<div class="record-details-fields ui-helper-clearfix">';
     foreach ($availableFields as $field => $caption) {
         if ($test === in_array(strtolower($caption), $fieldsLower) && !empty(self::$record[$field])) {
             $details_report .= str_replace(array('{caption}', '{value}'), array($caption, self::$record[$field]), $attrsTemplate);
         }
     }
     $created = date('jS F Y \\a\\t H:i', strtotime(self::$record['created_on']));
     $updated = date('jS F Y \\a\\t H:i', strtotime(self::$record['updated_on']));
     $dateInfo = lang::get('Entered on {1}', $created);
     if ($created !== $updated) {
         $dateInfo .= lang::get(' and last updated on {1}', $updated);
     }
     $details_report .= str_replace(array('{caption}', '{value}'), array(lang::get('Submission date'), $dateInfo), $attrsTemplate);
     $details_report .= '</div>';
     if (!self::$record['sensitivity_precision']) {
         //draw any custom attributes added by the user, but only for a non-sensitive record
         $attrs_report = report_helper::freeform_report(array('readAuth' => $auth['read'], 'class' => 'record-details-fields ui-helper-clearfix', 'dataSource' => $options['dataSource'], 'bands' => array(array('content' => $attrsTemplate)), 'extraParams' => array('occurrence_id' => $_GET['occurrence_id'], 'attrs' => strtolower(self::convert_array_to_set($fields)), 'testagainst' => $args['testagainst'], 'operator' => $args['operator'], 'sharing' => 'reporting')));
     }
     $r = '<div class="detail-panel" id="detail-panel-recorddetails"><h3>Record Details</h3>';
     $r .= $details_report;
     if (isset($attrs_report)) {
         $r .= $attrs_report;
     }
     $r .= '</div>';
     return $r;
 }
 /**
  * Helper function to generate a species checklist from a given taxon list.
  *
  * Please not that although this is based on the data_entry_helper function, it has only been tested with the following
  * options for seasearch - @id,@useThirdLevelSamples,@lookupListId,@gridIdAttributeId,@speciesControlToUseSubSamples,@subSamplePerRow,@resizeWidth,@resizeHeight
  * If you intend to use any other options, they will require further testing or development.
  *
  */
 private static function species_checklist($options)
 {
     global $indicia_templates;
     data_entry_helper::add_resource('addrowtogrid');
     $options = data_entry_helper::get_species_checklist_options($options);
     $classlist = array('ui-widget', 'ui-widget-content', 'species-grid');
     if (!empty($options['class'])) {
         $classlist[] = $options['class'];
     }
     if ($options['subSamplePerRow']) {
         // we'll track 1 sample per grid row.
         $smpIdx = 0;
     }
     if ($options['columns'] > 1 && count($options['mediaTypes']) > 1) {
         throw new Exception('The species_checklist control does not support having more than one occurrence per row (columns option > 0) ' . 'at the same time has having the mediaTypes option in use.');
     }
     data_entry_helper::add_resource('json');
     data_entry_helper::add_resource('autocomplete');
     $filterArray = data_entry_helper::get_species_names_filter($options);
     $filterNameTypes = array('all', 'currentLanguage', 'preferred', 'excludeSynonyms');
     //make a copy of the options so that we can maipulate it
     $overrideOptions = $options;
     //We are going to cycle through each of the name filter types
     //and save the parameters required for each type in an array so
     //that the Javascript can quickly access the required parameters
     foreach ($filterNameTypes as $filterType) {
         $overrideOptions['speciesNameFilterMode'] = $filterType;
         $nameFilter[$filterType] = data_entry_helper::get_species_names_filter($overrideOptions);
         $nameFilter[$filterType] = json_encode($nameFilter[$filterType]);
     }
     if (count($filterArray)) {
         $filterParam = json_encode($filterArray);
         data_entry_helper::$javascript .= "indiciaData['taxonExtraParams-" . $options['id'] . "'] = {$filterParam};\n";
         // Apply a filter to extraParams that can be used when loading the initial species list, to get just the correct names.
         if (isset($options['speciesNameFilterMode']) && !empty($options['listId'])) {
             $filterFields = array();
             $filterWheres = array();
             self::parse_species_name_filter_mode($options, $filterFields, $filterWheres);
             if (count($filterWheres)) {
                 $options['extraParams'] += array('query' => json_encode(array('where' => $filterWheres)));
             }
             $options['extraParams'] += $filterFields;
         }
     }
     data_entry_helper::$js_read_tokens = $options['readAuth'];
     data_entry_helper::$javascript .= "indiciaData['rowInclusionCheck-" . $options['id'] . "'] = '" . $options['rowInclusionCheck'] . "';\n";
     data_entry_helper::$javascript .= "indiciaData['copyDataFromPreviousRow-" . $options['id'] . "'] = '" . $options['copyDataFromPreviousRow'] . "';\n";
     data_entry_helper::$javascript .= "indiciaData['includeSpeciesGridLinkPage-" . $options['id'] . "'] = '" . $options['includeSpeciesGridLinkPage'] . "';\n";
     data_entry_helper::$javascript .= "indiciaData.speciesGridPageLinkUrl = '" . $options['speciesGridPageLinkUrl'] . "';\n";
     data_entry_helper::$javascript .= "indiciaData.speciesGridPageLinkParameter = '" . $options['speciesGridPageLinkParameter'] . "';\n";
     data_entry_helper::$javascript .= "indiciaData.speciesGridPageLinkTooltip = '" . $options['speciesGridPageLinkTooltip'] . "';\n";
     data_entry_helper::$javascript .= "indiciaData['editTaxaNames-" . $options['id'] . "'] = '" . $options['editTaxaNames'] . "';\n";
     data_entry_helper::$javascript .= "indiciaData['subSpeciesColumn-" . $options['id'] . "'] = '" . $options['subSpeciesColumn'] . "';\n";
     data_entry_helper::$javascript .= "indiciaData['subSamplePerRow-" . $options['id'] . "'] = " . ($options['subSamplePerRow'] ? 'true' : 'false') . ";\n";
     if ($options['copyDataFromPreviousRow']) {
         data_entry_helper::$javascript .= "indiciaData['previousRowColumnsToInclude-" . $options['id'] . "'] = '" . $options['previousRowColumnsToInclude'] . "';\n";
         data_entry_helper::$javascript .= "indiciaData.langAddAnother='" . lang::get('Add another') . "';\n";
     }
     if (count($options['mediaTypes'])) {
         data_entry_helper::add_resource('plupload');
         // store some globals that we need later when creating uploaders
         $relpath = data_entry_helper::getRootFolder() . data_entry_helper::client_helper_path();
         $interim_image_folder = isset(parent::$interim_image_folder) ? parent::$interim_image_folder : 'upload/';
         data_entry_helper::$javascript .= "indiciaData.uploadSettings = {\n";
         data_entry_helper::$javascript .= "  uploadScript: '" . $relpath . "upload.php',\n";
         data_entry_helper::$javascript .= "  destinationFolder: '" . $relpath . $interim_image_folder . "',\n";
         data_entry_helper::$javascript .= "  jsPath: '" . data_entry_helper::$js_path . "'";
         if (isset($options['resizeWidth'])) {
             data_entry_helper::$javascript .= ",\n  resizeWidth: " . $options['resizeWidth'];
         }
         if (isset($options['resizeHeight'])) {
             data_entry_helper::$javascript .= ",\n  resizeHeight: " . $options['resizeHeight'];
         }
         if (isset($options['resizeQuality'])) {
             data_entry_helper::$javascript .= ",\n  resizeQuality: " . $options['resizeQuality'];
         }
         data_entry_helper::$javascript .= "\n}\n";
         if ($indicia_templates['file_box'] != '') {
             data_entry_helper::$javascript .= "file_boxTemplate = '" . str_replace('"', '\\"', $indicia_templates['file_box']) . "';\n";
         }
         if ($indicia_templates['file_box_initial_file_info'] != '') {
             data_entry_helper::$javascript .= "file_box_initial_file_infoTemplate = '" . str_replace('"', '\\"', $indicia_templates['file_box_initial_file_info']) . "';\n";
         }
         if ($indicia_templates['file_box_uploaded_image'] != '') {
             data_entry_helper::$javascript .= "file_box_uploaded_imageTemplate = '" . str_replace('"', '\\"', $indicia_templates['file_box_uploaded_image']) . "';\n";
         }
     }
     $occAttrControls = array();
     $occAttrs = array();
     $occAttrControlsExisting = array();
     $taxonRows = array();
     $subSampleRows = array();
     if (!empty($options['useThirdLevelSamples']) && $options['useThirdLevelSamples'] == true) {
         $useThirdLevelSamples = true;
     } else {
         $useThirdLevelSamples = false;
     }
     // Load any existing sample's occurrence data into $entity_to_load
     if (isset(data_entry_helper::$entity_to_load['sample:id']) && $options['useLoadedExistingRecords'] === false) {
         self::preload_species_checklist_occurrences(data_entry_helper::$entity_to_load['sample:id'], $options['readAuth'], $options['mediaTypes'], $options['reloadExtraParams'], $subSampleRows, $options['speciesControlToUseSubSamples'], isset($options['subSampleSampleMethodID']) ? $options['subSampleSampleMethodID'] : '', $options['id'], $useThirdLevelSamples);
     }
     // load the full list of species for the grid, including the main checklist plus any additional species in the reloaded occurrences.
     $taxalist = data_entry_helper::get_species_checklist_taxa_list($options, $taxonRows);
     // If we managed to read the species list data we can proceed
     if (!array_key_exists('error', $taxalist)) {
         $attrOptions = array('id' => null, 'valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => "sc:-idx-::occAttr", 'extraParams' => $options['readAuth'], 'survey_id' => array_key_exists('survey_id', $options) ? $options['survey_id'] : null);
         if (isset($options['attributeIds'])) {
             // make sure we load the grid ID attribute
             if (!empty($options['gridIdAttributeId']) && !in_array($options['gridIdAttributeId'], $options['attributeIds'])) {
                 $options['attributeIds'][] = $options['gridIdAttributeId'];
             }
             $attrOptions['extraParams'] += array('query' => json_encode(array('in' => array('id' => $options['attributeIds']))));
         }
         $attributes = data_entry_helper::getAttributes($attrOptions);
         // Merge in the attribute options passed into the control which can override the warehouse config
         if (isset($options['occAttrOptions'])) {
             foreach ($options['occAttrOptions'] as $attrId => $attr) {
                 if (isset($attributes[$attrId])) {
                     $attributes[$attrId] = array_merge($attributes[$attrId], $attr);
                 }
             }
         }
         // Get the attribute and control information required to build the custom occurrence attribute columns
         data_entry_helper::species_checklist_prepare_attributes($options, $attributes, $occAttrControls, $occAttrControlsExisting, $occAttrs);
         $beforegrid = '<span style="display: none;">Step 1</span>' . "\n";
         if (isset($options['lookupListId'])) {
             $subSampleImagesToLoad = array();
             //Cycle through sub-samples of the main parent sample
             foreach ($subSampleRows as $subSampleIdx => $subSampleRow) {
                 foreach (data_entry_helper::$entity_to_load as $key => $value) {
                     $keyParts = explode(':', $key);
                     //Get an array of sample media to load onto the grid
                     if (strpos($key, 'third-level-smp-occ-grid') !== false && strpos($key, ':sample_medium:id') !== false) {
                         if (!in_array($keyParts[3], $subSampleImagesToLoad)) {
                             $subSampleImagesToLoad[] = $keyParts[3];
                         }
                     }
                 }
             }
             //For each sub-sample, add a row to the occurrences grid with the image loaded, this is then ready for the user.
             //To create occurrences with
             if (isset($subSampleImagesToLoad)) {
                 $mediaIdArray = array();
                 foreach ($subSampleImagesToLoad as $subSampleImageIdx => $subSampleImageToLoad) {
                     $mediaIdArray[] = $subSampleImageToLoad;
                     $beforegrid .= self::get_species_checklist_empty_row_with_image($options, $occAttrControls, $attributes, $subSampleImageIdx, $subSampleImageToLoad);
                 }
                 $encodedMediaArray = json_encode($mediaIdArray);
                 data_entry_helper::$javascript .= "indiciaData.encodedMediaArray=" . json_encode($encodedMediaArray) . ";\n";
             }
             $beforegrid .= self::get_species_checklist_clonable_row($options, $occAttrControls, $attributes);
         }
         $onlyImages = true;
         if ($options['mediaTypes']) {
             foreach ($options['mediaTypes'] as $mediaType) {
                 if (substr($mediaType, 0, 6) !== 'Image:') {
                     $onlyImages = false;
                 }
             }
         }
         $grid = data_entry_helper::get_species_checklist_header($options, $occAttrs, $onlyImages);
         $rows = array();
         $imageRowIdxs = array();
         $taxonCounter = array();
         $rowIdx = 0;
         // tell the addTowToGrid javascript how many rows are already used, so it has a unique index for new rows
         data_entry_helper::$javascript .= "indiciaData['gridCounter-" . $options['id'] . "'] = " . count($taxonRows) . ";\n";
         data_entry_helper::$javascript .= "indiciaData['gridSampleCounter-" . $options['id'] . "'] = " . count($subSampleRows) . ";\n";
         // Loop through all the rows needed in the grid
         // Get the checkboxes (hidden or otherwise) that indicate a species is present
         if (is_array(data_entry_helper::$entity_to_load)) {
             $presenceValues = preg_grep("/^sc:[0-9]*:[0-9]*:present\$/", array_keys(data_entry_helper::$entity_to_load));
         }
         // if subspecies are stored, then need to load up the parent species info into the $taxonRows data
         if ($options['subSpeciesColumn']) {
             self::load_parent_species($taxalist, $options);
             if ($options['subSpeciesRemoveSspRank']) {
                 // remove subspecific rank information from the displayed subspecies names by passing a regex
                 data_entry_helper::$javascript .= "indiciaData.subspeciesRanksToStrip='" . lang::get('(form[a\\.]?|var\\.?|ssp\\.)') . "';\n";
             }
         }
         // track if there is a row we are editing in this grid
         $hasEditedRecord = false;
         if ($options['mediaTypes']) {
             $mediaBtnLabel = lang::get($onlyImages ? 'Add images' : 'Add media');
             $mediaBtnClass = 'sc' . $onlyImages ? 'Image' : 'Media' . 'Link';
         }
         foreach ($taxonRows as $txIdx => $rowIds) {
             $ttlId = $rowIds['ttlId'];
             $loadedTxIdx = isset($rowIds['loadedTxIdx']) ? $rowIds['loadedTxIdx'] : -1;
             $existing_record_id = isset($rowIds['occId']) ? $rowIds['occId'] : false;
             // Multi-column input does not work when image upload allowed
             $colIdx = count($options['mediaTypes']) ? 0 : (int) floor($rowIdx / (count($taxonRows) / $options['columns']));
             // Find the taxon in our preloaded list data that we want to output for this row
             $taxonIdx = 0;
             while ($taxonIdx < count($taxalist) && $taxalist[$taxonIdx]['id'] != $ttlId) {
                 $taxonIdx += 1;
             }
             if ($taxonIdx >= count($taxalist)) {
                 continue;
             }
             // next taxon, as this one was not found in the list
             $taxon = $taxalist[$taxonIdx];
             // If we are using the sub-species column then when the taxon has a parent (=species) this goes in the
             // first column and we put the subsp in the second column in a moment.
             if (isset($options['subSpeciesColumn']) && $options['subSpeciesColumn'] && !empty($taxon['parent'])) {
                 $firstColumnTaxon = $taxon['parent'];
             } else {
                 $firstColumnTaxon = $taxon;
             }
             // map field names if using a cached lookup
             if ($options['cacheLookup']) {
                 $firstColumnTaxon = $firstColumnTaxon + array('preferred_name' => $firstColumnTaxon['preferred_taxon'], 'common' => $firstColumnTaxon['default_common_name']);
             }
             // Get the cell content from the taxon_label template
             $firstCell = helper_base::mergeParamsIntoTemplate($firstColumnTaxon, 'taxon_label');
             // If the taxon label template is PHP, evaluate it.
             if ($options['PHPtaxonLabel']) {
                 $firstCell = eval($firstCell);
             }
             // Now create the table cell to contain this.
             $colspan = isset($options['lookupListId']) && $options['rowInclusionCheck'] != 'alwaysRemovable' ? ' colspan="2"' : '';
             $row = '';
             // Add a delete button if the user can remove rows, add an edit button if the user has the edit option set, add a page link if user has that option set.
             if ($options['rowInclusionCheck'] == 'alwaysRemovable') {
                 $imgPath = empty(helper_base::$images_path) ? helper_base::relative_client_helper_path() . "../media/images/" : helper_base::$images_path;
                 $speciesGridLinkPageIconSource = $imgPath . "nuvola/find-22px.png";
                 if ($options['editTaxaNames']) {
                     $row .= '<td class="row-buttons">
                  <img class="action-button remove-row" src=' . $imgPath . 'nuvola/cancel-16px.png>
                  <img class="action-button edit-taxon-name" src=' . $imgPath . 'nuvola/package_editors-16px.png>';
                     if ($options['includeSpeciesGridLinkPage']) {
                         $row .= '<img class="species-grid-link-page-icon" title="' . $options['speciesGridPageLinkTooltip'] . '" alt="Notes icon" src=' . $speciesGridLinkPageIconSource . '>';
                     }
                     $row .= '</td>';
                 } else {
                     $row .= '<td class="row-buttons"><img class="action-button remove-row" src=' . $imgPath . 'nuvola/cancel-16px.png>';
                     if ($options['includeSpeciesGridLinkPage']) {
                         $row .= '<img class="species-grid-link-page-icon" title="' . $options['speciesGridPageLinkTooltip'] . '" alt="Notes icon" src=' . $speciesGridLinkPageIconSource . '>';
                     }
                     $row .= '</td>';
                 }
             }
             // if editing a specific occurrence, mark it up
             $editedRecord = isset($_GET['occurrence_id']) && $_GET['occurrence_id'] == $existing_record_id;
             $editClass = $editedRecord ? ' edited-record ui-state-highlight' : '';
             $hasEditedRecord = $hasEditedRecord || $editedRecord;
             // Verified records can be flagged with an icon
             //Do an isset check as the npms_paths form for example uses the species checklist, but doesn't use an entity_to_load
             if (isset(data_entry_helper::$entity_to_load["sc:{$loadedTxIdx}:{$existing_record_id}:record_status"])) {
                 $status = data_entry_helper::$entity_to_load["sc:{$loadedTxIdx}:{$existing_record_id}:record_status"];
                 if (preg_match('/[VDR]/', $status)) {
                     $img = false;
                     switch ($status) {
                         case 'V':
                             $img = 'ok';
                             $statusLabel = 'verified';
                             break;
                         case 'D':
                             $img = 'dubious';
                             $statusLabel = 'queried';
                             break;
                         case 'R':
                             $img = 'cancel';
                             $statusLabel = 'rejected';
                             break;
                     }
                     if ($img) {
                         $label = lang::get($statusLabel);
                         $title = lang::get('This record has been {1}. Changing it will mean that it will need to be rechecked by an expert.', $label);
                         $firstCell .= "<img alt=\"{$label}\" title=\"{$title}\" src=\"{$imgPath}nuvola/{$img}-16px.png\">";
                     }
                 }
             }
             $row .= str_replace(array('{content}', '{colspan}', '{editClass}', '{tableId}', '{idx}'), array($firstCell, $colspan, $editClass, $options['id'], $colIdx), $indicia_templates['taxon_label_cell']);
             $hidden = $options['rowInclusionCheck'] == 'checkbox' ? '' : ' style="display:none"';
             // AlwaysFixed mode means all rows in the default checklist are included as occurrences. Same for
             // AlwayeRemovable except that the rows can be removed.
             // If we are reloading a record there will be an entity_to_load which will indicate whether present should be checked.
             // This has to be evaluated true or false if reloading a submission with errors.
             if ($options['rowInclusionCheck'] == 'alwaysFixed' || $options['rowInclusionCheck'] == 'alwaysRemovable' || data_entry_helper::$entity_to_load != null && array_key_exists("sc:{$loadedTxIdx}:{$existing_record_id}:present", data_entry_helper::$entity_to_load) && data_entry_helper::$entity_to_load["sc:{$loadedTxIdx}:{$existing_record_id}:present"] == true) {
                 $checked = ' checked="checked"';
             } else {
                 $checked = '';
             }
             $row .= "\n<td class=\"scPresenceCell\" headers=\"{$options['id']}-present-{$colIdx}\"{$hidden}>";
             $fieldname = "sc:{$options['id']}-{$txIdx}:{$existing_record_id}:present";
             if ($options['rowInclusionCheck'] === 'hasData') {
                 $row .= "<input type=\"hidden\" name=\"{$fieldname}\" id=\"{$fieldname}\" value=\"{$taxon['id']}\"/>";
             } else {
                 // this includes a control to force out a 0 value when the checkbox is unchecked.
                 $row .= "<input type=\"hidden\" class=\"scPresence\" name=\"{$fieldname}\" value=\"0\"/>" . "<input type=\"checkbox\" class=\"scPresence\" name=\"{$fieldname}\" id=\"{$fieldname}\" value=\"{$taxon['id']}\" {$checked} />";
             }
             // If we have a grid ID attribute, output a hidden
             if (!empty($options['gridIdAttributeId'])) {
                 $gridAttributeId = $options['gridIdAttributeId'];
                 if (empty($existing_record_id)) {
                     //If in add mode we don't need to include the occurrence attribute id
                     $fieldname = "sc:{$options['id']}-{$txIdx}::occAttr:{$gridAttributeId}";
                     $row .= "<input type=\"hidden\" name=\"{$fieldname}\" id=\"{$fieldname}\" value=\"{$options['id']}\"/>";
                 } else {
                     $search = preg_grep("/^sc:[0-9]*:{$existing_record_id}:occAttr:{$gridAttributeId}:" . '[0-9]*$/', array_keys(data_entry_helper::$entity_to_load));
                     if (!empty($search)) {
                         $match = array_pop($search);
                         $parts = explode(':', $match);
                         //The id of the existing occurrence attribute value is at the end of the data
                         $idxOfOccValId = count($parts) - 1;
                         //$txIdx is row number in the grid. We cannot simply take the data from entity_to_load as it doesn't contain the row number.
                         $fieldname = "sc:{$options['id']}-{$txIdx}:{$existing_record_id}:occAttr:{$gridAttributeId}:{$parts[$idxOfOccValId]}";
                         $row .= "<input type=\"hidden\" name=\"{$fieldname}\" id=\"{$fieldname}\" value=\"{$options['id']}\"/>";
                     }
                 }
             }
             $row .= "</td>";
             if ($options['speciesControlToUseSubSamples']) {
                 $row .= "\n<td class=\"scSampleCell\" style=\"display:none\">";
                 $fieldname = "sc:{$options['id']}-{$txIdx}:{$existing_record_id}:occurrence:sampleIDX";
                 $value = $options['subSamplePerRow'] ? $smpIdx : $rowIds['smpIdx'];
                 $row .= "<input type=\"hidden\" class=\"scSample\" name=\"{$fieldname}\" id=\"{$fieldname}\" value=\"{$value}\" />";
                 $row .= "</td>";
                 // always increment the sample index if 1 per row.
                 if ($options['subSamplePerRow']) {
                     $smpIdx++;
                 }
             }
             $idx = 0;
             if ($options['mediaTypes']) {
                 $existingImages = is_array(data_entry_helper::$entity_to_load) ? preg_grep("/^sc:{$loadedTxIdx}:{$existing_record_id}:occurrence_medium:id:[a-z0-9]*\$/", array_keys(data_entry_helper::$entity_to_load)) : array();
                 $row .= "\n<td class=\"ui-widget-content scAddMediaCell\">";
                 $style = count($existingImages) > 0 ? ' style="display: none"' : '';
                 $fieldname = "add-media:{$options['id']}-{$txIdx}:{$existing_record_id}";
                 $row .= "<a href=\"\"{$style} class=\"add-media-link button {$mediaBtnClass}\" id=\"{$fieldname}\">" . "{$mediaBtnLabel}</a>";
                 $row .= "</td>";
             }
             // Are we in the first column of a multicolumn grid, or doing single column grid? If so start new row.
             if ($colIdx === 0) {
                 $rows[$rowIdx] = $row;
             } else {
                 $rows[$rowIdx % ceil(count($taxonRows) / $options['columns'])] .= $row;
             }
             $rowIdx++;
             if ($options['mediaTypes'] && count($existingImages) > 0) {
                 $totalCols = ($options['lookupListId'] ? 2 : 1) + 1 + count($occAttrControls) + ($options['occurrenceComment'] ? 1 : 0) + ($options['occurrenceSensitivity'] ? 1 : 0) + (count($options['mediaTypes']) ? 1 : 0);
                 $rows[$rowIdx] = '<td colspan="' . $totalCols . '">' . data_entry_helper::file_box(array('table' => "sc:{$options['id']}-{$txIdx}:{$existing_record_id}:occurrence_medium", 'loadExistingRecordKey' => "sc:{$loadedTxIdx}:{$existing_record_id}:occurrence_medium", 'mediaTypes' => $options['mediaTypes'], 'readAuth' => $options['readAuth'])) . '</td>';
                 $imageRowIdxs[] = $rowIdx;
                 $rowIdx++;
             }
         }
         $grid .= "\n<tbody>\n";
         if (count($rows) > 0) {
             $grid .= data_entry_helper::species_checklist_implode_rows($rows, $imageRowIdxs);
         }
         $grid .= "</tbody>\n";
         $grid = str_replace(array('{class}', '{id}', '{content}'), array(' class="' . implode(' ', $classlist) . '"', " id=\"{$options['id']}\"", $grid), $indicia_templates['data-input-table']);
         // in hasData mode, the wrap_species_checklist method must be notified of the different default
         // way of checking if a row is to be made into an occurrence. This may differ between grids when
         // there are multiple grids on a page.
         if ($options['rowInclusionCheck'] == 'hasData') {
             $grid .= '<input name="rowInclusionCheck-' . $options['id'] . '" value="hasData" type="hidden" />';
             if (!empty($options['hasDataIgnoreAttrs'])) {
                 $grid .= '<input name="hasDataIgnoreAttrs-' . $options['id'] . '" value="' . implode(',', $options['hasDataIgnoreAttrs']) . '" type="hidden" />';
             }
         }
         // If the lookupListId parameter is specified then the user is able to add extra rows to the grid,
         // selecting the species from this list. Add the required controls for this.
         if (isset($options['lookupListId'])) {
             // Javascript to add further rows to the grid
             if (isset($indicia_templates['format_species_autocomplete_fn'])) {
                 data_entry_helper::$javascript .= 'formatter = ' . $indicia_templates['format_species_autocomplete_fn'];
             } else {
                 data_entry_helper::$javascript .= "formatter = '" . $indicia_templates['taxon_label'] . "';\n";
             }
             if (!empty(parent::$warehouse_proxy)) {
                 $url = parent::$warehouse_proxy . "index.php/services/data";
             } else {
                 $url = helper_base::$base_url . "index.php/services/data";
             }
             data_entry_helper::$javascript .= "if (typeof indiciaData.speciesGrid==='undefined') {indiciaData.speciesGrid={};}\n";
             data_entry_helper::$javascript .= "indiciaData.speciesGrid['{$options['id']}']={};\n";
             data_entry_helper::$javascript .= "indiciaData.speciesGrid['{$options['id']}'].cacheLookup=" . ($options['cacheLookup'] ? 'true' : 'false') . ";\n";
             data_entry_helper::$javascript .= "indiciaData.speciesGrid['{$options['id']}'].numValues=" . (!empty($options['numValues']) ? $options['numValues'] : 20) . ";\n";
             data_entry_helper::$javascript .= "indiciaData.speciesGrid['{$options['id']}'].selectMode=" . (!empty($options['selectMode']) && $options['selectMode'] ? 'true' : 'false') . ";\n";
             //encoded media array is just and array of media items that has been json_encoded.
             //Add a row to the occurrence grid for each media item.
             data_entry_helper::$javascript .= "\n        if (indiciaData.encodedMediaArray) {\n          var encodedMediaArray = eval(indiciaData.encodedMediaArray);\n          for (var i=0; i<encodedMediaArray.length; i++) {\n            makeImageRowOrSpareRow('" . $options['id'] . "', {'auth_token' : '" . $options['readAuth']['auth_token'] . "', 'nonce' : '" . $options['readAuth']['nonce'] . "'},'" . $options['lookupListId'] . "','{$url}', null, false, null, null, encodedMediaArray[i]);\n          }\n        }\n        \r\n";
             data_entry_helper::$javascript .= "makeImageRowOrSpareRow('" . $options['id'] . "', {'auth_token' : '" . $options['readAuth']['auth_token'] . "', 'nonce' : '" . $options['readAuth']['nonce'] . "'},'" . $options['lookupListId'] . "','{$url}', null, false, null, null);\r\n";
         }
         // If options contain a help text, output it at the end if that is the preferred position
         $options['helpTextClass'] = isset($options['helpTextClass']) ? $options['helpTextClass'] : 'helpTextLeft';
         $r = $beforegrid . $grid;
         data_entry_helper::$javascript .= "\$('#" . $options['id'] . "').find('input,select').keydown(keyHandler);\n";
         //nameFilter is an array containing all the parameters required to return data for each of the
         //"Choose species names available for selection" filter types
         data_entry_helper::species_checklist_filter_popup($options, $nameFilter);
         if ($options['subSamplePerRow']) {
             // output a hidden block to contain sub-sample hidden input values.
             $r .= '<div id="' . $options['id'] . '-blocks">' . data_entry_helper::get_subsample_per_row_hidden_inputs() . '</div>';
         }
         if ($hasEditedRecord) {
             data_entry_helper::$javascript .= "\$('#{$options['id']} tbody tr').hide();\n";
             data_entry_helper::$javascript .= "\$('#{$options['id']} tbody tr td.edited-record').parent().show();\n";
             data_entry_helper::$javascript .= "\$('#{$options['id']} tbody tr td.edited-record').parent().next('tr.supplementary-row').show();\n";
             $r .= '<p>' . lang::get('You are editing a single record that is part of a larger sample, so any changes to the sample\'s information such as edits to the date or map reference ' . 'will affect the whole sample.') . " <a id=\"species-grid-view-all-{$options['id']}\">" . lang::get('View all the records in this sample or add more records.') . '</a></p>';
             data_entry_helper::$javascript .= "\$('#species-grid-view-all-{$options['id']}').click(function(e) {\n  \$('#{$options['id']} tbody tr').show();\n  \$(e.currentTarget).hide();\n});\n";
             self::$onload_javascript .= "\nif (\$('#{$options['id']}').parents('.ui-tabs-panel').length) {\n  indiciaFns.activeTab(\$('#controls'), \$('#{$options['id']}').parents('.ui-tabs-panel')[0].id);\n}\n";
         }
         return $r;
     } else {
         return $taxalist['error'];
     }
 }
 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;
 }
 /**
  * The species filter can be taken from the edit tab or overridden by a URL
  * filter. This method determines the filter to be used.
  * @param array $args Form arguments
  * @return array List of items to filter against, e.g. species names or
  * meaning IDs.
  */
 protected static function get_species_filter($args)
 {
     // we must have a filter field specified in order to apply a filter
     if (!empty($args['taxon_filter_field'])) {
         // if URL params are enabled and we have one, then this is the top
         // priority filter to apply
         if (!empty($_GET['taxon']) && $args['use_url_taxon_parameter']) {
             // convert commas to newline, so url provided filters are the same
             // format as those on the edit tab, also allowing for url encoding.
             return explode(',', urldecode($_GET['taxon']));
         } elseif (!empty($args['taxon_filter'])) {
             // filter is provided on the edit tab
             return helper_base::explode_lines($args['taxon_filter']);
         }
     }
     // default - no filter to apply
     return array();
 }
Esempio n. 14
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 '';
 }
Esempio n. 15
0
 /**
  * Call the enable_validation method to turn on client-side validation for any controls with
  * validation rules defined.
  * To specify validation on each control, set the control's options array
  * to contain a 'validation' entry. This must be set to an array of validation rules in Indicia
  * validation format. For example, 'validation' => array('required', 'email').
  * @param string @form_id Id of the form the validation is being attached to.
  */
 public static function enable_validation($form_id)
 {
     self::$validated_form_id = $form_id;
     self::$javascript .= "indiciaData.validatedFormId = '" . self::$validated_form_id . "';\n";
     // prevent double submission of the form
     self::$javascript .= "\$('#{$form_id}').submit(function(e) {\n  if (typeof \$('#{$form_id}').valid === 'undefined' || \$('#{$form_id}').valid()) {\n    if (typeof indiciaData.formSubmitted==='undefined' || !indiciaData.formSubmitted) {\n      indiciaData.formSubmitted=true;\n    } else {\n      e.preventDefault();\n      return false;\n    }\n  }\n});\n";
     self::add_resource('validation');
 }
 /**
  * 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;
 }
 /**
  * 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 $nid The Drupal node object's ID.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  */
 public static function get_form($args, $nid, $response = null)
 {
     drupal_add_js(iform_client_helpers_path() . "prebuilt_forms/js/easy_download_2.js");
     drupal_add_css(iform_client_helpers_path() . "prebuilt_forms/css/easy_download_2.css");
     $conn = iform_get_connection_details($nid);
     $args = array_merge(array('download_administered_groups' => 'indicia data admin', 'download_group_types' => ''), $args);
     $readAuth = data_entry_helper::get_read_auth($conn['website_id'], $conn['password']);
     if (data_entry_helper::$js_read_tokens === null) {
         data_entry_helper::$js_read_tokens = $readAuth;
     }
     if (!empty($_POST) && !empty($_POST['format'])) {
         self::do_data_services_download($args, $nid);
     }
     $types = self::get_download_types($args);
     $formats = self::get_download_formats($args);
     if (count($types) === 0) {
         return 'This download page is configured so that no download type options are available.';
     }
     if (count($formats) === 0) {
         return 'This download page is configured so that no download format options are available.';
     }
     $reload = data_entry_helper::get_reload_link_parts();
     $reloadPath = $reload['path'];
     if (count($reload['params'])) {
         $reloadPath .= '?' . helper_base::array_to_query_string($reload['params']);
     }
     $r = '<form method="POST" action="' . $reloadPath . '">';
     $r .= '<fieldset id="download-type-fieldset"><legend>' . lang::get('Records to download') . '</legend>';
     if (count($types) === 1) {
         $r .= '<input type="hidden" name="download-type" id="download-type" value="' . implode('', array_keys($types)) . '"/>';
         hostsite_set_page_title(lang::get('Download {1}', strtolower(implode('', $types))));
     } else {
         $r .= data_entry_helper::select(array('fieldname' => 'download-type', 'label' => lang::get('Download type'), 'lookupValues' => $types, 'class' => 'control-width-5', 'helpText' => 'Select the type of download you require, i.e. the purpose for the data. This defines which records are available to download.'));
     }
     $r .= data_entry_helper::select(array('fieldname' => 'download-subfilter', 'label' => lang::get('Filter to apply'), 'lookupValues' => array(), 'class' => 'control-width-5', 'helpText' => lang::get('Optionally select from the available filters. Filters you create on the Explore pages will be available here.')));
     $r .= "</fieldset>\n";
     $r .= '<fieldset><legend>' . lang::get('Limit the records') . '</legend>';
     // Hub
     // TODO may run into URL size limits
     $vocabulary = taxonomy_vocabulary_machine_name_load('hubs');
     $terms = entity_load('taxonomy_term', FALSE, array('vid' => $vocabulary->vid));
     // the hub is driven by a user field, stored as tid.
     $hubList = array('' => lang::get('<All>'));
     foreach ($terms as $term) {
         // TODO Cache
         $query = new EntityFieldQuery();
         $query->entityCondition('entity_type', 'user')->fieldCondition('field_preferred_training_hub', 'tid', $term->tid);
         $result = $query->execute();
         // This gives us the list of users which are in the hub: CMS user ID: now convert to indicia user id
         $userIDList = array();
         if (count($result) > 0) {
             $cmsUserIDs = array_keys($result['user']);
             foreach ($cmsUserIDs as $cmsUserID) {
                 $user_data = user_load($cmsUserID);
                 // TODO Making assumption about language
                 if (!empty($user_data->field_indicia_user_id['und'][0]['value'])) {
                     $userIDList[] = $user_data->field_indicia_user_id['und'][0]['value'];
                 }
             }
             if (count($userIDList) > 0) {
                 $hubList[implode(',', $userIDList)] = $term->tid . ' ' . $term->name;
             }
         }
     }
     $r .= data_entry_helper::select(array('fieldname' => 'user_id_list', 'label' => lang::get('Hub to include'), 'helpText' => 'Choose a Hub, or &lt;All&gt; to not filter by Hub. This is driven off the users currently allocated to the hub. This currently does not apply to the NBN download.', 'lookupValues' => $hubList, 'class' => 'control-width-5'));
     // End Cocoast Hub
     if (empty($args['survey_id'])) {
         // put up an empty surveys drop down. AJAX will populate it.
         $r .= data_entry_helper::select(array('fieldname' => 'survey_id', 'label' => lang::get('Survey to include'), 'helpText' => 'Choose a survey, or &lt;All&gt; to not filter by survey.', 'lookupValues' => array(), 'class' => 'control-width-5'));
     } else {
         $r .= '<input type="hidden" name="survey_id" value="' . $args['survey_id'] . '"/>';
     }
     // Let the user pick the date range to download.
     $r .= data_entry_helper::select(array('label' => lang::get('Date field'), 'fieldname' => 'date_type', 'lookupValues' => array('recorded' => lang::get('Field record date'), 'input' => lang::get('Input date'), 'edited' => lang::get('Last changed date'), 'verified' => 'Verification status change date'), 'helpText' => 'If filtering on date, which date field would you like to filter on?'));
     $r .= data_entry_helper::date_picker(array('fieldname' => 'date_from', 'label' => lang::get('Start Date'), 'helpText' => 'Leave blank for no start date filter', 'class' => 'control-width-4'));
     $r .= data_entry_helper::date_picker(array('fieldname' => 'date_to', 'label' => lang::get('End Date'), 'helpText' => 'Leave blank for no end date filter', 'class' => 'control-width-4'));
     $r .= '</fieldset>';
     if (!empty($args['custom_formats'])) {
         $customFormats = json_decode($args['custom_formats'], true);
         foreach ($customFormats as $idx => $format) {
             if (empty($format['permission']) || hostsite_user_has_permission($format['permission'])) {
                 $formats["custom-{$idx}"] = lang::get(isset($format['title']) ? $format['title'] : 'Untitled format');
             }
         }
     }
     if (count($formats) > 1) {
         $r .= '<fieldset><legend>' . lang::get('Select a format to download') . '</legend>';
         $keys = array_keys($formats);
         $r .= data_entry_helper::radio_group(array('fieldname' => 'format', 'lookupValues' => $formats, 'default' => $keys[0]));
         $r .= '</fieldset>';
     } else {
         // only allowed 1 format, so no need for a selection control
         $keys = array_keys($formats);
         $r .= '<input type="hidden" name="format" value="' . array_pop($keys) . '"/>';
     }
     $r .= '<input type="submit" value="' . lang::get('Download') . '"/></form>';
     data_entry_helper::$javascript .= 'indiciaData.ajaxUrl="' . url('iform/ajax/easy_download_2') . "\";\n";
     data_entry_helper::$javascript .= 'indiciaData.nid = "' . $nid . "\";\n";
     data_entry_helper::$javascript .= "setAvailableDownloadFilters();\n";
     return $r;
 }
 /**
  * Overrides the postSubmit function to add in additional metadata and data values. 
  */
 protected function postSubmit($isInsert)
 {
     require_once DOCROOT . 'client_helpers/helper_base.php';
     $result = true;
     if (isset($this->submission['metaFields'])) {
         $currentRule = data_cleaner::get_rule($this->test_type);
         if (isset($this->submission['metaFields']['metadata']['value'])) {
             $metadata = helper_base::explode_lines_key_value_pairs($this->submission['metaFields']['metadata']['value']);
             $this->save_verification_rule_metadata($currentRule, $metadata);
             $data = data_cleaner::parse_test_file($this->submission['metaFields']['data']['value']);
             $this->save_verification_rule_data($currentRule, $data);
             $this->postProcessRule($currentRule);
         }
     }
     return true;
 }
Esempio n. 20
0
 /**
  * Draw the Species Details section of the page.
  * @return string The output html string.
  * 
  * @package    Client
  * @subpackage PrebuiltForms
  */
 protected static function get_control_speciesdetails($auth, $args, $tabalias, $options)
 {
     $fields = helper_base::explode_lines($args['fields']);
     $fieldsLower = helper_base::explode_lines(strtolower($args['fields']));
     //If the user sets the option to exclude particular fields then we set to the hide flag
     //on the name types they have specified.
     if ($args['operator'] == 'not in') {
         $hidePreferred = false;
         $hideCommon = false;
         $hideSynonym = false;
         $hideTaxonomy = false;
         foreach ($fieldsLower as $theField) {
             if ($theField == 'preferred names' || $theField == 'preferred name' || $theField == 'preferred') {
                 $hidePreferred = true;
             } elseif ($theField == 'common names' || $theField == 'common name' || $theField == 'common') {
                 $hideCommon = true;
             } elseif ($theField == 'synonym names' || $theField == 'synonym name' || $theField == 'synonym') {
                 $hideSynonym = true;
             } elseif ($theField == 'taxonomy') {
                 $hideTaxonomy = true;
             }
         }
     }
     //If the user sets the option to only include particular fields then we set to the hide flag
     //to true unless they have specified the name type.
     if ($args['operator'] == 'in') {
         $hidePreferred = true;
         $hideCommon = true;
         $hideSynonym = true;
         $hideTaxonomy = true;
         foreach ($fieldsLower as $theField) {
             if ($theField == 'preferred names' || $theField == 'preferred name' || $theField == 'preferred') {
                 $hidePreferred = false;
             } elseif ($theField == 'common names' || $theField == 'common name' || $theField == 'common') {
                 $hideCommon = false;
             } elseif ($theField == 'synonym names' || $theField == 'synonym name' || $theField == 'synonym') {
                 $hideSynonym = false;
             } elseif ($theField == 'taxonomy') {
                 $hideTaxonomy = true;
             }
         }
     }
     //Draw the names on the page
     $details_report = self::draw_names($auth['read'], $hidePreferred, $hideCommon, $hideSynonym, $hideTaxonomy);
     $attrsTemplate = '<div class="field ui-helper-clearfix"><span>{caption}:</span><span>{value}</span></div>';
     //draw any custom attributes for the species added by the user
     $attrs_report = report_helper::freeform_report(array('readAuth' => $auth['read'], 'class' => 'species-details-fields', 'dataSource' => 'library/taxa/taxon_attributes_with_hiddens', 'bands' => array(array('content' => $attrsTemplate)), 'extraParams' => array('taxa_taxon_list_id' => self::$taxa_taxon_list_id, 'attrs' => strtolower(self::convert_array_to_set($fields)), 'testagainst' => $args['testagainst'], 'operator' => $args['operator'], 'sharing' => 'reporting')));
     $r = '<div class="detail-panel" id="detail-panel-speciesdetails"><h3>' . lang::get('Species Details') . '</h3><div class="record-details-fields ui-helper-clearfix">';
     //draw the species names and custom attributes
     if (isset($details_report)) {
         $r .= $details_report;
     }
     if (isset($attrs_report)) {
         $r .= $attrs_report;
     }
     $r .= '</div></div>';
     return $r;
 }
 /**
  * Convert the unstructured textarea of default values into a structured array.
  */
 protected static function parse_defaults(&$args)
 {
     $result = array();
     if (isset($args['defaults'])) {
         $result = helper_base::explode_lines_key_value_pairs($args['defaults']);
     }
     $args['defaults'] = $result;
 }
Esempio n. 22
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;
 }
 /**
  * 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;
 }
 /**
  * Finds a record cleaner server index page and returns the list of files it refers to.
  */
 private function fetch_server_file_list($server)
 {
     // as redirections cause a recursion, let's set a limit
     static $curl_loops = 0;
     static $curl_max_loops = 20;
     if ($curl_loops++ >= $curl_max_loops) {
         $curl_loops = 0;
         throw new exception("cUrl request to {$server} resulted in too many redirections");
     }
     $session = curl_init($server);
     curl_setopt($session, CURLOPT_HEADER, true);
     curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($session, CURLOPT_SSL_VERIFYPEER, false);
     $files = array();
     $response = curl_exec($session);
     if (curl_errno($session)) {
         kohana::log('error', 'cUrl error : ' . curl_errno($session));
         kohana::log('error', 'cUrl message : ' . curl_error($session));
         throw new exception("cUrl request to {$server} failed");
     }
     $http_code = curl_getinfo($session, CURLINFO_HTTP_CODE);
     // did we get a redirect response?
     if ($http_code == 301 || $http_code == 302) {
         // find the redirect location in the response
         preg_match('/Location:(.*?)\\n/', $response, $matches);
         $url = @parse_url(trim(array_pop($matches)));
         if (!$url) {
             throw new exception("Redirect from {$server} failed");
         }
         $last_url = parse_url(curl_getinfo($session, CURLINFO_EFFECTIVE_URL));
         if (!$url['scheme']) {
             $url['scheme'] = $last_url['scheme'];
         }
         if (!$url['host']) {
             $url['host'] = $last_url['host'];
         }
         if (!$url['path']) {
             $url['path'] = $last_url['path'];
         }
         $newUrl = $url['scheme'] . '://' . $url['host'] . $url['path'] . (isset($url['query']) ? '?' . $url['query'] : '');
         return self::fetch_server_file_list($newUrl);
     }
     list($header, $data) = explode("\r\n\r\n", $response, 2);
     foreach (helper_base::explode_lines($data) as $line) {
         $tokens = explode('#', $line);
         $files[] = array('file' => $tokens[0], 'title' => $tokens[1], 'date' => $tokens[2]);
     }
     return $files;
 }
 /**
  * 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)
 {
     $conn = iform_get_connection_details($node);
     data_entry_helper::$js_read_tokens = data_entry_helper::get_read_auth($conn['website_id'], $conn['password']);
     if (!empty($_POST) && !empty($_POST['format'])) {
         self::do_data_services_download($args, $node);
     }
     $conn = iform_get_connection_details($node);
     data_entry_helper::$js_read_tokens = data_entry_helper::get_read_auth($conn['website_id'], $conn['password']);
     $types = self::get_download_types($args);
     $formats = self::get_download_formats($args);
     if (count($types) === 0) {
         return 'This download page is configured so that no download type options are available.';
     }
     if (count($formats) === 0) {
         return 'This download page is configured so that no download format options are available.';
     }
     $reload = data_entry_helper::get_reload_link_parts();
     $reloadPath = $reload['path'];
     if (count($reload['params'])) {
         $reloadPath .= '?' . helper_base::array_to_query_string($reload['params']);
     }
     $r = '<form method="POST" action="' . $reloadPath . '">';
     $r .= '<fieldset id="download-type-fieldset"><legend>' . lang::get('Records to download') . '</legend>';
     if (count($types) === 1) {
         $r .= '<input type="hidden" name="download-type" id="download-type" value="' . implode('', array_keys($types)) . '"/>';
         hostsite_set_page_title(lang::get('Download {1}', strtolower(implode('', $types))));
     } else {
         $r .= data_entry_helper::select(array('fieldname' => 'download-type', 'label' => lang::get('Download type'), 'lookupValues' => $types, 'class' => 'control-width-5', 'helpText' => 'Select the type of download you require, i.e. the purpose for the data. This defines which records are available to download.'));
     }
     $r .= data_entry_helper::select(array('fieldname' => 'download-subfilter', 'label' => lang::get('Filter to apply'), 'lookupValues' => array(), 'class' => 'control-width-5', 'helpText' => lang::get('Optionally select from the available filters. Filters you create on the Explore pages will be available here.')));
     $r .= "</fieldset>\n";
     $r .= '<fieldset><legend>' . lang::get('Limit the records') . '</legend>';
     if (empty($args['survey_id'])) {
         // put up an empty surveys drop down. AJAX will populate it.
         $r .= data_entry_helper::select(array('fieldname' => 'survey_id', 'label' => lang::get('Survey to include'), 'helpText' => 'Choose a survey, or <all> to not filter by survey.', 'lookupValues' => array(), 'class' => 'control-width-5'));
     } else {
         $r .= '<input type="hidden" name="survey_id" value="' . $args['survey_id'] . '"/>';
     }
     // Let the user pick the date range to download.
     $r .= data_entry_helper::select(array('label' => lang::get('Date field'), 'fieldname' => 'date_type', 'lookupValues' => array('recorded' => lang::get('Field record date'), 'input' => lang::get('Input date'), 'edited' => lang::get('Last changed date'), 'verified' => 'Verification status change date'), 'helpText' => 'If filtering on date, which date field would you like to filter on?'));
     $r .= data_entry_helper::date_picker(array('fieldname' => 'date_from', 'label' => lang::get('Start Date'), 'helpText' => 'Leave blank for no start date filter', 'class' => 'control-width-4'));
     $r .= data_entry_helper::date_picker(array('fieldname' => 'date_to', 'label' => lang::get('End Date'), 'helpText' => 'Leave blank for no end date filter', 'class' => 'control-width-4'));
     $r .= '</fieldset>';
     if (!empty($args['custom_formats'])) {
         $customFormats = json_decode($args['custom_formats'], true);
         foreach ($customFormats as $idx => $format) {
             if (empty($format['permission']) || user_access($format['permission'])) {
                 $formats["custom-{$idx}"] = lang::get(isset($format['title']) ? $format['title'] : 'Untitled format');
             }
         }
     }
     if (count($formats) > 1) {
         $r .= '<fieldset><legend>' . lang::get('Select a format to download') . '</legend>';
         $keys = array_keys($formats);
         $r .= data_entry_helper::radio_group(array('fieldname' => 'format', 'lookupValues' => $formats, 'default' => $keys[0]));
         $r .= '</fieldset>';
     } else {
         // only allowed 1 format, so no need for a selection control
         $keys = array_keys($formats);
         $r .= '<input type="hidden" name="format" value="' . array_pop($keys) . '"/>';
     }
     $r .= '<input type="submit" value="' . lang::get('Download') . '"/></form>';
     data_entry_helper::$javascript .= 'indiciaData.ajaxUrl="' . url('iform/ajax/easy_download_2') . "\";\n";
     data_entry_helper::$javascript .= 'indiciaData.nid = "' . $node->nid . "\";\n";
     data_entry_helper::$javascript .= "setAvailableDownloadFilters();\n";
     return $r;
 }
Esempio n. 26
0
 /**
  * Performs the sending of invitation emails.
  * @param array $args Form configuration arguments
  * @param array $auth Authorisation tokens
  * @todo Integrate with notifications for logged in users.
  */
 private static function sendInvites($args, $auth)
 {
     $emails = helper_base::explode_lines($_POST['invitee_emails']);
     // first task is to populate the groups_invitations table
     $base = uniqid();
     $success = true;
     $failedRecipients = array();
     foreach ($emails as $idx => $email) {
         $values = array('group_invitation:group_id' => $_GET['group_id'], 'group_invitation:email' => $email, 'group_invitation:token' => $base . $idx, 'website_id' => $args['website_id']);
         $s = submission_builder::build_submission($values, array('model' => 'group_invitation'));
         $r = data_entry_helper::forward_post_to('group_invitation', $s, $auth['write_tokens']);
         $pathParam = function_exists('variable_get') && variable_get('clean_url', 0) == '0' ? 'q' : '';
         $rootFolder = data_entry_helper::getRootFolder() . (empty($pathParam) ? '' : "?{$pathParam}=");
         $protocol = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' || $_SERVER['SERVER_PORT'] == 443 ? "https://" : "http://";
         $acceptUrl = $protocol . $_SERVER['HTTP_HOST'] . $rootFolder . $args['accept_invite_path'] . (empty($pathParam) ? '?' : '&') . 'token=' . $base . $idx;
         $body = $_POST['invite_message'] . "<br/><br/>" . '<a href="' . $acceptUrl . '">' . lang::get('Accept this invitation') . '</a>';
         $message = array('id' => 'iform_group_invite', 'to' => implode(',', $emails), 'subject' => 'Invitation to join a recording group', 'body' => $body, 'headers' => array('MIME-Version' => '1.0', 'Content-type' => 'text/html; charset=iso-8859-1'));
         $mimeheaders = array();
         foreach ($message['headers'] as $name => $value) {
             $mimeheaders[] = $name . ': ' . mime_header_encode($value);
         }
         $thismailsuccess = mail($message['to'], mime_header_encode($message['subject']), str_replace("\r", '', $message['body']), join("\n", $mimeheaders));
         if (!$thismailsuccess) {
             $failedRecipients[$message['to']] = $acceptUrl;
         }
         $success = $success && $thismailsuccess;
     }
     if ($success) {
         drupal_set_message(lang::get('Invitation emails sent'));
     } else {
         drupal_set_message(lang::get('The emails could not be sent due to a server configuration issue. Please contact the site admin. ' . 'The list below gives the emails and the links you need to send to each invitee which they need to click on in order to join the group.'), 'warning');
         $list = array();
         foreach ($failedRecipients as $email => $link) {
             $list[] = lang::get("Send link {1} to {2}.", $link, $email);
         }
         drupal_set_message(implode('<br/>', $list), 'warning');
     }
     drupal_goto($args['redirect_on_success']);
 }
Esempio n. 27
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)
 {
     // Do they have expert access?
     $expert = function_exists('user_access') && user_access($args['permission']);
     $conn = iform_get_connection_details($node);
     $readAuth = data_entry_helper::get_read_auth($conn['website_id'], $conn['password']);
     // Find out which types of filters and formats are available to the user
     $filters = self::get_filters($args, $readAuth);
     $formats = array();
     if ($args['csv_format'] === 'yes' || $args['csv_format'] === 'expert' && $expert) {
         $formats[] = 'csv';
     }
     if ($args['tsv_format'] === 'yes' || $args['tsv_format'] === 'expert' && $expert) {
         $formats[] = 'tsv';
     }
     if ($args['kml_format'] === 'yes' || $args['kml_format'] === 'expert' && $expert) {
         $formats[] = 'kml';
     }
     if ($args['gpx_format'] === 'yes' || $args['gpx_format'] === 'expert' && $expert) {
         $formats[] = 'gpx';
     }
     if ($args['nbn_format'] === 'yes' || $args['nbn_format'] === 'expert' && $expert) {
         $formats[] = 'nbn';
     }
     if (count($filters) === 0) {
         return 'This download page is configured so that no filter options are available.';
     }
     if (count($formats) === 0) {
         return 'This download page is configured so that no download format options are available.';
     }
     if (!empty($_POST)) {
         self::do_download($args, $filters);
     }
     iform_load_helpers(array('data_entry_helper'));
     $reload = data_entry_helper::get_reload_link_parts();
     $reloadPath = $reload['path'];
     if (count($reload['params'])) {
         $reloadPath .= '?' . helper_base::array_to_query_string($reload['params']);
     }
     $r = '<form method="POST" action="' . $reloadPath . '">';
     $r .= '<fieldset><legend>' . lang::get('Filters') . '</legend>';
     if (count($filters) === 0) {
         return 'This download page is configured so that no filter options are available.';
     } elseif (count($filters) === 1) {
         $r .= '<input type="hidden" name="user-filter" value="' . implode('', array_keys($filters)) . '"/>';
         // Since there is only one option, we may as well tell the user what it is.
         drupal_set_title(implode('', array_values($filters)));
         if (implode('', array_keys($filters)) === 'mine') {
             $r .= '<p>' . lang::get('Use this form to download your own records.') . '</p>';
         }
     } else {
         $r .= data_entry_helper::radio_group(array('label' => lang::get('User filter'), 'fieldname' => 'user-filter', 'lookupValues' => $filters, 'default' => empty($_POST['user-filter']) ? 'mine' : $_POST['user-filter']));
     }
     if (empty($args['survey_id'])) {
         // A survey picker when downloading my data
         $r .= '<div id="survey_all">';
         $r .= data_entry_helper::select(array('fieldname' => 'survey_id_all', 'label' => lang::get('Survey to include'), 'table' => 'survey', 'valueField' => 'id', 'captionField' => 'title', 'helpText' => 'Choose a survey, or <all> to not filter by survey.', 'blankText' => '<all>', 'class' => 'control-width-4', 'extraParams' => $readAuth + array('sharing' => 'data_flow', 'orderby' => 'title')));
         $r .= '</div>';
         // A survey picker when downloading data you are an expert for
         $surveys_expertise = hostsite_get_user_field('surveys_expertise');
         if ($surveys_expertise) {
             $surveys_expertise = unserialize($surveys_expertise);
             $surveysFilter = array('query' => json_encode(array('in' => array('id' => $surveys_expertise))));
         } else {
             // no filter as there are no specific surveys this user is an expert for
             $surveysFilter = array();
         }
         $r .= '<div id="survey_expertise">';
         $r .= data_entry_helper::select(array('fieldname' => 'survey_id_expert', 'label' => lang::get('Survey to include'), 'table' => 'survey', 'valueField' => 'id', 'captionField' => 'title', 'helpText' => 'Choose a survey, or <all> to not filter by survey.', 'blankText' => '<all>', 'class' => 'control-width-4', 'extraParams' => $readAuth + array('sharing' => 'verification', 'orderby' => 'title') + $surveysFilter));
         $r .= '</div>';
     }
     // Let the user pick the date range to download.
     $r .= data_entry_helper::date_picker(array('fieldname' => 'date_from', 'label' => lang::get('Start Date'), 'helpText' => 'Leave blank for no start date filter', 'class' => 'control-width-4'));
     $r .= data_entry_helper::date_picker(array('fieldname' => 'date_to', 'label' => lang::get('End Date'), 'helpText' => 'Leave blank for no end date filter', 'class' => 'control-width-4'));
     $r .= '</fieldset>';
     $r .= '<fieldset><legend>' . lang::get('Downloads') . '</legend>';
     $r .= '<label>Download options:</label>';
     if (in_array('csv', $formats)) {
         $r .= '<input class="inline-control" type="submit" name="format" value="' . lang::get('Spreadsheet (CSV)') . '"/>';
     }
     if (in_array('tsv', $formats)) {
         $r .= '<input class="inline-control" type="submit" name="format" value="' . lang::get('Tab Separated File (TSV)') . '"/>';
     }
     if (in_array('kml', $formats)) {
         $r .= '<input class="inline-control" type="submit" name="format" value="' . lang::get('Google Earth File') . '"/>';
     }
     if (in_array('gpx', $formats)) {
         $r .= '<input class="inline-control" type="submit" name="format" value="' . lang::get('GPS Track File') . '"/>';
     }
     if (in_array('nbn', $formats)) {
         $r .= '<input class="inline-control" type="submit" name="format" value="' . lang::get('NBN Format') . '"/>';
         $r .= '<p class="helpText">' . lang::get('Note that the NBN format download will only include verified data and excludes records where the date or spatial reference is not compatible with the NBN Gateway.') . '</p>';
     }
     $r .= '</fieldset></form>';
     return $r;
 }
Esempio n. 28
0
function iform_mnhnl_getTermID($auth, $termListExtKey, $term)
{
    $termList = helper_base::get_termlist_terms($auth, $termListExtKey, array($term));
    return $termList[0]['id'];
}
 /**
  * Return the generated output for the occurrences grid tab.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  *                    This array always contains a value for language.
  * @param integer $nid The Drupal node object's ID.
  * @param object $auth The full read-write authorisation.
  * @return HTML.
  */
 private static function get_occurrences_tab($args, $nid, $auth, $packageAttr)
 {
     global $user;
     global $indicia_templates;
     // initially not ajax due to uncertainty over mandatory status of sample attributes.
     $r = '';
     // In the situation where there are multiple species packages to be selected from, we can't
     // display the species grid until that decision is made.
     if (self::$multiPackageOptions) {
         return '<div id="occurrences">' . '<p>' . lang::get('There are multiple possible species packages: you must select the species package (on the first tab) and then save the record before you can enter data on the species tab.') . '</p>' . data_entry_helper::hidden_text(array('fieldname' => 'force_page_reload')) . '</div>';
     }
     // Because the initial save sets the species package
     // remove the ctrlWrap as it complicates the grid & JavaScript unnecessarily
     $oldCtrlWrapTemplate = $indicia_templates['controlWrap'];
     $indicia_templates['controlWrap'] = '{control}';
     data_entry_helper::add_resource('jquery_form');
     $defaults = helper_base::explode_lines_key_value_pairs($args['defaults']);
     $record_status = isset($defaults['occurrence:record_status']) ? $defaults['occurrence:record_status'] : 'C';
     // find any attributes that apply to quadrat samples.
     // We need attribute list in both ordered and indexed formats
     $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' => $args['quadrat_level_sample_method_id']));
     $attributesIdx = 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' => $args['quadrat_level_sample_method_id'], 'multiValue' => false));
     $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));
     if (self::$sampleId == null) {
         $subSamples = array();
         $o = array();
     } else {
         $subSamples = data_entry_helper::get_population_data(array('report' => 'library/samples/samples_list_for_parent_sample', 'extraParams' => $auth['read'] + array('sample_id' => self::$sampleId, 'date_from' => '', 'date_to' => '', 'sample_method_id' => $args['quadrat_level_sample_method_id'], 'smpattrs' => implode(',', array_keys($attributesIdx))), 'nocache' => true));
         $o = data_entry_helper::get_population_data(array('report' => 'reports_for_prebuilt_forms/UKBMS/ukbms_occurrences_list_for_parent_sample', 'extraParams' => $auth['read'] + array('sample_id' => self::$sampleId, 'survey_id' => $args['survey_id'], 'date_from' => '', 'date_to' => '', 'taxon_group_id' => '', 'smpattrs' => '', 'occattrs' => implode(',', array_keys($occ_attributes)), 'orderby' => 'occurrence_id'), 'nocache' => true));
     }
     // build an array of occurrence and attribute data keyed for easy lookup
     $occurrences = array();
     if (self::$readOnly) {
         $taxalist = array();
     } else {
         $taxalist = self::_get_species($user->uid, $args, $packageAttr['default']);
     }
     foreach ($o as $occurrence) {
         $occurrences[$occurrence['sample_id'] . ':' . $occurrence['taxa_taxon_list_id']] = array('ttl_id' => $occurrence['taxa_taxon_list_id'], 'o_id' => $occurrence['occurrence_id'], 'processed' => false);
         if (!in_array($occurrence['taxa_taxon_list_id'], $taxalist)) {
             // ensure taxa list includes all old data. Required if going into view old data when list has changed.
             $taxalist[] = $occurrence['taxa_taxon_list_id'];
         }
         foreach ($occ_attributes as $attr => $defn) {
             $occurrences[$occurrence['sample_id'] . ':' . $occurrence['taxa_taxon_list_id']]['value_' . $attr] = $occurrence['attr_occurrence_' . $attr];
             $occurrences[$occurrence['sample_id'] . ':' . $occurrence['taxa_taxon_list_id']]['a_id_' . $attr] = $occurrence['attr_id_occurrence_' . $attr];
         }
     }
     $limit1 = $args['sample_attribute_id_1_limit'];
     if (!in_array($args['sample_attribute_id_1'], array_keys($attributesIdx))) {
         return "INTERNAL CONFIGURATION ERROR: Supplied primary sample loop attribute (ID " . $args['sample_attribute_id_1'] . ") is not in the list of sample attributes configured for this survey (Survey ID " . $args['survey_id'] . ", attribute IDs " . implode(',', array_keys($attributes)) . "). Ensure that the Indicia Cache is cleared.<br/>";
     }
     $limit2 = $args['sample_attribute_id_2_limit'];
     if (isset($args['sample_attribute_id_2']) && $args['sample_attribute_id_2'] != "") {
         if (!in_array($args['sample_attribute_id_2'], array_keys($attributesIdx))) {
             return "INTERNAL CONFIGURATION ERROR: Supplied optional secondary sample loop attribute (ID " . $args['sample_attribute_id_2'] . ") is not in the list of sample attributes configured for this survey (Survey ID " . $args['survey_id'] . ", attribute IDs " . implode(',', array_keys($attributes)) . "). Ensure that the Indicia Cache is cleared.<br/>";
         }
     } else {
         $limit2 = 1;
     }
     foreach ($subSamples as $subSample) {
         $attrVal = self::_get_sample_attr_value($subSample, $args['sample_attribute_id_1_limit']);
         if ($attrVal > $limit1) {
             $limit1 = $attrVal;
         }
         if (isset($args['sample_attribute_id_2']) && $args['sample_attribute_id_2'] != "") {
             $attrVal = self::_get_sample_attr_value($subSample, $args['sample_attribute_id_2_limit']);
             if ($attrVal > $limit2) {
                 $limit2 = $attrVal;
             }
         }
     }
     $t = data_entry_helper::get_population_data(array('table' => 'taxa_taxon_list', 'extraParams' => $auth['read'] + array('view' => 'detail', 'id' => $taxalist)));
     $r .= '<div id="occurrences">' . '<input type="hidden" id="occurrence:record_status" name="occurrence:record_status" value="' . $record_status . '" />' . "\n" . '<p>' . lang::get('Using Species Package : ') . species_packages_get_name($packageAttr['default']) . '</p>' . '<table id="transect-input1" class="ui-widget species-grid"><thead class="table-header">';
     // Build header
     $r .= '<tr>' . '<th class="ui-widget-header"></th>' . '<th class="ui-widget-header">' . $attributesIdx[$args['sample_attribute_id_1']]['caption'] . '</th>' . (!isset($args['sample_attribute_id_2']) || $args['sample_attribute_id_2'] == "" ? '' : '<th class="ui-widget-header">' . $attributesIdx[$args['sample_attribute_id_2']]['caption'] . '</th>');
     foreach ($attributes as $smpAttr) {
         if ($smpAttr['attributeId'] != $args['sample_attribute_id_1'] && (!isset($args['sample_attribute_id_2']) || $args['sample_attribute_id_2'] == "" || $smpAttr['attributeId'] != $args['sample_attribute_id_2'])) {
             $r .= '<th class="ui-widget-header">' . $smpAttr['caption'] . '</th>';
         }
     }
     // need to maintain order as defined in $taxalist
     $extraDetails = array();
     if (isset($args['taxon_headings_extras']) && $args['taxon_headings_extras'] != '') {
         $extras = explode(',', $args['taxon_headings_extras']);
         foreach ($extras as $extra) {
             $parts = explode(':', $extra);
             $extraDetails[$parts[0]] = $parts[1];
         }
     }
     foreach ($taxalist as $ttlid) {
         foreach ($t as $taxon) {
             if ($ttlid == $taxon['id']) {
                 $attr = self::_get_species_attribute($user->uid, $args, $packageAttr['default'], $ttlid);
                 $r .= '<th class="ui-widget-header"' . ($taxon['common'] != '' && $taxon['taxon'] != $taxon['common'] ? ' title="' . $taxon['common'] . '"' : '') . '>' . $taxon['taxon'] . (isset($extraDetails[$attr]) ? ' (' . $extraDetails[$attr] . ')' : '') . (isset($extraDetails[$taxon['common']]) ? ' (' . $extraDetails[$taxon['common']] . ')' : '') . '</th>';
             }
         }
     }
     $r .= '</tr></thead><tbody class="ui-widget-content">';
     // fieldname naming conventions
     // Each sample attribute has a fieldname "Grid:Row<rowNumber>:[subsampleID]:smpAttr:<attributeID>:[<attributeValueID>]"
     // Each occurrence attribute has a fieldname "Grid:Row<rowNumber>:[subsampleID]:occ:<ttlid>:[occurrenceID]:occAttr:<attributeID>[:<attributeValueID>]"
     // If any smpAttr is filled in, or any occAttr is filled in, then the other occAttr on that line are set to zero
     // If any occAttr is set to zero, the zero abundance flag is set.
     $altRow = false;
     $defAttrOptions = array('extraParams' => $auth['read']);
     $roAttrOptions = array('extraParams' => $auth['read'], 'readonly' => 'readonly="readonly"', 'class' => 'ignore', 'ctrl' => 'hidden');
     $rowNumber = 1;
     unset($attributesIdx[$args['sample_attribute_id_1']]['caption']);
     if (isset($args['sample_attribute_id_2']) && $args['sample_attribute_id_2'] != "") {
         unset($attributesIdx[$args['sample_attribute_id_2']]['caption']);
     }
     foreach ($attributes as &$attr) {
         unset($attr['caption']);
     }
     foreach ($occ_attributes as &$attr) {
         unset($attr['caption']);
     }
     for ($loop1 = 1; $loop1 <= $limit1; $loop1++) {
         for ($loop2 = 1; $loop2 <= $limit2; $loop2++) {
             $existingSample = self::_get_row_sample($subSamples, $args['sample_attribute_id_1'], $loop1, isset($args['sample_attribute_id_2']) && $args['sample_attribute_id_2'] != "" ? $args['sample_attribute_id_2'] : false, $loop2);
             $rowPrefix = "Grid:Row" . $rowNumber . ":" . ($existingSample ? $existingSample['sample_id'] : '') . ":";
             $r .= '<tr class="datarow' . ($loop2 == 1 ? ' level1' : ' level2') . '">';
             $r .= '<td class="ui-state-default clear-row" style="width: 1%" title="' . lang::get('Clear all contents of this row') . '">X</td>';
             $roAttrOptions['id'] = $roAttrOptions['fieldname'] = self::_get_sample_attr_name($rowPrefix, $existingSample, $args['sample_attribute_id_1']);
             $roAttrOptions['default'] = $loop1;
             $r .= '<td>' . data_entry_helper::outputAttribute($attributesIdx[$args['sample_attribute_id_1']], $roAttrOptions) . '</td>';
             if (isset($args['sample_attribute_id_2']) && $args['sample_attribute_id_2'] != "") {
                 $roAttrOptions['id'] = $roAttrOptions['fieldname'] = self::_get_sample_attr_name($rowPrefix, $existingSample, $args['sample_attribute_id_2']);
                 $roAttrOptions['default'] = $loop2;
                 $r .= '<td>' . data_entry_helper::outputAttribute($attributesIdx[$args['sample_attribute_id_2']], $roAttrOptions) . '</td>';
             }
             foreach ($attributes as $smpAttr) {
                 if ($smpAttr['attributeId'] != $args['sample_attribute_id_1'] && (!isset($args['sample_attribute_id_2']) || $args['sample_attribute_id_2'] == "" || $smpAttr['attributeId'] != $args['sample_attribute_id_2'])) {
                     unset($defAttrOptions['class']);
                     $defAttrOptions['id'] = $defAttrOptions['fieldname'] = self::_get_sample_attr_name($rowPrefix, $existingSample, $smpAttr['attributeId']);
                     $defAttrOptions['default'] = self::_get_sample_attr_value($existingSample, $smpAttr['attributeId']);
                     if ($loop2 == 1 || !in_array($smpAttr['attributeId'], explode(',', $args['level_1_attributes']))) {
                         if (in_array($smpAttr['attributeId'], explode(',', $args['level_1_attributes']))) {
                             $defAttrOptions['class'] = 'lvl1Master lvl1-' . $loop1 . '-' . $smpAttr['attributeId'];
                         }
                         $r .= '<td>' . data_entry_helper::outputAttribute($smpAttr, $defAttrOptions) . '</td>';
                     } else {
                         $r .= '<td><input class="ignore copydown lvl1-' . $loop1 . '-' . $smpAttr['attributeId'] . '" readonly="readonly" type="hidden" name="' . $defAttrOptions['fieldname'] . '" value="' . $defAttrOptions['default'] . '" /></td>';
                     }
                 }
             }
             // need to maintain order as defined in $taxalist
             $first = true;
             foreach ($taxalist as $ttlid) {
                 foreach ($t as $taxon) {
                     if ($ttlid == $taxon['id']) {
                         $defOccAttrOptions = array('extraParams' => $auth['read']);
                         $occAttrID = self::_get_species_attribute($user->uid, $args, $packageAttr['default'], $ttlid);
                         if ($occAttrID === false) {
                             foreach ($occ_attributes as $attrID => $occ_attribute) {
                                 if (isset($occurrences[$existingSample['sample_id'] . ':' . $ttlid]) && isset($occurrences[$existingSample['sample_id'] . ':' . $ttlid]['value_' . $attrID]) && $occurrences[$existingSample['sample_id'] . ':' . $ttlid]['value_' . $attrID] != '') {
                                     $occAttrID = $attrID;
                                     break;
                                 }
                             }
                         }
                         if ($occAttrID === false) {
                             // old data - ttl no longer in list, no detectable attr held: enter dummy
                             $r .= '<td title="Taxon no longer in Species Package. No old data found."></td>';
                         } else {
                             $defOccAttrOptions['id'] = $defOccAttrOptions['fieldname'] = self::_get_occurrence_attr_name($rowPrefix, $existingSample, $ttlid, $occAttrID, $occurrences);
                             $defOccAttrOptions['default'] = self::_get_occurrence_attr_value($existingSample, $ttlid, $occAttrID, $occurrences);
                             $defOccAttrOptions['class'] = self::_get_occurrence_attr_class($first, $existingSample, $ttlid, $occurrences);
                             $r .= '<td>' . data_entry_helper::outputAttribute($occ_attributes[$occAttrID], $defOccAttrOptions) . '</td>';
                         }
                     }
                 }
             }
             $r .= '</tr>';
             $altRow = !$altRow;
             $rowNumber++;
         }
     }
     $r .= '</table>' . (self::$readOnly ? '' : '<br/><input type="submit" value="' . lang::get('Save') . '" title="' . lang::get('Saves any data entered across all the tabs.') . '" />') . '</div>';
     data_entry_helper::add_resource('jquery_ui');
     data_entry_helper::$javascript .= "indiciaData.fill_zeroes=" . (isset($args['fill_zeroes']) && $args['fill_zeroes'] ? 'true' : 'false') . ";\n";
     return $r;
 }
 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;
 }