Esempio n. 1
0
 public static function link_to_parent($auth, $args, $tabalias, $options, $path)
 {
     if (empty($_GET['table']) || $_GET['table'] !== 'sample' || empty($_GET['id'])) {
         throw new exception('paths_editor.link_to_parent control needs to be called from a form that saves a sample');
     }
     // construct a query to pull back the parent sample and any existing child samples in one go
     $samples = data_entry_helper::get_population_data(array('table' => 'sample', 'extraParams' => $auth['read'] + array('query' => json_encode(array('where' => array('id', $_GET['id']), 'orwhere' => array('parent_id', $_GET['id']))), 'view' => 'detail'), 'caching' => false));
     $childGeoms = array();
     $r = '';
     foreach ($samples as $sample) {
         if ($sample['id'] === $_GET['id']) {
             // found the parent sample. Send to JS so it can be shown on the map
             data_entry_helper::$javascript .= "indiciaData.showParentSampleGeom = '{$sample['geom']}';\n";
             $r = data_entry_helper::hidden_text(array('fieldname' => 'sample:date', 'default' => $sample['date_start']));
         } else {
             // found an already input child sample
             $childGeoms[] = "'{$sample['geom']}'";
         }
     }
     // Output some instructions to the user which will depend on whether we are on the first
     // child sample or not.
     if (!empty($options['outputInstructionsTo'])) {
         $instruct = empty($childGeoms) ? $options['firstInstructions'] : $options['otherInstructions'];
         data_entry_helper::$javascript .= "\$('#{$options['outputInstructionsTo']}').html('{$instruct}');\n";
     }
     $childGeoms = implode(',', $childGeoms);
     data_entry_helper::$javascript .= "indiciaData.showChildSampleGeoms = [{$childGeoms}];\n";
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'sample:parent_id', 'default' => $_GET['id']));
     return $r;
 }
 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. 3
0
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  */
 public static function get_form($args, $node, $response = null)
 {
     $reloadPath = self::get_reload_path();
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $r = "<form method=\"post\" id=\"entry_form\" action=\"{$reloadPath}\">\n";
     $r .= $auth['write'];
     data_entry_helper::$entity_to_load = array();
     if (!empty($_GET['termlists_term_id'])) {
         data_entry_helper::load_existing_record($auth['read'], 'termlists_term', $_GET['termlists_term_id']);
         // map fields to their appropriate supermodels
         data_entry_helper::$entity_to_load['term:term'] = data_entry_helper::$entity_to_load['termlists_term:term'];
         data_entry_helper::$entity_to_load['term:id'] = data_entry_helper::$entity_to_load['termlists_term:term_id'];
         data_entry_helper::$entity_to_load['meaning:id'] = data_entry_helper::$entity_to_load['termlists_term:meaning_id'];
         if (function_exists('hostsite_set_page_title')) {
             hostsite_set_page_title(lang::get('Edit {1}', data_entry_helper::$entity_to_load['term:term']));
         }
     }
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'website_id', 'default' => $args['website_id']));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'termlists_term:id'));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'termlists_term:termlist_id', 'default' => $args['termlist_id']));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'termlists_term:preferred', 'default' => 't'));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'term:id'));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'term:language_id', 'default' => $args['language_id']));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'meaning:id'));
     // request automatic JS validation
     data_entry_helper::enable_validation('entry_form');
     $r .= data_entry_helper::text_input(array('label' => lang::get('Term'), 'fieldname' => 'term:term', 'helpText' => lang::get('Please provide the term'), 'validation' => array('required'), 'class' => 'control-width-5'));
     $r .= "<input type=\"submit\" name=\"form-submit\" id=\"delete\" value=\"Delete\" />\n";
     $r .= "<input type=\"submit\" name=\"form-submit\" value=\"Save\" />\n";
     $r .= '<form>';
     self::set_breadcrumb($args);
     return $r;
 }
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  */
 public static function get_form($args, $node, $response = null)
 {
     global $indicia_templates;
     iform_load_helpers(array('map_helper', 'report_helper'));
     // apply defaults
     $args = array_merge(array(), $args);
     $reloadPath = self::getReloadPath();
     data_entry_helper::$website_id = $args['website_id'];
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     if (!empty($_GET['user_trust_id'])) {
         self::loadExistingUserTrust($_GET['user_trust_id'], $auth, $args);
     }
     $r = "<form method=\"post\" id=\"entry_form\" action=\"{$reloadPath}\">\n";
     $r .= $auth['write'] . "<input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'user_trust:id'));
     $r .= data_entry_helper::autocomplete(array('label' => lang::get('Recorder to trust'), 'fieldname' => 'user_trust:user_id', 'table' => 'user', 'valueField' => 'id', 'captionField' => 'person_name', 'extraParams' => $auth['read'] + array('view' => 'detail'), 'class' => 'control-width-4'));
     $col1 = '<p>Define the combination of survey, taxon group and/or location that this recorder is trusted for below.</p>';
     $col1 .= '<fieldset><legend>' . lang::get('Trust settings') . '</legend>';
     $col1 .= data_entry_helper::autocomplete(array('label' => lang::get('Trust records in this survey'), 'fieldname' => 'user_trust:survey_id', 'table' => 'survey', 'valueField' => 'id', 'captionField' => 'title', 'blankText' => '<' . lang::get('any') . '>', 'extraParams' => $auth['read'] + array('sharing' => 'verification'), 'class' => 'control-width-4'));
     $col1 .= data_entry_helper::autocomplete(array('label' => lang::get('Trust records in this taxon group'), 'fieldname' => 'user_trust:taxon_group_id', 'table' => 'taxon_group', 'valueField' => 'id', 'captionField' => 'title', 'blankText' => '<' . lang::get('any') . '>', 'extraParams' => $auth['read'], 'class' => 'control-width-4'));
     $col1 .= data_entry_helper::autocomplete(array('label' => lang::get('Trust records in this location'), 'fieldname' => 'user_trust:location_id', 'table' => 'location', 'valueField' => 'id', 'captionField' => 'name', 'blankText' => '<' . lang::get('any') . '>', 'extraParams' => $auth['read'] + array('location_type_id' => variable_get('indicia_profile_location_type_id', '')), 'class' => 'control-width-4'));
     $col2 = '<p>' . lang::get('Review this recorder\'s experience in the tabs below') . '</p>';
     $col2 .= '<div id="summary-tabs">';
     $col2 .= data_entry_helper::tab_header(array('tabs' => array('#tab-surveys' => lang::get('Surveys'), '#tab-taxon-groups' => lang::get('Taxon groups'), '#tab-locations' => lang::get('Locations'))));
     data_entry_helper::enable_tabs(array('divId' => 'summary-tabs'));
     $col2 .= '<div id="tab-surveys">';
     $col2 .= report_helper::report_grid(array('id' => 'surveys-summary', 'readAuth' => $auth['read'], 'dataSource' => 'library/surveys/filterable_surveys_verification_breakdown', 'ajax' => TRUE, 'autoloadAjax' => FALSE, 'extraParams' => array('my_records' => 1)));
     $col2 .= '</div>';
     $col2 .= '<div id="tab-taxon-groups">';
     $col2 .= report_helper::report_grid(array('id' => 'taxon-groups-summary', 'readAuth' => $auth['read'], 'dataSource' => 'library/taxon_groups/filterable_taxon_groups_verification_breakdown', 'ajax' => TRUE, 'autoloadAjax' => FALSE, 'extraParams' => array('my_records' => 1)));
     $col2 .= '</div>';
     $col2 .= '<div id="tab-locations">';
     $col2 .= report_helper::report_grid(array('id' => 'locations-summary', 'readAuth' => $auth['read'], 'dataSource' => 'library/locations/filterable_locations_verification_breakdown', 'ajax' => TRUE, 'autoloadAjax' => FALSE, 'extraParams' => array('my_records' => 1, 'location_type_id' => variable_get('indicia_profile_location_type_id', ''))));
     $col2 .= '</div>';
     $col2 .= '</div>';
     $r .= str_replace(array('{col-1}', '{col-2}'), array($col1, $col2), $indicia_templates['two-col-50']);
     $r .= '</fieldset>';
     $r .= '<input type="submit" class="indicia-button" id="save-button" value="' . (empty(data_entry_helper::$entity_to_load['user_trust_id:id']) ? lang::get('Grant trust') : lang::get('Update trust settings')) . "\" />\n";
     if (!empty($_GET['user_trust_id'])) {
         $r .= '<input type="submit" class="indicia-button" id="delete-button" name="delete-button" value="' . lang::get('Revoke this trust') . "\" />\n";
         data_entry_helper::$javascript .= "\$('#delete-button').click(function(e) {\n        if (!confirm(\"Are you sure you want to revoke this trust?\")) {\n          e.preventDefault();\n          return false;\n        }\n      });\n";
     }
     $r .= '</form>';
     data_entry_helper::enable_validation('entry_form');
     return $r;
 }
