/**
  * Build a PHP function  to format the species added to the grid according to the form parameters
  * autocomplete_include_both_names and autocomplete_include_taxon_group.
  */
 protected static function build_grid_autocomplete_function($args)
 {
     global $indicia_templates;
     // always include the searched name. In this JavaScript we need to behave slightly differently
     // if using the cached as opposed to the standard versions of taxa_taxon_list.
     $db = data_entry_helper::get_species_lookup_db_definition($args['cache_lookup']);
     // get local vars for the array
     extract($db);
     $fn = "function(item) { \n" . "  var r;\n" . "  if (item.{$colLanguage}!==null && item.{$colLanguage}.toLowerCase()==='{$valLatinLanguage}') {\n" . "    r = '<em>'+item.{$colTaxon}+'</em>';\n" . "  } else {\n" . "    r = '<span>'+item.{$colTaxon}+'</span>';\n" . "  }\n";
     // This bit optionally adds '- common' or '- latin' depending on what was being searched
     if (isset($args['species_include_both_names']) && $args['species_include_both_names']) {
         $fn .= "  if (item.preferred==='t' && item.{$colCommon}!=item.{$colTaxon} && item.{$colCommon}) {\n" . "    r += ' - ' + item.{$colCommon};\n" . "  } else if (item.preferred='f' && item.{$colPreferred}!=item.{$colTaxon} && item.{$colPreferred}) {\n" . "    r += ' - <em>' + item.{$colPreferred} + '</em>';\n" . "  }\n";
     }
     // this bit optionally adds the taxon group
     if (isset($args['species_include_taxon_group']) && $args['species_include_taxon_group']) {
         $fn .= "  r += '<br/><strong>' + item.taxon_group + '</strong>'\n";
     }
     if (!isset($args['species_include_id_diff']) || $args['species_include_id_diff']) {
         $fn .= "  if (item.identification_difficulty && item.identification_difficulty>1) {\n" . "    item.icon = ' <span class=\"item-icon id-diff id-diff-'+item.identification_difficulty+" . "      '\" data-diff=\"'+item.identification_difficulty+'\" data-rule=\"'+item.id_diff_verification_rule_id+'\"></span>';\n" . "    r += item.icon;\n" . "  }\n";
     }
     // Close the function
     $fn .= "  return r;\n" . "}\n";
     // Set it into the indicia templates
     $indicia_templates['format_species_autocomplete_fn'] = $fn;
 }
