/** * Return the generated form output. * @param array $args List of parameter values passed through to the form depending on how the form has been configured. * This array always contains a value for language. * @param object $node The Drupal node object. * @param array $response When this form is reloading after saving a submission, contains the response from the service call. * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data). * @return Form HTML. */ public static function get_form($args, $node, $response = null) { $conn = iform_get_connection_details($node); data_entry_helper::$js_read_tokens = data_entry_helper::get_read_auth($conn['website_id'], $conn['password']); if (!empty($_GET)) { self::do_data_services_download($args, $node); } }
/** * Return the Indicia form code. * Expects there to be a sample attribute with caption 'Email' containing the email * address. * @param array $args Input parameters. * @param array $node Drupal node object * @param array $response Response from Indicia services after posting a verification. * @return HTML string */ public static function get_form($args, $node, $response) { iform_load_helpers(array('data_entry_helper', 'map_helper', 'report_helper')); $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']); //Clear Verifier Tasks automatically when they open the screen if the option is set. if ($args['clear_verification_task_notifications'] && hostsite_get_user_field('indicia_user_id')) { self::clear_verifier_task_notifications($auth); } // set some defaults, applied when upgrading from a form configured on a previous form version. if (empty($args['email_subject_send_to_recorder'])) { $args['email_subject_send_to_recorder'] = 'Record of %taxon% requires confirmation (ID:%id%)'; } if (empty($args['email_body_send_to_recorder'])) { $args['email_body_send_to_recorder'] = 'The following record requires confirmation. Please could you reply to this email stating how confident you are that the record is correct ' . 'and any other information you have which may help to confirm this.' . "\n\n%record%"; } if (isset($_POST['enable'])) { module_enable(array('iform_ajaxproxy')); drupal_set_message(lang::get('The Indicia AJAX Proxy module has been enabled.', 'info')); } elseif (!defined('IFORM_AJAXPROXY_PATH')) { $r = '<p>' . lang::get('The Indicia AJAX Proxy module must be enabled to use this form. This lets the form save verifications to the ' . 'Indicia Warehouse without having to reload the page.') . '</p>'; $r .= '<form method="post">'; $r .= '<input type="hidden" name="enable" value="t"/>'; $r .= '<input type="submit" value="' . lang::get('Enable Indicia AJAX Proxy') . '"/>'; $r .= '</form>'; return $r; } if (function_exists('drupal_add_js')) { drupal_add_js('misc/collapse.js'); } // fancybox for popup comment forms etc data_entry_helper::add_resource('fancybox'); data_entry_helper::add_resource('validation'); global $user, $indicia_templates; $indicia_user_id = self::get_indicia_user_id($args); data_entry_helper::$js_read_tokens = $auth['read']; // Find a list of websites we are allowed verify $websiteIds = iform_get_allowed_website_ids($auth['read'], 'verification'); if (function_exists('module_exists') && module_exists('easy_login')) { if (strpos($args['param_presets'] . $args['param_defaults'], 'expertise_location') === false) { $args['param_presets'] .= "\nexpertise_location={profile_location_expertise}"; } if (strpos($args['param_presets'] . $args['param_defaults'], 'expertise_taxon_groups') === false) { $args['param_presets'] .= "\nexpertise_taxon_groups={profile_taxon_groups_expertise}"; } if (strpos($args['param_presets'] . $args['param_defaults'], 'expertise_surveys') === false) { $args['param_presets'] .= "\nexpertise_surveys={profile_surveys_expertise}"; } } $args['sharing'] = 'verification'; $opts = array_merge(iform_report_get_report_options($args, $auth['read']), array('id' => 'verification-grid', 'reportGroup' => 'verification', 'rowId' => 'occurrence_id', 'paramsFormButtonCaption' => lang::get('Filter'), 'paramPrefix' => '<div class="report-param">', 'paramSuffix' => '</div>', 'sharing' => 'verification', 'ajax' => TRUE, 'callback' => 'verificationGridLoaded', 'rowClass' => 'zero-{zero_abundance}')); $opts['columns'][] = array('display' => '', 'template' => '<div class="nowrap"><button class="default-button quick-verify tools-btn" type="button" id="quick-{occurrence_id}" title="Record tools">...</button>' . '<input type="hidden" class="row-input-form" value="{rootFolder}{input_form}"/><input type="hidden" class="row-belongs-to-site" value="{belongs_to_site}"/><ul class="verify-tools"><li><a href="#" class="quick-verify-tool">Bulk verify similar records</a></li>' . '<li><a href="#" class="trust-tool">Recorder\'s trust settings</a></li><li><a href="#" class="edit-record">Edit record</a></li></ul>' . '<input type="checkbox" class="check-row no-select" style="display: none" value="{occurrence_id}" /></div>'); $params = self::report_filter_panel($args, $auth['read']); $opts['zoomMapToOutput'] = false; $grid = report_helper::report_grid($opts); $r = str_replace(array('{grid}', '{paramsForm}'), array($grid, $params), self::get_template_with_map($args, $auth['read'], $opts['extraParams'], $opts['paramDefaults'])); $link = data_entry_helper::get_reload_link_parts(); global $user; data_entry_helper::$js_read_tokens = $auth['read']; data_entry_helper::$javascript .= 'indiciaData.nid = "' . $node->nid . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.username = "******"\";\n"; data_entry_helper::$javascript .= 'indiciaData.userId = "' . $indicia_user_id . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.rootUrl = "' . $link['path'] . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.website_id = ' . $args['website_id'] . ";\n"; data_entry_helper::$javascript .= 'indiciaData.ajaxFormPostUrl="' . iform_ajaxproxy_url($node, 'occurrence') . "&user_id={$indicia_user_id}&sharing=verification\";\n"; data_entry_helper::$javascript .= 'indiciaData.ajaxUrl="' . url('iform/ajax/verification_4') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.autoDiscard = ' . $args['auto_discard_rows'] . ";\n"; if (!empty($args['indicia_species_layer_feature_type']) && !empty(data_entry_helper::$geoserver_url)) { data_entry_helper::$javascript .= "indiciaData.indiciaSpeciesLayer = {\n" . ' "title":"' . lang::get('Online recording data for this species') . "\",\n" . ' "featureType":"' . $args['indicia_species_layer_feature_type'] . "\",\n" . ' "wmsUrl":"' . data_entry_helper::$geoserver_url . "wms\",\n" . ' "cqlFilter":"website_id IN (' . implode(',', $websiteIds) . ') AND ' . $args['indicia_species_layer_filter_field'] . "='{filterValue}'\",\n" . ' "filterField":"' . $args['indicia_species_layer_ds_filter_field'] . "\",\n" . ' "sld":"' . (isset($args['indicia_species_layer_sld']) ? $args['indicia_species_layer_sld'] : '') . "\"\n" . "};\n"; } if (!empty($args['additional_wms_species_layer_title'])) { data_entry_helper::$javascript .= 'indiciaData.wmsSpeciesLayers = [{"title":"' . $args['additional_wms_species_layer_title'] . '",' . '"url":"' . $args['additional_wms_species_layer_url'] . '",' . '"settings":' . $args['additional_wms_species_layer_settings'] . ',' . '"olSettings":' . $args['additional_wms_species_layer_ol_settings'] . "}];\n"; } // output some translations for JS to use data_entry_helper::$javascript .= "indiciaData.popupTranslations = {};\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.title="' . lang::get('Add {1} comment') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.save="' . lang::get('Save and {1}') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.verbV="' . lang::get('verify') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.verbR="' . lang::get('reject') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.verbD="' . lang::get('query') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.V="' . lang::get('Verification') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.R="' . lang::get('Rejection') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.D="' . lang::get('Query') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.emailTitle="' . lang::get('Email record details for checking') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.sendEmail="' . lang::get('Send Email') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.emailSent="' . lang::get('The email was sent successfully.') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.requestManualEmail="' . lang::get('The webserver is not correctly configured to send emails. Please send the following email usual your email client:') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.multipleWarning="' . lang::get('You are about to verify multiple records. Please note that this comment will apply to all the ticked records. ' . 'If you did not intend to do this, please close this box and turn off the Select Records tool before proceeding.') . "\";\n"; data_entry_helper::$javascript .= "indiciaData.statusTranslations = {};\n"; data_entry_helper::$javascript .= 'indiciaData.statusTranslations.V = "' . lang::get('Verified') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.statusTranslations.R = "' . lang::get('Rejected') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.statusTranslations.D = "' . lang::get('Query') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.statusTranslations.I = "' . lang::get('In progress') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.statusTranslations.T = "' . lang::get('Test record') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.statusTranslations.S = "' . lang::get('Sent for verification') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.statusTranslations.C = "' . lang::get('Awaiting verification') . "\";\n"; data_entry_helper::$javascript .= "indiciaData.commentTranslations = {};\n"; data_entry_helper::$javascript .= 'indiciaData.commentTranslations.emailed = "' . lang::get('I emailed this record to {1} for checking.') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.commentTranslations.recorder = "' . lang::get('the recorder') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.commentTranslations.expert = "' . lang::get('an expert') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.email_subject_send_to_verifier = "' . $args['email_subject_send_to_verifier'] . "\";\n"; $body = str_replace(array("\r", "\n"), array('', '\\n'), $args['email_body_send_to_verifier']); data_entry_helper::$javascript .= 'indiciaData.email_body_send_to_verifier = "' . $body . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.email_subject_send_to_recorder = "' . $args['email_subject_send_to_recorder'] . "\";\n"; $body = str_replace(array("\r", "\n"), array('', '\\n'), $args['email_body_send_to_recorder']); data_entry_helper::$javascript .= 'indiciaData.email_body_send_to_recorder = "' . $body . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.str_month = "' . lang::get('month') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.expertise_location = "' . $opts['extraParams']['expertise_location'] . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.expertise_surveys = "' . $opts['extraParams']['expertise_surveys'] . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.expertise_taxon_groups = "' . $opts['extraParams']['expertise_taxon_groups'] . "\";\n"; data_entry_helper::add_resource('jqplot'); data_entry_helper::add_resource('jqplot_bar'); 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) { $conn = iform_get_connection_details($node); data_entry_helper::$js_read_tokens = data_entry_helper::get_read_auth($conn['website_id'], $conn['password']); if (!empty($_POST) && !empty($_POST['format'])) { self::do_data_services_download($args, $node); } $conn = iform_get_connection_details($node); data_entry_helper::$js_read_tokens = data_entry_helper::get_read_auth($conn['website_id'], $conn['password']); $types = self::get_download_types($args); $formats = self::get_download_formats($args); if (count($types) === 0) { return 'This download page is configured so that no download type options are available.'; } if (count($formats) === 0) { return 'This download page is configured so that no download format options are available.'; } $reload = data_entry_helper::get_reload_link_parts(); $reloadPath = $reload['path']; if (count($reload['params'])) { $reloadPath .= '?' . helper_base::array_to_query_string($reload['params']); } $r = '<form method="POST" action="' . $reloadPath . '">'; $r .= '<fieldset id="download-type-fieldset"><legend>' . lang::get('Records to download') . '</legend>'; if (count($types) === 1) { $r .= '<input type="hidden" name="download-type" id="download-type" value="' . implode('', array_keys($types)) . '"/>'; hostsite_set_page_title(lang::get('Download {1}', strtolower(implode('', $types)))); } else { $r .= data_entry_helper::select(array('fieldname' => 'download-type', 'label' => lang::get('Download type'), 'lookupValues' => $types, 'class' => 'control-width-5', 'helpText' => 'Select the type of download you require, i.e. the purpose for the data. This defines which records are available to download.')); } $r .= data_entry_helper::select(array('fieldname' => 'download-subfilter', 'label' => lang::get('Filter to apply'), 'lookupValues' => array(), 'class' => 'control-width-5', 'helpText' => lang::get('Optionally select from the available filters. Filters you create on the Explore pages will be available here.'))); $r .= "</fieldset>\n"; $r .= '<fieldset><legend>' . lang::get('Limit the records') . '</legend>'; if (empty($args['survey_id'])) { // put up an empty surveys drop down. AJAX will populate it. $r .= data_entry_helper::select(array('fieldname' => 'survey_id', 'label' => lang::get('Survey to include'), 'helpText' => 'Choose a survey, or <all> to not filter by survey.', 'lookupValues' => array(), 'class' => 'control-width-5')); } else { $r .= '<input type="hidden" name="survey_id" value="' . $args['survey_id'] . '"/>'; } // Let the user pick the date range to download. $r .= data_entry_helper::select(array('label' => lang::get('Date field'), 'fieldname' => 'date_type', 'lookupValues' => array('recorded' => lang::get('Field record date'), 'input' => lang::get('Input date'), 'edited' => lang::get('Last changed date'), 'verified' => 'Verification status change date'), 'helpText' => 'If filtering on date, which date field would you like to filter on?')); $r .= data_entry_helper::date_picker(array('fieldname' => 'date_from', 'label' => lang::get('Start Date'), 'helpText' => 'Leave blank for no start date filter', 'class' => 'control-width-4')); $r .= data_entry_helper::date_picker(array('fieldname' => 'date_to', 'label' => lang::get('End Date'), 'helpText' => 'Leave blank for no end date filter', 'class' => 'control-width-4')); $r .= '</fieldset>'; if (!empty($args['custom_formats'])) { $customFormats = json_decode($args['custom_formats'], true); foreach ($customFormats as $idx => $format) { if (empty($format['permission']) || user_access($format['permission'])) { $formats["custom-{$idx}"] = lang::get(isset($format['title']) ? $format['title'] : 'Untitled format'); } } } if (count($formats) > 1) { $r .= '<fieldset><legend>' . lang::get('Select a format to download') . '</legend>'; $keys = array_keys($formats); $r .= data_entry_helper::radio_group(array('fieldname' => 'format', 'lookupValues' => $formats, 'default' => $keys[0])); $r .= '</fieldset>'; } else { // only allowed 1 format, so no need for a selection control $keys = array_keys($formats); $r .= '<input type="hidden" name="format" value="' . array_pop($keys) . '"/>'; } $r .= '<input type="submit" value="' . lang::get('Download') . '"/></form>'; data_entry_helper::$javascript .= 'indiciaData.ajaxUrl="' . url('iform/ajax/easy_download_2') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.nid = "' . $node->nid . "\";\n"; data_entry_helper::$javascript .= "setAvailableDownloadFilters();\n"; return $r; }
/** * Outputs a panel and "Precheck my records" button. When clicked, the contents of the * current form are sent to the warehouse and run through any data cleaner verification * rules. The results are then displayed in the panel allowing the user to provide more * details for records of interest before submitting the form. Requires the data_cleaner * module to be enabled on the warehouse. * The output of this control can be configured using the following templates: * <ul> * <li><b>verification_panel</b></br> * HTML template used to generate container element for the verification panel. * </li> * </ul> * @global type $indicia_templates * @param array $options Options array with the following possibilities:<ul> * <li><b>readAuth</b><br/> * Read authorisation tokens * </ul> * <li><b>panelOnly</b><br/> * Default false. If true, then the button is ommited and the button's functionality * must be included elsewhere on the page. * </li> * </ul> * @return type HTML to insert onto the page for the verification panel. */ public function verification_panel($options) { global $indicia_templates; $options = array_merge(array('panelOnly' => false), $options); $button = $options['panelOnly'] ? '' : self::apply_replacements_to_template($indicia_templates['button'], array('href' => '#', 'id' => 'verify-btn', 'class' => 'class="indicia-button"', 'caption' => lang::get('Precheck my records'), 'title' => '')); $replacements = array('button' => $button); self::add_resource('verification'); self::$js_read_tokens = $options['readAuth']; self::$javascript .= "indiciaData.verifyMessages=[];\n"; self::$javascript .= "indiciaData.verifyMessages.nothingToCheck='" . lang::get('There are no records on this form to check.') . "';\n"; self::$javascript .= "indiciaData.verifyMessages.completeRecordFirst='" . lang::get('Before checking, please complete at least the date and grid reference of the record.') . "';\n"; self::$javascript .= "indiciaData.verifyMessages.noProblems='" . lang::get('Automated verification checks did not find anything of note.') . "';\n"; self::$javascript .= "indiciaData.verifyMessages.problems='" . lang::get('Automated verification checks resulted in the following messages:') . "';\n"; self::$javascript .= "indiciaData.verifyMessages.problemsFooter='" . lang::get('A message not mean that there is anything wrong with the record, but if you can provide as much information ' . 'as possible, including photos, then it will help with its confirmation.') . "';\n"; return self::apply_replacements_to_template($indicia_templates['verification_panel'], $replacements); }
public static function add_sites_to_any_user($auth, $args, $tabalias, $options, $path) { //Need to call this so we can use indiciaData.read data_entry_helper::$js_read_tokens = $auth['read']; if (!function_exists('iform_ajaxproxy_url')) { return 'An AJAX Proxy module must be enabled for user sites administration to work.'; } $r = "<form><fieldset><legend>" . lang::get('Add locations to the sites lists for other users') . "</legend>"; if (empty($options['locationTypes']) || !preg_match('/^([0-9]+,( )?)*[0-9]+$/', $options['locationTypes'])) { return 'The sites form is not correctly configured. Please provide the location type you can add.'; } $locationTypes = explode(',', str_replace(' ', '', $options['locationTypes'])); if (empty($options['mySitesPsnAttrId']) || !preg_match('/^[0-9]+$/', $options['mySitesPsnAttrId'])) { return 'The sites form is not correctly configured. Please provide the person attribute ID used to store My Sites.'; } if (!empty($options['locationParamFromURL']) && !empty($_GET[$options['locationParamFromURL']])) { $locationIdFromURL = $_GET[$options['locationParamFromURL']]; } else { $locationIdFromURL = 0; } //If we don't want to automatically get the location id from the URL, then display a drop-down of locations the user can select from if (empty($locationIdFromURL)) { $r .= '<label>' . lang::get('Location :') . '</label> '; //Get a list of all the locations that match the given location types (in this case my sites are returned first, although this isn't a requirement) $r .= data_entry_helper::location_select(array('id' => 'location-select', 'nocache' => true, 'report' => 'reports_for_prebuilt_forms/Shorewatch/locations_with_my_sites_first', 'extraParams' => $auth['read'] + array('location_type_ids' => $options['locationTypes'], 'user_id' => hostsite_get_user_field('indicia_user_id'), 'my_sites_person_attr_id' => $options['mySitesPsnAttrId']), 'blankText' => '<' . lang::get('please select') . '>')); } //Get the user select control $r .= self::user_select_for_add_sites_to_any_user_control($auth['read'], $args); $r .= '<input id="add-user-site-button" type="button" value="' . lang::get('Add to this User\'s Sites List') . '"/><br></form><br>'; $postUrl = iform_ajaxproxy_url(null, 'person_attribute_value'); //Firstly check both a uer and location have been selected. //Then get the current user/sites saved in the database and if the new combination doesn't already exist then call a function to add it. data_entry_helper::$javascript .= "\n function duplicateCheck(locationId, userId) {\n var userIdToAdd = \$('#user-select').val();\n var locationIdToAdd = locationId;\n var sitesReport = indiciaData.read.url +'/index.php/services/report/requestReport?report=library/locations/all_user_sites.xml&mode=json&mode=json&callback=?';\n \n var sitesReportParameters = {\n 'person_site_attr_id': '" . $options['mySitesPsnAttrId'] . "',\n 'auth_token': indiciaData.read.auth_token,\n 'nonce': indiciaData.read.nonce,\n 'reportSource':'local'\n };\n \n if (!userIdToAdd||!locationIdToAdd) {\n alert('Please select both a user and a location to add.');\n } else {\n \$.getJSON (\n sitesReport,\n sitesReportParameters,\n function (data) {\n var duplicateDetected=false;\n \$.each(data, function(i, dataItem) {\n if (userIdToAdd==dataItem.pav_user_id&&locationIdToAdd==dataItem.location_id) {\n duplicateDetected=true;\n }\n });\n if (duplicateDetected===true) {\n alert('The site/user combination you are adding already exists in the database.');\n } else {\n addUserSiteData(locationId, userIdToAdd);\n }\n }\n );\n } \n }\n "; //After duplicate check is performed, add the user/site combination to the person_attribute_values database table data_entry_helper::$javascript .= "\n function addUserSiteData(locationId, userIdToAdd) {\n if (!isNaN(locationId) && locationId!=='') {\n \$.post('{$postUrl}', \n {\"website_id\":" . $args['website_id'] . ",\"person_attribute_id\":" . $options['mySitesPsnAttrId'] . ",\"user_id\":userIdToAdd,\"int_value\":locationId},\n function (data) {\n if (typeof data.error === 'undefined') {\n alert('User site configuration saved successfully');\n location.reload();\n } else {\n alert(data.error);\n } \n },\n 'json'\n );\n }\n }\n "; //Call duplicate check when administrator elects to save a user/site combination data_entry_helper::$javascript .= "\n \$('#add-user-site-button').click(function() {\n //We can get the location id from the url or from the locations drop-down depending on the option the administrator has set.\n var locationId;\n if (" . $locationIdFromURL . ") {\n locationId = " . $locationIdFromURL . ";\n } else {\n locationId = \$('#location-select').val() \n }\n duplicateCheck(locationId,\$('#dynamic-the_user_id').val());\n });"; //Zoom map as user selects locations data_entry_helper::$javascript .= "\n \$('#location-select, #location-search, #locality_id').change(function() {\n if (typeof indiciaData.mapdiv!=='undefined') {\n indiciaData.mapdiv.locationSelectedInInput(indiciaData.mapdiv, this.value);\n }\n });\n "; //Function for when user elects to remove sites data_entry_helper::$javascript .= "\n user_site_delete = function(pav_id) {\n var userId=\$('#dynamic-the_user_id').val();\n \$.post('{$postUrl}', \n {\"website_id\":" . $args['website_id'] . ",\"id\":pav_id, \"deleted\":\"t\"},\n function (data) {\n if (typeof data.error === 'undefined') {\n location.reload(); \n } else {\n alert(data.error);\n }\n },\n 'json'\n );\n }\n "; return $r; }
/** * Helper function to generate a species checklist from a given taxon list. * * Please not that although this is based on the data_entry_helper function, it has only been tested with the following * options for seasearch - @id,@useThirdLevelSamples,@lookupListId,@gridIdAttributeId,@speciesControlToUseSubSamples,@subSamplePerRow,@resizeWidth,@resizeHeight * If you intend to use any other options, they will require further testing or development. * */ private static function species_checklist($options) { global $indicia_templates; data_entry_helper::add_resource('addrowtogrid'); $options = data_entry_helper::get_species_checklist_options($options); $classlist = array('ui-widget', 'ui-widget-content', 'species-grid'); if (!empty($options['class'])) { $classlist[] = $options['class']; } if ($options['subSamplePerRow']) { // we'll track 1 sample per grid row. $smpIdx = 0; } if ($options['columns'] > 1 && count($options['mediaTypes']) > 1) { throw new Exception('The species_checklist control does not support having more than one occurrence per row (columns option > 0) ' . 'at the same time has having the mediaTypes option in use.'); } data_entry_helper::add_resource('json'); data_entry_helper::add_resource('autocomplete'); $filterArray = data_entry_helper::get_species_names_filter($options); $filterNameTypes = array('all', 'currentLanguage', 'preferred', 'excludeSynonyms'); //make a copy of the options so that we can maipulate it $overrideOptions = $options; //We are going to cycle through each of the name filter types //and save the parameters required for each type in an array so //that the Javascript can quickly access the required parameters foreach ($filterNameTypes as $filterType) { $overrideOptions['speciesNameFilterMode'] = $filterType; $nameFilter[$filterType] = data_entry_helper::get_species_names_filter($overrideOptions); $nameFilter[$filterType] = json_encode($nameFilter[$filterType]); } if (count($filterArray)) { $filterParam = json_encode($filterArray); data_entry_helper::$javascript .= "indiciaData['taxonExtraParams-" . $options['id'] . "'] = {$filterParam};\n"; // Apply a filter to extraParams that can be used when loading the initial species list, to get just the correct names. if (isset($options['speciesNameFilterMode']) && !empty($options['listId'])) { $filterFields = array(); $filterWheres = array(); self::parse_species_name_filter_mode($options, $filterFields, $filterWheres); if (count($filterWheres)) { $options['extraParams'] += array('query' => json_encode(array('where' => $filterWheres))); } $options['extraParams'] += $filterFields; } } data_entry_helper::$js_read_tokens = $options['readAuth']; data_entry_helper::$javascript .= "indiciaData['rowInclusionCheck-" . $options['id'] . "'] = '" . $options['rowInclusionCheck'] . "';\n"; data_entry_helper::$javascript .= "indiciaData['copyDataFromPreviousRow-" . $options['id'] . "'] = '" . $options['copyDataFromPreviousRow'] . "';\n"; data_entry_helper::$javascript .= "indiciaData['includeSpeciesGridLinkPage-" . $options['id'] . "'] = '" . $options['includeSpeciesGridLinkPage'] . "';\n"; data_entry_helper::$javascript .= "indiciaData.speciesGridPageLinkUrl = '" . $options['speciesGridPageLinkUrl'] . "';\n"; data_entry_helper::$javascript .= "indiciaData.speciesGridPageLinkParameter = '" . $options['speciesGridPageLinkParameter'] . "';\n"; data_entry_helper::$javascript .= "indiciaData.speciesGridPageLinkTooltip = '" . $options['speciesGridPageLinkTooltip'] . "';\n"; data_entry_helper::$javascript .= "indiciaData['editTaxaNames-" . $options['id'] . "'] = '" . $options['editTaxaNames'] . "';\n"; data_entry_helper::$javascript .= "indiciaData['subSpeciesColumn-" . $options['id'] . "'] = '" . $options['subSpeciesColumn'] . "';\n"; data_entry_helper::$javascript .= "indiciaData['subSamplePerRow-" . $options['id'] . "'] = " . ($options['subSamplePerRow'] ? 'true' : 'false') . ";\n"; if ($options['copyDataFromPreviousRow']) { data_entry_helper::$javascript .= "indiciaData['previousRowColumnsToInclude-" . $options['id'] . "'] = '" . $options['previousRowColumnsToInclude'] . "';\n"; data_entry_helper::$javascript .= "indiciaData.langAddAnother='" . lang::get('Add another') . "';\n"; } if (count($options['mediaTypes'])) { data_entry_helper::add_resource('plupload'); // store some globals that we need later when creating uploaders $relpath = data_entry_helper::getRootFolder() . data_entry_helper::client_helper_path(); $interim_image_folder = isset(parent::$interim_image_folder) ? parent::$interim_image_folder : 'upload/'; data_entry_helper::$javascript .= "indiciaData.uploadSettings = {\n"; data_entry_helper::$javascript .= " uploadScript: '" . $relpath . "upload.php',\n"; data_entry_helper::$javascript .= " destinationFolder: '" . $relpath . $interim_image_folder . "',\n"; data_entry_helper::$javascript .= " jsPath: '" . data_entry_helper::$js_path . "'"; if (isset($options['resizeWidth'])) { data_entry_helper::$javascript .= ",\n resizeWidth: " . $options['resizeWidth']; } if (isset($options['resizeHeight'])) { data_entry_helper::$javascript .= ",\n resizeHeight: " . $options['resizeHeight']; } if (isset($options['resizeQuality'])) { data_entry_helper::$javascript .= ",\n resizeQuality: " . $options['resizeQuality']; } data_entry_helper::$javascript .= "\n}\n"; if ($indicia_templates['file_box'] != '') { data_entry_helper::$javascript .= "file_boxTemplate = '" . str_replace('"', '\\"', $indicia_templates['file_box']) . "';\n"; } if ($indicia_templates['file_box_initial_file_info'] != '') { data_entry_helper::$javascript .= "file_box_initial_file_infoTemplate = '" . str_replace('"', '\\"', $indicia_templates['file_box_initial_file_info']) . "';\n"; } if ($indicia_templates['file_box_uploaded_image'] != '') { data_entry_helper::$javascript .= "file_box_uploaded_imageTemplate = '" . str_replace('"', '\\"', $indicia_templates['file_box_uploaded_image']) . "';\n"; } } $occAttrControls = array(); $occAttrs = array(); $occAttrControlsExisting = array(); $taxonRows = array(); $subSampleRows = array(); if (!empty($options['useThirdLevelSamples']) && $options['useThirdLevelSamples'] == true) { $useThirdLevelSamples = true; } else { $useThirdLevelSamples = false; } // Load any existing sample's occurrence data into $entity_to_load if (isset(data_entry_helper::$entity_to_load['sample:id']) && $options['useLoadedExistingRecords'] === false) { self::preload_species_checklist_occurrences(data_entry_helper::$entity_to_load['sample:id'], $options['readAuth'], $options['mediaTypes'], $options['reloadExtraParams'], $subSampleRows, $options['speciesControlToUseSubSamples'], isset($options['subSampleSampleMethodID']) ? $options['subSampleSampleMethodID'] : '', $options['id'], $useThirdLevelSamples); } // load the full list of species for the grid, including the main checklist plus any additional species in the reloaded occurrences. $taxalist = data_entry_helper::get_species_checklist_taxa_list($options, $taxonRows); // If we managed to read the species list data we can proceed if (!array_key_exists('error', $taxalist)) { $attrOptions = array('id' => null, 'valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => "sc:-idx-::occAttr", 'extraParams' => $options['readAuth'], 'survey_id' => array_key_exists('survey_id', $options) ? $options['survey_id'] : null); if (isset($options['attributeIds'])) { // make sure we load the grid ID attribute if (!empty($options['gridIdAttributeId']) && !in_array($options['gridIdAttributeId'], $options['attributeIds'])) { $options['attributeIds'][] = $options['gridIdAttributeId']; } $attrOptions['extraParams'] += array('query' => json_encode(array('in' => array('id' => $options['attributeIds'])))); } $attributes = data_entry_helper::getAttributes($attrOptions); // Merge in the attribute options passed into the control which can override the warehouse config if (isset($options['occAttrOptions'])) { foreach ($options['occAttrOptions'] as $attrId => $attr) { if (isset($attributes[$attrId])) { $attributes[$attrId] = array_merge($attributes[$attrId], $attr); } } } // Get the attribute and control information required to build the custom occurrence attribute columns data_entry_helper::species_checklist_prepare_attributes($options, $attributes, $occAttrControls, $occAttrControlsExisting, $occAttrs); $beforegrid = '<span style="display: none;">Step 1</span>' . "\n"; if (isset($options['lookupListId'])) { $subSampleImagesToLoad = array(); //Cycle through sub-samples of the main parent sample foreach ($subSampleRows as $subSampleIdx => $subSampleRow) { foreach (data_entry_helper::$entity_to_load as $key => $value) { $keyParts = explode(':', $key); //Get an array of sample media to load onto the grid if (strpos($key, 'third-level-smp-occ-grid') !== false && strpos($key, ':sample_medium:id') !== false) { if (!in_array($keyParts[3], $subSampleImagesToLoad)) { $subSampleImagesToLoad[] = $keyParts[3]; } } } } //For each sub-sample, add a row to the occurrences grid with the image loaded, this is then ready for the user. //To create occurrences with if (isset($subSampleImagesToLoad)) { $mediaIdArray = array(); foreach ($subSampleImagesToLoad as $subSampleImageIdx => $subSampleImageToLoad) { $mediaIdArray[] = $subSampleImageToLoad; $beforegrid .= self::get_species_checklist_empty_row_with_image($options, $occAttrControls, $attributes, $subSampleImageIdx, $subSampleImageToLoad); } $encodedMediaArray = json_encode($mediaIdArray); data_entry_helper::$javascript .= "indiciaData.encodedMediaArray=" . json_encode($encodedMediaArray) . ";\n"; } $beforegrid .= self::get_species_checklist_clonable_row($options, $occAttrControls, $attributes); } $onlyImages = true; if ($options['mediaTypes']) { foreach ($options['mediaTypes'] as $mediaType) { if (substr($mediaType, 0, 6) !== 'Image:') { $onlyImages = false; } } } $grid = data_entry_helper::get_species_checklist_header($options, $occAttrs, $onlyImages); $rows = array(); $imageRowIdxs = array(); $taxonCounter = array(); $rowIdx = 0; // tell the addTowToGrid javascript how many rows are already used, so it has a unique index for new rows data_entry_helper::$javascript .= "indiciaData['gridCounter-" . $options['id'] . "'] = " . count($taxonRows) . ";\n"; data_entry_helper::$javascript .= "indiciaData['gridSampleCounter-" . $options['id'] . "'] = " . count($subSampleRows) . ";\n"; // Loop through all the rows needed in the grid // Get the checkboxes (hidden or otherwise) that indicate a species is present if (is_array(data_entry_helper::$entity_to_load)) { $presenceValues = preg_grep("/^sc:[0-9]*:[0-9]*:present\$/", array_keys(data_entry_helper::$entity_to_load)); } // if subspecies are stored, then need to load up the parent species info into the $taxonRows data if ($options['subSpeciesColumn']) { self::load_parent_species($taxalist, $options); if ($options['subSpeciesRemoveSspRank']) { // remove subspecific rank information from the displayed subspecies names by passing a regex data_entry_helper::$javascript .= "indiciaData.subspeciesRanksToStrip='" . lang::get('(form[a\\.]?|var\\.?|ssp\\.)') . "';\n"; } } // track if there is a row we are editing in this grid $hasEditedRecord = false; if ($options['mediaTypes']) { $mediaBtnLabel = lang::get($onlyImages ? 'Add images' : 'Add media'); $mediaBtnClass = 'sc' . $onlyImages ? 'Image' : 'Media' . 'Link'; } foreach ($taxonRows as $txIdx => $rowIds) { $ttlId = $rowIds['ttlId']; $loadedTxIdx = isset($rowIds['loadedTxIdx']) ? $rowIds['loadedTxIdx'] : -1; $existing_record_id = isset($rowIds['occId']) ? $rowIds['occId'] : false; // Multi-column input does not work when image upload allowed $colIdx = count($options['mediaTypes']) ? 0 : (int) floor($rowIdx / (count($taxonRows) / $options['columns'])); // Find the taxon in our preloaded list data that we want to output for this row $taxonIdx = 0; while ($taxonIdx < count($taxalist) && $taxalist[$taxonIdx]['id'] != $ttlId) { $taxonIdx += 1; } if ($taxonIdx >= count($taxalist)) { continue; } // next taxon, as this one was not found in the list $taxon = $taxalist[$taxonIdx]; // If we are using the sub-species column then when the taxon has a parent (=species) this goes in the // first column and we put the subsp in the second column in a moment. if (isset($options['subSpeciesColumn']) && $options['subSpeciesColumn'] && !empty($taxon['parent'])) { $firstColumnTaxon = $taxon['parent']; } else { $firstColumnTaxon = $taxon; } // map field names if using a cached lookup if ($options['cacheLookup']) { $firstColumnTaxon = $firstColumnTaxon + array('preferred_name' => $firstColumnTaxon['preferred_taxon'], 'common' => $firstColumnTaxon['default_common_name']); } // Get the cell content from the taxon_label template $firstCell = helper_base::mergeParamsIntoTemplate($firstColumnTaxon, 'taxon_label'); // If the taxon label template is PHP, evaluate it. if ($options['PHPtaxonLabel']) { $firstCell = eval($firstCell); } // Now create the table cell to contain this. $colspan = isset($options['lookupListId']) && $options['rowInclusionCheck'] != 'alwaysRemovable' ? ' colspan="2"' : ''; $row = ''; // Add a delete button if the user can remove rows, add an edit button if the user has the edit option set, add a page link if user has that option set. if ($options['rowInclusionCheck'] == 'alwaysRemovable') { $imgPath = empty(helper_base::$images_path) ? helper_base::relative_client_helper_path() . "../media/images/" : helper_base::$images_path; $speciesGridLinkPageIconSource = $imgPath . "nuvola/find-22px.png"; if ($options['editTaxaNames']) { $row .= '<td class="row-buttons"> <img class="action-button remove-row" src=' . $imgPath . 'nuvola/cancel-16px.png> <img class="action-button edit-taxon-name" src=' . $imgPath . 'nuvola/package_editors-16px.png>'; if ($options['includeSpeciesGridLinkPage']) { $row .= '<img class="species-grid-link-page-icon" title="' . $options['speciesGridPageLinkTooltip'] . '" alt="Notes icon" src=' . $speciesGridLinkPageIconSource . '>'; } $row .= '</td>'; } else { $row .= '<td class="row-buttons"><img class="action-button remove-row" src=' . $imgPath . 'nuvola/cancel-16px.png>'; if ($options['includeSpeciesGridLinkPage']) { $row .= '<img class="species-grid-link-page-icon" title="' . $options['speciesGridPageLinkTooltip'] . '" alt="Notes icon" src=' . $speciesGridLinkPageIconSource . '>'; } $row .= '</td>'; } } // if editing a specific occurrence, mark it up $editedRecord = isset($_GET['occurrence_id']) && $_GET['occurrence_id'] == $existing_record_id; $editClass = $editedRecord ? ' edited-record ui-state-highlight' : ''; $hasEditedRecord = $hasEditedRecord || $editedRecord; // Verified records can be flagged with an icon //Do an isset check as the npms_paths form for example uses the species checklist, but doesn't use an entity_to_load if (isset(data_entry_helper::$entity_to_load["sc:{$loadedTxIdx}:{$existing_record_id}:record_status"])) { $status = data_entry_helper::$entity_to_load["sc:{$loadedTxIdx}:{$existing_record_id}:record_status"]; if (preg_match('/[VDR]/', $status)) { $img = false; switch ($status) { case 'V': $img = 'ok'; $statusLabel = 'verified'; break; case 'D': $img = 'dubious'; $statusLabel = 'queried'; break; case 'R': $img = 'cancel'; $statusLabel = 'rejected'; break; } if ($img) { $label = lang::get($statusLabel); $title = lang::get('This record has been {1}. Changing it will mean that it will need to be rechecked by an expert.', $label); $firstCell .= "<img alt=\"{$label}\" title=\"{$title}\" src=\"{$imgPath}nuvola/{$img}-16px.png\">"; } } } $row .= str_replace(array('{content}', '{colspan}', '{editClass}', '{tableId}', '{idx}'), array($firstCell, $colspan, $editClass, $options['id'], $colIdx), $indicia_templates['taxon_label_cell']); $hidden = $options['rowInclusionCheck'] == 'checkbox' ? '' : ' style="display:none"'; // AlwaysFixed mode means all rows in the default checklist are included as occurrences. Same for // AlwayeRemovable except that the rows can be removed. // If we are reloading a record there will be an entity_to_load which will indicate whether present should be checked. // This has to be evaluated true or false if reloading a submission with errors. if ($options['rowInclusionCheck'] == 'alwaysFixed' || $options['rowInclusionCheck'] == 'alwaysRemovable' || data_entry_helper::$entity_to_load != null && array_key_exists("sc:{$loadedTxIdx}:{$existing_record_id}:present", data_entry_helper::$entity_to_load) && data_entry_helper::$entity_to_load["sc:{$loadedTxIdx}:{$existing_record_id}:present"] == true) { $checked = ' checked="checked"'; } else { $checked = ''; } $row .= "\n<td class=\"scPresenceCell\" headers=\"{$options['id']}-present-{$colIdx}\"{$hidden}>"; $fieldname = "sc:{$options['id']}-{$txIdx}:{$existing_record_id}:present"; if ($options['rowInclusionCheck'] === 'hasData') { $row .= "<input type=\"hidden\" name=\"{$fieldname}\" id=\"{$fieldname}\" value=\"{$taxon['id']}\"/>"; } else { // this includes a control to force out a 0 value when the checkbox is unchecked. $row .= "<input type=\"hidden\" class=\"scPresence\" name=\"{$fieldname}\" value=\"0\"/>" . "<input type=\"checkbox\" class=\"scPresence\" name=\"{$fieldname}\" id=\"{$fieldname}\" value=\"{$taxon['id']}\" {$checked} />"; } // If we have a grid ID attribute, output a hidden if (!empty($options['gridIdAttributeId'])) { $gridAttributeId = $options['gridIdAttributeId']; if (empty($existing_record_id)) { //If in add mode we don't need to include the occurrence attribute id $fieldname = "sc:{$options['id']}-{$txIdx}::occAttr:{$gridAttributeId}"; $row .= "<input type=\"hidden\" name=\"{$fieldname}\" id=\"{$fieldname}\" value=\"{$options['id']}\"/>"; } else { $search = preg_grep("/^sc:[0-9]*:{$existing_record_id}:occAttr:{$gridAttributeId}:" . '[0-9]*$/', array_keys(data_entry_helper::$entity_to_load)); if (!empty($search)) { $match = array_pop($search); $parts = explode(':', $match); //The id of the existing occurrence attribute value is at the end of the data $idxOfOccValId = count($parts) - 1; //$txIdx is row number in the grid. We cannot simply take the data from entity_to_load as it doesn't contain the row number. $fieldname = "sc:{$options['id']}-{$txIdx}:{$existing_record_id}:occAttr:{$gridAttributeId}:{$parts[$idxOfOccValId]}"; $row .= "<input type=\"hidden\" name=\"{$fieldname}\" id=\"{$fieldname}\" value=\"{$options['id']}\"/>"; } } } $row .= "</td>"; if ($options['speciesControlToUseSubSamples']) { $row .= "\n<td class=\"scSampleCell\" style=\"display:none\">"; $fieldname = "sc:{$options['id']}-{$txIdx}:{$existing_record_id}:occurrence:sampleIDX"; $value = $options['subSamplePerRow'] ? $smpIdx : $rowIds['smpIdx']; $row .= "<input type=\"hidden\" class=\"scSample\" name=\"{$fieldname}\" id=\"{$fieldname}\" value=\"{$value}\" />"; $row .= "</td>"; // always increment the sample index if 1 per row. if ($options['subSamplePerRow']) { $smpIdx++; } } $idx = 0; if ($options['mediaTypes']) { $existingImages = is_array(data_entry_helper::$entity_to_load) ? preg_grep("/^sc:{$loadedTxIdx}:{$existing_record_id}:occurrence_medium:id:[a-z0-9]*\$/", array_keys(data_entry_helper::$entity_to_load)) : array(); $row .= "\n<td class=\"ui-widget-content scAddMediaCell\">"; $style = count($existingImages) > 0 ? ' style="display: none"' : ''; $fieldname = "add-media:{$options['id']}-{$txIdx}:{$existing_record_id}"; $row .= "<a href=\"\"{$style} class=\"add-media-link button {$mediaBtnClass}\" id=\"{$fieldname}\">" . "{$mediaBtnLabel}</a>"; $row .= "</td>"; } // Are we in the first column of a multicolumn grid, or doing single column grid? If so start new row. if ($colIdx === 0) { $rows[$rowIdx] = $row; } else { $rows[$rowIdx % ceil(count($taxonRows) / $options['columns'])] .= $row; } $rowIdx++; if ($options['mediaTypes'] && count($existingImages) > 0) { $totalCols = ($options['lookupListId'] ? 2 : 1) + 1 + count($occAttrControls) + ($options['occurrenceComment'] ? 1 : 0) + ($options['occurrenceSensitivity'] ? 1 : 0) + (count($options['mediaTypes']) ? 1 : 0); $rows[$rowIdx] = '<td colspan="' . $totalCols . '">' . data_entry_helper::file_box(array('table' => "sc:{$options['id']}-{$txIdx}:{$existing_record_id}:occurrence_medium", 'loadExistingRecordKey' => "sc:{$loadedTxIdx}:{$existing_record_id}:occurrence_medium", 'mediaTypes' => $options['mediaTypes'], 'readAuth' => $options['readAuth'])) . '</td>'; $imageRowIdxs[] = $rowIdx; $rowIdx++; } } $grid .= "\n<tbody>\n"; if (count($rows) > 0) { $grid .= data_entry_helper::species_checklist_implode_rows($rows, $imageRowIdxs); } $grid .= "</tbody>\n"; $grid = str_replace(array('{class}', '{id}', '{content}'), array(' class="' . implode(' ', $classlist) . '"', " id=\"{$options['id']}\"", $grid), $indicia_templates['data-input-table']); // in hasData mode, the wrap_species_checklist method must be notified of the different default // way of checking if a row is to be made into an occurrence. This may differ between grids when // there are multiple grids on a page. if ($options['rowInclusionCheck'] == 'hasData') { $grid .= '<input name="rowInclusionCheck-' . $options['id'] . '" value="hasData" type="hidden" />'; if (!empty($options['hasDataIgnoreAttrs'])) { $grid .= '<input name="hasDataIgnoreAttrs-' . $options['id'] . '" value="' . implode(',', $options['hasDataIgnoreAttrs']) . '" type="hidden" />'; } } // If the lookupListId parameter is specified then the user is able to add extra rows to the grid, // selecting the species from this list. Add the required controls for this. if (isset($options['lookupListId'])) { // Javascript to add further rows to the grid if (isset($indicia_templates['format_species_autocomplete_fn'])) { data_entry_helper::$javascript .= 'formatter = ' . $indicia_templates['format_species_autocomplete_fn']; } else { data_entry_helper::$javascript .= "formatter = '" . $indicia_templates['taxon_label'] . "';\n"; } if (!empty(parent::$warehouse_proxy)) { $url = parent::$warehouse_proxy . "index.php/services/data"; } else { $url = helper_base::$base_url . "index.php/services/data"; } data_entry_helper::$javascript .= "if (typeof indiciaData.speciesGrid==='undefined') {indiciaData.speciesGrid={};}\n"; data_entry_helper::$javascript .= "indiciaData.speciesGrid['{$options['id']}']={};\n"; data_entry_helper::$javascript .= "indiciaData.speciesGrid['{$options['id']}'].cacheLookup=" . ($options['cacheLookup'] ? 'true' : 'false') . ";\n"; data_entry_helper::$javascript .= "indiciaData.speciesGrid['{$options['id']}'].numValues=" . (!empty($options['numValues']) ? $options['numValues'] : 20) . ";\n"; data_entry_helper::$javascript .= "indiciaData.speciesGrid['{$options['id']}'].selectMode=" . (!empty($options['selectMode']) && $options['selectMode'] ? 'true' : 'false') . ";\n"; //encoded media array is just and array of media items that has been json_encoded. //Add a row to the occurrence grid for each media item. data_entry_helper::$javascript .= "\n if (indiciaData.encodedMediaArray) {\n var encodedMediaArray = eval(indiciaData.encodedMediaArray);\n for (var i=0; i<encodedMediaArray.length; i++) {\n makeImageRowOrSpareRow('" . $options['id'] . "', {'auth_token' : '" . $options['readAuth']['auth_token'] . "', 'nonce' : '" . $options['readAuth']['nonce'] . "'},'" . $options['lookupListId'] . "','{$url}', null, false, null, null, encodedMediaArray[i]);\n }\n }\n \r\n"; data_entry_helper::$javascript .= "makeImageRowOrSpareRow('" . $options['id'] . "', {'auth_token' : '" . $options['readAuth']['auth_token'] . "', 'nonce' : '" . $options['readAuth']['nonce'] . "'},'" . $options['lookupListId'] . "','{$url}', null, false, null, null);\r\n"; } // If options contain a help text, output it at the end if that is the preferred position $options['helpTextClass'] = isset($options['helpTextClass']) ? $options['helpTextClass'] : 'helpTextLeft'; $r = $beforegrid . $grid; data_entry_helper::$javascript .= "\$('#" . $options['id'] . "').find('input,select').keydown(keyHandler);\n"; //nameFilter is an array containing all the parameters required to return data for each of the //"Choose species names available for selection" filter types data_entry_helper::species_checklist_filter_popup($options, $nameFilter); if ($options['subSamplePerRow']) { // output a hidden block to contain sub-sample hidden input values. $r .= '<div id="' . $options['id'] . '-blocks">' . data_entry_helper::get_subsample_per_row_hidden_inputs() . '</div>'; } if ($hasEditedRecord) { data_entry_helper::$javascript .= "\$('#{$options['id']} tbody tr').hide();\n"; data_entry_helper::$javascript .= "\$('#{$options['id']} tbody tr td.edited-record').parent().show();\n"; data_entry_helper::$javascript .= "\$('#{$options['id']} tbody tr td.edited-record').parent().next('tr.supplementary-row').show();\n"; $r .= '<p>' . lang::get('You are editing a single record that is part of a larger sample, so any changes to the sample\'s information such as edits to the date or map reference ' . 'will affect the whole sample.') . " <a id=\"species-grid-view-all-{$options['id']}\">" . lang::get('View all the records in this sample or add more records.') . '</a></p>'; data_entry_helper::$javascript .= "\$('#species-grid-view-all-{$options['id']}').click(function(e) {\n \$('#{$options['id']} tbody tr').show();\n \$(e.currentTarget).hide();\n});\n"; self::$onload_javascript .= "\nif (\$('#{$options['id']}').parents('.ui-tabs-panel').length) {\n indiciaFns.activeTab(\$('#controls'), \$('#{$options['id']}').parents('.ui-tabs-panel')[0].id);\n}\n"; } return $r; } else { return $taxalist['error']; } }
/** * Return the Indicia form code. * Expects there to be a sample attribute with caption 'Email' containing the email * address. * @param array $args Input parameters. * @param array $node Drupal node object * @param array $response Response from Indicia services after posting a verification. * @return string HTML */ public static function get_form($args, $node, $response) { if (!self::check_prerequisites()) { return ''; } iform_load_helpers(array('data_entry_helper', 'map_helper', 'report_helper')); $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']); //Clear Verifier Tasks automatically when they open the screen if the option is set. if ($args['clear_verification_task_notifications'] && hostsite_get_user_field('indicia_user_id')) { self::clear_verifier_task_notifications($auth); } // set some defaults, applied when upgrading from a form configured on a previous form version. if (empty($args['email_subject_send_to_recorder'])) { $args['email_subject_send_to_recorder'] = 'Sample requires confirmation (ID:%id%)'; } if (empty($args['email_body_send_to_recorder'])) { $args['email_body_send_to_recorder'] = 'The following record requires confirmation. Please could you reply to this email stating how confident you are that the record is correct ' . 'and any other information you have which may help to confirm this.' . "\n\n%record%"; } if (isset($_POST['enable'])) { module_enable(array('iform_ajaxproxy')); drupal_set_message(lang::get('The Indicia AJAX Proxy module has been enabled.', 'info')); } elseif (!defined('IFORM_AJAXPROXY_PATH')) { $r = '<p>' . lang::get('The Indicia AJAX Proxy module must be enabled to use this form. This lets the form save verifications to the ' . 'Indicia Warehouse without having to reload the page.') . '</p>'; $r .= '<form method="post">'; $r .= '<input type="hidden" name="enable" value="t"/>'; $r .= '<input type="submit" value="' . lang::get('Enable Indicia AJAX Proxy') . '"/>'; $r .= '</form>'; return $r; } if (function_exists('drupal_add_js')) { drupal_add_js('misc/collapse.js'); } // fancybox for popup comment forms etc data_entry_helper::add_resource('fancybox'); data_entry_helper::add_resource('validation'); $indicia_user_id = self::get_indicia_user_id($args); data_entry_helper::$js_read_tokens = $auth['read']; // Find a list of websites we are allowed verify if (function_exists('module_exists') && module_exists('easy_login')) { if (strpos($args['param_presets'] . $args['param_defaults'], 'expertise_location') === false) { $args['param_presets'] .= "\nexpertise_location={profile_location_expertise}"; } if (strpos($args['param_presets'] . $args['param_defaults'], 'expertise_taxon_groups') === false) { $args['param_presets'] .= "\nexpertise_taxon_groups={profile_taxon_groups_expertise}"; } if (strpos($args['param_presets'] . $args['param_defaults'], 'expertise_surveys') === false) { $args['param_presets'] .= "\nexpertise_surveys={profile_surveys_expertise}"; } } $args['sharing'] = 'verification'; $opts = array_merge(iform_report_get_report_options($args, $auth['read']), array('id' => 'verification-grid', 'reportGroup' => 'verification', 'rowId' => 'sample_id', 'paramsFormButtonCaption' => lang::get('Filter'), 'paramPrefix' => '<div class="report-param">', 'paramSuffix' => '</div>', 'sharing' => 'verification', 'ajax' => TRUE, 'callback' => 'verificationGridLoaded')); $opts['columns'][] = array('display' => '', 'template' => '<div class="nowrap">' . '<input type="hidden" class="row-input-form" value="{rootFolder}{input_form}"/><input type="hidden" class="row-belongs-to-site" value="{belongs_to_site}"/>' . '<input type="checkbox" class="check-row no-select" style="display: none" value="{occurrence_id}" /></div>'); $params = self::report_filter_panel($args, $auth['read']); $opts['zoomMapToOutput'] = false; $grid = report_helper::report_grid($opts); $r = str_replace(array('{grid}', '{paramsForm}'), array($grid, $params), self::get_template_with_map($args, $auth['read'], $opts['extraParams'], $opts['paramDefaults'])); $link = data_entry_helper::get_reload_link_parts(); global $user; data_entry_helper::$js_read_tokens = $auth['read']; data_entry_helper::$javascript .= 'indiciaData.nid = "' . $node->nid . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.username = "******"\";\n"; data_entry_helper::$javascript .= 'indiciaData.userId = "' . $indicia_user_id . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.rootUrl = "' . $link['path'] . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.website_id = ' . $args['website_id'] . ";\n"; data_entry_helper::$javascript .= 'indiciaData.ajaxFormPostUrl="' . iform_ajaxproxy_url($node, 'sample') . "&user_id={$indicia_user_id}&sharing=verification\";\n"; data_entry_helper::$javascript .= 'indiciaData.ajaxUrl="' . url('iform/ajax/verification_samples') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.autoDiscard = ' . $args['auto_discard_rows'] . ";\n"; $imgPath = empty(data_entry_helper::$images_path) ? data_entry_helper::relative_client_helper_path() . "../media/images/" : data_entry_helper::$images_path; data_entry_helper::$javascript .= 'indiciaData.imgPath = "' . $imgPath . "\";\n"; // output some translations for JS to use // @todo: Check list for unused (e.g. query stuff) data_entry_helper::$javascript .= "indiciaData.popupTranslations = {};\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.title="' . lang::get('Add comment regarding setting status to {1}') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.save="' . lang::get('Save and {1}') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.verbV="' . lang::get('accept') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.verbR="' . lang::get('don\'t accept') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.verbC3="' . lang::get('mark as plausible') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.V="' . lang::get('accepted') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.R="' . lang::get('not accepted') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.sub1="' . lang::get('correct') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.sub2="' . lang::get('considered correct') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.sub3="' . lang::get('plausible') . "\";\n"; // @todo: Should this term be unable to accept data_entry_helper::$javascript .= 'indiciaData.popupTranslations.sub4="' . lang::get('unable to verify') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.sub5="' . lang::get('incorrect') . "\";\n"; // IS THIS REQUIRED data_entry_helper::$javascript .= 'indiciaData.popupTranslations.D="' . lang::get('Query') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.tab_email="' . lang::get('Send query as email') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.tab_comment="' . lang::get('Save query to comments log') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.emailTitle="' . lang::get('Email record details') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.emailInstruction="' . lang::get('Use this form to send an email a copy of the record, for example when you would ' . 'like to get the opinion of another expert.') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.sendEmail="' . lang::get('Send Email') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.emailSent="' . lang::get('The email was sent successfully.') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.requestManualEmail="' . lang::get('The webserver is not correctly configured to send emails. Please send the following email usual your email client:') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.multipleWarning="' . lang::get('You are about to process multiple records. Please note that this comment will apply to all the ticked records. ' . 'If you did not intend to do this, please close this box and turn off the Select Records tool before proceeding.') . "\";\n"; // translations for querying data_entry_helper::$javascript .= 'indiciaData.popupTranslations.queryProbablyCantContact="' . lang::get('The record does not have sufficient information for us to be able to contact the recorder. You can leave a query ' . 'in the box below but we cannot guarantee that they will see it.') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.queryNeedsEmail="' . lang::get('The recorder can be contacted by email. If you prefer you can just leave the query as a comment on the ' . 'record but it is unlikely that they will see it as they haven\'t previously checked their notifications.') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.queryProbablyNeedsEmailNo="' . lang::get('The recorder can be contacted by email. If you prefer you can just leave the query as a comment on the ' . 'record but it they are not known to check their notifications so may not spot the query.') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.queryProbablyNeedsEmailUnknown="' . lang::get('The recorder can be contacted by email. If you prefer you can just leave the query as a comment on the ' . 'record though we don\'t have any information to confirm that they will receive the associated notification.') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.popupTranslations.queryProbablyWillGetNotified="' . lang::get('The recorder normally checks their notifications so your query can be posted as a comment ' . 'against the record. If you prefer, you can send a direct email.') . "\";\n"; self::translateStatusTerms(); data_entry_helper::$javascript .= "indiciaData.statusTranslations = " . json_encode(self::$statusTerms) . ";\n"; data_entry_helper::$javascript .= "indiciaData.commentTranslations = {};\n"; data_entry_helper::$javascript .= 'indiciaData.commentTranslations.emailed = "' . lang::get('I emailed this sample to {1} for checking.') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.commentTranslations.recorder = "' . lang::get('the recorder') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.commentTranslations.expert = "' . lang::get('an expert') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.email_subject_send_to_verifier = "' . $args['email_subject_send_to_verifier'] . "\";\n"; $body = str_replace(array("\r", "\n", '"'), array('', '\\n', '\\"'), $args['email_body_send_to_verifier']); data_entry_helper::$javascript .= 'indiciaData.email_body_send_to_verifier = "' . $body . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.email_subject_send_to_recorder = "' . $args['email_subject_send_to_recorder'] . "\";\n"; $body = str_replace(array("\r", "\n"), array('', '\\n'), $args['email_body_send_to_recorder']); data_entry_helper::$javascript .= 'indiciaData.email_body_send_to_recorder = "' . $body . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.str_month = "' . lang::get('month') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.expertise_location = "' . $opts['extraParams']['expertise_location'] . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.expertise_surveys = "' . $opts['extraParams']['expertise_surveys'] . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.expertise_taxon_groups = "' . $opts['extraParams']['expertise_taxon_groups'] . "\";\n"; data_entry_helper::add_resource('jqplot'); data_entry_helper::add_resource('jqplot_bar'); return $r; }
public static function add_locations_to_user($auth, $args, $tabalias, $options, $path) { global $user; //Need to call this so we can use indiciaData.read data_entry_helper::$js_read_tokens = $auth['read']; if (!function_exists('iform_ajaxproxy_url')) { return 'An AJAX Proxy module must be enabled for user sites administration to work.'; } if (!empty($options['locationDropDownLabel'])) { $locationDropDownLabel = $addButtonLabel = $options['locationDropDownLabel'] . ' :'; } else { $locationDropDownLabel = lang::get('Location :'); } if (!empty($options['addButtonLabel'])) { $addButtonLabel = $options['addButtonLabel']; } else { $addButtonLabel = lang::get('Add to this User\'s Sites List'); } if (!empty($options['fieldSetLegend'])) { $fieldSetLegendText = $options['fieldSetLegend']; } else { $fieldSetLegendText = lang::get('Add locations to the sites lists for other users'); } if (!empty($options['rolesExemptFromApproval'])) { $RolesExemptFromApproval = explode(',', $options['rolesExemptFromApproval']); } else { $RolesExemptFromApproval = array(); } $r = "<form><fieldset><legend>" . $fieldSetLegendText . "</legend>"; if (empty($options['locationTypes']) || !preg_match('/^([0-9]+,( )?)*[0-9]+$/', $options['locationTypes'])) { return 'The sites form is not correctly configured. Please provide the location type you can add.'; } $locationTypes = explode(',', str_replace(' ', '', $options['locationTypes'])); if (empty($options['mySitesPsnAttrId']) || !preg_match('/^[0-9]+$/', $options['mySitesPsnAttrId'])) { return 'The sites form is not correctly configured. Please provide the person attribute ID used to store My Sites.'; } if (!empty($options['locationParamFromURL']) && !empty($_GET[$options['locationParamFromURL']])) { $locationIdFromURL = $_GET[$options['locationParamFromURL']]; } else { $locationIdFromURL = 0; } //Get the user_id from the URL if we can, this would hide the user drop-down and make //the control applicable to a single user. if (!empty($options['userParamFromURL']) && !empty($_GET[$options['userParamFromURL']])) { $userIdFromURL = $_GET[$options['userParamFromURL']]; } elseif (!empty($_GET['dynamic-the_user_id'])) { $userIdFromURL = $_GET['dynamic-the_user_id']; } else { $userIdFromURL = 0; } $extraParams = array('location_type_ids' => $options['locationTypes'], 'user_id' => hostsite_get_user_field('indicia_user_id'), 'my_sites_person_attr_id' => $options['mySitesPsnAttrId']); //Can limit results in location drop-down to certain distance of a post code if (!empty($options['postCodeGeomParamName']) && !empty($_GET[$options['postCodeGeomParamName']])) { $extraParams['post_code_geom'] = $_GET[$options['postCodeGeomParamName']]; } if (!empty($options['distanceFromPostCodeParamName']) && !empty($_GET[$options['distanceFromPostCodeParamName']])) { $extraParams['distance_from_post_code'] = $_GET[$options['distanceFromPostCodeParamName']]; } if (!empty($options['excludedSquareAttrId'])) { $extraParams['excluded_square_attr_id'] = $options['excludedSquareAttrId']; } if (!empty($options['dontReturnAllocatedLocations'])) { $extraParams['dont_return_allocated_locations'] = $options['dontReturnAllocatedLocations']; } if (!empty($options['maxAllocationForLocationAttrId'])) { $extraParams['max_allocation_for_location_attr_id'] = $options['maxAllocationForLocationAttrId']; } //If we don't want to automatically get the location id from the URL, then display a drop-down of locations the user can select from if (empty($locationIdFromURL)) { $r .= '<label>' . $locationDropDownLabel . '</label> '; //Get a list of all the locations that match the given location types (in this case my sites are returned first, although this isn't a requirement) $r .= data_entry_helper::location_select(array('id' => 'location-select', 'nocache' => true, 'report' => 'reports_for_prebuilt_forms/Splash/locations_for_add_location_drop_down', 'extraParams' => $auth['read'] + $extraParams, 'blankText' => '<' . lang::get('please select') . '>')); } //Get the user select control if the user id isn't in the url if (empty($userIdFromURL)) { $r .= self::user_select_for_add_sites_to_any_user_control($auth['read'], $args); } $r .= '<input id="add-user-site-button" type="button" value="' . $addButtonLabel . '"/><br></form><br>'; $postUrl = iform_ajaxproxy_url(null, 'person_attribute_value'); //Firstly check both a uer and location have been selected. //Then get the current user/sites saved in the database and if the new combination doesn't already exist then call a function to add it. data_entry_helper::$javascript .= "\n function duplicateCheck(locationId, userId) {\n var userIdToAdd = userId;\n var locationIdToAdd = locationId;\n var sitesReport = indiciaData.read.url +'/index.php/services/report/requestReport?report=library/locations/all_user_sites.xml&mode=json&mode=json&callback=?';\n \n var sitesReportParameters = {\n 'person_site_attr_id': '" . $options['mySitesPsnAttrId'] . "',\n 'auth_token': indiciaData.read.auth_token,\n 'nonce': indiciaData.read.nonce,\n 'reportSource':'local'\n };\n \n if (!userIdToAdd||!locationIdToAdd) {\n alert('Please select both a user and a location to add.');\n } else {\n \$.getJSON (\n sitesReport,\n sitesReportParameters,\n function (data) {\n var duplicateDetected=false;\n \$.each(data, function(i, dataItem) {\n if (userIdToAdd==dataItem.pav_user_id&&locationIdToAdd==dataItem.location_id) {\n duplicateDetected=true;\n }\n });\n if (duplicateDetected===true) {\n alert('The site/user combination you are adding already exists in the database.');\n } else {\n addUserSiteData(locationId, userIdToAdd);\n }\n }\n );\n } \n }\n "; //This veriabe holds the updated_by_id=1 if the user is found to be exempt, if they aren't exempt then this is blank so that the //updated_by_id is set automatically by the system. $updatedBySystem = ''; //See if any of the user's roles are in the exempt list. foreach ($RolesExemptFromApproval as $exemptRole) { foreach ($user->roles as $userRole) { if ($exemptRole === $userRole) { $updatedBySystem = ',"updated_by_id":1'; } } } //Add the user/site combination to the person_attribute_values database table. //This overrides the function in the my_sites.php file. data_entry_helper::$javascript .= "\n var addUserSiteData = function (locationId, userIdToAdd) {\n if (!isNaN(locationId) && locationId!=='') {\n \$.post('{$postUrl}', \n {\"website_id\":" . $args['website_id'] . ",\"person_attribute_id\":" . $options['mySitesPsnAttrId'] . ",\"user_id\":userIdToAdd,\"int_value\":locationId" . $updatedBySystem . "},\n function (data) {\n if (typeof data.error === 'undefined') {\n alert('User site configuration saved successfully');\n location.reload();\n } else {\n alert(data.error);\n } \n },\n 'json'\n );\n }\n }\n "; //Call duplicate check when administrator elects to save a user/site combination data_entry_helper::$javascript .= "\n \$('#add-user-site-button').click(function() {\n //We can get the location id from the url or from the locations drop-down depending on the option the administrator has set.\n var locationId;\n var userId;\n if (" . $locationIdFromURL . ") {\n locationId = " . $locationIdFromURL . ";\n } else {\n locationId = \$('#location-select').val(); \n }\n if (" . $userIdFromURL . ") {\n userId = " . $userIdFromURL . ";\n } else {\n userId = \$('#user-select').val(); \n }\n duplicateCheck(locationId,userId);\n });"; //Zoom map as user selects locations data_entry_helper::$javascript .= "\n \$('#location-select, #location-search, #locality_id').change(function() {\n if (typeof indiciaData.mapdiv!=='undefined') {\n indiciaData.mapdiv.locationSelectedInInput(indiciaData.mapdiv, this.value);\n }\n });\n "; self::user_site_delete($postUrl, $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 $nid The Drupal node object's ID. * @param array $response When this form is reloading after saving a submission, contains the response from the service call. * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data). * @return Form HTML. */ public static function get_form($args, $nid, $response = null) { drupal_add_js(iform_client_helpers_path() . "prebuilt_forms/js/easy_download_2.js"); drupal_add_css(iform_client_helpers_path() . "prebuilt_forms/css/easy_download_2.css"); $conn = iform_get_connection_details($nid); $args = array_merge(array('download_administered_groups' => 'indicia data admin', 'download_group_types' => ''), $args); $readAuth = data_entry_helper::get_read_auth($conn['website_id'], $conn['password']); if (data_entry_helper::$js_read_tokens === null) { data_entry_helper::$js_read_tokens = $readAuth; } if (!empty($_POST) && !empty($_POST['format'])) { self::do_data_services_download($args, $nid); } $types = self::get_download_types($args); $formats = self::get_download_formats($args); if (count($types) === 0) { return 'This download page is configured so that no download type options are available.'; } if (count($formats) === 0) { return 'This download page is configured so that no download format options are available.'; } $reload = data_entry_helper::get_reload_link_parts(); $reloadPath = $reload['path']; if (count($reload['params'])) { $reloadPath .= '?' . helper_base::array_to_query_string($reload['params']); } $r = '<form method="POST" action="' . $reloadPath . '">'; $r .= '<fieldset id="download-type-fieldset"><legend>' . lang::get('Records to download') . '</legend>'; if (count($types) === 1) { $r .= '<input type="hidden" name="download-type" id="download-type" value="' . implode('', array_keys($types)) . '"/>'; hostsite_set_page_title(lang::get('Download {1}', strtolower(implode('', $types)))); } else { $r .= data_entry_helper::select(array('fieldname' => 'download-type', 'label' => lang::get('Download type'), 'lookupValues' => $types, 'class' => 'control-width-5', 'helpText' => 'Select the type of download you require, i.e. the purpose for the data. This defines which records are available to download.')); } $r .= data_entry_helper::select(array('fieldname' => 'download-subfilter', 'label' => lang::get('Filter to apply'), 'lookupValues' => array(), 'class' => 'control-width-5', 'helpText' => lang::get('Optionally select from the available filters. Filters you create on the Explore pages will be available here.'))); $r .= "</fieldset>\n"; $r .= '<fieldset><legend>' . lang::get('Limit the records') . '</legend>'; // Hub // TODO may run into URL size limits $vocabulary = taxonomy_vocabulary_machine_name_load('hubs'); $terms = entity_load('taxonomy_term', FALSE, array('vid' => $vocabulary->vid)); // the hub is driven by a user field, stored as tid. $hubList = array('' => lang::get('<All>')); foreach ($terms as $term) { // TODO Cache $query = new EntityFieldQuery(); $query->entityCondition('entity_type', 'user')->fieldCondition('field_preferred_training_hub', 'tid', $term->tid); $result = $query->execute(); // This gives us the list of users which are in the hub: CMS user ID: now convert to indicia user id $userIDList = array(); if (count($result) > 0) { $cmsUserIDs = array_keys($result['user']); foreach ($cmsUserIDs as $cmsUserID) { $user_data = user_load($cmsUserID); // TODO Making assumption about language if (!empty($user_data->field_indicia_user_id['und'][0]['value'])) { $userIDList[] = $user_data->field_indicia_user_id['und'][0]['value']; } } if (count($userIDList) > 0) { $hubList[implode(',', $userIDList)] = $term->tid . ' ' . $term->name; } } } $r .= data_entry_helper::select(array('fieldname' => 'user_id_list', 'label' => lang::get('Hub to include'), 'helpText' => 'Choose a Hub, or <All> to not filter by Hub. This is driven off the users currently allocated to the hub. This currently does not apply to the NBN download.', 'lookupValues' => $hubList, 'class' => 'control-width-5')); // End Cocoast Hub if (empty($args['survey_id'])) { // put up an empty surveys drop down. AJAX will populate it. $r .= data_entry_helper::select(array('fieldname' => 'survey_id', 'label' => lang::get('Survey to include'), 'helpText' => 'Choose a survey, or <All> to not filter by survey.', 'lookupValues' => array(), 'class' => 'control-width-5')); } else { $r .= '<input type="hidden" name="survey_id" value="' . $args['survey_id'] . '"/>'; } // Let the user pick the date range to download. $r .= data_entry_helper::select(array('label' => lang::get('Date field'), 'fieldname' => 'date_type', 'lookupValues' => array('recorded' => lang::get('Field record date'), 'input' => lang::get('Input date'), 'edited' => lang::get('Last changed date'), 'verified' => 'Verification status change date'), 'helpText' => 'If filtering on date, which date field would you like to filter on?')); $r .= data_entry_helper::date_picker(array('fieldname' => 'date_from', 'label' => lang::get('Start Date'), 'helpText' => 'Leave blank for no start date filter', 'class' => 'control-width-4')); $r .= data_entry_helper::date_picker(array('fieldname' => 'date_to', 'label' => lang::get('End Date'), 'helpText' => 'Leave blank for no end date filter', 'class' => 'control-width-4')); $r .= '</fieldset>'; if (!empty($args['custom_formats'])) { $customFormats = json_decode($args['custom_formats'], true); foreach ($customFormats as $idx => $format) { if (empty($format['permission']) || hostsite_user_has_permission($format['permission'])) { $formats["custom-{$idx}"] = lang::get(isset($format['title']) ? $format['title'] : 'Untitled format'); } } } if (count($formats) > 1) { $r .= '<fieldset><legend>' . lang::get('Select a format to download') . '</legend>'; $keys = array_keys($formats); $r .= data_entry_helper::radio_group(array('fieldname' => 'format', 'lookupValues' => $formats, 'default' => $keys[0])); $r .= '</fieldset>'; } else { // only allowed 1 format, so no need for a selection control $keys = array_keys($formats); $r .= '<input type="hidden" name="format" value="' . array_pop($keys) . '"/>'; } $r .= '<input type="submit" value="' . lang::get('Download') . '"/></form>'; data_entry_helper::$javascript .= 'indiciaData.ajaxUrl="' . url('iform/ajax/easy_download_2') . "\";\n"; data_entry_helper::$javascript .= 'indiciaData.nid = "' . $nid . "\";\n"; data_entry_helper::$javascript .= "setAvailableDownloadFilters();\n"; return $r; }