<?php 
echo $metadata;
?>
<fieldset>
<?php 
echo data_entry_helper::hidden_text(array('fieldname' => 'location_medium:id', 'default' => $id));
echo data_entry_helper::hidden_text(array('fieldname' => 'location_medium:location_id', 'default' => html::initial_value($values, 'location_medium:location_id')));
?>
<legend>Media file details</legend>
<?php 
$mediaTypeId = html::initial_value($values, 'location_medium:media_type_id');
$mediaType = $mediaTypeId ? $other_data['media_type_terms'][$mediaTypeId] : 'Image:Local';
if ($mediaType === 'Image:Local') {
    echo '<label>Image:</label>';
    echo html::sized_image(html::initial_value($values, 'occurrence_medium:path')) . '</br>';
    echo data_entry_helper::hidden_text(array('fieldname' => 'location_medium:path', 'default' => html::initial_value($values, 'location_medium:path')));
    echo data_entry_helper::image_upload(array('label' => 'Upload image file', 'fieldname' => 'image_upload', 'default' => html::initial_value($values, 'location_medium:path')));
} else {
    echo data_entry_helper::text_input(array('label' => 'Path or URL', 'fieldname' => 'location_medium:path', 'default' => html::initial_value($values, 'location_medium:path'), 'class' => 'control-width-5'));
}
echo data_entry_helper::text_input(array('label' => 'Caption', 'fieldname' => 'location_medium:caption', 'default' => html::initial_value($values, 'location_medium:caption'), 'class' => 'control-width-5'));
if ($mediaTypeId && $mediaType !== 'Image:Local') {
    echo data_entry_helper::select(array('label' => 'Media type', 'fieldname' => 'location_medium:media_type_id', 'default' => $mediaTypeId, 'lookupValues' => $other_data['media_type_terms'], 'blankText' => '<Please select>', 'class' => 'control-width-5'));
}
?>

</fieldset>
<?php 
echo html::form_buttons($id != null, false, false);
data_entry_helper::$dumped_resources[] = 'jquery';
data_entry_helper::$dumped_resources[] = 'jquery_ui';
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  */
 public static function get_form($args, $node, $response = null)
 {
     $form = '<form action="#" method="POST" id="entry_form">';
     if ($_POST) {
         $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
         self::subscribe($args, $auth);
     } else {
         // don't bother with write auth for initial form load, as read auth is cached and faster
         $auth = array('read' => data_entry_helper::get_read_auth($args['website_id'], $args['password']));
     }
     if (!empty($_GET['id'])) {
         data_entry_helper::load_existing_record($auth['read'], 'species_alert', $_GET['id']);
         // enforce permissions
         if (data_entry_helper::$entity_to_load['species_alert:user_id'] != hostsite_get_user_field('indicia_user_id')) {
             return lang::get('You cannot modify a species alert subscription created by someone else');
         }
         $form .= data_entry_helper::hidden_text(array('fieldname' => 'species_alert:id', 'default' => $_GET['id']));
     }
     // if not logged in, then ask for details to register against
     global $user;
     if (!hostsite_get_user_field('id') || !isset($user) || empty($user->mail) || !hostsite_get_user_field('last_name')) {
         $form .= "<fieldset><legend>" . lang::get('Your details') . ":</legend>\n";
         $default = empty($_POST['first_name']) ? hostsite_get_user_field('first_name', '') : $_POST['first_name'];
         $form .= data_entry_helper::text_input(array('label' => lang::get('First name'), 'fieldname' => 'first_name', 'validation' => array('required'), 'default' => $default, 'class' => 'control-width-4'));
         $default = empty($_POST['surname']) ? hostsite_get_user_field('last_name', '') : $_POST['surname'];
         $form .= data_entry_helper::text_input(array('label' => lang::get('Last name'), 'fieldname' => 'surname', 'validation' => array('required'), 'default' => $default, 'class' => 'control-width-4'));
         $default = empty($_POST['email']) ? empty($user->mail) ? '' : $user->mail : $_POST['email'];
         $form .= data_entry_helper::text_input(array('label' => lang::get('Email'), 'fieldname' => 'email', 'validation' => array('required', 'email'), 'default' => $default, 'class' => 'control-width-4'));
         $form .= "</fieldset>\n";
     } else {
         $form .= data_entry_helper::hidden_text(array('fieldname' => 'first_name', 'default' => hostsite_get_user_field('first_name')));
         $form .= data_entry_helper::hidden_text(array('fieldname' => 'surname', 'default' => hostsite_get_user_field('last_name')));
         $form .= data_entry_helper::hidden_text(array('fieldname' => 'email', 'default' => $user->mail));
         $form .= data_entry_helper::hidden_text(array('fieldname' => 'user_id', 'default' => hostsite_get_user_field('indicia_user_id')));
     }
     $form .= "<fieldset><legend>" . lang::get('Alert criteria') . ":</legend>\n";
     // Output the species selection control
     // Default after saving with a validation failure can be pulled direct from the post, but
     // when reloading we don't need a default taxa taxon list ID since we already know the meaning
     // ID or external key.
     $default = empty($_POST['taxa_taxon_list_id']) ? '' : $_POST['taxa_taxon_list_id'];
     if (empty($_POST['taxa_taxon_list_id:taxon'])) {
         $defaultCaption = empty(data_entry_helper::$entity_to_load['species_alert:preferred_taxon']) ? '' : data_entry_helper::$entity_to_load['species_alert:preferred_taxon'];
     } else {
         $defaultCaption = $_POST['taxa_taxon_list_id:taxon'];
     }
     $form .= data_entry_helper::species_autocomplete(array('label' => lang::get('Alert species'), 'helpText' => lang::get('Select the species you are interested in receiving alerts in ' . 'relation to if you want to receive alerts on a single species.'), 'fieldname' => 'taxa_taxon_list_id', 'cacheLookup' => true, 'extraParams' => $auth['read'] + array('taxon_list_id' => $args['list_id']), 'class' => 'control-width-4', 'default' => $default, 'defaultCaption' => $defaultCaption));
     if (empty($default)) {
         // Unless we've searched for the species name then posted (and failed), then the
         // default will be empty. We might therefore be reloading existing data which has
         // a meaning ID or external key.
         if (!empty(data_entry_helper::$entity_to_load['species_alert:external_key'])) {
             $form .= data_entry_helper::hidden_text(array('fieldname' => 'species_alert:external_key', 'default' => data_entry_helper::$entity_to_load['species_alert:external_key']));
         } elseif (!empty(data_entry_helper::$entity_to_load['species_alert:taxon_meaning_id'])) {
             $form .= data_entry_helper::hidden_text(array('fieldname' => 'species_alert:taxon_meaning_id', 'default' => data_entry_helper::$entity_to_load['species_alert:taxon_meaning_id']));
         }
     }
     if (!empty($args['full_lists'])) {
         $form .= data_entry_helper::select(array('label' => lang::get('Select full species lists'), 'helpText' => lang::get('If you want to restrict the alerts to records of any ' . 'species within a species list, then select the list here.'), 'fieldname' => 'species_alert:taxon_list_id', 'blankText' => lang::get('<Select a species list>'), 'table' => 'taxon_list', 'valueField' => 'id', 'captionField' => 'title', 'extraParams' => $auth['read'] + array('id' => $args['full_lists'], 'orderby' => 'title'), 'class' => 'control-width-4'));
     }
     $form .= data_entry_helper::location_select(array('label' => lang::get('Select location'), 'helpText' => lang::get('If you want to restrict the alerts to records within a certain boundary, select it here.'), 'fieldname' => 'species_alert:location_id', 'id' => 'imp-location', 'blankText' => lang::get('<Select boundary>'), 'extraParams' => $auth['read'] + array('location_type_id' => $args['location_type_id'], 'orderby' => 'name'), 'class' => 'control-width-4'));
     $form .= data_entry_helper::checkbox(array('label' => lang::get('Alert on initial entry'), 'helpText' => lang::get('Tick this box if you want to receive a notification when the record is first input into the system.'), 'fieldname' => 'species_alert:alert_on_entry'));
     $form .= data_entry_helper::checkbox(array('label' => lang::get('Alert on verification as correct'), 'helpText' => lang::get('Tick this box if you want to receive a notification when the record has been verified as correct.'), 'fieldname' => 'species_alert:alert_on_verify'));
     $form .= "</fieldset>\n";
     $form .= '<input type="Submit" value="Subscribe" />';
     $form .= '</form>';
     data_entry_helper::enable_validation('entry_form');
     iform_load_helpers(array('map_helper'));
     $mapOptions = iform_map_get_map_options($args, $auth['read']);
     $map = map_helper::map_panel($mapOptions);
     global $indicia_templates;
     return str_replace(array('{col-1}', '{col-2}'), array($form, $map), $indicia_templates['two-col-50']);
 }
 /**
  * Implements the [location url param] control, for accepting the site to record against using a location_id URL parameter.
  *
  * Outputs hidden inputs into the form to specify the location_id for the sample. Uses the location's centroid and spatial ref system to 
  * fill in the sample's geometry data. If loading an existing sample, then the location_id in the URL is ignored.
  */
 protected static function get_control_locationurlparam($auth, $args, $tabAlias, $options)
 {
     $location_id = isset(data_entry_helper::$entity_to_load['sample:location_id']) ? data_entry_helper::$entity_to_load['sample:location_id'] : (empty($_GET['location_id']) ? '' : $_GET['location_id']);
     if (empty($location_id)) {
         return 'This form requires a URL parameter called location_id to specify which site to record against.';
     }
     if (!preg_match('/^[0-9]+$/', $location_id)) {
         return 'The location_id parameter must be an integer.';
     }
     if (isset(data_entry_helper::$entity_to_load['sample:location_id'])) {
         // no need for values as the entity to load will override any defaults.
         $location = array('id' => '', 'centroid_sref' => '', 'centroid_sref_system' => '');
     } else {
         $response = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $auth['read'] + array('id' => $_GET['location_id'], 'view' => 'detail')));
         $location = $response[0];
     }
     $r = data_entry_helper::hidden_text(array('fieldname' => 'sample:location_id', 'default' => $location['id']));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'sample:entered_sref', 'default' => $location['centroid_sref']));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'sample:entered_sref_system', 'default' => $location['centroid_sref_system']));
     return $r;
 }