Esempio n. 2
0
 /**
  * A version of the autocomplete control preconfigured for species lookups.
  * The output of this control can be configured using the following templates: 
  * <ul>
  * <li><b>autocomplete</b></br>
  * Defines a hidden input and a visible input, to hold the underlying database ID and to 
  * allow input and display of the text search string respectively.
  * </li>
  * <li><b>autocomplete_javascript</b></br>
  * Defines the JavaScript which will be inserted onto the page in order to activate the 
  * autocomplete control.
  * </li>
  * </ul>
  * @param type $options Array of configuration options with the following possible entries.
  * <ul>
  * <li><b>cacheLookup</b>
  * Defaults to false. Set to true to lookup species against cache_taxon_searchterms rather than detail_taxa_taxon_lists.
  * </li>
  * <li><b>speciesNameFilterMode</b><br/>
  * Optional. Method of filtering the available species names (both for initial population into the grid and additional rows). Options are
  *   preferred - only preferred names
  *   currentLanguage - only names in the language identified by the language option are included
  *   excludeSynonyms - all names except synonyms (non-preferred latin names) are included.
  * </li>
  * <li><b>extraParams</b>
  * Should contain the read authorisation array and taxon_list_id to filter against. 
  * </li>
  * <li><b>warnIfNoMatch</b>
  * Should the autocomplete control warn the user if they leave the control whilst searching
  * and then nothing is matched? Default true.
  * </li>
  * </ul>
  * @return string Html for the species autocomplete control.
  */
 public static function species_autocomplete($options)
 {
     global $indicia_templates;
     if (!isset($options['cacheLookup'])) {
         $options['cacheLookup'] = false;
     }
     $db = data_entry_helper::get_species_lookup_db_definition($options['cacheLookup']);
     // get local vars for the array
     extract($db);
     $options['extraParams']['orderby'] = $options['cacheLookup'] ? 'searchterm_length,original,preferred_taxon' : 'taxon';
     $options = array_merge(array('fieldname' => 'occurrence:taxa_taxon_list_id', 'table' => $tblTaxon, 'captionField' => $colSearch, 'captionFieldInEntity' => 'taxon', 'valueField' => $colId, 'formatFunction' => $indicia_templates['format_species_autocomplete_fn'], 'simplify' => $options['cacheLookup'] ? 'true' : 'false'), $options);
     if (isset($duplicateCheckFields)) {
         $options['duplicateCheckFields'] = $duplicateCheckFields;
     }
     $options['extraParams'] += self::get_species_names_filter($options);
     if (!empty($options['default']) && empty($options['defaultCaption'])) {
         // We've been given an attribute value but no caption for the species name in the data to load for an existing record. So look it up.
         $r = self::get_population_data(array('table' => 'cache_taxa_taxon_list', 'extraParams' => array('nonce' => $options['extraParams']['nonce'], 'auth_token' => $options['extraParams']['auth_token']) + array('id' => $options['default'], 'columns' => "taxon")));
         $options['defaultCaption'] = $r[0]['taxon'];
     }
     return self::autocomplete($options);
 }
 /**
  * Returns a control for picking a single species
  * @global array $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 = '';
     $extraParams['taxon_list_id'] = empty($args['extra_list_id']) ? $args['list_id'] : $args['extra_list_id'];
     // Add a taxon group selector if that option was chosen
     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.';
         if (!empty(data_entry_helper::$entity_to_load['occurrence:taxa_taxon_list_id'])) {
             // need to find the default value
             $ttlid = data_entry_helper::$entity_to_load['occurrence:taxa_taxon_list_id'];
             $species = data_entry_helper::get_population_data(array('table' => 'cache_taxa_taxon_list', 'extraParams' => $auth['read'] + array('id' => $ttlid)));
             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';
     }
     // Set up options for control
     $options['speciesNameFilterMode'] = self::getSpeciesNameFilterMode($args);
     $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', 'view' => 'detail', '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;
     }
     $species_ctrl_opts['extraParams'] = array_merge(array('view' => 'detail', 'orderby' => 'taxonomic_sort_order', 'sortdir' => 'ASC'), $species_ctrl_opts['extraParams']);
     if (!empty($args['taxon_filter'])) {
         // applies to autocompletes
         $species_ctrl_opts['taxonFilterField'] = $args['taxon_filter_field'];
         $species_ctrl_opts['taxonFilter'] = helper_base::explode_lines($args['taxon_filter']);
     }
     // obtain table to query and hence fields to use
     $db = data_entry_helper::get_species_lookup_db_definition($args['cache_lookup']);
     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' => $db['tblTaxon'], 'captionField' => $db['colTaxon'], 'valueField' => $db['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.
     global $indicia_templates;
     if ($ctrl !== 'autocomplete' && isset($args['species_include_both_names']) && $args['species_include_both_names']) {
         if ($args['species_names_filter'] === 'all') {
             $indicia_templates['species_caption'] = "{{$db['colTaxon']}}";
         } elseif ($args['species_names_filter'] === 'language') {
             $indicia_templates['species_caption'] = "{{$db['colTaxon']}} - {{$db['colPreferred']}}";
         } else {
             $indicia_templates['species_caption'] = "{{$db['colTaxon']}} - {{$db['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('mobile_entry_helper', $ctrl), $species_ctrl_opts);
     return $r;
 }
 private static function get_site_trees_tab($auth, $args, $settings)
 {
     global $indicia_templates;
     $r = '<div id="site-trees" class="ui-helper-clearfix">';
     $r .= '<form method="post" id="tree-form" action="' . self::$ajaxFormUrl . '">';
     $help = '<p>' . lang::get('To add a tree, click on the "Add Tree" button. You can then use the map\'s Location Tool to select the approximate location of your tree on the map. A new tree will then appear on the map.') . '</p>' . '<p>' . lang::get('To select a tree from the existing list of trees at this site you can either:') . '</p>' . '<ol><li>' . lang::get('Click on the button for the tree you wish to view, or') . '</li>' . '<li>' . lang::get('Use the map\'s Query Tool to click on the tree you wish to view on the map.') . '</li></ol>' . '<p>' . lang::get('To remove a tree, first select the tree you wish to remove, then click on the "Remove Tree" button. It will remove the current tree you are viewing completely.') . '</p>';
     $r .= '<div class="ui-state-highlight page-notice ui-corner-all">' . $help . '</div>';
     $r .= self::tree_selector($settings);
     $r .= '<input type="button" value="' . lang::get('Remove Tree') . '" class="remove-tree form-button right" title="' . lang::get('Completely remove the highlighted tree. The total number of tree will be reduced by one. The form will be reloaded after the tree is deleted.') . '">';
     $r .= '<input type="button" value="' . lang::get('Add Tree') . '" class="insert-tree form-button right" title="' . lang::get('This inserts an extra tree.') . '">';
     $r .= '<div id="cols" class="ui-helper-clearfix"><div class="left" style="width: ' . (98 - (isset($args['percent_width']) ? $args['percent_width'] : 50)) . '%">';
     $r .= '<fieldset><legend>' . lang::get('Tree Details') . '</legend>';
     $r .= '<input type="hidden" name="location:id" value="" id="tree-location-id" />';
     $r .= '<input type="hidden" name="locations_website:website_id" value="' . $args['website_id'] . '" id="locations-website-website-id" />';
     $r .= '<input type="hidden" name="location:parent_id" value="' . $settings['locationId'] . '" />';
     $r .= '<input type="hidden" name="location:location_type_id" value="' . $settings['TreeLocationType'][0]['id'] . '" />';
     $r .= '<input type="hidden" name="website_id" value="' . $args['website_id'] . "\" />\n";
     $r .= data_entry_helper::text_input(array('fieldname' => 'location:name', 'label' => lang::get('Tree ID'), 'class' => 'control-width-4 required'));
     $systems = array();
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get($system);
     }
     $srefOptions = array('id' => 'imp-sref-tree', 'fieldname' => 'location:centroid_sref', 'geomid' => 'imp-geom-tree', 'geomFieldname' => 'location:centroid_geom', 'label' => 'Grid Ref', 'labelClass' => 'auto', 'class' => 'required', 'helpText' => lang::get('You can also click on the map to set the grid reference. If directly entering the coordinates from a GPS device, set the format to "Lat/Long" first. To enter an OS Grid square, choose the "OSGB" or "OSIE" formats.'));
     data_entry_helper::$javascript .= "\n\$('#imp-sref-tree').attr('title',\n    '" . lang::get("When directly entering coordinates as a GPS Lat/Long reading, there should be no spaces between the numbers and the letter. " . "The degrees, minutes and seconds must all be separated by a colon (:). The direction letter can be placed at the start or the end of the number (e.g. N56.532 or 56.532N). " . "The figures may be entered as decimal degrees (e.g. 56.532), degrees and decimal minutes (e.g. 56:31.92), or degrees, minutes and decimal seconds (e.g. 56:31:55.2). " . "You can mix the formats of the Latitude and Longitude, provided they each follow the previous guidelines and a space separates them (e.g. N56.532 2:30W).") . "  " . lang::get("When directly entering an OS map reference, there should be no spaces between any of the characters. " . "An OSGB reference should comprise of 2 letters followed by an even number of digits (e.g. NT274628). " . "An OSIE reference should comprise of of 1 letter followed by an even number of digits (e.g. J081880).") . "');\n";
     // Output the sref control
     $r .= data_entry_helper::sref_textbox($srefOptions);
     $srefOptions = array('id' => 'imp-sref-system-tree', 'fieldname' => 'location:centroid_sref_system', 'class' => 'required', 'systems' => $systems);
     // Output the system control
     if (count($systems) < 2) {
         // Hidden field for the system
         $keys = array_keys($options['systems']);
         $r .= "<input type=\"hidden\" id=\"imp-sref-system-tree\" name=\"" . $options['fieldname'] . "\" value=\"" . $keys[0] . "\" />\n";
         // TODO    	self::include_sref_handler_js($options['systems']);
     } else {
         $r .= data_entry_helper::sref_system_select($srefOptions);
     }
     $r .= '<input type="hidden" name="survey_id" value="' . $args['survey_id'] . '" />';
     $r .= '<input type="hidden" name="sample:survey_id" value="' . $args['survey_id'] . '" />';
     $r .= '<input type="hidden" name="sample:id" value="" />';
     // this sample will reference the location id.
     if (isset(data_entry_helper::$entity_to_load['sample:date']) && preg_match('/^(\\d{4})/', data_entry_helper::$entity_to_load['sample:date'])) {
         // Date has 4 digit year first (ISO style) - convert date to expected output format
         // @todo The date format should be a global configurable option. It should also be applied to reloading of custom date attributes.
         $d = new DateTime(data_entry_helper::$entity_to_load['sample:date']);
         data_entry_helper::$entity_to_load['sample:date'] = $d->format('d/m/Y');
     }
     $r .= data_entry_helper::date_picker(array('label' => lang::get('Date Tree Selected'), 'fieldname' => 'sample:date', 'class' => 'control-width-2 required'));
     $r .= '<input type="hidden" id="sample:sample_method_id" value="' . $settings['treeSampleMethod']['id'] . '" name="sample:sample_method_id">';
     $r .= '<input type="hidden" id="sample:location_name" value="" name="sample:location_name">';
     $r .= '<input type="hidden" name="occurrence:id" value="" id="occurrence:id" />';
     $r .= '<input type="hidden" name="occurrence:record_status" value="C" id="occurrence:record_status" />';
     $extraParams = $auth['read'];
     $extraParams['taxon_list_id'] = $args['taxon_list_id'];
     $options = array('speciesNameFilterMode' => $args['speciesNameFilterMode']);
     $ctrl = $args['species_ctrl'];
     $species_ctrl_opts = array_merge(array('fieldname' => 'occurrence:taxa_taxon_list_id', 'label' => lang::get('Tree Species'), 'columns' => 1, 'parentField' => 'parent_id', 'blankText' => lang::get('Please select'), 'cacheLookup' => false), $options);
     if (isset($species_ctrl_opts['extraParams'])) {
         $species_ctrl_opts['extraParams'] = array_merge($extraParams, $species_ctrl_opts['extraParams']);
     } else {
         $species_ctrl_opts['extraParams'] = $extraParams;
     }
     if (!empty($args['taxon_filter'])) {
         $species_ctrl_opts['taxonFilterField'] = $args['taxon_filter_field'];
         // applies to autocompletes
         $species_ctrl_opts['taxonFilter'] = helper_base::explode_lines($args['taxon_filter']);
         // applies to autocompletes
     }
     // obtain table to query and hence fields to use
     $db = data_entry_helper::get_species_lookup_db_definition(false);
     // get local vars for the array
     extract($db);
     if ($ctrl !== 'species_autocomplete') {
         // The species autocomplete has built in support for the species name filter.
         // For other controls we need to apply the species name filter to the params used for population
         if (!empty($species_ctrl_opts['taxonFilter']) || $options['speciesNameFilterMode']) {
             $species_ctrl_opts['extraParams'] = array_merge($species_ctrl_opts['extraParams'], data_entry_helper::get_species_names_filter($species_ctrl_opts));
         }
         // for controls which don't know how to do the lookup, we need to tell them
         $species_ctrl_opts = array_merge(array('table' => $tblTaxon, 'captionField' => $colTaxon, 'valueField' => $colId), $species_ctrl_opts);
     }
     // if using something other than an autocomplete, then set the caption template to include the appropriate names. Autocompletes
     // use a JS function instead.
     if ($ctrl !== 'autocomplete' && isset($args['species_include_both_names']) && $args['species_include_both_names']) {
         if ($args['speciesNameFilterMode'] === 'all') {
             $indicia_templates['species_caption'] = "{{$colTaxon}}";
         } elseif ($args['speciesNameFilterMode'] === 'language') {
             $indicia_templates['species_caption'] = "{{$colTaxon}} - {{$colPreferred}}";
         } else {
             $indicia_templates['species_caption'] = "{{$colTaxon}} - {{$colCommon}}";
         }
         $species_ctrl_opts['captionTemplate'] = 'species_caption';
     }
     if ($ctrl == 'tree_browser') {
         // change the node template to include images
         $indicia_templates['tree_browser_node'] = '<div>' . '<img src="' . data_entry_helper::$base_url . '/upload/thumb-{image_path}" alt="Image of {caption}" width="80" /></div>' . '<span>{caption}</span>';
     }
     // Dynamically generate the species selection control required.
     $r .= call_user_func(array('data_entry_helper', $ctrl), $species_ctrl_opts);
     $ctrlOptions = array('extraParams' => $auth['read']);
     $attrSpecificOptions = array();
     $options = helper_base::explode_lines_key_value_pairs($args['attrOptions']);
     self::parseForAttrSpecificOptions($options, $ctrlOptions, $attrSpecificOptions);
     $r .= get_attribute_html($settings['tree_attributes'], $args, $ctrlOptions, '', $attrSpecificOptions);
     $r .= '</fieldset>';
     $r .= "</div>" . '<div class="right" style="width: ' . (isset($args['percent_width']) ? $args['percent_width'] : 50) . '%">';
     $olOptions = iform_map_get_ol_options($args);
     $options = iform_map_get_map_options($args, $auth['read']);
     $options['divId'] = 'trees-map';
     $options['toolbarDiv'] = 'top';
     $options['tabDiv'] = 'site-trees';
     $options['gridRefHint'] = true;
     $options['latLongFormat'] = 'DMS';
     // TODO drive from args or user.
     if (array_key_exists('standard_controls_trees', $args) && $args['standard_controls_trees']) {
         $standard_controls_trees = str_replace("\r\n", "\n", $args['standard_controls_trees']);
         $options['standardControls'] = explode("\n", $standard_controls_trees);
         // If drawing controls are enabled, then allow polygon recording.
         if (in_array('drawPolygon', $options['standardControls']) || in_array('drawLine', $options['standardControls'])) {
             $options['allowPolygonRecording'] = true;
         }
     }
     // also let the user click on a feature to select it. The highlighter just makes it easier to select one.
     // these controls are not present in read-only mode: all you can do is look at the map.
     $options['switchOffSrefRetrigger'] = true;
     $options['clickForSpatialRef'] = true;
     // override the opacity so the parent square does not appear filled in.
     $options['fillOpacity'] = 0;
     // override the map height and buffer size, which are specific to this map.
     $options['height'] = $args['tree_map_height'];
     $options['maxZoomBuffer'] = $args['tree_map_buffer'];
     $options['srefId'] = 'imp-sref-tree';
     $options['geomId'] = 'imp-geom-tree';
     $options['srefSystemId'] = 'imp-sref-system-tree';
     $help = '<p>' . lang::get('Add your trees using the appropriate tools in the top right of the map') . ':</p>' . '<ol><li>' . lang::get('Navigation Tool.') . '</li>' . '<li>' . lang::get('Query Tool. This tool allows you to click on a tree on the map to view its tree details.') . '</li>' . '<li>' . lang::get('Location Tool. This tool allows you to select the approximate location of a new tree on your site map. You can also reposition existing trees by first clicking on the tree and then clicking on its new location on the map.') . '</li></ol>';
     $r .= '<div class="ui-state-highlight page-notice ui-corner-all">' . $help . '</div>';
     $r .= map_helper::map_panel($options, $olOptions);
     $r .= data_entry_helper::file_box(array('table' => 'location_medium', 'readAuth' => $auth['read'], 'caption' => lang::get('Photos of Tree'), 'readAuth' => $auth['read']));
     $r .= "</div>";
     // right
     $r .= '<div class="follow_on_block" style="clear:both;">';
     $r .= get_attribute_html($settings['tree_attributes'], $args, $ctrlOptions, 'Lower Block', $attrSpecificOptions);
     data_entry_helper::$javascript .= "\n\$('#fieldset-optional-external-sc').prepend(\"" . lang::get('If you choose to record this tree for one of the citizen science projects below, please submit the tree ID used for that scheme.') . "\");\n";
     $r .= data_entry_helper::textarea(array('id' => 'location-comment', 'fieldname' => 'location:comment', 'label' => lang::get("Additional information"), 'labelClass' => 'autowidth')) . "<br />";
     $r .= '<input type="submit" value="' . lang::get('Save') . '" class="form-button right" id="submit-tree" />';
     $r .= '</div></form></div>';
     data_entry_helper::$onload_javascript .= "\$('#current-tree').change(selectTree);\n";
     return $r;
 }