Esempio n. 8
0
 /**
  * Returns controls allowing a records filter to be defined and associated with the group. 
  * @param array $args Form configuration arguments
  * @return string HTML to output
  */
 private static function reportFilterBlock($args, $auth, &$hiddenPopupDivs)
 {
     $r = '';
     $hiddenPopupDivs = '';
     if ($args['include_report_filter']) {
         $r .= '<fieldset><legend>' . lang::get('Records that are of interest to the {1}', lang::get(self::$groupType)) . '</legend>';
         $r .= '<p>' . lang::get('LANG_Filter_Instruct', lang::get(self::$groupType), lang::get("group's")) . '</p>';
         $indexedLocationTypeIds = explode(',', $args['indexed_location_type_ids']);
         $otherLocationTypeIds = explode(',', $args['other_location_type_ids']);
         $r .= report_filter_panel($auth['read'], array('allowLoad' => false, 'allowSave' => false, 'filterTypes' => $args['filter_types'], 'embedInExistingForm' => true, 'indexedLocationTypeIds' => $indexedLocationTypeIds, 'otherLocationTypeIds' => $otherLocationTypeIds), $args['website_id'], $hiddenPopupDivs);
         // fields to auto-create a filter record for this group's defined set of records
         $r .= data_entry_helper::hidden_text(array('fieldname' => 'filter:id'));
         $r .= '<input type="hidden" name="filter:title" id="filter-title-val"/>';
         $r .= '<input type="hidden" name="filter:definition" id="filter-def-val"/>';
         $r .= '<input type="hidden" name="filter:sharing" value="R"/>';
         $r .= '</fieldset>';
     }
     return $r;
 }
Esempio n. 9
0
<?php

require_once DOCROOT . 'client_helpers/data_entry_helper.php';
echo data_entry_helper::textarea(array('label' => 'Exported survey structure', 'fieldname' => 'export survey structure', 'class' => 'control-width-6', 'helpText' => 'Copy this text to the clipboard. You can then paste it into another survey to clone the attributes.', 'default' => $export));
?>
<form class="iform" action="<?php 
echo url::site();
?>
survey_structure_export/save" method="post" id="entry-form"">
<fieldset>
<?php 
echo data_entry_helper::textarea(array('label' => 'Import survey structure', 'fieldname' => 'import survey structure', 'class' => 'control-width-6', 'helpText' => 'Paste in the export of another survey to import its attributes'));
echo data_entry_helper::hidden_text(array('fieldname' => 'survey_id', 'default' => $surveyId));
echo '<input type="submit" name="submit" value="Import" class="ui-corner-all ui-state-default button ui-priority-primary" />' . "\n";
data_entry_helper::link_default_stylesheet();
echo data_entry_helper::dump_javascript();
?>
</fieldset>
</form>
Esempio n. 10
0
/**
 * Code to output a standardised report filtering panel.
 *
 * Filters can be saved and loaded by each user. Additionally, filters can define permissions to a certain task, e.g. they can be used to define the
 * context within which someone can verify. In this case they provide the "outer limit" of the available records.
 * Requires a [map] control on the page. If you don't want a map, the current option is to include one anyway and use css to hide the #map-container div.
 *
 * @param array $readAuth Pass read authorisation tokens.
 * @param array $options Options array with the following possibilities:
 *   sharing - define the record sharing task that is being filtered against. Options are reporting (default), peer_review, verification, moderation, data_flow.
 *   context_id - can also be passed as URL parameter. Force the initial selection of a particular context (a record which has defines_permissions=true in the
 *   filters table. Set to "default" to select their profile verification settings when sharing=verification.
 *   filter_id - can also be passed as URL parameter. Force the initial selection of a particular filter record in the filters table.
 *   filterTypes - allows control of the list of filter panels available, e.g. to turn one off. Associative array keyed by category
 *   so that the filter panels can be grouped (use a blank key if not required). The array values are an array of or strings with a comma separated list
 *   of the filter types to included in the category - options are what, where, when, who, quality, source.
 *   filter-#name# - set the initial value of a report filter parameter #name#.
 *   allowLoad - set to false to disable the load bar at the top of the panel.
 *   allowSave - set to false to disable the save bar at the foot of the panel.
 *   presets - provide an array of preset filters to provide in the filters drop down. Choose from my-records, my-groups (uses
 *     your list of taxon groups in the user account), my-locality (uses your recording locality from the user account),
 *     my-groups-locality (uses taxon groups and recording locality from the user account), my-queried-records, queried-records,
 *     answered-records, accepted-records, not-accepted-records.
 * @param integer $website_id The current website's warehouse ID.
 * @param string $hiddenStuff Output parameter which will contain the hidden popup HTML that will be shown
 * using fancybox during filter editing. Should be appended AFTER any form element on the page as nested forms are not allowed.
 * @return string HTML for the report filter panel
 */
function report_filter_panel($readAuth, $options, $website_id, &$hiddenStuff)
{
    if (function_exists('iform_load_helpers')) {
        iform_load_helpers(array('report_helper'));
    } else {
        //When running on warehouse we don't have iform_load_helpers
        require_once DOCROOT . 'client_helpers/report_helper.php';
    }
    if (!empty($_POST['filter:sharing'])) {
        $options['sharing'] = $_POST['filter:sharing'];
    }
    $options = array_merge(array('sharing' => 'reporting', 'admin' => false, 'adminCanSetSharingTo' => array('R' => 'reporting', 'V' => 'verification'), 'allowLoad' => true, 'allowSave' => true, 'redirect_on_success' => '', 'presets' => array('my-records', 'my-queried-records', 'my-queried-or-not-accepted-records', 'my-not-reviewed-records', 'my-accepted-records', 'my-groups', 'my-locality', 'my-groups-locality'), 'entity' => 'occurrence'), $options);
    // Introduce some extra quick filters useful for verifiers.
    if ($options['sharing'] === 'verification') {
        $options['presets'] = array_merge(array('queried-records', 'answered-records', 'accepted-records', 'not-accepted-records'), $options['presets']);
    }
    if ($options['entity'] === 'sample') {
        unset($options['presets']['my-groups']);
        unset($options['presets']['my-groups-locality']);
    }
    //If in the warehouse we don't need to worry about the iform master list.
    if (function_exists('variable_get')) {
        $options = array_merge(array('taxon_list_id' => variable_get('iform_master_checklist_id', 0)), $options);
    }
    $options['sharing'] = report_filters_sharing_code_to_full_term($options['sharing']);
    $options['sharingCode'] = report_filters_full_term_to_sharing_code($options['sharing']);
    if (!preg_match('/^(reporting|peer_review|verification|data_flow|moderation)$/', $options['sharing'])) {
        return 'The @sharing option must be one of reporting, peer_review, verification, data_flow or moderation (currently ' . $options['sharing'] . ').';
    }
    report_helper::add_resource('reportfilters');
    report_helper::add_resource('validation');
    report_helper::add_resource('fancybox');
    if (function_exists('hostsite_add_library')) {
        hostsite_add_library('collapse');
    }
    $filterData = report_filters_load_existing($readAuth, $options['sharingCode']);
    $existing = '';
    $contexts = '';
    // add some preset filters in
    //If in the warehouse we don't need to worry about user specific preferences when setting up milestones.
    if (function_exists('hostsite_get_user_field')) {
        foreach ($options['presets'] as $preset) {
            $title = false;
            switch ($preset) {
                case 'my-records':
                    if (hostsite_get_user_field('id')) {
                        $title = lang::get('My records');
                    }
                    break;
                case 'my-queried-records':
                    if (hostsite_get_user_field('id')) {
                        $title = lang::get('My queried records');
                    }
                    break;
                case 'my-queried-or-not-accepted-records':
                    if (hostsite_get_user_field('id')) {
                        $title = lang::get('My not accepted or queried records');
                    }
                    break;
                case 'my-not-reviewed-records':
                    if (hostsite_get_user_field('id')) {
                        $title = lang::get('My not reviewed records');
                    }
                    break;
                case 'my-accepted-records':
                    if (hostsite_get_user_field('id')) {
                        $title = lang::get('My accepted records');
                    }
                    break;
                case 'my-groups':
                    if (hostsite_get_user_field('taxon_groups', false, true)) {
                        $title = lang::get('Records in species groups I like to record');
                    }
                    break;
                case 'my-locality':
                    if (hostsite_get_user_field('location')) {
                        $title = lang::get('Records in the locality I generally record in');
                    }
                    break;
                case 'my-groups-locality':
                    if (hostsite_get_user_field('taxon_groups', false, true) && hostsite_get_user_field('location')) {
                        $title = lang::get('Records of my species groups in my locality');
                    }
                    break;
                case 'queried-records':
                    $title = lang::get('Queried records');
                    break;
                case 'answered-records':
                    $title = lang::get('Records with answers');
                    break;
                case 'accepted-records':
                    $title = lang::get('Accepted records');
                    break;
                case 'not-accepted-records':
                    $title = lang::get('Not accepted records');
                    break;
                default:
                    throw new exception("Unsupported preset {$preset} for the filter panel");
            }
            if ($title) {
                $presetFilter = array('id' => $preset, 'title' => $title, 'defines_permissions' => 'f');
                $filterData[] = $presetFilter;
            }
        }
        if (count($options['presets'])) {
            if ($groups = hostsite_get_user_field('taxon_groups', false, true)) {
                data_entry_helper::$javascript .= "indiciaData.userPrefsTaxonGroups='" . implode(',', $groups) . "';\n";
            }
            if ($location = hostsite_get_user_field('location')) {
                data_entry_helper::$javascript .= "indiciaData.userPrefsLocation=" . $location . ";\n";
            }
        }
        $contextDefs = array();
        if ($options['sharing'] === 'verification') {
            // apply legacy verification settings from their profile
            $location_id = hostsite_get_user_field('location_expertise');
            $taxon_group_ids = hostsite_get_user_field('taxon_groups_expertise', false, true);
            $survey_ids = hostsite_get_user_field('surveys_expertise', false, true);
            if ($location_id || $taxon_group_ids || $survey_ids) {
                $selected = !empty($options['context_id']) && $options['context_id'] === 'default' ? 'selected="selected" ' : '';
                $contexts .= "<option value=\"default\" {$selected}>" . lang::get('My verification records') . "</option>";
                $def = array();
                if ($location_id) {
                    // user profile geographic limits should always be based on an indexed location.
                    $def['indexed_location_id'] = $location_id;
                }
                if ($taxon_group_ids) {
                    $def['taxon_group_list'] = implode(',', $taxon_group_ids);
                    $def['taxon_group_names'] = array();
                    $groups = data_entry_helper::get_population_data(array('table' => 'taxon_group', 'extraParams' => $readAuth + array('id' => $taxon_group_ids)));
                    foreach ($groups as $group) {
                        $def['taxon_group_names'][$group['id']] = $group['title'];
                    }
                }
                if ($survey_ids) {
                    $def['survey_list'] = implode(',', array_filter($survey_ids));
                }
                $contextDefs['default'] = $def;
            }
        }
    }
    if (!empty($_GET['context_id'])) {
        $options['context_id'] = $_GET['context_id'];
    }
    if (!empty($_GET['filter_id'])) {
        $options['filter_id'] = $_GET['filter_id'];
    }
    if (!empty($_GET['filters_user_id'])) {
        $options['filters_user_id'] = $_GET['filters_user_id'];
    }
    foreach ($filterData as $filter) {
        if ($filter['defines_permissions'] === 't') {
            $selected = !empty($options['context_id']) && $options['context_id'] == $filter['id'] ? 'selected="selected" ' : '';
            $contexts .= "<option value=\"{$filter['id']}\" {$selected}>{$filter['title']}</option>";
            $contextDefs[$filter['id']] = json_decode($filter['definition']);
        } else {
            $selected = !empty($options['filter_id']) && $options['filter_id'] == $filter['id'] ? 'selected="selected" ' : '';
            $existing .= "<option value=\"{$filter['id']}\" {$selected}>{$filter['title']}</option>";
        }
    }
    $r = '<div id="standard-params" class="ui-widget">';
    if ($options['allowSave'] && $options['admin']) {
        if (empty($_GET['filters_user_id'])) {
            // new filter to create, so sharing type can be edited
            $reload = data_entry_helper::get_reload_link_parts();
            $reloadPath = $reload['path'];
            if (count($reload['params'])) {
                $reloadPath .= '?' . data_entry_helper::array_to_query_string($reload['params']);
            }
            $r .= "<form action=\"{$reloadPath}\" method=\"post\" >";
            $r .= data_entry_helper::select(array('label' => lang::get('Select filter type'), 'fieldname' => 'filter:sharing', 'lookupValues' => $options['adminCanSetSharingTo'], 'afterControl' => '<input type="submit" value="Go"/>', 'default' => $options['sharingCode']));
            $r .= '</form>';
        } else {
            // existing filter to edit, type is therefore fixed. JS will fill these values in.
            $r .= '<p>' . lang::get('This filter is for <span id="sharing-type-label"></span>.') . '</p>';
            $r .= data_entry_helper::hidden_text(array('fieldname' => 'filter:sharing'));
        }
    }
    if ($options['allowLoad']) {
        $r .= '<div class="header ui-toolbar ui-widget-header ui-helper-clearfix"><div><span id="active-filter-label">' . lang::get('New report') . '</span></div><span class="changed" style="display:none" title="This filter has been changed">*</span>';
        $r .= '<div>';
        if ($contexts) {
            data_entry_helper::$javascript .= "indiciaData.filterContextDefs = " . json_encode($contextDefs) . ";\n";
            if (count($contextDefs) > 1) {
                $r .= '<label for="context-filter">' . lang::get('Context:') . "</label><select id=\"context-filter\">{$contexts}</select>";
            } else {
                $keys = array_keys($contextDefs);
                $r .= '<input type="hidden" id="context-filter" value="' . $keys[0] . '" />';
            }
        }
        $r .= '<label for="select-filter">' . lang::get('Filter:') . '</label><select id="select-filter"><option value="" selected="selected">' . lang::get('Select filter') . "...</option>{$existing}</select>";
        $r .= '<button type="button" id="filter-apply">' . lang::get('Apply') . '</button>';
        $r .= '<button type="button" id="filter-reset" class="disabled">' . lang::get('Reset') . '</button>';
        $r .= '<button type="button" id="filter-build">' . lang::get('Create a filter') . '</button></div>';
        $r .= '</div>';
        $r .= '<div id="filter-details" style="display: none">';
        $r .= '<img src="' . data_entry_helper::$images_path . 'nuvola/close-22px.png" width="22" height="22" alt="Close filter builder" title="Close filter builder" class="button" id="filter-done"/>' . "\n";
    } else {
        $r .= '<div id="filter-details">';
        if (!empty($options['filter_id'])) {
            $r .= "<input type=\"hidden\" id=\"select-filter\" value=\"{$options['filter_id']}\"/>";
        } elseif (!empty($options['filters_user_id'])) {
            $r .= "<input type=\"hidden\" id=\"select-filters-user\" value=\"{$options['filters_user_id']}\"/>";
        }
    }
    $r .= '<div id="filter-panes">';
    if ($options['entity'] === 'occurrence') {
        $filters = array('filter_what' => new filter_what(), 'filter_where' => new filter_where(), 'filter_when' => new filter_when(), 'filter_who' => new filter_who(), 'filter_occurrence_id' => new filter_occurrence_id(), 'filter_quality' => new filter_quality(), 'filter_source' => new filter_source());
    } elseif ($options['entity'] === 'sample') {
        $filters = array('filter_where' => new filter_where(), 'filter_when' => new filter_when(), 'filter_who' => new filter_who(), 'filter_sample_id' => new filter_sample_id(), 'filter_quality' => new filter_quality_sample(), 'filter_source' => new filter_source());
    }
    if (!empty($options['filterTypes'])) {
        $filterModules = array();
        foreach ($options['filterTypes'] as $category => $list) {
            // $list can be an array or comma separated list
            if (is_array($list)) {
                $list = implode(',', $list);
            }
            $paneNames = 'filter_' . str_replace(',', ',filter_', $list);
            $paneList = explode(',', $paneNames);
            $filterModules[$category] = array_intersect_key($filters, array_fill_keys($paneList, 1));
        }
    } else {
        $filterModules = array('' => $filters);
    }
    foreach ($filterModules as $category => $list) {
        if ($category) {
            $r .= '<fieldset class="collapsible collapsed">' . '<legend>' . '<span class="fieldset-legend">' . $category . '</span>' . '</legend>' . '<div class="fieldset-wrapper">';
        }
        foreach ($list as $moduleName => $module) {
            $r .= "<div class=\"pane\" id=\"pane-{$moduleName}\"><a class=\"fb-filter-link\" href=\"#controls-{$moduleName}\"><span class=\"pane-title\">" . $module->get_title() . '</span>';
            $r .= '<span class="filter-desc"></span></a>';
            $r .= "</div>";
        }
        if ($category) {
            $r .= '</div></fieldset>';
        }
    }
    $r .= '</div>';
    // filter panes
    $r .= '<div class="toolbar">';
    if ($options['allowSave']) {
        $r .= '<label for="filter:title">' . lang::get('Save filter as') . ':</label> <input id="filter:title" class="control-width-5"/>';
        if ($options['admin']) {
            $r .= '<br/>';
            if (empty($options['adminCanSetSharingTo'])) {
                throw new exception('Report standard params panel in admin mode so adminCanSetSharingTo option must be populated.');
            }
            $r .= data_entry_helper::autocomplete(array('label' => 'For who?', 'fieldname' => 'filters_user:user_id', 'table' => 'user', 'valueField' => 'id', 'captionField' => 'person_name', 'formatFunction' => "function(item) { return item.person_name + ' (' + item.email_address + ')'; }", 'extraParams' => $readAuth + array('view' => 'detail'), 'class' => 'control-width-5'));
            $r .= data_entry_helper::textarea(array('label' => 'Description', 'fieldname' => 'filter:description'));
        }
        $r .= '<img src="' . data_entry_helper::$images_path . 'nuvola/save-22px.png" width="22" height="22" alt="Save filter" title="Save filter" class="button" id="filter-save"/>';
        $r .= '<img src="' . data_entry_helper::$images_path . 'trash-22px.png" width="22" height="22" alt="Bin this filter" title="Bin this filter" class="button disabled" id="filter-delete"/>';
    }
    $r .= '</div></div>';
    // toolbar + clearfix
    if (!empty($options['filters_user_id'])) {
        // if we are preloading based on a filter user ID, we need to get the information now so that the sharing mode can be known
        // when loading controls
        $fu = data_entry_helper::get_population_data(array('table' => 'filters_user', 'extraParams' => $readAuth + array('id' => $options['filters_user_id']), 'caching' => false));
        if (count($fu) !== 1) {
            throw new exception('Could not find filter user record');
        }
        $options['sharing'] = report_filters_sharing_code_to_full_term($fu[0]['filter_sharing']);
    }
    report_helper::$javascript .= "indiciaData.lang={pleaseSelect:\"" . lang::get('Please select') . "\"};\n";
    // create the hidden panels required to populate the popups for setting each type of filter up.
    $hiddenStuff = '';
    foreach ($filterModules as $category => $list) {
        foreach ($list as $moduleName => $module) {
            $hiddenStuff .= "<div style=\"display: none\"><div class=\"filter-popup\" id=\"controls-{$moduleName}\"><form action=\"#\" class=\"filter-controls\"><fieldset>" . $module->get_controls($readAuth, $options) . '<button class="fb-close" type="button">Cancel</button>' . '<button class="fb-apply" type="submit">Apply</button></fieldset></form></div></div>';
            $shortName = str_replace('filter_', '', $moduleName);
            report_helper::$javascript .= "indiciaData.lang.NoDescription{$shortName}='" . lang::get('Click to Filter ' . ucfirst($shortName)) . "';\n";
        }
    }
    $r .= '</div>';
    report_helper::$js_read_tokens = $readAuth;
    report_helper::$javascript .= "indiciaData.lang.CreateAFilter='" . lang::get('Create a filter') . "';\n";
    report_helper::$javascript .= "indiciaData.lang.ModifyFilter='" . lang::get('Modify filter') . "';\n";
    report_helper::$javascript .= "indiciaData.lang.FilterReport='" . lang::get('New report') . "';\n";
    report_helper::$javascript .= "indiciaData.lang.FilterSaved='" . lang::get('The filter has been saved') . "';\n";
    report_helper::$javascript .= "indiciaData.lang.FilterDeleted='" . lang::get('The filter has been deleted') . "';\n";
    report_helper::$javascript .= "indiciaData.lang.ConfirmFilterChangedLoad='" . lang::get('Do you want to load the selected filter and lose your current changes?') . "';\n";
    report_helper::$javascript .= "indiciaData.lang.FilterExistsOverwrite='" . lang::get('A filter with that name already exists. Would you like to overwrite it?') . "';\n";
    report_helper::$javascript .= "indiciaData.lang.AutochecksFailed='" . lang::get('Automated checks failed') . "';\n";
    report_helper::$javascript .= "indiciaData.lang.AutochecksPassed='" . lang::get('Automated checks passed') . "';\n";
    report_helper::$javascript .= "indiciaData.lang.HasPhotos='" . lang::get('Records which have photos') . "';\n";
    report_helper::$javascript .= "indiciaData.lang.ConfirmFilterDelete='" . lang::get('Are you sure you want to permanently delete the {title} filter?') . "';\n";
    report_helper::$javascript .= "indiciaData.lang.MyRecords='" . lang::get('My records only') . "';\n";
    if (function_exists('iform_ajaxproxy_url')) {
        report_helper::$javascript .= "indiciaData.filterPostUrl='" . iform_ajaxproxy_url(null, 'filter') . "';\n";
        report_helper::$javascript .= "indiciaData.filterAndUserPostUrl='" . iform_ajaxproxy_url(null, 'filter_and_user') . "';\n";
    }
    report_helper::$javascript .= "indiciaData.filterSharing='" . strtoupper(substr($options['sharing'], 0, 1)) . "';\n";
    if (function_exists('hostsite_get_user_field')) {
        report_helper::$javascript .= "indiciaData.user_id='" . hostsite_get_user_field('indicia_user_id') . "';\n";
    } else {
        report_helper::$javascript .= "indiciaData.user_id='" . $_SESSION['auth_user']->id . "';\n";
    }
    if (!empty($website_id)) {
        report_helper::$javascript .= "indiciaData.website_id=" . $website_id . ";\n";
    }
    report_helper::$javascript .= "indiciaData.redirectOnSuccess='{$options['redirect_on_success']}';\n";
    // load up the filter, BEFORE any AJAX load of the grid code. First fetch any URL param overrides.
    $getParams = array();
    $optionParams = array();
    foreach ($_GET as $key => $value) {
        if (substr($key, 0, 7) === 'filter-') {
            $getParams[substr($key, 7)] = $value;
        }
    }
    foreach ($options as $key => $value) {
        if (substr($key, 0, 7) === 'filter-') {
            $optionParams[substr($key, 7)] = $value;
        }
    }
    $allParams = array_merge($optionParams, $getParams);
    if (!empty($allParams)) {
        $allParams = json_encode($allParams);
        report_helper::$onload_javascript .= "var params = {$allParams};\n";
        report_helper::$onload_javascript .= "indiciaData.filter.def=\$.extend(indiciaData.filter.def, params);\n";
        report_helper::$onload_javascript .= "indiciaData.filter.orig=\$.extend({}, params);\n";
    }
    $getParams = empty($getParams) ? '{}' : json_encode($getParams);
    if (!empty($options['filters_user_id'])) {
        report_helper::$onload_javascript .= "loadFilterUser(" . json_encode($fu[0]) . ", {$getParams});\n";
    } else {
        report_helper::$onload_javascript .= "if (\$('#select-filter').val()) {\n" . "  loadFilter(\$('#select-filter').val(), {$getParams});\n" . "} else {\n" . "  applyFilterToReports(false);\n" . "}\n";
    }
    return $r;
}
Esempio n. 11
0
//title duplciate detection.
//So to fix this, collect the existing filters from the database so we can compare the titles with the one we create and then
//do the validation manually.
$readAuth = data_entry_helper::get_read_auth(0 - $_SESSION['auth_user']->id, kohana::config('indicia.private_key'));
$existingFilterData = data_entry_helper::get_population_data(array('table' => 'filter', 'extraParams' => $readAuth, 'nocache' => true));
//When we save a milestone when we need to automatically set the filter title as there isn't a separate field
//to fill this in.
//Also hide the "who" filter as we don't need this for milestones as they can apply to all users
//Also manually do the unique milestone/filter title validation (see note above)
data_entry_helper::$javascript .= "\nvar existingFilterData=" . json_encode($existingFilterData) . ";  \n\$('#pane-filter_who').hide();\n\$('#milestones-form').submit(function() {\n  \$('#filter-title-val').val('" . 'Filter for milestone' . " ' + \$('#milestone\\\\:title').val());\n  for (var i = 0; i<existingFilterData.length;i++) {\n    //Note we must allow a duplicate title in the situaton where the duplicate title is for the already existing item\n    if (existingFilterData[i]['title']==\$('#filter-title-val').val() && existingFilterData[i]['id']!=\$('#filter\\\\:id').val()) {\n      alert('The filter title is generated from the milestone title you have entered and would cause a duplicate filter title, please choose a different title');\n      return false;\n    }\n  }\n  \$('#filter-def-val').val(JSON.stringify(indiciaData.filter.def));\n});\n";
$readAuth = data_entry_helper::get_read_auth(0 - $_SESSION['auth_user']->id, kohana::config('indicia.private_key'));
$filterPanelHTML = '<h3>Specify the filter used to define which records count</h3>';
$hiddenPopupDivs = '';
$filterPanelHTML .= report_filter_panel($readAuth, array('allowLoad' => false, 'allowSave' => false, 'embedInExistingForm' => true, 'runningOnWarehouse' => true, 'taxon_list_id' => kohana::config('cache_builder_variables.master_list_id'), 'website_id' => html::initial_value($values, 'milestone:website_id') ? html::initial_value($values, 'milestone:website_id') : $values['website_id']), $this->uri->argument(1), $hiddenStuff);
// fields to auto-create a filter record for this group's defined set of records
$filterPanelHTML .= data_entry_helper::hidden_text(array('fieldname' => 'filter:id', 'default' => html::initial_value($values, 'filter:id')));
$filterPanelHTML .= '<input type="hidden" name="filter:title" id="filter-title-val"/>';
$filterPanelHTML .= '<input type="hidden" name="filter:definition" id="filter-def-val"/>';
$filterPanelHTML .= '<input type="hidden" name="filter:sharing" value="R"/>';
echo $filterPanelHTML;
echo html::form_buttons(html::initial_value($values, 'milestone:id') != null, false, false);
data_entry_helper::$dumped_resources[] = 'jquery';
data_entry_helper::$dumped_resources[] = 'jquery_ui';
data_entry_helper::$dumped_resources[] = 'fancybox';
data_entry_helper::enable_validation('milestones-form');
data_entry_helper::link_default_stylesheet();
echo data_entry_helper::dump_javascript();
?>
</fieldset>
</form>
<?php 
echo data_entry_helper::text_input(array('label' => 'Period Start', 'fieldname' => 'summariser_definition:period_start', 'default' => html::initial_value($values, 'summariser_definition:period_start'), 'helpText' => 'Define the first day of each period. There are 2 options.<br/>' . "&nbsp;&nbsp;<strong>weekday=&lt;n&gt;</strong> where <strong>&lt;n&gt;</strong> is a number between 1 (for Monday) and 7 (for Sunday).<br/>" . "&nbsp;&nbsp;<strong>date=MMM/DD</strong> where <strong>MMM/DD</strong> is a month/day combination: e.g. choosing Apr-1 will start each week on the day of the week on which the 1st of April occurs.<br/>", 'validation' => 'required'));
echo data_entry_helper::text_input(array('label' => 'Period One Contains', 'fieldname' => 'summariser_definition:period_one_contains', 'default' => html::initial_value($values, 'summariser_definition:period_one_contains'), 'helpText' => 'Calculate week one as the week containing this date: value should be in the format <strong>MMM/DD</strong>, which is a month/day combination: e.g. choosing Apr-1 will mean week one contains the date of the 1st of April. Default is the Jan-01', 'validation' => 'required'));
echo data_entry_helper::select(array('label' => 'Attribute to Sum', 'fieldname' => 'summariser_definition:occurrence_attribute_id', 'lookupValues' => $other_data['occAttrs'], 'default' => html::initial_value($values, 'summariser_definition:occurrence_attribute_id'), 'helpText' => 'The occurrence attribute which is used as the count associated with the occurrence. If not provided then each occurrence has a count of one.'));
echo data_entry_helper::checkbox(array('label' => 'Calculate Estimates', 'fieldname' => 'summariser_definition:calculate_estimates', 'default' => html::initial_value($values, 'summariser_definition:calculate_estimates')));
?>
<fieldset><legend>Data Handling</legend>
<?php 
echo data_entry_helper::select(array('label' => 'Summary Data Combination method', 'fieldname' => 'summariser_definition:data_combination_method', 'lookupValues' => array('A' => 'Add all occurrences together', 'M' => 'Choose the value from the sample with the greatest count', 'L' => 'Average over all samples for that location during that period'), 'default' => html::initial_value($values, 'summariser_definition:data_combination_method'), 'helpText' => 'When data is aggregated for a location/period combination, this determines how.'));
echo data_entry_helper::select(array('label' => 'Data Rounding', 'fieldname' => 'summariser_definition:data_rounding_method', 'lookupValues' => array('N' => 'To the nearest integer, .5 rounds up', 'U' => 'Up: To the integer greater than or equal to the value', 'D' => 'Down: To the integer less than or equal to the value', 'X' => 'None (may result in non-integer values)'), 'default' => html::initial_value($values, 'summariser_definition:data_rounding_method'), 'helpText' => 'When data is averaged, this determines what rounding is carried out. Note that anything between 0 and 1 will be rounded up to 1.'));
?>
</fieldset><fieldset><legend>Estimate Generation</legend>
<p>Only one interpolation option (linear) available at the moment.</p>
<?php 
// Only one interpolation option at the moment. This may change in future. Keep hidden control until that point.
// 'L' = 'Linear interpolation'
echo data_entry_helper::hidden_text(array('fieldname' => 'summariser_definition:interpolation', 'default' => 'L'));
echo data_entry_helper::text_input(array('label' => 'Season Limits', 'fieldname' => 'summariser_definition:season_limits', 'default' => html::initial_value($values, 'summariser_definition:season_limits'), 'helpText' => 'This is a comma separated pair of the week numbers for the start and end of the season. When provided, and data is not entered for these weeks, the value is taken as zero, irrespective of the First/Last value processing. First/Last value processing is not carried out outwith these weeks.'));
echo data_entry_helper::select(array('label' => 'First Value Processing', 'fieldname' => 'summariser_definition:first_value', 'lookupValues' => array('X' => 'No special processing', 'H' => 'The entry for the previous week is half the entered value'), 'default' => html::initial_value($values, 'summariser_definition:first_value'), 'helpText' => 'When encountering the first entered value, this determines what happens.'));
echo data_entry_helper::select(array('label' => 'Last Value Processing', 'fieldname' => 'summariser_definition:last_value', 'lookupValues' => array('X' => 'No special processing', 'H' => 'The entry for the next week is half the entered value'), 'default' => html::initial_value($values, 'summariser_definition:last_value'), 'helpText' => 'When encountering the last entered value, this determines what happens.'));
?>
</fieldset>
<?php 
echo $metadata;
echo html::form_buttons($existing, false, false);
data_entry_helper::$dumped_resources[] = 'jquery';
data_entry_helper::$dumped_resources[] = 'jquery_ui';
data_entry_helper::$dumped_resources[] = 'fancybox';
echo data_entry_helper::dump_javascript();
?>
</fieldset>
</form>
Esempio n. 13
0
 /**
  * Returns controls allowing a records filter to be defined and associated with the group. 
  * @param array $args Form configuration arguments
  * @return string HTML to output
  */
 private static function reportFilterBlock($args, $auth, &$hiddenPopupDivs)
 {
     $r = '';
     $hiddenPopupDivs = '';
     if ($args['include_report_filter']) {
         $r .= '<p>' . lang::get('LANG_Filter_Instruct') . '</p>';
         $r .= '<label>' . lang::get(ucfirst(self::$groupType) . ' parameters') . ':</label>';
         $r .= report_filter_panel($auth['read'], array('allowLoad' => false, 'allowSave' => false, 'filterTypes' => $args['filter_types'], 'embedInExistingForm' => true), $args['website_id'], $hiddenPopupDivs);
         // fields to auto-create a filter record for this group's defined set of records
         $r .= data_entry_helper::hidden_text(array('fieldname' => 'filter:id'));
         $r .= '<input type="hidden" name="filter:title" id="filter-title-val"/>';
         $r .= '<input type="hidden" name="filter:definition" id="filter-def-val"/>';
         $r .= '<input type="hidden" name="filter:sharing" value="R"/>';
     }
     return $r;
 }
Esempio n. 14
0
<p>This tab allows you to generate a piece of text which describes the terms in a termlist. The text generated can
  be used to recreate the same termlist on another warehouse. It is therefore ideal for migrating development
  or test versions of your surveys to the live warehouse server.</p>
<?php 
require_once DOCROOT . 'client_helpers/data_entry_helper.php';
echo data_entry_helper::textarea(array('label' => 'Exported termlist contents', 'fieldname' => 'export_termlist_contents', 'cols' => 100, 'rows' => 8, 'helpText' => 'Copy this text to the clipboard. You can then paste it into another termlist on another warehouse to clone the content.', 'default' => $export));
?>
<form class="iform" action="<?php 
echo url::site();
?>
termlist_export/save" method="post" id="entry-form"">
<fieldset>
<?php 
echo data_entry_helper::textarea(array('label' => 'Import termlist contents', 'fieldname' => 'import_termlist_contents', 'cols' => 100, 'rows' => 8, 'helpText' => 'Paste in the export of another termlist to import its terms.'));
echo data_entry_helper::hidden_text(array('fieldname' => 'termlist_id', 'default' => $termlistId));
echo '<input type="submit" name="submit" value="Import" class="ui-corner-all ui-state-default button ui-priority-primary" />' . "\n";
data_entry_helper::link_default_stylesheet();
echo data_entry_helper::dump_javascript();
?>
</fieldset>
</form>
Esempio n. 15
0
 */
require_once DOCROOT . 'client_helpers/data_entry_helper.php';
$readAuth = data_entry_helper::get_read_auth(0 - $_SESSION['auth_user']->id, kohana::config('indicia.private_key'));
?>
<p>This page allows you to specify the details of a survey in which samples and records can be organised.</p>
<form class="cmxform" action="<?php 
echo url::site() . 'survey/save';
?>
" method="post" id="survey-edit">
<?php 
echo $metadata;
?>
<fieldset>
<legend>Survey dataset details</legend>
<?php 
echo data_entry_helper::hidden_text(array('fieldname' => 'survey:id', 'default' => html::initial_value($values, 'survey:id')));
echo data_entry_helper::text_input(array('label' => 'Title', 'fieldname' => 'survey:title', 'default' => html::initial_value($values, 'survey:title'), 'validation' => 'required', 'helpText' => 'Provide a title for your survey dataset'));
echo data_entry_helper::textarea(array('label' => 'Description', 'fieldname' => 'survey:description', 'default' => html::initial_value($values, 'survey:description'), 'validation' => 'required', 'helpText' => 'Provide an optional description of your survey to help when browsing survey datasets on the warehouse'));
echo data_entry_helper::autocomplete(array('label' => 'Parent survey', 'fieldname' => 'survey:parent_id', 'table' => 'survey', 'captionField' => 'title', 'valueField' => 'id', 'extraParams' => $readAuth, 'default' => html::initial_value($values, 'survey:parent_id'), 'defaultCaption' => html::initial_value($values, 'parent:title'), 'helpText' => 'Set a parent for your survey to allow grouping of survey datasets in reports'));
echo data_entry_helper::select(array('label' => 'Website', 'fieldname' => 'survey:website_id', 'default' => html::initial_value($values, 'survey:website_id'), 'lookupValues' => $other_data['websites'], 'helpText' => 'The survey must belong to a website registration'));
?>
</fieldset>
<?php 
if (array_key_exists('attributes', $values) && count($values['attributes']) > 0) {
    ?>
 <fieldset>
 <legend>Custom attributes</legend>
 <ol>
 <?php 
    foreach ($values['attributes'] as $attr) {
        $name = 'srvAttr:' . $attr['survey_attribute_id'];
 private static function get_control_identifier($auth, $args, $tabalias, $options)
 {
     $fieldPrefix = !empty($options['fieldprefix']) ? $options['fieldprefix'] : '';
     $r = '';
     $r .= '<h3 id="' . $fieldPrefix . 'header" class="idn:accordion:header"><a href="#">' . $options['identifierName'] . '</a></h2>';
     $r .= '<div id="' . $fieldPrefix . 'panel" class="idn:accordion:panel">';
     $r .= '<input type="hidden" name="' . $fieldPrefix . 'identifier:identifier_type_id" value="' . $options['identifierTypeId'] . '" />' . "\n";
     $r .= '<input type="hidden" name="' . $fieldPrefix . 'identifier:coded_value" id="' . $fieldPrefix . 'identifier:coded_value" class="identifier_coded_value" value="" />' . "\n";
     $val = isset(data_entry_helper::$entity_to_load[$fieldPrefix . 'identifier:id']) ? data_entry_helper::$entity_to_load[$fieldPrefix . 'identifier:id'] : '0';
     $r .= '<input type="hidden" name="' . $fieldPrefix . 'identifier:id" id="' . $fieldPrefix . 'identifier:id" class="identifier_id" value="' . $val . '" />' . "\n";
     if (isset(data_entry_helper::$entity_to_load[$fieldPrefix . 'identifiers_subject_observation:id'])) {
         $r .= '<input type="hidden" id="' . $fieldPrefix . 'identifiers_subject_observation:id" name="' . $fieldPrefix . 'identifiers_subject_observation:id" ' . 'value="' . data_entry_helper::$entity_to_load[$fieldPrefix . 'identifiers_subject_observation:id'] . '" />' . "\n";
     }
     // checkbox - (now hidden by CSS, probably should refactor to hidden input?)
     $r .= data_entry_helper::checkbox(array_merge(array('label' => '', 'fieldname' => $fieldPrefix . 'identifier:checkbox', 'class' => 'identifier_checkbox identifierRequired noDuplicateIdentifiers'), $options));
     // loop through the requested attributes and output an appropriate control
     $classes = $options['class'];
     foreach ($options['attrList'] as $attribute) {
         // find the definition of this attribute
         $found = false;
         if ($attribute['attrType'] === 'idn') {
             foreach ($options['idnAttributeTypes'] as $attrType) {
                 if ($attrType['id'] === $attribute['typeId']) {
                     $found = true;
                     break;
                 }
             }
         } else {
             if ($attribute['attrType'] === 'iso') {
                 foreach ($options['isoAttributeTypes'] as $attrType) {
                     if ($attrType['id'] === $attribute['typeId']) {
                         $found = true;
                         break;
                     }
                 }
             }
         }
         if (!$found) {
             throw new exception(lang::get('Unknown ' . $attribute['attrType'] . ' attribute type id [' . $attribute['typeId'] . '] specified for ' . $options['identifierName'] . ' in Identifier Attributes array.'));
         }
         // setup any locking
         if (!empty($attribute['lockable']) && $attribute['lockable'] === true) {
             $options['lockable'] = $options['identifiers_lockable'];
         }
         // setup any data filters
         if ($attribute['attrType'] === 'idn' && $options['baseColourId'] == $attribute['typeId']) {
             if (!empty($args['base_colours'])) {
                 // filter the colours available
                 $query = array('in' => array('id', $args['base_colours']));
             }
             $attr_name = 'base-colour';
         } elseif ($attribute['attrType'] === 'idn' && $options['textColourId'] == $attribute['typeId']) {
             if (!empty($args['text_colours'])) {
                 // filter the colours available
                 $query = array('in' => array('id', $args['text_colours']));
             }
             $attr_name = 'text-colour';
         } elseif ($attribute['attrType'] === 'idn' && $options['positionId'] == $attribute['typeId']) {
             $attr_name = 'position';
             if (count($args['position']) > 0) {
                 // filter the identifier position available
                 $query = array('in' => array('id', $args['position']));
             }
         } elseif ($attribute['attrType'] === 'idn' && $options['sequenceId'] == $attribute['typeId']) {
             $attr_name = 'sequence';
             $options['maxlength'] = $options['seq_maxlength'] ? $options['seq_maxlength'] : '';
             if ($options['seq_format_class']) {
                 $options['class'] = empty($options['class']) ? $options['seq_format_class'] : (strstr($options['class'], $options['seq_format_class']) ? $options['class'] : $options['class'] . ' ' . $options['seq_format_class']);
             }
         } elseif ($attribute['attrType'] === 'iso' && $options['conditionsId'] == $attribute['typeId']) {
             // filter the identifier conditions available
             if ($options['identifierTypeId'] == $args['neck_collar_type'] && !empty($args['neck_collar_conditions'])) {
                 $query = array('in' => array('id', $args['neck_collar_conditions']));
             } elseif ($options['identifierTypeId'] == $args['enscribed_colour_ring_type'] && !empty($args['coloured_ring_conditions'])) {
                 $query = array('in' => array('id', $args['coloured_ring_conditions']));
             } elseif ($options['identifierTypeId'] == $args['metal_ring_type'] && !empty($args['metal_ring_conditions'])) {
                 $query = array('in' => array('id', $args['metal_ring_conditions']));
             }
             $attr_name = 'conditions';
         }
         // add classes as identifiers
         $options['class'] = empty($options['class']) ? $options['classprefix'] . $attr_name : (strstr($options['class'], $options['classprefix'] . $attr_name) ? $options['class'] : $options['class'] . ' ' . $options['classprefix'] . $attr_name);
         $options['class'] = $options['class'] . ' idn-' . $attr_name;
         if ($attribute['attrType'] === 'idn' && ($options['baseColourId'] == $attribute['typeId'] || $options['textColourId'] == $attribute['typeId'])) {
             $options['class'] = strstr($options['class'], 'select_colour') ? $options['class'] : $options['class'] . ' select_colour';
             $options['class'] = strstr($options['class'], 'textAndBaseMustDiffer') ? $options['class'] : $options['class'] . ' textAndBaseMustDiffer';
         }
         if ($attribute['attrType'] === 'idn' && $options['sequenceId'] == $attribute['typeId']) {
             $options['class'] = strstr($options['class'], 'identifier_sequence') ? $options['class'] : $options['class'] . ' identifier_sequence';
         }
         if (!empty($attribute['hidden']) && $attribute['hidden'] === true) {
             $dataType = 'H';
             // hidden
             if (!empty($attribute['hiddenValue'])) {
                 $dataDefault = $attribute['hiddenValue'];
             } else {
                 $dataDefault = '';
             }
         } else {
             $dataType = $attrType['data_type'];
         }
         // output an appropriate control for the attribute data type
         switch ($dataType) {
             case 'D':
             case 'V':
                 $r .= data_entry_helper::date_picker(array_merge(array('label' => lang::get($attrType['caption']), 'fieldname' => $fieldPrefix . $attribute['attrType'] . 'Attr:' . $attrType['id']), $options));
                 break;
             case 'L':
                 $filter = array('termlist_id' => $attrType['termlist_id']);
                 if (!empty($query)) {
                     $filter += array('query' => json_encode($query));
                 }
                 $extraParams = array_merge($filter, $auth['read']);
                 if ($attribute['attrType'] === 'iso' && $options['conditionsId'] == $attribute['typeId']) {
                     $fieldname = $fieldPrefix . $attribute['attrType'] . 'Attr:' . $attrType['id'];
                     $default = array();
                     // if this attribute exists on DB, we need to write a hidden with id appended to fieldname and set defaults for checkboxes
                     if (is_array(data_entry_helper::$entity_to_load)) {
                         $stored_keys = preg_grep('/^' . $fieldname . ':[0-9]+$/', array_keys(data_entry_helper::$entity_to_load));
                         foreach ($stored_keys as $stored_key) {
                             $r .= '<input type="hidden" name="' . $stored_key . '" value="" />';
                             $default[] = array('fieldname' => $stored_key, 'default' => data_entry_helper::$entity_to_load[$stored_key]);
                             unset(data_entry_helper::$entity_to_load[$stored_key]);
                         }
                     }
                     $r .= data_entry_helper::checkbox_group(array_merge(array('label' => lang::get($attrType['caption']), 'fieldname' => $fieldname, 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'id', 'default' => $default, 'extraParams' => $extraParams), $options));
                 } else {
                     $r .= data_entry_helper::select(array_merge(array('label' => lang::get($attrType['caption']), 'fieldname' => $fieldPrefix . $attribute['attrType'] . 'Attr:' . $attrType['id'], 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'id', 'blankText' => '<Please select>', 'extraParams' => $extraParams), $options));
                 }
                 break;
             case 'B':
                 $r .= data_entry_helper::checkbox(array_merge(array('label' => lang::get($attrType['caption']), 'fieldname' => $fieldPrefix . $attribute['attrType'] . 'Attr:' . $attrType['id']), $options));
                 break;
             case 'H':
                 // Any multi-value attributes shown as hidden will be single-valued
                 // so transform the array to a scalar
                 $fieldname = $fieldPrefix . $attribute['attrType'] . 'Attr:' . $attrType['id'];
                 if (!empty(data_entry_helper::$entity_to_load[$fieldname]) && is_array(data_entry_helper::$entity_to_load[$fieldname])) {
                     data_entry_helper::$entity_to_load[$fieldname] = data_entry_helper::$entity_to_load[$fieldname][0];
                 }
                 $r .= data_entry_helper::hidden_text(array_merge(array('fieldname' => $fieldname, 'default' => $dataDefault), $options));
                 break;
             default:
                 $r .= data_entry_helper::text_input(array_merge(array('label' => lang::get($attrType['caption']), 'fieldname' => $fieldPrefix . $attribute['attrType'] . 'Attr:' . $attrType['id']), $options));
         }
         $options['class'] = $classes;
         if (isset($options['maxlength'])) {
             unset($options['maxlength']);
         }
         if (isset($options['lockable'])) {
             unset($options['lockable']);
         }
     }
     $r .= '</div>';
     return $r;
 }
 /**
  * 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;
 }
 /**
  * Output a lat long field split into 2 fields.
  * @param type $auth
  * @param type $args
  * @param type $tabalias
  * @param type $options
  * @param type $path
  */
 public static function lat_long($auth, $args, $tabalias, $options, $path)
 {
     $r = '';
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'sample:entered_sref_system', 'default' => 4326));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'sample:entered_sref'));
     $r .= data_entry_helper::text_input(array('fieldname' => 'lat_long-lat', 'label' => lang::get('Position'), 'afterControl' => 'Latitude'));
     // a null label ensures correct padding for the 2nd control.
     $r .= '<label> </label> ';
     $r .= data_entry_helper::text_input(array('fieldname' => 'lat_long-long', 'afterControl' => 'Longitude'));
     return $r;
 }