예제 #1
0
 public static function get_form($args, $node, $response = null)
 {
     global $indicia_templates;
     global $user;
     $indicia_templates['select_item'] = '<option value="{value}" {selected} >{caption}&nbsp;</option>';
     // we don't use the map, but a lot of the inherited code assumes the map is present.
     self::$svcUrl = data_entry_helper::$base_url . '/index.php/services';
     data_entry_helper::add_resource('openlayers');
     $indicia_templates['label'] = '<label for="{id}"{labelClass}>{label}:</label>';
     // can't have the CR on the end
     $indicia_templates['zilch'] = '';
     // can't have the CR on the end
     self::$locations = iform_loctools_listlocations($node);
     $retVal = parent::get_form($args, $node, $response);
     $reload = data_entry_helper::get_reload_link_parts();
     $reloadPath = $reload['path'];
     if (self::$mode != 0) {
         data_entry_helper::$javascript .= "\njQuery('<div class=\"ui-widget-content ui-state-default ui-corner-all indicia-button tab-cancel\"><span><a href=\"" . $reloadPath . "\">Cancel</a></span></div>').appendTo('.buttons');\n\$.validator.messages.required = \"" . lang::get('validation_required') . "\";";
         if (!iform_loctools_checkaccess($node, 'superuser')) {
             data_entry_helper::$javascript .= "\njQuery('[name=smpAttr\\:" . $args['observer_attr_id'] . "],[name^=smpAttr\\:" . $args['observer_attr_id'] . "\\:]').attr('readonly',true)";
             if (self::$mode == 1) {
                 data_entry_helper::$javascript .= ".val(\"" . $user->name . "\");";
             } else {
                 data_entry_helper::$javascript .= ";";
             }
         } else {
             $userlist = iform_loctools_listusers($node);
             data_entry_helper::$javascript .= "\nexisting = jQuery('[name=smpAttr\\:" . $args['observer_attr_id'] . "],[name^=smpAttr\\:" . $args['observer_attr_id'] . "\\:]');\nreplacement = '<select name=\"'+existing.attr('name')+'\" >";
             foreach ($userlist as $uid => $a_user) {
                 data_entry_helper::$javascript .= "<option value=\"" . $a_user->name . "\">" . $a_user->name . "&nbsp;</option>";
             }
             data_entry_helper::$javascript .= "</select>';\njQuery(replacement).insertBefore(existing).val(existing.val());\nexisting.remove();\n";
         }
         data_entry_helper::$javascript .= "\n// jQuery('#sample\\\\:date').datepicker( \"option\", \"minDate\", new Date(2010, 4 - 1, 1) );\nDate.prototype.getMonthName = function() {\nvar m = ['" . lang::get('January') . "','" . lang::get('February') . "','" . lang::get('March') . "',\n'" . lang::get('April') . "','" . lang::get('May') . "','" . lang::get('June') . "',\n'" . lang::get('July') . "','" . lang::get('August') . "','" . lang::get('September') . "',\n'" . lang::get('October') . "','" . lang::get('November') . "','" . lang::get('December') . "'];\nreturn m[this.getMonth()];\n} \nvar monthAttr = jQuery('[name=smpAttr\\\\:" . $args['month_attr_id'] . "],[name^=smpAttr\\\\:" . $args['month_attr_id'] . "\\\\:]').attr('disabled', true);\nmonthAttr.before('<input type=\"hidden\" id=\"storedMonth\" name=\"'+monthAttr.attr('name')+'\">');\nupdateSampleDate = function(context, doAlert){\n  jQuery('.displayDateDetails').empty().append('<span>'+jQuery('[name=sample\\:date]').val()+'</span>');\n  var myDate = jQuery(context).datepicker(\"getDate\").getMonthName();\n  var monthAttr = jQuery('[name=smpAttr\\\\:" . $args['month_attr_id'] . "],[name^=smpAttr\\\\:" . $args['month_attr_id'] . "\\\\:]').filter('select').val(\"\");\n  monthAttr.find(\"option:contains('\"+myDate+\"')\").attr('selected',true) ; \n  jQuery('#storedMonth').val(monthAttr.val()); // doing in this order converts the text to a number and stores that number in the storedMonth\n  if(doAlert && monthAttr.val() == \"\")\n  \talert('Given date is outside valid month range (April to September).');\n};\njQuery('#sample\\\\:date').change(function(){updateSampleDate(this, true);});\nupdateSampleDate('#sample\\\\:date', false);\njQuery('.tab-submit').unbind('click');\njQuery('.tab-submit').click(function() {\n  var current=jQuery('#controls').tabs('option', 'selected');\n  var tabinputs = jQuery('#entry_form div > .ui-tabs-panel:eq('+current+')').find('input,select');\n  var secList = '';\n  if (!tabinputs.valid()) { return; }\n  var rows = jQuery('.sectionlist').find('tr');\n  for(var i=1; i<= " . $args['max_number_sections'] . "; i++){\n    if(jQuery('.sectionlist').find('[section='+i+']').length > 0) {\n      var aucuneControl = jQuery(':checkbox[name^=\"SLA\\:'+i+'\\:\"]').filter('[name\$=\"\\:" . $args['aucune_attr_id'] . "\"]');\n      var foundEntry = false;\n      for(var j = 1; j < (rows.length-(numAttrs+1)); j++){\n        foundEntry = foundEntry || (jQuery(rows[j]).find('td').filter(':eq('+i+')').find('[value!=\"\"]').length > 0);\n      }\n      if(!foundEntry && !aucuneControl.attr('checked')){\n          secList = secList + (secList=='' ? '' : ', ') + i;\n      }\n    }\n  }\n  if (secList != ''){\n    alert('The following sections have no species recorded against them: Section(s) '+secList+'. In these circumstances, the \"No Observation\" checkbox must be checked for the relevant section.'); \n    return;\n  }\n  var form = jQuery(this).parents('form:first');\n  form.submit();\n});\n";
     } else {
         $retVal .= "<div style=\"display:none\" />\n    <form id=\"form-delete-survey\" action=\"" . $reloadPath . "\" method=\"POST\">" . self::$auth['write'] . "\n       <input type=\"hidden\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n       <input type=\"hidden\" name=\"survey_id\" value=\"" . $args['survey_id'] . "\" />\n       <input type=\"hidden\" name=\"sample:id\" value=\"\" />\n       <input type=\"hidden\" name=\"sample:date\" value=\"2010-01-01\"/>\n       <input type=\"hidden\" name=\"sample:location_id\" value=\"\" />\n       <input type=\"hidden\" name=\"sample:deleted\" value=\"t\" />\n    </form>\n</div>";
         data_entry_helper::$javascript .= "\ndeleteSurvey = function(sampleID){\n  if(confirm(\"Are you sure you wish to delete survey \"+sampleID)){\n    jQuery.getJSON(\"" . self::$svcUrl . "/data/sample/\"+sampleID +\n            \"?mode=json&view=detail&auth_token=" . self::$auth['read']['auth_token'] . "&nonce=" . self::$auth['read']["nonce"] . "\" +\n            \"&callback=?\", function(data) {\n        if (data.length>0) {\n          jQuery('#form-delete-survey').find('[name=sample\\:id]').val(data[0].id);\n          jQuery('#form-delete-survey').find('[name=sample\\:date]').val(data[0].date_start);\n          jQuery('#form-delete-survey').find('[name=sample\\:location_id]').val(data[0].location_id);\n          jQuery('#form-delete-survey').submit();\n  }});\n  };\n};\n";
     }
     return $retVal;
 }
예제 #2
0
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  */
 public static function get_form($args, $node, $response = null)
 {
     if (!($user_id = hostsite_get_user_field('indicia_user_id'))) {
         return self::abort('Please ensure that you\'ve filled in your surname on your user profile before leaving a group.', $args);
     }
     if (empty($_GET['group_id'])) {
         return self::abort('This form must be called with a group_id in the URL parameters.', $args);
     }
     $r = '';
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $group = data_entry_helper::get_population_data(array('table' => 'group', 'extraParams' => $auth['read'] + array('id' => $_GET['group_id']), 'nocache' => true));
     if (count($group) !== 1) {
         return self::abort('The group you\'ve requested membership of does not exist.', $args);
     }
     iform_load_helpers(array('submission_builder'));
     $group = $group[0];
     // Check for an existing group user record
     $existing = data_entry_helper::get_population_data(array('table' => 'groups_user', 'extraParams' => $auth['read'] + array('group_id' => $_GET['group_id'], 'user_id' => $user_id), 'nocache' => true));
     if (count($existing) !== 1) {
         return self::abort('You are not a member of this group.', $args);
     }
     if (!empty($_POST['response']) && $_POST['response'] === lang::get('Cancel')) {
         drupal_goto($args['groups_page_path']);
     } elseif (!empty($_POST['response']) && $_POST['response'] === lang::get('Confirm')) {
         $data = array('groups_user:id' => $existing[0]['id'], 'groups_user:group_id' => $group['id'], 'groups_user:user_id' => $user_id, 'deleted' => 't');
         $wrap = submission_builder::wrap($data, 'groups_user');
         $response = data_entry_helper::forward_post_to('groups_user', $wrap, $auth['write_tokens']);
         if (isset($response['success'])) {
             hostsite_show_message("You are no longer participating in {$group['title']}!");
             drupal_goto($args['groups_page_path']);
         } else {
             return self::abort('An error occurred whilst trying to update your group membership.');
         }
     } else {
         // First access of the form. Let's get confirmation
         $reload = data_entry_helper::get_reload_link_parts();
         $reloadpath = $reload['path'] . '?' . data_entry_helper::array_to_query_string($reload['params']);
         $r = '<form action="' . $reloadpath . '" method="POST"><fieldset>';
         $r .= '<legend>' . lang::get('Confirmation') . '</legend>';
         $r .= '<input type="hidden" name="leave" value="1" />';
         $r .= '<p>' . lang::get('Are you sure you want to stop participating in {1}?', $group['title']) . '</p>';
         $r .= '<input type="submit" value="' . lang::get('Confirm') . '" name="response" />';
         $r .= '<input type="submit" value="' . lang::get('Cancel') . '" name="response" />';
         $r .= '</fieldset></form>';
     }
     return $r;
 }
예제 #3
0
/**
 * Code to output a standardised report filtering panel.
 *
 * Filters can be saved and loaded by each user. Additionally, filters can define permissions to a certain task, e.g. they can be used to define the
 * context within which someone can verify. In this case they provide the "outer limit" of the available records.
 * Requires a [map] control on the page. If you don't want a map, the current option is to include one anyway and use css to hide the #map-container div.
 *
 * @param array $readAuth Pass read authorisation tokens.
 * @param array $options Options array with the following possibilities:
 *   sharing - define the record sharing task that is being filtered against. Options are reporting (default), peer_review, verification, moderation, data_flow.
 *   context_id - can also be passed as URL parameter. Force the initial selection of a particular context (a record which has defines_permissions=true in the
 *   filters table. Set to "default" to select their profile verification settings when sharing=verification.
 *   filter_id - can also be passed as URL parameter. Force the initial selection of a particular filter record in the filters table.
 *   filterTypes - allows control of the list of filter panels available, e.g. to turn one off. Associative array keyed by category
 *   so that the filter panels can be grouped (use a blank key if not required). The array values are an array of or strings with a comma separated list
 *   of the filter types to included in the category - options are what, where, when, who, quality, source.
 *   filter-#name# - set the initial value of a report filter parameter #name#.
 *   allowLoad - set to false to disable the load bar at the top of the panel.
 *   allowSave - set to false to disable the save bar at the foot of the panel.
 *   presets - provide an array of preset filters to provide in the filters drop down. Choose from my-records, my-groups (uses
 *     your list of taxon groups in the user account), my-locality (uses your recording locality from the user account),
 *     my-groups-locality (uses taxon groups and recording locality from the user account), my-queried-records, queried-records,
 *     answered-records, accepted-records, not-accepted-records.
 * @param integer $website_id The current website's warehouse ID.
 * @param string $hiddenStuff Output parameter which will contain the hidden popup HTML that will be shown
 * using fancybox during filter editing. Should be appended AFTER any form element on the page as nested forms are not allowed.
 * @return string HTML for the report filter panel
 */
function report_filter_panel($readAuth, $options, $website_id, &$hiddenStuff)
{
    if (function_exists('iform_load_helpers')) {
        iform_load_helpers(array('report_helper'));
    } else {
        //When running on warehouse we don't have iform_load_helpers
        require_once DOCROOT . 'client_helpers/report_helper.php';
    }
    if (!empty($_POST['filter:sharing'])) {
        $options['sharing'] = $_POST['filter:sharing'];
    }
    $options = array_merge(array('sharing' => 'reporting', 'admin' => false, 'adminCanSetSharingTo' => array('R' => 'reporting', 'V' => 'verification'), 'allowLoad' => true, 'allowSave' => true, 'redirect_on_success' => '', 'presets' => array('my-records', 'my-queried-records', 'my-queried-or-not-accepted-records', 'my-not-reviewed-records', 'my-accepted-records', 'my-groups', 'my-locality', 'my-groups-locality'), 'entity' => 'occurrence'), $options);
    // Introduce some extra quick filters useful for verifiers.
    if ($options['sharing'] === 'verification') {
        $options['presets'] = array_merge(array('queried-records', 'answered-records', 'accepted-records', 'not-accepted-records'), $options['presets']);
    }
    if ($options['entity'] === 'sample') {
        unset($options['presets']['my-groups']);
        unset($options['presets']['my-groups-locality']);
    }
    //If in the warehouse we don't need to worry about the iform master list.
    if (function_exists('variable_get')) {
        $options = array_merge(array('taxon_list_id' => variable_get('iform_master_checklist_id', 0)), $options);
    }
    $options['sharing'] = report_filters_sharing_code_to_full_term($options['sharing']);
    $options['sharingCode'] = report_filters_full_term_to_sharing_code($options['sharing']);
    if (!preg_match('/^(reporting|peer_review|verification|data_flow|moderation)$/', $options['sharing'])) {
        return 'The @sharing option must be one of reporting, peer_review, verification, data_flow or moderation (currently ' . $options['sharing'] . ').';
    }
    report_helper::add_resource('reportfilters');
    report_helper::add_resource('validation');
    report_helper::add_resource('fancybox');
    if (function_exists('hostsite_add_library')) {
        hostsite_add_library('collapse');
    }
    $filterData = report_filters_load_existing($readAuth, $options['sharingCode']);
    $existing = '';
    $contexts = '';
    // add some preset filters in
    //If in the warehouse we don't need to worry about user specific preferences when setting up milestones.
    if (function_exists('hostsite_get_user_field')) {
        foreach ($options['presets'] as $preset) {
            $title = false;
            switch ($preset) {
                case 'my-records':
                    if (hostsite_get_user_field('id')) {
                        $title = lang::get('My records');
                    }
                    break;
                case 'my-queried-records':
                    if (hostsite_get_user_field('id')) {
                        $title = lang::get('My queried records');
                    }
                    break;
                case 'my-queried-or-not-accepted-records':
                    if (hostsite_get_user_field('id')) {
                        $title = lang::get('My not accepted or queried records');
                    }
                    break;
                case 'my-not-reviewed-records':
                    if (hostsite_get_user_field('id')) {
                        $title = lang::get('My not reviewed records');
                    }
                    break;
                case 'my-accepted-records':
                    if (hostsite_get_user_field('id')) {
                        $title = lang::get('My accepted records');
                    }
                    break;
                case 'my-groups':
                    if (hostsite_get_user_field('taxon_groups', false, true)) {
                        $title = lang::get('Records in species groups I like to record');
                    }
                    break;
                case 'my-locality':
                    if (hostsite_get_user_field('location')) {
                        $title = lang::get('Records in the locality I generally record in');
                    }
                    break;
                case 'my-groups-locality':
                    if (hostsite_get_user_field('taxon_groups', false, true) && hostsite_get_user_field('location')) {
                        $title = lang::get('Records of my species groups in my locality');
                    }
                    break;
                case 'queried-records':
                    $title = lang::get('Queried records');
                    break;
                case 'answered-records':
                    $title = lang::get('Records with answers');
                    break;
                case 'accepted-records':
                    $title = lang::get('Accepted records');
                    break;
                case 'not-accepted-records':
                    $title = lang::get('Not accepted records');
                    break;
                default:
                    throw new exception("Unsupported preset {$preset} for the filter panel");
            }
            if ($title) {
                $presetFilter = array('id' => $preset, 'title' => $title, 'defines_permissions' => 'f');
                $filterData[] = $presetFilter;
            }
        }
        if (count($options['presets'])) {
            if ($groups = hostsite_get_user_field('taxon_groups', false, true)) {
                data_entry_helper::$javascript .= "indiciaData.userPrefsTaxonGroups='" . implode(',', $groups) . "';\n";
            }
            if ($location = hostsite_get_user_field('location')) {
                data_entry_helper::$javascript .= "indiciaData.userPrefsLocation=" . $location . ";\n";
            }
        }
        $contextDefs = array();
        if ($options['sharing'] === 'verification') {
            // apply legacy verification settings from their profile
            $location_id = hostsite_get_user_field('location_expertise');
            $taxon_group_ids = hostsite_get_user_field('taxon_groups_expertise', false, true);
            $survey_ids = hostsite_get_user_field('surveys_expertise', false, true);
            if ($location_id || $taxon_group_ids || $survey_ids) {
                $selected = !empty($options['context_id']) && $options['context_id'] === 'default' ? 'selected="selected" ' : '';
                $contexts .= "<option value=\"default\" {$selected}>" . lang::get('My verification records') . "</option>";
                $def = array();
                if ($location_id) {
                    // user profile geographic limits should always be based on an indexed location.
                    $def['indexed_location_id'] = $location_id;
                }
                if ($taxon_group_ids) {
                    $def['taxon_group_list'] = implode(',', $taxon_group_ids);
                    $def['taxon_group_names'] = array();
                    $groups = data_entry_helper::get_population_data(array('table' => 'taxon_group', 'extraParams' => $readAuth + array('id' => $taxon_group_ids)));
                    foreach ($groups as $group) {
                        $def['taxon_group_names'][$group['id']] = $group['title'];
                    }
                }
                if ($survey_ids) {
                    $def['survey_list'] = implode(',', array_filter($survey_ids));
                }
                $contextDefs['default'] = $def;
            }
        }
    }
    if (!empty($_GET['context_id'])) {
        $options['context_id'] = $_GET['context_id'];
    }
    if (!empty($_GET['filter_id'])) {
        $options['filter_id'] = $_GET['filter_id'];
    }
    if (!empty($_GET['filters_user_id'])) {
        $options['filters_user_id'] = $_GET['filters_user_id'];
    }
    foreach ($filterData as $filter) {
        if ($filter['defines_permissions'] === 't') {
            $selected = !empty($options['context_id']) && $options['context_id'] == $filter['id'] ? 'selected="selected" ' : '';
            $contexts .= "<option value=\"{$filter['id']}\" {$selected}>{$filter['title']}</option>";
            $contextDefs[$filter['id']] = json_decode($filter['definition']);
        } else {
            $selected = !empty($options['filter_id']) && $options['filter_id'] == $filter['id'] ? 'selected="selected" ' : '';
            $existing .= "<option value=\"{$filter['id']}\" {$selected}>{$filter['title']}</option>";
        }
    }
    $r = '<div id="standard-params" class="ui-widget">';
    if ($options['allowSave'] && $options['admin']) {
        if (empty($_GET['filters_user_id'])) {
            // new filter to create, so sharing type can be edited
            $reload = data_entry_helper::get_reload_link_parts();
            $reloadPath = $reload['path'];
            if (count($reload['params'])) {
                $reloadPath .= '?' . data_entry_helper::array_to_query_string($reload['params']);
            }
            $r .= "<form action=\"{$reloadPath}\" method=\"post\" >";
            $r .= data_entry_helper::select(array('label' => lang::get('Select filter type'), 'fieldname' => 'filter:sharing', 'lookupValues' => $options['adminCanSetSharingTo'], 'afterControl' => '<input type="submit" value="Go"/>', 'default' => $options['sharingCode']));
            $r .= '</form>';
        } else {
            // existing filter to edit, type is therefore fixed. JS will fill these values in.
            $r .= '<p>' . lang::get('This filter is for <span id="sharing-type-label"></span>.') . '</p>';
            $r .= data_entry_helper::hidden_text(array('fieldname' => 'filter:sharing'));
        }
    }
    if ($options['allowLoad']) {
        $r .= '<div class="header ui-toolbar ui-widget-header ui-helper-clearfix"><div><span id="active-filter-label">' . lang::get('New report') . '</span></div><span class="changed" style="display:none" title="This filter has been changed">*</span>';
        $r .= '<div>';
        if ($contexts) {
            data_entry_helper::$javascript .= "indiciaData.filterContextDefs = " . json_encode($contextDefs) . ";\n";
            if (count($contextDefs) > 1) {
                $r .= '<label for="context-filter">' . lang::get('Context:') . "</label><select id=\"context-filter\">{$contexts}</select>";
            } else {
                $keys = array_keys($contextDefs);
                $r .= '<input type="hidden" id="context-filter" value="' . $keys[0] . '" />';
            }
        }
        $r .= '<label for="select-filter">' . lang::get('Filter:') . '</label><select id="select-filter"><option value="" selected="selected">' . lang::get('Select filter') . "...</option>{$existing}</select>";
        $r .= '<button type="button" id="filter-apply">' . lang::get('Apply') . '</button>';
        $r .= '<button type="button" id="filter-reset" class="disabled">' . lang::get('Reset') . '</button>';
        $r .= '<button type="button" id="filter-build">' . lang::get('Create a filter') . '</button></div>';
        $r .= '</div>';
        $r .= '<div id="filter-details" style="display: none">';
        $r .= '<img src="' . data_entry_helper::$images_path . 'nuvola/close-22px.png" width="22" height="22" alt="Close filter builder" title="Close filter builder" class="button" id="filter-done"/>' . "\n";
    } else {
        $r .= '<div id="filter-details">';
        if (!empty($options['filter_id'])) {
            $r .= "<input type=\"hidden\" id=\"select-filter\" value=\"{$options['filter_id']}\"/>";
        } elseif (!empty($options['filters_user_id'])) {
            $r .= "<input type=\"hidden\" id=\"select-filters-user\" value=\"{$options['filters_user_id']}\"/>";
        }
    }
    $r .= '<div id="filter-panes">';
    if ($options['entity'] === 'occurrence') {
        $filters = array('filter_what' => new filter_what(), 'filter_where' => new filter_where(), 'filter_when' => new filter_when(), 'filter_who' => new filter_who(), 'filter_occurrence_id' => new filter_occurrence_id(), 'filter_quality' => new filter_quality(), 'filter_source' => new filter_source());
    } elseif ($options['entity'] === 'sample') {
        $filters = array('filter_where' => new filter_where(), 'filter_when' => new filter_when(), 'filter_who' => new filter_who(), 'filter_sample_id' => new filter_sample_id(), 'filter_quality' => new filter_quality_sample(), 'filter_source' => new filter_source());
    }
    if (!empty($options['filterTypes'])) {
        $filterModules = array();
        foreach ($options['filterTypes'] as $category => $list) {
            // $list can be an array or comma separated list
            if (is_array($list)) {
                $list = implode(',', $list);
            }
            $paneNames = 'filter_' . str_replace(',', ',filter_', $list);
            $paneList = explode(',', $paneNames);
            $filterModules[$category] = array_intersect_key($filters, array_fill_keys($paneList, 1));
        }
    } else {
        $filterModules = array('' => $filters);
    }
    foreach ($filterModules as $category => $list) {
        if ($category) {
            $r .= '<fieldset class="collapsible collapsed">' . '<legend>' . '<span class="fieldset-legend">' . $category . '</span>' . '</legend>' . '<div class="fieldset-wrapper">';
        }
        foreach ($list as $moduleName => $module) {
            $r .= "<div class=\"pane\" id=\"pane-{$moduleName}\"><a class=\"fb-filter-link\" href=\"#controls-{$moduleName}\"><span class=\"pane-title\">" . $module->get_title() . '</span>';
            $r .= '<span class="filter-desc"></span></a>';
            $r .= "</div>";
        }
        if ($category) {
            $r .= '</div></fieldset>';
        }
    }
    $r .= '</div>';
    // filter panes
    $r .= '<div class="toolbar">';
    if ($options['allowSave']) {
        $r .= '<label for="filter:title">' . lang::get('Save filter as') . ':</label> <input id="filter:title" class="control-width-5"/>';
        if ($options['admin']) {
            $r .= '<br/>';
            if (empty($options['adminCanSetSharingTo'])) {
                throw new exception('Report standard params panel in admin mode so adminCanSetSharingTo option must be populated.');
            }
            $r .= data_entry_helper::autocomplete(array('label' => 'For who?', 'fieldname' => 'filters_user:user_id', 'table' => 'user', 'valueField' => 'id', 'captionField' => 'person_name', 'formatFunction' => "function(item) { return item.person_name + ' (' + item.email_address + ')'; }", 'extraParams' => $readAuth + array('view' => 'detail'), 'class' => 'control-width-5'));
            $r .= data_entry_helper::textarea(array('label' => 'Description', 'fieldname' => 'filter:description'));
        }
        $r .= '<img src="' . data_entry_helper::$images_path . 'nuvola/save-22px.png" width="22" height="22" alt="Save filter" title="Save filter" class="button" id="filter-save"/>';
        $r .= '<img src="' . data_entry_helper::$images_path . 'trash-22px.png" width="22" height="22" alt="Bin this filter" title="Bin this filter" class="button disabled" id="filter-delete"/>';
    }
    $r .= '</div></div>';
    // toolbar + clearfix
    if (!empty($options['filters_user_id'])) {
        // if we are preloading based on a filter user ID, we need to get the information now so that the sharing mode can be known
        // when loading controls
        $fu = data_entry_helper::get_population_data(array('table' => 'filters_user', 'extraParams' => $readAuth + array('id' => $options['filters_user_id']), 'caching' => false));
        if (count($fu) !== 1) {
            throw new exception('Could not find filter user record');
        }
        $options['sharing'] = report_filters_sharing_code_to_full_term($fu[0]['filter_sharing']);
    }
    report_helper::$javascript .= "indiciaData.lang={pleaseSelect:\"" . lang::get('Please select') . "\"};\n";
    // create the hidden panels required to populate the popups for setting each type of filter up.
    $hiddenStuff = '';
    foreach ($filterModules as $category => $list) {
        foreach ($list as $moduleName => $module) {
            $hiddenStuff .= "<div style=\"display: none\"><div class=\"filter-popup\" id=\"controls-{$moduleName}\"><form action=\"#\" class=\"filter-controls\"><fieldset>" . $module->get_controls($readAuth, $options) . '<button class="fb-close" type="button">Cancel</button>' . '<button class="fb-apply" type="submit">Apply</button></fieldset></form></div></div>';
            $shortName = str_replace('filter_', '', $moduleName);
            report_helper::$javascript .= "indiciaData.lang.NoDescription{$shortName}='" . lang::get('Click to Filter ' . ucfirst($shortName)) . "';\n";
        }
    }
    $r .= '</div>';
    report_helper::$js_read_tokens = $readAuth;
    report_helper::$javascript .= "indiciaData.lang.CreateAFilter='" . lang::get('Create a filter') . "';\n";
    report_helper::$javascript .= "indiciaData.lang.ModifyFilter='" . lang::get('Modify filter') . "';\n";
    report_helper::$javascript .= "indiciaData.lang.FilterReport='" . lang::get('New report') . "';\n";
    report_helper::$javascript .= "indiciaData.lang.FilterSaved='" . lang::get('The filter has been saved') . "';\n";
    report_helper::$javascript .= "indiciaData.lang.FilterDeleted='" . lang::get('The filter has been deleted') . "';\n";
    report_helper::$javascript .= "indiciaData.lang.ConfirmFilterChangedLoad='" . lang::get('Do you want to load the selected filter and lose your current changes?') . "';\n";
    report_helper::$javascript .= "indiciaData.lang.FilterExistsOverwrite='" . lang::get('A filter with that name already exists. Would you like to overwrite it?') . "';\n";
    report_helper::$javascript .= "indiciaData.lang.AutochecksFailed='" . lang::get('Automated checks failed') . "';\n";
    report_helper::$javascript .= "indiciaData.lang.AutochecksPassed='" . lang::get('Automated checks passed') . "';\n";
    report_helper::$javascript .= "indiciaData.lang.HasPhotos='" . lang::get('Records which have photos') . "';\n";
    report_helper::$javascript .= "indiciaData.lang.ConfirmFilterDelete='" . lang::get('Are you sure you want to permanently delete the {title} filter?') . "';\n";
    report_helper::$javascript .= "indiciaData.lang.MyRecords='" . lang::get('My records only') . "';\n";
    if (function_exists('iform_ajaxproxy_url')) {
        report_helper::$javascript .= "indiciaData.filterPostUrl='" . iform_ajaxproxy_url(null, 'filter') . "';\n";
        report_helper::$javascript .= "indiciaData.filterAndUserPostUrl='" . iform_ajaxproxy_url(null, 'filter_and_user') . "';\n";
    }
    report_helper::$javascript .= "indiciaData.filterSharing='" . strtoupper(substr($options['sharing'], 0, 1)) . "';\n";
    if (function_exists('hostsite_get_user_field')) {
        report_helper::$javascript .= "indiciaData.user_id='" . hostsite_get_user_field('indicia_user_id') . "';\n";
    } else {
        report_helper::$javascript .= "indiciaData.user_id='" . $_SESSION['auth_user']->id . "';\n";
    }
    if (!empty($website_id)) {
        report_helper::$javascript .= "indiciaData.website_id=" . $website_id . ";\n";
    }
    report_helper::$javascript .= "indiciaData.redirectOnSuccess='{$options['redirect_on_success']}';\n";
    // load up the filter, BEFORE any AJAX load of the grid code. First fetch any URL param overrides.
    $getParams = array();
    $optionParams = array();
    foreach ($_GET as $key => $value) {
        if (substr($key, 0, 7) === 'filter-') {
            $getParams[substr($key, 7)] = $value;
        }
    }
    foreach ($options as $key => $value) {
        if (substr($key, 0, 7) === 'filter-') {
            $optionParams[substr($key, 7)] = $value;
        }
    }
    $allParams = array_merge($optionParams, $getParams);
    if (!empty($allParams)) {
        $allParams = json_encode($allParams);
        report_helper::$onload_javascript .= "var params = {$allParams};\n";
        report_helper::$onload_javascript .= "indiciaData.filter.def=\$.extend(indiciaData.filter.def, params);\n";
        report_helper::$onload_javascript .= "indiciaData.filter.orig=\$.extend({}, params);\n";
    }
    $getParams = empty($getParams) ? '{}' : json_encode($getParams);
    if (!empty($options['filters_user_id'])) {
        report_helper::$onload_javascript .= "loadFilterUser(" . json_encode($fu[0]) . ", {$getParams});\n";
    } else {
        report_helper::$onload_javascript .= "if (\$('#select-filter').val()) {\n" . "  loadFilter(\$('#select-filter').val(), {$getParams});\n" . "} else {\n" . "  applyFilterToReports(false);\n" . "}\n";
    }
    return $r;
}
예제 #4
0
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  */
 public static function get_form($args, $node, $response = null)
 {
     // Do they have expert access?
     $expert = function_exists('user_access') && user_access($args['permission']);
     $conn = iform_get_connection_details($node);
     $readAuth = data_entry_helper::get_read_auth($conn['website_id'], $conn['password']);
     // Find out which types of filters and formats are available to the user
     $filters = self::get_filters($args, $readAuth);
     $formats = array();
     if ($args['csv_format'] === 'yes' || $args['csv_format'] === 'expert' && $expert) {
         $formats[] = 'csv';
     }
     if ($args['tsv_format'] === 'yes' || $args['tsv_format'] === 'expert' && $expert) {
         $formats[] = 'tsv';
     }
     if ($args['kml_format'] === 'yes' || $args['kml_format'] === 'expert' && $expert) {
         $formats[] = 'kml';
     }
     if ($args['gpx_format'] === 'yes' || $args['gpx_format'] === 'expert' && $expert) {
         $formats[] = 'gpx';
     }
     if ($args['nbn_format'] === 'yes' || $args['nbn_format'] === 'expert' && $expert) {
         $formats[] = 'nbn';
     }
     if (count($filters) === 0) {
         return 'This download page is configured so that no filter options are available.';
     }
     if (count($formats) === 0) {
         return 'This download page is configured so that no download format options are available.';
     }
     if (!empty($_POST)) {
         self::do_download($args, $filters);
     }
     iform_load_helpers(array('data_entry_helper'));
     $reload = data_entry_helper::get_reload_link_parts();
     $reloadPath = $reload['path'];
     if (count($reload['params'])) {
         $reloadPath .= '?' . helper_base::array_to_query_string($reload['params']);
     }
     $r = '<form method="POST" action="' . $reloadPath . '">';
     $r .= '<fieldset><legend>' . lang::get('Filters') . '</legend>';
     if (count($filters) === 0) {
         return 'This download page is configured so that no filter options are available.';
     } elseif (count($filters) === 1) {
         $r .= '<input type="hidden" name="user-filter" value="' . implode('', array_keys($filters)) . '"/>';
         // Since there is only one option, we may as well tell the user what it is.
         drupal_set_title(implode('', array_values($filters)));
         if (implode('', array_keys($filters)) === 'mine') {
             $r .= '<p>' . lang::get('Use this form to download your own records.') . '</p>';
         }
     } else {
         $r .= data_entry_helper::radio_group(array('label' => lang::get('User filter'), 'fieldname' => 'user-filter', 'lookupValues' => $filters, 'default' => empty($_POST['user-filter']) ? 'mine' : $_POST['user-filter']));
     }
     if (empty($args['survey_id'])) {
         // A survey picker when downloading my data
         $r .= '<div id="survey_all">';
         $r .= data_entry_helper::select(array('fieldname' => 'survey_id_all', 'label' => lang::get('Survey to include'), 'table' => 'survey', 'valueField' => 'id', 'captionField' => 'title', 'helpText' => 'Choose a survey, or <all> to not filter by survey.', 'blankText' => '<all>', 'class' => 'control-width-4', 'extraParams' => $readAuth + array('sharing' => 'data_flow', 'orderby' => 'title')));
         $r .= '</div>';
         // A survey picker when downloading data you are an expert for
         $surveys_expertise = hostsite_get_user_field('surveys_expertise');
         if ($surveys_expertise) {
             $surveys_expertise = unserialize($surveys_expertise);
             $surveysFilter = array('query' => json_encode(array('in' => array('id' => $surveys_expertise))));
         } else {
             // no filter as there are no specific surveys this user is an expert for
             $surveysFilter = array();
         }
         $r .= '<div id="survey_expertise">';
         $r .= data_entry_helper::select(array('fieldname' => 'survey_id_expert', 'label' => lang::get('Survey to include'), 'table' => 'survey', 'valueField' => 'id', 'captionField' => 'title', 'helpText' => 'Choose a survey, or <all> to not filter by survey.', 'blankText' => '<all>', 'class' => 'control-width-4', 'extraParams' => $readAuth + array('sharing' => 'verification', 'orderby' => 'title') + $surveysFilter));
         $r .= '</div>';
     }
     // Let the user pick the date range to download.
     $r .= data_entry_helper::date_picker(array('fieldname' => 'date_from', 'label' => lang::get('Start Date'), 'helpText' => 'Leave blank for no start date filter', 'class' => 'control-width-4'));
     $r .= data_entry_helper::date_picker(array('fieldname' => 'date_to', 'label' => lang::get('End Date'), 'helpText' => 'Leave blank for no end date filter', 'class' => 'control-width-4'));
     $r .= '</fieldset>';
     $r .= '<fieldset><legend>' . lang::get('Downloads') . '</legend>';
     $r .= '<label>Download options:</label>';
     if (in_array('csv', $formats)) {
         $r .= '<input class="inline-control" type="submit" name="format" value="' . lang::get('Spreadsheet (CSV)') . '"/>';
     }
     if (in_array('tsv', $formats)) {
         $r .= '<input class="inline-control" type="submit" name="format" value="' . lang::get('Tab Separated File (TSV)') . '"/>';
     }
     if (in_array('kml', $formats)) {
         $r .= '<input class="inline-control" type="submit" name="format" value="' . lang::get('Google Earth File') . '"/>';
     }
     if (in_array('gpx', $formats)) {
         $r .= '<input class="inline-control" type="submit" name="format" value="' . lang::get('GPS Track File') . '"/>';
     }
     if (in_array('nbn', $formats)) {
         $r .= '<input class="inline-control" type="submit" name="format" value="' . lang::get('NBN Format') . '"/>';
         $r .= '<p class="helpText">' . lang::get('Note that the NBN format download will only include verified data and excludes records where the date or spatial reference is not compatible with the NBN Gateway.') . '</p>';
     }
     $r .= '</fieldset></form>';
     return $r;
 }
 /** 
  * Retrieve the path to the current page, so the form can submit to itself.
  * @return string 
  */
 private static function getReloadPath()
 {
     $reload = data_entry_helper::get_reload_link_parts();
     $reloadPath = $reload['path'];
     if (count($reload['params'])) {
         // decode params prior to encoding to prevent double encoding.
         foreach ($reload['params'] as $key => $param) {
             $reload['params'][$key] = urldecode($param);
         }
         $reloadPath .= '?' . http_build_query($reload['params']);
     }
     return $reloadPath;
 }
 public static function get_occurrences_form($args, $node, $response)
 {
     global $user;
     if (!module_exists('iform_ajaxproxy')) {
         return 'This form must be used in Drupal with the Indicia AJAX Proxy module enabled.';
     }
     drupal_add_js('misc/tableheader.js');
     // for sticky heading
     data_entry_helper::add_resource('jquery_form');
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     // did the parent sample previously exist? Default is no.
     $existing = false;
     $url = explode('?', $args['my_obs_page'], 2);
     $params = NULL;
     $fragment = NULL;
     // fragment is always at the end.
     if (count($url) > 1) {
         $params = explode('#', $url[1], 2);
         if (count($params) > 1) {
             $fragment = $params[1];
         }
         $params = $params[0];
     } else {
         $url = explode('#', $url[0], 2);
         if (count($url) > 1) {
             $fragment = $url[1];
         }
     }
     $args['my_obs_page'] = url($url[0], array('query' => $params, 'fragment' => $fragment, 'absolute' => TRUE));
     if (isset($_POST['sample:id'])) {
         // have just posted an edit to the existing sample
         $sampleId = $_POST['sample:id'];
         $existing = true;
         data_entry_helper::load_existing_record($auth['read'], 'sample', $sampleId);
     } else {
         if (isset($response['outer_id'])) {
             // have just posted a new sample.
             $sampleId = $response['outer_id'];
         } else {
             $sampleId = $_GET['sample_id'];
             $existing = true;
         }
     }
     $sample = data_entry_helper::get_population_data(array('table' => 'sample', 'extraParams' => $auth['read'] + array('view' => 'detail', 'id' => $sampleId, 'deleted' => 'f')));
     $sample = $sample[0];
     $date = $sample['date_start'];
     if (!function_exists('module_exists') || !module_exists('easy_login')) {
         // work out the CMS User sample ID.
         $sampleMethods = helper_base::get_termlist_terms($auth, 'indicia:sample_methods', array('Field Observation'));
         $attributes = data_entry_helper::getAttributes(array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'sample_method_id' => $sampleMethods[0]['id']));
         if (false == ($cmsUserAttr = extract_cms_user_attr($attributes))) {
             return 'Easy Login not active: This form is designed to be used with the CMS User ID attribute setup for samples in the survey.';
         }
     }
     $allTaxonMeaningIdsAtSample = array();
     if ($existing) {
         // Only need to load the occurrences for a pre-existing sample
         $o = data_entry_helper::get_population_data(array('report' => 'reports_for_prebuilt_forms/UKBMS/ukbms_occurrences_list_for_sample', 'extraParams' => $auth['read'] + array('view' => 'detail', 'sample_id' => $sampleId, 'survey_id' => $args['survey_id'], 'date_from' => '', 'date_to' => '', 'taxon_group_id' => '', 'smpattrs' => '', 'occattrs' => $args['occurrence_attribute_ids']), 'nocache' => true));
         // build an array keyed for easy lookup
         $occurrences = array();
         $attrs = explode(',', $args['occurrence_attribute_ids']);
         if (!isset($o['error'])) {
             foreach ($o as $occurrence) {
                 if (!in_array($occurrence['taxon_meaning_id'], $allTaxonMeaningIdsAtSample)) {
                     $allTaxonMeaningIdsAtSample[] = $occurrence['taxon_meaning_id'];
                 }
                 $occurrences[$occurrence['taxon_meaning_id']] = array('ttl_id' => $occurrence['taxa_taxon_list_id'], 'ttl_id' => $occurrence['taxa_taxon_list_id'], 'preferred_ttl_id' => $occurrence['preferred_ttl_id'], 'o_id' => $occurrence['occurrence_id'], 'processed' => false);
                 foreach ($attrs as $attr) {
                     $occurrences[$occurrence['taxon_meaning_id']]['value_' . $attr] = $occurrence['attr_occurrence_' . $attr];
                     $occurrences[$occurrence['taxon_meaning_id']]['a_id_' . $attr] = $occurrence['attr_id_occurrence_' . $attr];
                 }
             }
         }
         // store it in data for JS to read when populating the grid
         data_entry_helper::$javascript .= "indiciaData.existingOccurrences = " . json_encode($occurrences) . ";\n";
     } else {
         data_entry_helper::$javascript .= "indiciaData.existingOccurrences = {};\n";
     }
     $occ_attributes = data_entry_helper::getAttributes(array('valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => 'occAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'multiValue' => false));
     data_entry_helper::$javascript .= "indiciaData.occurrence_totals = [];\n";
     data_entry_helper::$javascript .= "indiciaData.occurrence_attribute = [];\n";
     data_entry_helper::$javascript .= "indiciaData.occurrence_attribute_ctrl = [];\n";
     $defAttrOptions = array('extraParams' => $auth['read'] + array('orderby' => 'id'), 'suffixTemplate' => 'nosuffix');
     $occ_attributes_captions = array();
     foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
         $occ_attributes_captions[$idx] = $occ_attributes[$attr]['caption'];
         unset($occ_attributes[$attr]['caption']);
         $ctrl = data_entry_helper::outputAttribute($occ_attributes[$attr], $defAttrOptions);
         data_entry_helper::$javascript .= "indiciaData.occurrence_totals[" . $idx . "] = [];\n";
         data_entry_helper::$javascript .= "indiciaData.occurrence_attribute[" . $idx . "] = {$attr};\n";
         data_entry_helper::$javascript .= "indiciaData.occurrence_attribute_ctrl[" . $idx . "] = jQuery('" . str_replace("\n", "", $ctrl) . "');\n";
     }
     //    $r = "<h2>".$location[0]['name']." on ".$date."</h2>\n";
     $r = '<div id="tabs">';
     $tabs = array('#grid1' => t($args['species_tab_1']));
     // tab 1 is required.
     if (isset($args['taxon_list_id_2']) && $args['taxon_list_id_2'] != '') {
         $tabs['#grid2'] = t(isset($args['species_tab_2']) && $args['species_tab_2'] != '' ? $args['species_tab_2'] : 'Species Tab 2');
     }
     if (isset($args['taxon_list_id_3']) && $args['taxon_list_id_3'] != '') {
         $tabs['#grid3'] = t(isset($args['species_tab_3']) && $args['species_tab_3'] != '' ? $args['species_tab_3'] : 'Species Tab 3');
     }
     if (isset($args['taxon_list_id_4']) && $args['taxon_list_id_4'] != '') {
         $tabs['#grid4'] = t(isset($args['species_tab_4']) && $args['species_tab_4'] != '' ? $args['species_tab_4'] : 'Species Tab 4');
     }
     $tabs['#notes'] = lang::get('Notes');
     $r .= data_entry_helper::tab_header(array('tabs' => $tabs));
     data_entry_helper::enable_tabs(array('divId' => 'tabs', 'style' => 'Tabs'));
     // will assume that first table is based on abundance count, so do totals
     $r .= '<div id="grid1"><table id="observation-input1" class="ui-widget species-grid"><thead class="table-header"><tr><th class="ui-widget-header"></th>';
     foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
         $r .= '<th class="ui-widget-header col-' . ($idx + 1) . '">' . $occ_attributes_captions[$idx] . '</th>';
     }
     $r .= '<th class="ui-widget-header">' . lang::get('Total') . '</th></tr></thead>';
     $r .= '<tbody class="ui-widget-content occs-body"></tbody><tfoot><tr><td>Total</td>';
     foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
         $r .= '<td class="col-' . ($idx + 1) . ' ' . ($idx % 5 == 0 ? 'first' : '') . ' col-total"></td>';
     }
     $r .= '<td class="ui-state-disabled first"></td></tr></tfoot></table><br /><a href="' . $args['my_obs_page'] . '" class="button">' . lang::get('Finish') . '</a></div>';
     $extraParams = array_merge($auth['read'], array('taxon_list_id' => $args['taxon_list_id_1'], 'preferred' => 't', 'allow_data_entry' => 't', 'view' => 'cache', 'orderby' => 'taxonomic_sort_order'));
     if (!empty($args['taxon_filter_field_1']) && !empty($args['taxon_filter_1'])) {
         $extraParams[$args['taxon_filter_field_1']] = helper_base::explode_lines($args['taxon_filter_1']);
     }
     $taxa = data_entry_helper::get_population_data(array('table' => 'taxa_taxon_list', 'extraParams' => $extraParams));
     data_entry_helper::$javascript .= "indiciaData.speciesList1List = [";
     $first = true;
     foreach ($taxa as $taxon) {
         data_entry_helper::$javascript .= ($first ? "\n" : ",\n") . "{'id':" . $taxon['id'] . ",'taxon_meaning_id':" . $taxon['taxon_meaning_id'] . ",'preferred_language_iso':'" . $taxon["preferred_language_iso"] . "','default_common_name':'" . str_replace("'", "\\'", $taxon["default_common_name"]) . "'}";
         $first = false;
     }
     data_entry_helper::$javascript .= "];\n";
     data_entry_helper::$javascript .= "indiciaData.allTaxonMeaningIdsAtSample = [" . implode(',', $allTaxonMeaningIdsAtSample) . "];\n";
     if (isset($args['taxon_list_id_2']) && $args['taxon_list_id_2'] != '') {
         $r .= '<div id="grid2"><p id="grid2-loading">' . lang::get('Loading - Please Wait') . '</p><table id="observation-input2" class="ui-widget species-grid"><thead class="table-header"><tr><th class="ui-widget-header"></th>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<th class="ui-widget-header col-' . ($idx + 1) . '">' . $occ_attributes_captions[$idx] . '</th>';
         }
         $r .= '<th class="ui-widget-header">' . lang::get('Total') . '</th></tr></thead><tbody class="ui-widget-content occs-body"></tbody><tfoot><tr><td>Total</td>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<td class="col-' . ($idx + 1) . ' ' . ($idx % 5 == 0 ? 'first' : '') . ' col-total"></td>';
         }
         $r .= '<td class="ui-state-disabled first"></td></tr></tfoot></table><br /><a href="' . $args['my_obs_page'] . '" class="button">' . lang::get('Finish') . '</a></div>';
     }
     if (isset($args['taxon_list_id_3']) && $args['taxon_list_id_3'] != '') {
         $r .= '<div id="grid3"><p id="grid3-loading">' . lang::get('Loading - Please Wait') . '</p><table id="observation-input3" class="ui-widget species-grid"><thead class="table-header"><tr><th class="ui-widget-header"></th>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<th class="ui-widget-header col-' . ($idx + 1) . '">' . $occ_attributes_captions[$idx] . '</th>';
         }
         $r .= '<th class="ui-widget-header">' . lang::get('Total') . '</th></tr></thead><tbody class="ui-widget-content occs-body"></tbody><tfoot><tr><td>Total</td>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<td class="col-' . ($idx + 1) . ' ' . ($idx % 5 == 0 ? 'first' : '') . ' col-total"></td>';
         }
         $r .= '<td class="ui-state-disabled first"></td></tr></tfoot></table><br /><a href="' . $args['my_obs_page'] . '" class="button">' . lang::get('Finish') . '</a></div>';
     }
     if (isset($args['taxon_list_id_4']) && $args['taxon_list_id_4'] != '') {
         $r .= '<div id="grid4"><p id="grid4-loading">' . lang::get('Loading - Please Wait') . '</p><table id="observation-input4" class="ui-widget species-grid"><thead class="table-header"><tr><th class="ui-widget-header"></th>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<th class="ui-widget-header col-' . ($idx + 1) . '">' . $occ_attributes_captions[$idx] . '</th>';
         }
         $r .= '<th class="ui-widget-header">' . lang::get('Total') . '</th></tr></thead><tbody class="ui-widget-content occs-body"></tbody><tfoot><tr><td>Total</td>';
         foreach (explode(',', $args['occurrence_attribute_ids']) as $idx => $attr) {
             $r .= '<td class="col-' . ($idx + 1) . ' ' . ($idx % 5 == 0 ? 'first' : '') . ' col-total"></td>';
         }
         $r .= '<td class="ui-state-disabled first"></td></tr></tfoot></table>';
         $r .= '<label for="taxonLookupControl4" class="auto-width">' . lang::get('Add species to list') . ':</label> <input id="taxonLookupControl4" name="taxonLookupControl4" >';
         $r .= '<br /><a href="' . $args['my_obs_page'] . '" class="button">' . lang::get('Finish') . '</a></div>';
     }
     // for the comment form, we want to ensure that if there is a timeout error that it reloads the
     // data as stored in the DB.
     $reload = data_entry_helper::get_reload_link_parts();
     $reload['params']['sample_id'] = $parentSampleId;
     unset($reload['params']['new']);
     $reloadPath = $reload['path'];
     if (count($reload['params'])) {
         // decode params prior to encoding to prevent double encoding.
         foreach ($reload['params'] as $key => $param) {
             $reload['params'][$key] = urldecode($param);
         }
         $reloadPath .= '?' . http_build_query($reload['params']);
     }
     // fragment is always at the end. discard this.
     $reloadPath = explode('#', $reloadPath, 2);
     $reloadPath = $reloadPath[0];
     $r .= "<div id=\"notes\"><form method=\"post\" id=\"notes_form\" action=\"" . $reloadPath . "#notes\">\n";
     $r .= $auth['write'];
     $r .= '<input type="hidden" name="sample:id" value="' . $sampleId . '" />' . '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>' . '<input type="hidden" name="survey_id" value="' . $args['survey_id'] . '"/>' . '<input type="hidden" name="page" value="notes"/>';
     $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('When using this page, please remember that the data is not saved to the database as you go (which is the case for the previous tabs). In order to save the data entered in this page you must click on the Submit button at the bottom of the page.') . '</p>';
     $r .= data_entry_helper::textarea(array('fieldname' => 'sample:comment', 'label' => lang::get('Notes'), 'helpText' => "Use this space to input comments about this week's walk."));
     $r .= '<input type="submit" value="' . lang::get('Submit') . '" id="save-button"/></form>';
     $r .= '<br /><a href="' . $args['my_walks_page'] . '" class="button">' . lang::get('Finish') . '</a></div></div>';
     // enable validation on the comments form in order to include the simplified ajax queuing for the autocomplete.
     data_entry_helper::enable_validation('notes_form');
     // A stub form for AJAX posting when we need to create an occurrence
     $r .= '<form style="display: none" id="occ-form" method="post" action="' . iform_ajaxproxy_url($node, 'occurrence') . '">';
     $r .= '<input name="website_id" value="' . $args['website_id'] . '"/>';
     $r .= '<input name="occurrence:id" id="occid" />';
     $r .= '<input name="occurrence:taxa_taxon_list_id" id="ttlid" />';
     $r .= '<input name="occurrence:sample_id" value="' . $sampleId . '"/>';
     $r .= '<input name="occAttr:" id="occattr"/>';
     $r .= '<input name="transaction_id" id="transaction_id"/>';
     $r .= '<input name="user_id" value="' . hostsite_get_user_field('user_id', 1) . '"/>';
     $r .= '</form>';
     // tell the Javascript where to get species from.
     data_entry_helper::add_resource('jquery_ui');
     data_entry_helper::add_resource('json');
     data_entry_helper::add_resource('autocomplete');
     data_entry_helper::$javascript .= "indiciaData.speciesList1 = " . $args['taxon_list_id_1'] . ";\n";
     if (!empty($args['taxon_filter_field_1']) && !empty($args['taxon_filter_1'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesList1FilterField = '" . $args['taxon_filter_field_1'] . "';\n";
         $filterLines = helper_base::explode_lines($args['taxon_filter_1']);
         data_entry_helper::$javascript .= "indiciaData.speciesList1FilterValues = '" . json_encode($filterLines) . "';\n";
     }
     data_entry_helper::$javascript .= "indiciaData.speciesList2 = " . (isset($args['taxon_list_id_2']) && $args['taxon_list_id_2'] != "" ? $args['taxon_list_id_2'] : "-1") . ";\n";
     if (!empty($args['taxon_filter_field_2']) && !empty($args['taxon_filter_2'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesList2FilterField = '" . $args['taxon_filter_field_2'] . "';\n";
         $filterLines = helper_base::explode_lines($args['taxon_filter_2']);
         data_entry_helper::$javascript .= "indiciaData.speciesList2FilterValues = " . json_encode($filterLines) . ";\n";
     }
     data_entry_helper::$javascript .= "indiciaData.speciesList3 = " . (isset($args['taxon_list_id_3']) && $args['taxon_list_id_3'] != "" ? $args['taxon_list_id_3'] : "-1") . ";\n";
     if (!empty($args['taxon_filter_field_3']) && !empty($args['taxon_filter_3'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesList3FilterField = '" . $args['taxon_filter_field_3'] . "';\n";
         $filterLines = helper_base::explode_lines($args['taxon_filter_3']);
         data_entry_helper::$javascript .= "indiciaData.speciesList3FilterValues = " . json_encode($filterLines) . ";\n";
     }
     data_entry_helper::$javascript .= "indiciaData.speciesList4 = " . (isset($args['taxon_list_id_4']) && $args['taxon_list_id_4'] != "" ? $args['taxon_list_id_4'] : "-1") . ";\n";
     if (!empty($args['taxon_filter_field_4']) && !empty($args['taxon_filter_4'])) {
         data_entry_helper::$javascript .= "indiciaData.speciesList4FilterField = '" . $args['taxon_filter_field_4'] . "';\n";
         $filterLines = helper_base::explode_lines($args['taxon_filter_4']);
         data_entry_helper::$javascript .= "indiciaData.speciesList4FilterValues = " . json_encode($filterLines) . ";\n";
     }
     // allow js to do AJAX by passing in the information it needs to post forms
     data_entry_helper::$javascript .= "bindSpeciesAutocomplete(\"taxonLookupControl4\",\"table#observation-input4\",\"" . data_entry_helper::$base_url . "index.php/services/data\", indiciaData.speciesList4,\n  indiciaData.speciesList4FilterField, indiciaData.speciesList4FilterValues, {\"auth_token\" : \"" . $auth['read']['auth_token'] . "\", \"nonce\" : \"" . $auth['read']['nonce'] . "\"},\n  \"" . lang::get('LANG_Duplicate_Taxon') . "\", 25, 4);\n\n";
     data_entry_helper::$javascript .= "indiciaData.indiciaSvc = '" . data_entry_helper::$base_url . "';\n";
     data_entry_helper::$javascript .= "indiciaData.readAuth = {nonce: '" . $auth['read']['nonce'] . "', auth_token: '" . $auth['read']['auth_token'] . "'};\n";
     data_entry_helper::$javascript .= "indiciaData.sample = " . $sampleId . ";\n";
     if (function_exists('module_exists') && module_exists('easy_login')) {
         data_entry_helper::$javascript .= "indiciaData.easyLogin = true;\n";
         $userId = hostsite_get_user_field('indicia_user_id');
         if (!empty($userId)) {
             data_entry_helper::$javascript .= "indiciaData.UserID = " . $userId . ";\n";
         } else {
             return '<p>Easy Login active but could not identify user</p>';
         }
         // something is wrong
     } else {
         data_entry_helper::$javascript .= "indiciaData.easyLogin = false;\n";
         data_entry_helper::$javascript .= "indiciaData.CMSUserAttrID = " . $cmsUserAttr['attributeId'] . ";\n";
         data_entry_helper::$javascript .= "indiciaData.CMSUserID = " . $user->uid . ";\n";
     }
     // Do an AJAX population of the grid rows.
     data_entry_helper::$javascript .= "loadSpeciesList();\njQuery('#tabs').bind('tabsshow', function(event, ui) {\n    var target = ui.panel;\n    // first get rid of any previous tables\n    jQuery('table.sticky-header').remove();\n    jQuery('table.sticky-enabled thead.tableHeader-processed').removeClass('tableHeader-processed');\n    jQuery('table.sticky-enabled.tableheader-processed').removeClass('tableheader-processed');\n    jQuery('table.species-grid.sticky-enabled').removeClass('sticky-enabled');\n    var table = jQuery('#'+target.id+' table.species-grid');\n    if(table.length > 0) {\n        table.addClass('sticky-enabled');\n        if(typeof Drupal.behaviors.tableHeader == 'object') // Drupal 7\n          Drupal.behaviors.tableHeader.attach(table.parent());\n        else // Drupal6 : it is a function\n          Drupal.behaviors.tableHeader(target);\n    }\n    // remove any hanging autocomplete select list.\n    jQuery('.ac_results').hide();\n});";
     return $r;
 }
   /**
    * Return the generated form output.
    * @return Form HTML.
    */
   public static function get_form($args, $node)
   {
       define("MODE_GRID", 0);
       define("MODE_NEW_SAMPLE", 1);
       define("MODE_EXISTING", 2);
       self::parse_defaults($args);
       self::getArgDefaults($args);
       self::$node = $node;
       // if we use locks, we want them to be distinct for each drupal user
       if (function_exists('profile_load_profile')) {
           // check we are in drupal
           global $user;
           data_entry_helper::$javascript .= "if (indicia && indicia.locks && indicia.locks.setUser) {\n        indicia.locks.setUser ('" . $user->uid . "');\n      }\n";
       }
       // hard-wire some 'dynamic' options to simplify the form. Todo: take out the dynamic code for these
       $args['subjectAccordion'] = false;
       $args['emailShow'] = false;
       $args['nameShow'] = false;
       $args['copyFromProfile'] = false;
       $args['multiple_subject_observation_mode'] = 'single';
       $args['extra_list_id'] = '';
       $args['occurrence_comment'] = false;
       $args['col_widths'] = '';
       $args['includeLocTools'] = false;
       $args['loctoolsLocTypeID'] = 0;
       $args['subject_observation_confidential'] = false;
       $args['observation_images'] = false;
       // Get authorisation tokens to update and read from the Warehouse.
       $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
       $svcUrl = self::warehouseUrl() . 'index.php/services';
       self::$auth = $auth;
       drupal_add_js(iform_media_folder_path() . 'js/jquery.form.js', 'module');
       $mode = isset($args['no_grid']) && $args['no_grid'] ? MODE_NEW_SAMPLE : MODE_GRID;
       // default mode when no grid set to false - display grid of existing data
       // mode MODE_EXISTING: display existing sample
       $loadedSampleId = null;
       $loadedSubjectObservationId = null;
       if ($_POST) {
           if (!array_key_exists('website_id', $_POST)) {
               // non Indicia POST, in this case must be the location allocations. add check to ensure we don't corrept the data by accident
               if (function_exists('iform_loctools_checkaccess') && iform_loctools_checkaccess($node, 'admin') && array_key_exists('mnhnld1', $_POST)) {
                   iform_loctools_deletelocations($node);
                   foreach ($_POST as $key => $value) {
                       $parts = explode(':', $key);
                       iform_loctools_insertlocation($node, $parts[2], $parts[1]);
                   }
               }
           } else {
               if (!is_null(data_entry_helper::$entity_to_load)) {
                   $mode = MODE_EXISTING;
                   // errors with new sample, entity populated with post, so display this data.
               }
           }
           // else valid save, so go back to gridview: default mode 0
       }
       if (array_key_exists('sample_id', $_GET) && $_GET['sample_id'] != '{sample_id}') {
           $mode = MODE_EXISTING;
           $loadedSampleId = $_GET['sample_id'];
       }
       if (array_key_exists('subject_observation_id', $_GET) && $_GET['subject_observation_id'] != '{subject_observation_id}') {
           $mode = MODE_EXISTING;
           // single subject_observation case
           $loadedSubjectObservationId = $_GET['subject_observation_id'];
           self::$subjectObservationIds = array($loadedSubjectObservationId);
       }
       if ($mode != MODE_EXISTING && array_key_exists('newSample', $_GET)) {
           $mode = MODE_NEW_SAMPLE;
           data_entry_helper::$entity_to_load = array();
       }
       // else default to mode MODE_GRID or MODE_NEW_SAMPLE depending on no_grid parameter
       self::$mode = $mode;
       // default mode  MODE_GRID : display grid of the samples to add a new one
       // or edit an existing one.
       if ($mode == MODE_GRID) {
           $r = '';
           // debug section
           if (!empty($args['debug_info']) && $args['debug_info']) {
               $r .= '<input type="button" value="Debug info" onclick="$(\'#debug-info-div\').slideToggle();" /><br />' . '<div id="debug-info-div" style="display: none;">';
               $r .= '<p>$_GET is:<br /><pre>' . print_r($_GET, true) . '</pre></p>';
               $r .= '<p>$_POST is:<br /><pre>' . print_r($_POST, true) . '</pre></p>';
               $r .= '<p>Entity to load is:<br /><pre>' . print_r(data_entry_helper::$entity_to_load, true) . '</pre></p>';
               $r .= '<p>Submission was:<br /><pre>' . print_r(self::$submission, true) . '</pre></p>';
               $r .= '<input type="button" value="Hide debug info" onclick="$(\'#debug-info-div\').slideToggle();" />';
               $r .= '</div>';
           }
           if (method_exists(get_called_class(), 'getHeaderHTML')) {
               $r .= call_user_func(array(get_called_class(), 'getHeaderHTML'), true, $args);
           }
           $attributes = data_entry_helper::getAttributes(array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']), false);
           $tabs = array('#sampleList' => lang::get('LANG_Main_Samples_Tab'));
           if ($args['includeLocTools'] && function_exists('iform_loctools_checkaccess') && iform_loctools_checkaccess($node, 'admin')) {
               $tabs['#setLocations'] = lang::get('LANG_Allocate_Locations');
           }
           if (method_exists(get_called_class(), 'getExtraGridModeTabs')) {
               $extraTabs = call_user_func(array(get_called_class(), 'getExtraGridModeTabs'), false, $auth['read'], $args, $attributes);
               if (is_array($extraTabs)) {
                   $tabs = $tabs + $extraTabs;
               }
           }
           if (count($tabs) > 1) {
               $r .= "<div id=\"controls\">" . data_entry_helper::enable_tabs(array('divId' => 'controls', 'active' => '#sampleList')) . "<div id=\"temp\"></div>";
               $r .= data_entry_helper::tab_header(array('tabs' => $tabs));
           }
           $r .= "<div id=\"sampleList\">" . call_user_func(array(get_called_class(), 'getSampleListGrid'), $args, $node, $auth, $attributes) . "</div>";
           if ($args['includeLocTools'] && function_exists('iform_loctools_checkaccess') && iform_loctools_checkaccess($node, 'admin')) {
               $r .= '
 <div id="setLocations">
   <form method="post">
     <input type="hidden" id="mnhnld1" name="mnhnld1" value="mnhnld1" /><table border="1"><tr><td></td>';
               $url = $svcUrl . '/data/location?mode=json&view=detail&auth_token=' . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&parent_id=NULL&orderby=name" . (isset($args['loctoolsLocTypeID']) && $args['loctoolsLocTypeID'] != '' ? '&location_type_id=' . $args['loctoolsLocTypeID'] : '');
               $session = curl_init($url);
               curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
               $entities = json_decode(curl_exec($session), true);
               $userlist = iform_loctools_listusers($node);
               foreach ($userlist as $uid => $a_user) {
                   $r .= '<td>' . $a_user->name . '</td>';
               }
               $r .= "</tr>";
               if (!empty($entities)) {
                   foreach ($entities as $entity) {
                       if (!$entity["parent_id"]) {
                           // only assign parent locations.
                           $r .= "<tr><td>" . $entity["name"] . "</td>";
                           $defaultuserids = iform_loctools_getusers($node, $entity["id"]);
                           foreach ($userlist as $uid => $a_user) {
                               $r .= '<td><input type="checkbox" name="location:' . $entity["id"] . ':' . $uid . (in_array($uid, $defaultuserids) ? '" checked="checked"' : '"') . '></td>';
                           }
                           $r .= "</tr>";
                       }
                   }
               }
               $r .= "</table>\n      <input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Save_Location_Allocations') . "\" />\n    </form>\n  </div>";
           }
           if (method_exists(get_called_class(), 'getExtraGridModeTabs')) {
               $r .= call_user_func(array(get_called_class(), 'getExtraGridModeTabs'), true, $auth['read'], $args, $attributes);
           }
           if (count($tabs) > 1) {
               // close tabs div if present
               $r .= "</div>";
           }
           if (method_exists(get_called_class(), 'getTrailerHTML')) {
               $r .= call_user_func(array(get_called_class(), 'getTrailerHTML'), true, $args);
           }
           return $r;
       }
       // from this point on, we are MODE_EXISTING or MODE_NEW_SAMPLE
       if ($mode == MODE_EXISTING && is_null(data_entry_helper::$entity_to_load)) {
           // only load if not in error situation
           // Displaying an existing sample. If we know the subject_observation ID, and don't know the sample ID
           // then we must get the sample id from the subject_observation data.
           if ($loadedSubjectObservationId && !$loadedSampleId) {
               data_entry_helper::load_existing_record($auth['read'], 'subject_observation', $loadedSubjectObservationId);
               $loadedSampleId = data_entry_helper::$entity_to_load['subject_observation:sample_id'];
           }
           data_entry_helper::$entity_to_load = self::reload_form_data($loadedSampleId, $args, $auth);
       }
       // get the sample attributes
       $attrOpts = array('id' => data_entry_helper::$entity_to_load['sample:id'], 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']);
       // select only the custom attributes that are for this sample method or all sample methods, if this
       // form is for a specific sample method.
       if (!empty($args['sample_method_id'])) {
           $attrOpts['sample_method_id'] = $args['sample_method_id'];
       }
       $attributes = data_entry_helper::getAttributes($attrOpts, false);
       // Check if Recorder details is included as a control.
       // If so, remove the recorder attributes from the $attributes array so not output anywhere else.
       $arr = helper_base::explode_lines($args['structure']);
       if (in_array('[recorder details]', $arr)) {
           $attrCount = count($attributes);
           for ($i = 0; $i < $attrCount; $i++) {
               if (strcasecmp($attributes[$i]['caption'], 'first name') === 0 || strcasecmp($attributes[$i]['caption'], 'last name') === 0 || strcasecmp($attributes[$i]['caption'], 'email') === 0) {
                   unset($attributes[$i]);
               }
           }
       }
       //// Make sure the form action points back to this page
       $reload = data_entry_helper::get_reload_link_parts();
       unset($reload['params']['sample_id']);
       unset($reload['params']['subject_observation_id']);
       unset($reload['params']['newSample']);
       $reloadPath = $reload['path'];
       // don't url-encode the drupal path id using dirty url
       $pathParam = function_exists('variable_get') && variable_get('clean_url', 0) == '0' ? 'q' : '';
       if (count($reload['params'])) {
           if ($pathParam === 'q' && array_key_exists('q', $reload['params'])) {
               $reloadPath .= '?q=' . $reload['params']['q'];
               unset($reload['params']['q']);
               if (count($reload['params'])) {
                   $reloadPath .= '&' . http_build_query($reload['params']);
               }
           } else {
               $reloadPath .= '?' . http_build_query($reload['params']);
           }
       }
       $r = "<form method=\"post\" id=\"entry_form\" action=\"{$reloadPath}\">\n";
       // debug section
       if (!empty($args['debug_info']) && $args['debug_info']) {
           $r .= '<input type="button" value="Debug info" onclick="$(\'#debug-info-div\').slideToggle();" /><br />' . '<div id="debug-info-div" style="display: none;">';
           $r .= '<p>$_GET is:<br /><pre>' . print_r($_GET, true) . '</pre></p>';
           $r .= '<p>$_POST is:<br /><pre>' . print_r($_POST, true) . '</pre></p>';
           $r .= '<p>Entity to load is:<br /><pre>' . print_r(data_entry_helper::$entity_to_load, true) . '</pre></p>';
           $r .= '<p>Submission was:<br /><pre>' . print_r(self::$submission, true) . '</pre></p>';
           $r .= '<input type="button" value="Hide debug info" onclick="$(\'#debug-info-div\').slideToggle();" />';
           $r .= '</div>';
       }
       // reset button
       $r .= '<input type="button" class="ui-state-default ui-corner-all" value="' . lang::get('Abandon Form and Reload') . '" ' . 'onclick="window.location.href=\'' . url('node/' . $node->nid, array('query' => 'newSample')) . '\'">';
       // clear all padlocks button
       $r .= ' <input type="button" class="ui-state-default ui-corner-all" value="' . lang::get('Clear All Padlocks') . '" ' . 'onclick="if (indicia && indicia.locks) indicia.locks.unlockRegion(\'body\');">';
       // Get authorisation tokens to update the Warehouse, plus any other hidden data.
       $hiddens = $auth['write'] . "<input type=\"hidden\" id=\"read_auth_token\" name=\"read_auth_token\" value=\"" . $auth['read']['auth_token'] . "\" />\n" . "<input type=\"hidden\" id=\"read_nonce\" name=\"read_nonce\" value=\"" . $auth['read']['nonce'] . "\" />\n" . "<input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n" . "<input type=\"hidden\" id=\"survey_id\" name=\"survey_id\" value=\"" . $args['survey_id'] . "\" />\n";
       if (!empty($args['sample_method_id'])) {
           $hiddens .= '<input type="hidden" name="sample:sample_method_id" value="' . $args['sample_method_id'] . '"/>';
       }
       if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
           $hiddens .= "<input type=\"hidden\" id=\"sample:id\" name=\"sample:id\" value=\"" . data_entry_helper::$entity_to_load['sample:id'] . "\" />\n";
       }
       // request automatic JS validation
       if (!isset($args['clientSideValidation']) || $args['clientSideValidation']) {
           data_entry_helper::enable_validation('entry_form');
           // override the default invalidHandler to activate the first accordion panels which has an error
           global $indicia_templates;
           $indicia_templates['invalid_handler_javascript'] = "function(form, validator) {\n          var tabselected=false;\n          var accordion\$=jQuery('.ui-accordion');\n          jQuery.each(validator.errorMap, function(ctrlId, error) {\n            // select the tab containing the first error control\n            var ctrl = jQuery('[name=' + ctrlId.replace(/:/g, '\\\\:').replace(/\\[/g, '\\\\[').replace(/]/g, '\\\\]') + ']');\n            if (!tabselected && typeof(tabs)!=='undefined') {\n              tabs.tabs('select',ctrl.filter('input,select').parents('.ui-tabs-panel')[0].id);\n              tabselected = true;\n            }\n            ctrl.parents('fieldset').removeClass('collapsed');\n            ctrl.parents('.fieldset-wrapper').show();\n            // for each accordion, activate the first panel which has an error\n            ctrl.parents('.ui-accordion-content').each(function (n) {\n              var acc\$ = \$(this).closest('.ui-accordion');\n              var accId = acc\$[0].id.replace(/:/g, '\\\\:').replace(/\\[/g, '\\\\[').replace(/]/g, '\\\\]');\n              if (accordion\$.is('#'+accId)) {\n                var header\$ = \$(this).prev('h3');\n                var accHeaderId = header\$.attr('id').replace(/:/g, '\\\\:').replace(/\\[/g, '\\\\[').replace(/]/g, '\\\\]');\n                acc\$.accordion('activate', '#'+accHeaderId);\n                accordion\$ = accordion\$.not('#'+accId);\n              }\n            });\n          });\n        }";
           // By default, validate doesn't validate any ':hidden' fields,
           // but we need to validate hidden with display: none; fields in accordions
           data_entry_helper::$javascript .= "jQuery.validator.setDefaults({ \n        ignore: \"input[type='hidden']\"\n      });\n";
       }
       if (method_exists(get_called_class(), 'getHeaderHTML')) {
           $r .= call_user_func(array(get_called_class(), 'getHeaderHTML'), true, $args);
       }
       if ($mode == MODE_EXISTING && ($loadedSampleId || $loadedSubjectObservationId)) {
           $existing = true;
       } else {
           $existing = false;
       }
       $hiddens .= get_user_profile_hidden_inputs($attributes, $args, $existing, $auth['read']);
       $customAttributeTabs = get_attribute_tabs($attributes);
       // remove added comment controls unless editing an existing sample
       if ($mode !== MODE_EXISTING || helper_base::$form_mode === 'ERRORS') {
           $controls = helper_base::explode_lines($args['structure']);
           $new_controls = array();
           foreach ($controls as $control) {
               if ($control !== '[show added sample comments]' && $control !== '[add sample comment]') {
                   $new_controls[] = $control;
               }
           }
           $args['structure'] = implode("\r\n", $new_controls);
       }
       $tabs = self::get_all_tabs($args['structure'], $customAttributeTabs);
       $r .= "<div id=\"controls\">\n";
       // Build a list of the tabs that actually have content
       $tabHtml = self::get_tab_html($tabs, $auth, $args, $attributes, $hiddens);
       // Output the dynamic tab headers
       if ($args['interface'] != 'one_page') {
           $headerOptions = array('tabs' => array());
           foreach ($tabHtml as $tab => $tabContent) {
               $alias = preg_replace('/[^a-zA-Z0-9]/', '', strtolower($tab));
               $tabtitle = lang::get("LANG_Tab_{$alias}");
               if ($tabtitle == "LANG_Tab_{$alias}") {
                   // if no translation provided, we'll just use the standard heading
                   $tabtitle = $tab;
               }
               $headerOptions['tabs']['#' . $alias] = $tabtitle;
           }
           $r .= data_entry_helper::tab_header($headerOptions);
           data_entry_helper::enable_tabs(array('divId' => 'controls', 'style' => $args['interface'], 'progressBar' => isset($args['tabProgress']) && $args['tabProgress'] == true));
       }
       // Output the dynamic tab content
       $pageIdx = 0;
       foreach ($tabHtml as $tab => $tabContent) {
           // get a machine readable alias for the heading
           $tabalias = preg_replace('/[^a-zA-Z0-9]/', '', strtolower($tab));
           $r .= '<div id="' . $tabalias . '">' . "\n";
           // For wizard include the tab title as a header.
           if ($args['interface'] == 'wizard') {
               $r .= '<h1>' . $headerOptions['tabs']['#' . $tabalias] . '</h1>';
           }
           $r .= $tabContent;
           // Add any buttons required at the bottom of the tab
           if ($args['interface'] == 'wizard') {
               $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => $pageIdx === 0 ? 'first' : ($pageIdx == count($tabHtml) - 1 ? 'last' : 'middle')));
           } elseif ($pageIdx == count($tabHtml) - 1 && !($args['interface'] == 'tabs' && $args['save_button_below_all_pages'])) {
               // last part of a non wizard interface must insert a save button, unless it is tabbed interface with save button beneath all pages
               $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" id=\"save-button\" value=\"" . lang::get('LANG_Save') . "\" />\n";
           }
           $pageIdx++;
           $r .= "</div>\n";
       }
       $r .= "</div>\n";
       if ($args['interface'] == 'tabs' && $args['save_button_below_all_pages']) {
           $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" id=\"save-button\" value=\"" . lang::get('LANG_Save') . "\" />\n";
       }
       if (!empty(data_entry_helper::$validation_errors)) {
           $r .= data_entry_helper::dump_remaining_errors();
       }
       $r .= "</form>";
       if (method_exists(get_called_class(), 'getTrailerHTML')) {
           $r .= call_user_func(array(get_called_class(), 'getTrailerHTML'), true, $args);
       }
       return $r;
   }
예제 #8
0
    /**
     * 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)
    {
        global $user, $indicia_templates;
        // put each param control in a div, which makes it easier to layout with CSS
        $indicia_templates['prefix'] = '<div id="container-{fieldname}" class="param-container">';
        $indicia_templates['suffix'] = '</div>';
        $indicia_user_id = self::get_indicia_user_id($args);
        $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
        $r = '';
        if ($_POST) {
            // dump out any errors that occurred on verification
            if (data_entry_helper::$validation_errors) {
                $r .= '<div class="page-notice ui-state-highlight ui-corner-all"><p>' . implode('</p></p>', array_values(data_entry_helper::$validation_errors)) . '</p></div>';
            } else {
                if (isset($_POST['email']) && !isset($response['error'])) {
                    // To send HTML mail, the Content-type header must be set
                    $headers = 'MIME-Version: 1.0' . "\r\n";
                    $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
                    $headers .= 'From: ' . $user->mail . PHP_EOL . "\r\n";
                    $headers .= 'Return-Path: ' . $user->mail . "\r\n";
                    if (isset($_POST['photoHTML'])) {
                        $emailBody = str_replace('[photo]', '<br/>' . $_POST['photoHTML'], $_POST['email_content']);
                    } else {
                        $emailBody = $_POST['email_content'];
                    }
                    $emailBody = str_replace("\n", "<br/>", $emailBody);
                    // Send email. Depends upon settings in php.ini being correct
                    $success = mail($_POST['email_to'], $_POST['email_subject'], wordwrap($emailBody, 70), $headers);
                    if ($success) {
                        $r .= '<div class="page-notice ui-state-highlight ui-corner-all"><p>An email was sent to ' . $_POST['email_to'] . '.</p></div>';
                    } else {
                        $r .= '<div class="page-notice ui-widget-content ui-corner-all ui-state-highlight left">The webserver is not correctly configured to send emails. Please send the following email manually: <br/>' . '<div id="manual-email"><span>To:</span><div>' . $_POST['email_to'] . '</div>' . '<span>Subject:</span><div>' . $_POST['email_subject'] . '</div>' . '<span>Content:</span><div>' . $emailBody . '</div>' . '</div></div><div style="clear: both">';
                    }
                } else {
                    if (isset($_POST['occurrence:record_status']) && isset($response['success']) && $args['emails_enabled']) {
                        $r .= self::get_notification_email_form($args, $response, $auth);
                    }
                }
            }
            if (isset($_POST['action']) && $_POST['action'] == 'send_to_verifier' && $args['log_send_to_verifier']) {
                $comment = str_replace(array('%email%', '%date%', '%user%'), array($_POST['email_to'], date('jS F Y'), $user->name), $args['log_send_to_verifier_comment']);
            } elseif (isset($_POST['action']) && ($_POST['action'] = 'general_comment')) {
                $comment = $_POST['comment'];
            }
            // If there is a comment to save, add it to the occurrence comments
            if (isset($comment)) {
                // get our own write tokens for this submission, as the main ones are used in the JavaScript form.
                $loggingAuth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
                $sub = data_entry_helper::wrap(array('comment' => $comment, 'occurrence_id' => $_POST['occurrence:id'], 'created_by_id' => $indicia_user_id), 'occurrence_comment');
                $logResponse = data_entry_helper::forward_post_to('occurrence_comment', $sub, $loggingAuth['write_tokens']);
                if (!array_key_exists('success', $logResponse)) {
                    $r .= data_entry_helper::dump_errors($response, false);
                }
            }
        }
        //extract fixed parameters for report grid.
        $params = explode(",", $args['fixed_params']);
        foreach ($params as $param) {
            $keyvals = explode("=", $param);
            $key = trim($keyvals[0]);
            $val = trim($keyvals[1]);
            $extraParams[$key] = $val;
        }
        // plus defaults which are not fixed
        $params = explode("\n", $args['param_defaults']);
        foreach ($params as $param) {
            $keyvals = explode("=", $param);
            $key = trim($keyvals[0]);
            $val = trim($keyvals[1]);
            $paramDefaults[$key] = $val;
        }
        $actions = array();
        if ($args['send_for_verification']) {
            // store authorisation details as a global in js, since some of the JavaScript needs to be able to access Indicia data
            data_entry_helper::$javascript .= 'auth=' . json_encode($auth) . ';';
            $actions[] = array('caption' => str_replace(' ', '&nbsp;', lang::get('Send to verifier')), 'class' => 'send_for_verification_btn', 'javascript' => 'indicia_send_to_verifier(\'{taxon}\', {occurrence_id}, ' . $user->uid . ', ' . $args['website_id'] . '); return false;');
            $r .= self::get_send_for_verification_form();
        }
        $actions[] = array('caption' => str_replace(' ', '&nbsp;', lang::get('Verify')), 'javascript' => 'indicia_verify(\'{taxon}\', {occurrence_id}, true, ' . $user->uid . '); return false;');
        $actions[] = array('caption' => str_replace(' ', '&nbsp;', lang::get('Reject')), 'javascript' => 'indicia_verify(\'{taxon}\', {occurrence_id}, false, ' . $user->uid . '); return false;');
        $actions[] = array('caption' => str_replace(' ', '&nbsp;', lang::get('Comments')), 'javascript' => 'indicia_comments(\'{taxon}\', {occurrence_id}, ' . $user->uid . ', \'' . $auth['read']['nonce'] . '\', \'' . $auth['read']['auth_token'] . '\'); return false;');
        if (isset($args['path_to_record_details_page']) && $args['path_to_record_details_page']) {
            $actions[] = array('caption' => str_replace(' ', '&nbsp;', lang::get('View details')), 'url' => '{rootFolder}' . $args['path_to_record_details_page'], 'urlParams' => array('occurrence_id' => '{occurrence_id}'));
        }
        // default columns behaviour is to just include anything returned by the report plus add an actions column
        $columns = array(array('display' => 'Actions', 'actions' => $actions));
        // this can be overridden
        if (isset($args['columns_config']) && !empty($args['columns_config'])) {
            $columns = array_merge(json_decode($args['columns_config'], true), $columns);
        }
        $r .= data_entry_helper::report_grid(array('id' => 'verification-grid', 'dataSource' => $args['report_name'], 'mode' => 'report', 'readAuth' => $auth['read'], 'columns' => $columns, 'rowId' => 'occurrence_id', 'itemsPerPage' => 10, 'autoParamsForm' => $args['auto_params_form'], 'extraParams' => $extraParams, 'paramDefaults' => $paramDefaults));
        // Put in a blank form, which lets JavaScript set the values and post the data.
        $r .= '
<form id="verify" method="post" action="">
  ' . $auth['write'] . '
  <input type="hidden" id="occurrence:id" name="occurrence:id" value="" />
  <input type="hidden" id="occurrence:record_status" name="occurrence:record_status" value="" />
  <input type="hidden" id="occurrence_comment:comment" name="occurrence_comment:comment" value="" />
  <input type="hidden" name="occurrence_comment:created_by_id" value="' . $indicia_user_id . '" />
  <input type="hidden" id="website_id" name="website_id" value="' . $args['website_id'] . '" />
  <input type="hidden" id="occurrence:verified_by_id" name="occurrence:verified_by_id" value="" />
</form>
';
        drupal_add_js('
var indicia_user_id = ' . $indicia_user_id . ';
var url = ' . json_encode(data_entry_helper::get_reload_link_parts()) . ';
var svc = "' . data_entry_helper::$base_url . 'index.php/services/data/";
var email_subject_send_to_verifier = "' . $args['email_subject_send_to_verifier'] . '";
var email_body_send_to_verifier = "' . str_replace(array("\r", "\n"), array('', '\\n'), $args['email_body_send_to_verifier']) . '";
', 'inline');
        /*.';
        
        ');*/
        return $r;
    }
 /**
  * Outputs the form for mapping columns to the import fields.
  * @param array $options Options array passed to the import control.
  */
 private static function upload_mappings_form($options)
 {
     //The Shorewatch importer only supports 4326 as this is required for the occurrence sample grid reference
     //calculations to work. This can be hardcoded.
     $_POST['sample:entered_sref_system'] = 4326;
     $_SESSION['importSettingsToCarryForward'] = $_POST;
     if (!file_exists($_SESSION['uploaded_file'])) {
         return lang::get('upload_not_available');
     }
     data_entry_helper::add_resource('jquery_ui');
     $filename = basename($_SESSION['uploaded_file']);
     // If the last step was skipped because the user did not have any settings to supply, presetSettings contains the presets.
     // Otherwise we'll use the settings form content which already in $_POST so will overwrite presetSettings.
     if (isset($options['presetSettings'])) {
         $settings = array_merge($options['presetSettings'], $_POST);
     } else {
         $settings = $_POST;
     }
     // only want defaults that actually have a value - others can be set on a per-row basis by mapping to a column
     foreach ($settings as $key => $value) {
         if (empty($value)) {
             unset($settings[$key]);
         }
     }
     //The Shorewatch importer only supports 4326 as this is required for the occurrence sample grid reference
     //calculations to work. This can be hardcoded.
     $settings['sample:entered_sref_system'] = 4326;
     // cache the mappings
     $metadata = array('settings' => json_encode($settings));
     $post = array_merge($options['auth']['write_tokens'], $metadata);
     $request = data_entry_helper::$base_url . "index.php/services/import/cache_upload_metadata?uploaded_csv={$filename}";
     $response = data_entry_helper::http_post($request, $post);
     if (!isset($response['output']) || $response['output'] != 'OK') {
         return "Could not upload the settings metadata. <br/>" . print_r($response, true);
     }
     $request = data_entry_helper::$base_url . "index.php/services/import/get_import_fields/" . $options['model'];
     $request .= '?' . data_entry_helper::array_to_query_string($options['auth']['read']);
     // include survey and website information in the request if available, as this limits the availability of custom attributes
     if (!empty($settings['website_id'])) {
         $request .= '&website_id=' . trim($settings['website_id']);
     }
     if (!empty($settings['survey_id'])) {
         $request .= '&survey_id=' . trim($settings['survey_id']);
     }
     $response = data_entry_helper::http_post($request, array());
     $fields = json_decode($response['output'], true);
     if (!is_array($fields)) {
         return "curl request to {$request} failed. Response " . print_r($response, true);
     }
     $request = str_replace('get_import_fields', 'get_required_fields', $request);
     $response = data_entry_helper::http_post($request);
     $responseIds = json_decode($response['output'], true);
     if (!is_array($responseIds)) {
         return "curl request to {$request} failed. Response " . print_r($response, true);
     }
     $model_required_fields = self::expand_ids_to_fks($responseIds);
     if (!empty($settings)) {
         $preset_fields = self::expand_ids_to_fks(array_keys($settings));
     } else {
         $preset_fields = array();
     }
     if (!empty($preset_fields)) {
         $unlinked_fields = array_diff_key($fields, array_combine($preset_fields, $preset_fields));
     } else {
         $unlinked_fields = $fields;
     }
     // only use the required fields that are available for selection - the rest are handled somehow else
     $unlinked_required_fields = array_intersect($model_required_fields, array_keys($unlinked_fields));
     ini_set('auto_detect_line_endings', 1);
     $handle = fopen($_SESSION['uploaded_file'], "r");
     $columns = fgetcsv($handle, 1000, ",");
     $reload = data_entry_helper::get_reload_link_parts();
     $reloadpath = $reload['path'] . '?' . data_entry_helper::array_to_query_string($reload['params']);
     self::clear_website_survey_fields($unlinked_fields, $settings);
     self::clear_website_survey_fields($unlinked_required_fields, $settings);
     $savedFieldMappings = array();
     // Note the Shorewatch importer doesn't currently support remembered fields, so set this to false (we are reusing a lot of the import_helper code, so leave the variable in the code as it already has proven reliability).
     self::$rememberingMappings = false;
     //  if the user checked the Remember All checkbox, save it in a variable
     if (isset($savedFieldMappings['RememberAll'])) {
         $checked['RememberAll'] = 'checked';
     }
     $r = "<form method=\"post\" id=\"entry_form\" action=\"{$reloadpath}\" class=\"iform\">\n" . '<p>' . lang::get('column_mapping_instructions') . '</p>' . '<div class="ui-helper-clearfix import-mappings-table"><table class="ui-widget ui-widget-content">' . '<thead class="ui-widget-header">' . "<tr><th>Column in CSV File</th><th>Maps to attribute</th>";
     if (self::$rememberingMappings) {
         $r .= "<th id='remember-all-header' name='remember-all-header'>" . lang::get('Remember choice?') . "<br/><input type='checkbox' name='RememberAll' id='RememberAll' value='1' title='Tick all boxes to remember every column mapping next time you import.' {$checked['RememberAll']} onclick='\n           if (this.checked) {\n             \$(\".rememberField\").attr(\"checked\",\"checked\")\n           } else {\n             \$(\".rememberField\").removeAttr(\"checked\")\n           }'/></th>";
     }
     $r .= '</tr></thead><tbody>';
     foreach ($columns as $column) {
         $colFieldName = preg_replace('/[^A-Za-z0-9]/', '_', $column);
         $r .= "<tr><td>{$column}</td><td><select name=\"{$colFieldName}\" id=\"{$colFieldName}\">";
         $r .= self::get_column_options($options['model'], $unlinked_fields, $column, ' ', $savedFieldMappings);
         $r .= "</select></td></tr>\n";
     }
     $r .= '</tbody>';
     $r .= '</table>';
     $r .= '<div id="required-instructions" class="import-mappings-instructions"><h2>' . lang::get('Tasks') . '</h2><span>' . lang::get('The following database attributes must be matched to a column in your import file before you can continue') . ':</span><ul></ul><br/></div>';
     $r .= '<div id="duplicate-instructions" class="import-mappings-instructions"><span id="duplicate-instruct">' . lang::get('There are currently two or more drop-downs allocated to the same value.') . '</span><ul></ul><br/></div></div>';
     $r .= '<input type="hidden" name="import_step" value="2" />';
     $r .= '<input type="submit" name="submit" id="submit" value="' . lang::get('Upload') . '" class="ui-corner-all ui-state-default button" />';
     $r .= '</form>';
     data_entry_helper::$javascript .= "function detect_duplicate_fields() {\n      var valueStore = [];\n      var duplicateStore = [];\n      var valueStoreIndex = 0;\n      var duplicateStoreIndex = 0;\n      \$.each(\$('#entry_form select'), function(i, select) {\n        if (valueStoreIndex==0) {\n          valueStore[valueStoreIndex] = select.value;\n          valueStoreIndex++;\n        } else {\n          for(i=0; i<valueStoreIndex; i++) {\n            if (select.value==valueStore[i] && select.value != '<" . lang::get('Not imported') . ">') {\n              duplicateStore[duplicateStoreIndex] = select.value;\n              duplicateStoreIndex++;\n            }\n             \n          }\n          valueStore[valueStoreIndex] = select.value;\n          valueStoreIndex++;\n        }      \n      })\n      if (duplicateStore.length==0) {\n        DuplicateAllowsUpload = 1;\n        \$('#duplicate-instruct').css('display', 'none');\n      } else {\n        DuplicateAllowsUpload = 0;\n        \$('#duplicate-instruct').css('display', 'inline');\n      }\n    }\n";
     data_entry_helper::$javascript .= "function update_required_fields() {\n      // copy the list of required fields\n      var fields = \$.extend(true, {}, required_fields);\n      \$('#required-instructions li').remove();\n      var sampleVagueDates = [];\n      // strip out the ones we have already allocated\n      \$.each(\$('#entry_form select'), function(i, select) {\n        delete fields[select.value];\n        // special case for vague dates - if we have a complete sample vague date, then can strike out the sample:date required field\n        if (select.value.substr(0,12)=='sample:date_') {\n          sampleVagueDates.push(select.value);\n        }\n      });\n      if (sampleVagueDates.length==3) {\n        // got a full vague date, so can remove the required date field\n        delete fields['sample:date'];\n      }\n      var output = '';\n      \$.each(fields, function(field, caption) {\n        output += '<li>'+caption+'</li>';\n      });\n      if (output==='') {\n        \$('#required-instructions').css('display', 'none');\n        RequiredAllowsUpload = 1;\n      } else {\n        \$('#required-instructions').css('display', 'inline');\n        RequiredAllowsUpload = 0;\n      }\n      if (RequiredAllowsUpload == 1 && DuplicateAllowsUpload == 1) {\n        \$('#submit').attr('disabled', false);\n      } else {\n        \$('#submit').attr('disabled', true);\n      }\n      \$('#required-instructions ul').html(output);\n    }\n";
     data_entry_helper::$javascript .= "required_fields={};\n";
     foreach ($unlinked_required_fields as $field) {
         $caption = $unlinked_fields[$field];
         if (empty($caption)) {
             $tokens = explode(':', $field);
             $fieldname = $tokens[count($tokens) - 1];
             $caption = lang::get(self::leadingCaps(preg_replace(array('/^fk_/', '/_id$/'), array('', ''), $fieldname)));
         }
         $caption = self::translate_field($field, $caption);
         data_entry_helper::$javascript .= "required_fields['{$field}']='{$caption}';\n";
     }
     data_entry_helper::$javascript .= "detect_duplicate_fields();\n";
     data_entry_helper::$javascript .= "update_required_fields();\n";
     data_entry_helper::$javascript .= "\$('#entry_form select').change(function() {detect_duplicate_fields(); update_required_fields();});\n";
     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 &lt;All&gt; to not filter by Hub. This is driven off the users currently allocated to the hub. This currently does not apply to the NBN download.', 'lookupValues' => $hubList, 'class' => 'control-width-5'));
     // End Cocoast Hub
     if (empty($args['survey_id'])) {
         // put up an empty surveys drop down. AJAX will populate it.
         $r .= data_entry_helper::select(array('fieldname' => 'survey_id', 'label' => lang::get('Survey to include'), 'helpText' => 'Choose a survey, or &lt;All&gt; to not filter by survey.', 'lookupValues' => array(), 'class' => 'control-width-5'));
     } else {
         $r .= '<input type="hidden" name="survey_id" value="' . $args['survey_id'] . '"/>';
     }
     // Let the user pick the date range to download.
     $r .= data_entry_helper::select(array('label' => lang::get('Date field'), 'fieldname' => 'date_type', 'lookupValues' => array('recorded' => lang::get('Field record date'), 'input' => lang::get('Input date'), 'edited' => lang::get('Last changed date'), 'verified' => 'Verification status change date'), 'helpText' => 'If filtering on date, which date field would you like to filter on?'));
     $r .= data_entry_helper::date_picker(array('fieldname' => 'date_from', 'label' => lang::get('Start Date'), 'helpText' => 'Leave blank for no start date filter', 'class' => 'control-width-4'));
     $r .= data_entry_helper::date_picker(array('fieldname' => 'date_to', 'label' => lang::get('End Date'), 'helpText' => 'Leave blank for no end date filter', 'class' => 'control-width-4'));
     $r .= '</fieldset>';
     if (!empty($args['custom_formats'])) {
         $customFormats = json_decode($args['custom_formats'], true);
         foreach ($customFormats as $idx => $format) {
             if (empty($format['permission']) || hostsite_user_has_permission($format['permission'])) {
                 $formats["custom-{$idx}"] = lang::get(isset($format['title']) ? $format['title'] : 'Untitled format');
             }
         }
     }
     if (count($formats) > 1) {
         $r .= '<fieldset><legend>' . lang::get('Select a format to download') . '</legend>';
         $keys = array_keys($formats);
         $r .= data_entry_helper::radio_group(array('fieldname' => 'format', 'lookupValues' => $formats, 'default' => $keys[0]));
         $r .= '</fieldset>';
     } else {
         // only allowed 1 format, so no need for a selection control
         $keys = array_keys($formats);
         $r .= '<input type="hidden" name="format" value="' . array_pop($keys) . '"/>';
     }
     $r .= '<input type="submit" value="' . lang::get('Download') . '"/></form>';
     data_entry_helper::$javascript .= 'indiciaData.ajaxUrl="' . url('iform/ajax/easy_download_2') . "\";\n";
     data_entry_helper::$javascript .= 'indiciaData.nid = "' . $nid . "\";\n";
     data_entry_helper::$javascript .= "setAvailableDownloadFilters();\n";
     return $r;
 }
예제 #11
0
 /**
  * Insert any custom JS for this form: this may be related to attributes, which are included
  * as part of inherited generic code.
  * Does not include any HTML.
  */
 protected static function get_control_customJS($auth, $args, $tabalias, $options)
 {
     $reload = data_entry_helper::get_reload_link_parts();
     $reloadPath = $reload['path'];
     if (lang::get('validation_required') != 'validation_required') {
         data_entry_helper::$late_javascript .= "\n\$.validator.messages.required = \"" . lang::get('validation_required') . "\";";
     }
     if (lang::get('validation_max') != 'validation_max') {
         data_entry_helper::$late_javascript .= "\n\$.validator.messages.max = \$.validator.format(\"" . lang::get('validation_max') . "\");";
     }
     if (lang::get('validation_min') != 'validation_min') {
         data_entry_helper::$late_javascript .= "\n\$.validator.messages.min = \$.validator.format(\"" . lang::get('validation_min') . "\");";
     }
     if (lang::get('validation_number') != 'validation_number') {
         data_entry_helper::$late_javascript .= "\n\$.validator.messages.number = \$.validator.format(\"" . lang::get('validation_number') . "\");";
     }
     if (lang::get('validation_digits') != 'validation_digits') {
         data_entry_helper::$late_javascript .= "\n\$.validator.messages.digits = \$.validator.format(\"" . lang::get('validation_digits') . "\");";
     }
     $numRows = 3;
     $numCols = 1;
     $startPos = 2;
     data_entry_helper::$javascript .= "\njQuery('<div class=\"ui-widget-content ui-state-default ui-corner-all indicia-button tab-cancel\"><span><a href=\"" . $reloadPath . "\">" . lang::get('LANG_Cancel') . "</a></span></div>').appendTo('.buttons');\n\ncheckRadioStatus = function(){\n  jQuery('[name^=locAttr]').filter(':radio').filter('[value=" . $args['siteTypeOtherTermID'] . "]').each(function(){\n    if(this.checked)\n      jQuery('[name=locAttr\\:" . $args['siteTypeOtherAttrID'] . "],[name^=locAttr\\:" . $args['siteTypeOtherAttrID'] . "\\:]').addClass('required').removeAttr('readonly');\n    else\n      jQuery('[name=locAttr\\:" . $args['siteTypeOtherAttrID'] . "],[name^=locAttr\\:" . $args['siteTypeOtherAttrID'] . "\\:]').removeClass('required').val('').attr('readonly',true);\n  });\n};\njQuery('[name^=locAttr]').filter(':radio').change(checkRadioStatus);\ncheckRadioStatus();\n\nvar other = jQuery('[name=locAttr\\:" . $args['siteTypeOtherAttrID'] . "],[name^=locAttr\\:" . $args['siteTypeOtherAttrID'] . "\\:]');\nother.next().remove(); // remove break\nother.prev().remove(); // remove legend\nother.remove(); // remove Other field, then bolt in after the other radio button.\njQuery('[name^=locAttr]').filter(':radio').filter('[value=" . $args['siteTypeOtherTermID'] . "]').parent().append(other);\n\nvar other = jQuery('[name=smpAttr\\:" . $args['entranceDefectiveCommentAttrID'] . "],[name^=smpAttr\\:" . $args['entranceDefectiveCommentAttrID'] . "\\:]');\nother.next().remove(); // remove break\nother.prev().remove(); // remove legend\nother.remove(); // remove Other field, then bolt in after the other radio button.\njQuery('[name^=smpAttr]').filter(':checkbox').filter('[value=" . $args['entranceDefectiveTermID'] . "]').parent().append(other);\n\nvar other = jQuery('[name=smpAttr\\:" . $args['disturbanceCommentAttrID'] . "],[name^=smpAttr\\:" . $args['disturbanceCommentAttrID'] . "\\:]');\nother.next().remove(); // remove break\nother.prev().remove(); // remove legend\nother.remove(); // remove Other field, then bolt in after the other radio button.\njQuery('[name^=smpAttr]').filter(':checkbox').filter('[value=" . $args['disturbanceOtherTermID'] . "]').parent().append(other);\n\ncheckCheckStatus = function(){\n  jQuery('[name^=smpAttr]').filter(':checkbox').filter('[value=" . $args['entranceDefectiveTermID'] . "]').each(function(){\n    if(this.checked) // note not setting the required flag.\n      jQuery('[name=smpAttr\\:" . $args['entranceDefectiveCommentAttrID'] . "],[name^=smpAttr\\:" . $args['entranceDefectiveCommentAttrID'] . "\\:]').removeAttr('readonly');\n    else\n      jQuery('[name=smpAttr\\:" . $args['entranceDefectiveCommentAttrID'] . "],[name^=smpAttr\\:" . $args['entranceDefectiveCommentAttrID'] . "\\:]').val('').attr('readonly',true);\n  });\n  jQuery('[name^=smpAttr]').filter(':checkbox').filter('[value=" . $args['disturbanceOtherTermID'] . "]').each(function(){\n    if(this.checked)\n      jQuery('[name=smpAttr\\:" . $args['disturbanceCommentAttrID'] . "],[name^=smpAttr\\:" . $args['disturbanceCommentAttrID'] . "\\:]').addClass('required').removeAttr('readonly');\n    else\n      jQuery('[name=smpAttr\\:" . $args['disturbanceCommentAttrID'] . "],[name^=smpAttr\\:" . $args['disturbanceCommentAttrID'] . "\\:]').removeClass('required').val('').attr('readonly',true);\n  });\n  };\njQuery('[name^=smpAttr]').filter(':checkbox').change(checkCheckStatus);\ncheckCheckStatus();\n\n// Two aspects: need to find scClonableRow, and then do existing rows in grid, and clear row being added.\nvar occAttrs = jQuery('.scClonableRow').find('.scOccAttrCell');\nvar newTable = jQuery('<table class=\"fullWidth\">');\nvar newElem = jQuery('<td class=\"noPadding\" >').append(newTable).insertBefore(occAttrs.filter(':first'));\nfor (var i=0;i<{$numRows};i++){\n\tswitch(i){";
     for ($i = 0; $i < $numRows; $i++) {
         data_entry_helper::$javascript .= "\n\t\tcase({$i}): jQuery(\"<tr><td class='scOccAttrCell ui-widget-content'>" . lang::get('SCLabel_Row' . ($i + 1)) . "</td></tr>\").appendTo(newTable); break;";
     }
     data_entry_helper::$javascript .= "\n\t}\n}\n// TBD\noccAttrs.find('input').filter(':text').addClass('digits').attr('min',1);\nfor (var i=0;i<occAttrs.length;i++){\n\tif(i%{$numRows} == 0){\n\t\tnewTable = jQuery('<table class=\"fullWidth\">');\n\t\tnewElem = jQuery('<td class=\"noPadding\">').append(newTable).insertAfter(newElem);\n\t}\n\tjQuery('<tr>').append(occAttrs[i]).appendTo(newTable);\n}\nvar CRgroup = jQuery('.scClonableRow').find('table').find('td');\n// Do main table header\noccAttrs = jQuery('.species-grid > thead').find('th');\nvar newElem = jQuery('<th>').insertBefore(occAttrs.filter(':eq({$startPos})'));\nfor (var i=0;i<{$numRows}*{$numCols};i++){\n\tjQuery(occAttrs[i+{$startPos}]).remove();\n}\nfor (var i=0;i<{$numCols};i++){\n\tswitch(i){";
     for ($i = 0; $i < $numCols; $i++) {
         data_entry_helper::$javascript .= "\n\t\tcase({$i}): newElem = jQuery(\"<th>" . lang::get('SCLabel_Col' . ($i + 1)) . "</th>\").insertAfter(newElem); break;";
     }
     data_entry_helper::$javascript .= "\n\t}\n}\n// Main table existing entries\nspeciesRows = jQuery('.species-grid > tbody').find('tr');\nfor(var j=0; j<speciesRows.length; j++){\n\toccAttrs = jQuery(speciesRows[j]).find('.scOccAttrCell');\n\tnewTable = jQuery('<table class=\"fullWidth\">');\n\tnewElem = jQuery('<td class=\"noPadding\" >').append(newTable).insertBefore(occAttrs.filter(':first'));\n\tfor (var i=0;i<{$numRows};i++){\n\t\tswitch(i){";
     for ($i = 0; $i < $numRows; $i++) {
         data_entry_helper::$javascript .= "\n\t\t\tcase({$i}): jQuery(\"<tr><td class='scOccAttrCell ui-widget-content'>" . lang::get('SCLabel_Row' . ($i + 1)) . "</td></tr>\").appendTo(newTable); break;";
     }
     data_entry_helper::$javascript .= "\n\t\t}\n\t}\n\toccAttrs.find('input').filter(':text').addClass('digits').attr('min',1);\n\tfor (var i=0;i<occAttrs.length;i++){\n\t\tif(i%{$numRows} == 0){\n\t\t\tnewTable = jQuery('<table class=\"fullWidth\">');\n\t\t\tnewElem = jQuery('<td class=\"noPadding\" >').append(newTable).insertAfter(newElem);\n\t\t}\n\t\tjQuery('<tr>').append(occAttrs[i]).appendTo(newTable);\n\t}\n\tvar group = jQuery(speciesRows[j]).find('table').find('td');\n\tvar tallest = 0;\n\tgroup.each(function(){ tallest = Math.max(\$(this).outerHeight(), tallest); });\n\tgroup.each(function(){ \n\t\t\$(this).height(tallest); });\n\tCRgroup.each(function(){ \n\t\t\$(this).height(tallest); });\n}\n";
     if (isset($args['col_widths']) && $args['col_widths']) {
         $colWidths = explode(',', $args['col_widths']);
         for ($i = 0; $i < count($colWidths); $i++) {
             data_entry_helper::$javascript .= "\njQuery('.species-grid > thead').find('th').filter(':eq(" . $i . ")').width('";
             if ($colWidths[$i] == '') {
                 data_entry_helper::$javascript .= "auto');";
             } else {
                 data_entry_helper::$javascript .= $colWidths[$i] . "%');";
             }
         }
     }
     // Move the Temperature and Humidity fields side by side.
     $removeBreakIDs = explode(';', $args['removeBreakIDs']);
     foreach ($removeBreakIDs as $removeBreakID) {
         $removeBreakID = str_replace(':', '\\:', $removeBreakID);
         data_entry_helper::$javascript .= "\njQuery('[name=" . $removeBreakID . "],[name^=" . $removeBreakID . "\\:]').css('margin-right', '20px').nextAll('br').eq(0).remove();";
     }
     if (!empty($args['attributeValidation'])) {
         $rules = array();
         $argRules = explode(';', $args['attributeValidation']);
         foreach ($argRules as $rule) {
             $rules[] = explode(',', $rule);
         }
         foreach ($rules as $rule) {
             // But only do if a parameter given as rule:param - eg min:-40
             for ($i = 1; $i < count($rule); $i++) {
                 if (strpos($rule[$i], ':') !== false) {
                     $details = explode(':', $rule[$i]);
                     data_entry_helper::$late_javascript .= "\njQuery('[name=" . str_replace(':', '\\:', $rule[0]) . "],[name^=" . str_replace(':', '\\:', $rule[0]) . "\\:]').attr('" . $details[0] . "'," . $details[1] . ");";
                 } else {
                     if ($rule[$i] == 'no_observation') {
                         data_entry_helper::$late_javascript .= "\njQuery('[name=" . str_replace(':', '\\:', $rule[0]) . "],[name^=" . str_replace(':', '\\:', $rule[0]) . "\\:]').filter(':checkbox').rules('add', {no_observation: true});\nhook_species_checklist_delete_row=function() {\n  var rows=jQuery('.species-grid > tbody > tr').not(':hidden').not('.scClonableRow').length;\n  if(rows==0)\n    jQuery('[name=" . str_replace(':', '\\:', $rule[0]) . "],[name^=" . str_replace(':', '\\:', $rule[0]) . "\\:]').removeAttr('disabled');\n  else\n    jQuery('[name=" . str_replace(':', '\\:', $rule[0]) . "],[name^=" . str_replace(':', '\\:', $rule[0]) . "\\:]').attr('disabled','disabled').removeAttr('checked');\n};\nhook_species_checklist_pre_delete_row=function(e) {\n    return confirm(\"" . lang::get('Are you sure you want to delete this row?') . "\");\n};\n// possible clash with link_species_popups, so latter disabled.\nhook_species_checklist_new_row=function(rowData) {\n  jQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/data/taxa_taxon_list/' + rowData.id +\n            '?mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&callback=?', function(mdata) {\n    if(mdata instanceof Array && mdata.length>0){\n      jQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/data/taxa_taxon_list' +\n            '?mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&taxon_meaning_id='+mdata[0].taxon_meaning_id+'&callback=?', function(data) {\n        var taxaList = '';\n        var duplicate=false;\n        if(data instanceof Array && data.length>0){\n          for (var i=0;i<data.length;i++){\n            if(data[i].id != mdata[0].id){\n              if(data[i].preferred == 'f')\n                taxaList += (taxaList == '' ? '' : ', ')+data[i].taxon;\n              else\n                taxaList = '<em>'+data[i].taxon+'</em>'+(taxaList == '' ? '' : ', '+taxaList);\n              if(jQuery('[name^=sc\\:'+data[i].id+'\\:]').length > 0)\n                duplicate=true;\n            } else\n              if(jQuery('[name^=sc\\:'+data[i].id+'\\:]').length > 8)\n                duplicate=true;\n          }\n          if(duplicate){\n            alert(\"" . lang::get('LANG_Duplicate_Taxon') . "\");\n            jQuery('.extraCommonNames').filter('[tID='+mdata[0].id+']').closest('tr').remove();\n          } else\n            jQuery('.extraCommonNames').filter('[tID='+mdata[0].id+']').append(' - '+taxaList).removeClass('extraCommonNames');\n        }\n      });\n    }})\n    hook_species_checklist_delete_row();\n}\nhook_species_checklist_delete_row();\n\$.validator.addMethod('no_observation', function(arg1, arg2){\nvar numChecked = jQuery('[name^=sc]').not(':hidden').not('[name^=sc\\:-ttlId-]').filter(':radio').filter('[checked=true]').length;\nvar numFilledIn = jQuery('[name^=sc]').not(':hidden').not('[name^=sc\\:-ttlId-]').not(':radio').filter('[value!=]').length;\nif(jQuery('[name='+jQuery(arg2).attr('name')+']').not(':hidden').filter('[checked=true]').length>0)\n // is checked.\n return(numChecked==0&&numFilledIn==0)\nelse if(numChecked>0||numFilledIn>0)\n return true;\n// there are no rows filled in, in which case ensure no obs can be filled in.\njQuery('[name=" . str_replace(':', '\\:', $rule[0]) . "],[name^=" . str_replace(':', '\\:', $rule[0]) . "\\:]').removeAttr('disabled','disabled');\nreturn false;\n},\n  \"" . lang::get('validation_no_observation') . "\");\n  ";
                     } else {
                         if (substr($rule[0], 3, 4) != 'Attr') {
                             // have to add for non attribute case.
                             data_entry_helper::$late_javascript .= "\njQuery('[name=" . str_replace(':', '\\:', $rule[0]) . "],[name^=" . str_replace(':', '\\:', $rule[0]) . "\\:]').addClass('" . $rule[$i] . "');";
                         }
                     }
                 }
             }
         }
     }
     if (array_key_exists('sample:id', data_entry_helper::$entity_to_load)) {
         data_entry_helper::$late_javascript .= "\nsetupButtons(\$('#controls'), 1);\nsetupButtons(\$('#controls'), 2);\nsetupButtons(\$('#controls'), 0);";
     }
     return '';
 }
예제 #12
0
    /**
     * Return the Indicia form code
     * @param array $args Input parameters.
     * @param array $node Drupal node object
     * @param array $response Response from Indicia services after posting a verification.
     * @return HTML string
     */
    public static function get_form($args, $node, $response)
    {
        $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
        $r = '';
        if ($_POST) {
            // dump out any errors that occurred on verification
            if (data_entry_helper::$validation_errors) {
                $r .= '<div class="page-notice ui-state-highlight ui-corner-all"><p>' . implode('</p></p>', array_values(data_entry_helper::$validation_errors)) . '</p></div>';
            } else {
                if (isset($_POST['occurrence:record_status']) && isset($response['success']) && $args['emails_enabled']) {
                    // Provide a send email form to allow the user to send a verification email
                    if ($_POST['occurrence:record_status'] == 'V') {
                        $action = 'verified';
                    } elseif ($_POST['occurrence:record_status'] == 'R') {
                        $action = 'rejected';
                    } else {
                        $action = '';
                    }
                    if ($action) {
                        $occ = data_entry_helper::get_population_data(array('table' => 'occurrence', 'extraParams' => $auth['read'] + array('id' => $response['outer_id'], 'view' => 'detail')));
                        $email_attr = data_entry_helper::get_population_data(array('table' => 'sample_attribute_value', 'extraParams' => $auth['read'] + array('caption' => 'Email', 'sample_id' => $occ[0]['sample_id'])));
                        $subject = self::get_email_component('subject', $action, $occ[0], $args);
                        $body = self::get_email_component('body', $action, $occ[0], $args);
                        if (!empty($email_attr[0]['value'])) {
                            $r .= '
<form id="email-form" action="mailto:' . $email_attr[0]['value'] . '?subject=' . $subject . '&body=' . $body . '" method="post" enctype="text/plain">
<fieldset>
<legend>Send a notification email to the recorder.</legend>
<input type="submit" value="Send Email">
</fieldset>
</form>
';
                        } else {
                            $r .= '<div class="page-notice ui-state-highlight ui-corner-all">The record has been ' . $action . '. The recorder did not leave an email address so cannot be notified.</div>';
                        }
                    }
                }
            }
        }
        global $user;
        $r .= data_entry_helper::report_grid(array('id' => 'verification-grid', 'dataSource' => $args['report_name'], 'mode' => 'report', 'readAuth' => $auth['read'], 'columns' => array(array('display' => 'Actions', 'actions' => array(array('caption' => 'Verify', 'javascript' => 'indicia_verify(\'{taxon}\', {occurrence_id}, true, ' . $user->uid . '); return false;'), array('caption' => 'Reject', 'javascript' => 'indicia_verify(\'{taxon}\', {occurrence_id}, false, ' . $user->uid . '); return false;')))), 'itemsPerPage' => 10, 'autoParamsForm' => $args['auto_params_form'], 'extraParams' => array()));
        $r .= '
<form id="verify" method="post" action="">
  ' . $auth['write'] . '
  <input type="hidden" id="occurrence:id" name="occurrence:id" value="" />
  <input type="hidden" id="occurrence:record_status" name="occurrence:record_status" value="" />
  <input type="hidden" id="website7_id" name="website_id" value="' . $args['website_id'] . '" />
  <input type="hidden" id="occurrence:verified_by_id" name="occurrence:verified_by_id" value="" />
</form>
';
        drupal_add_js('
var verifiers_mapping = "' . $args['verifiers_mapping'] . '";
var url = ' . json_encode(data_entry_helper::get_reload_link_parts()) . ';
function indicia_verify(taxon, id, valid, cmsUser){
  var action;
  if (valid) {
    $("#occurrence\\\\:record_status").attr("value", "V");
    action = "verify";
  } else {
    $("#occurrence\\\\:record_status").attr("value", "R");
    action = "reject";
  }
  if (confirm("Are you sure you want to " + action + " this record of " + taxon + "?")) {
    $("#occurrence\\\\:id").attr(\'value\', id);
    if (verifiers_mapping.indexOf("=")==-1) {
      verifier = verifiers_mapping;
    } else {
      var verifierMaps = verifiers_mapping.split(",");
      var keyval, verifiersArr = new Array();
      $.each(verifierMaps, function(idx, map) {
        keyval = map.split("=");
        if (parseInt(keyval[0].trim())==cmsUser) {
          verifier = keyval[1].trim();
        }
      });
    }
    $("#occurrence\\\\:verified_by_id").attr(\'value\', verifier);
    // We need to dynamically build the submitTo so we get the correct sort order
    var submitTo = "";
    // access globals created by the report grid to get the current state of pagination and sort as a result of AJAX calls
    url.params["page-verification-grid"] = report_grid_page;
    if (report_grid_orderby!="") {
      url.params["orderby-verification-grid"] = report_grid_orderby;
    } else {
      delete url.params["orderby-verification-grid"];
    }
    if (report_grid_sortdir!="") {
      url.params["sortdir-verification-grid"] = report_grid_sortdir;
    } else {
      delete url.params["sortdir-verification-grid"]
    }
    $.each(url.params, function(field, value) {
      submitTo += (submitTo ==="" ? "?" : "&");
      submitTo += field + "=" + value;
    });
    submitTo = url.path + submitTo;
    $("form#verify").attr("action", submitTo);
    $("form#verify").submit();
  }
}
', 'inline');
        return $r;
    }
예제 #13
0
 /**
  * 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)
 {
     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');
     }
     iform_load_helpers(array('data_entry_helper', 'map_helper'));
     // 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);
     $auth = data_entry_helper::get_read_auth($args['website_id'], $args['password']);
     //extract fixed parameters for report grid.
     $params = explode("\n", $args['param_presets']);
     foreach ($params as $param) {
         $keyvals = explode("=", $param);
         $key = trim($keyvals[0]);
         $val = trim($keyvals[1]);
         $extraParams[$key] = $val;
     }
     // plus defaults which are not fixed
     $params = explode("\n", $args['param_defaults']);
     foreach ($params as $param) {
         $keyvals = explode("=", $param);
         $key = trim($keyvals[0]);
         $val = trim($keyvals[1]);
         $paramDefaults[$key] = $val;
     }
     $opts = array('id' => 'verification-grid', 'dataSource' => $args['report_name'], 'mode' => 'report', 'readAuth' => $auth, 'rowId' => 'occurrence_id', 'itemsPerPage' => 10, 'autoParamsForm' => true, 'extraParams' => $extraParams, 'paramDefaults' => $paramDefaults, 'fieldsetClass' => 'collapsible collapsed');
     if (!empty($args['columns_config'])) {
         $opts['columns'] = json_decode($args['columns_config'], true);
     }
     $grid = data_entry_helper::report_grid($opts);
     $r = str_replace(array('{grid}'), array($grid), self::get_template_grid_left($args, $auth));
     $link = data_entry_helper::get_reload_link_parts();
     global $user;
     data_entry_helper::$javascript .= 'indiciaData.username = "******"\";\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') . "\";\n";
     data_entry_helper::$javascript .= 'indiciaData.ajaxUrl="' . url('iform/ajax/verification_3') . "\";\n";
     data_entry_helper::$javascript .= 'indiciaData.autoDiscard = ' . $args['auto_discard_rows'] . ";\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.V="' . lang::get('Verification') . "\";\n";
     data_entry_helper::$javascript .= 'indiciaData.popupTranslations.R="' . lang::get('Rejection') . "\";\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.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.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.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";
     return $r;
 }
예제 #14
0
 /**
  * Build a url suitable for inclusion in the links for the report calendar grid column pagination
  * bar. This effectively re-builds the current page's URL, but drops the query string parameters that
  * indicate the year and site.
  * Note there is no need to sort for the calender grid.
  * @param array $pageUrlParams List pagination parameters which should be excluded.
  * @return string
  */
 private static function report_calendar_grid_get_reload_url($pageUrlParams)
 {
     // get the url parameters. Don't use $_GET, because it contains any parameters that are not in the
     // URL when search friendly URLs are used (e.g. a Drupal path node/123 is mapped to index.php?q=node/123
     // using Apache mod_alias but we don't want to know about that)
     $reloadUrl = data_entry_helper::get_reload_link_parts();
     // find the names of the params we must not include
     $excludedParams = array();
     foreach ($pageUrlParams as $param) {
         $excludedParams[] = $param['name'];
     }
     foreach ($reloadUrl['params'] as $key => $value) {
         if (!in_array($key, $excludedParams)) {
             $reloadUrl['path'] .= (strpos($reloadUrl['path'], '?') === false ? '?' : '&') . "{$key}={$value}";
         }
     }
     return $reloadUrl['path'];
 }
예제 #15
0
function iform_mnhnl_getReloadPath($exclusions = array('sample_id', 'occurrence_id', 'new', 'page'))
{
    $reload = data_entry_helper::get_reload_link_parts();
    foreach ($exclusions as $exclude) {
        unset($reload['params'][$exclude]);
    }
    $reloadPath = $reload['path'];
    if (count($reload['params'])) {
        $reloadPath .= '?' . http_build_query($reload['params']);
    }
    return $reloadPath;
}
 /**
  * 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;
 }
 private static function year_control($args, $readAuth, $node, &$options)
 {
     switch ($args['dateFilter']) {
         case 'none':
             return '';
         default:
             // case year
             // Add year paginator where it can have an impact for both tables and plots.
             $siteUrlParams = self::get_site_url_params();
             $reloadUrl = data_entry_helper::get_reload_link_parts();
             // find the names of the params we must not include
             foreach ($reloadUrl['params'] as $key => $value) {
                 if (!array_key_exists($key, $siteUrlParams)) {
                     $reloadUrl['path'] .= (strpos($reloadUrl['path'], '?') === false ? '?' : '&') . "{$key}={$value}";
                 }
             }
             $param = (strpos($reloadUrl['path'], '?') === false ? '?' : '&') . self::$yearKey . '=';
             $r = "<th><a id=\"year-control-previous\" title=\"" . ($siteUrlParams[self::$yearKey]['value'] - 1) . "\" rel=\"nofollow\" href=\"" . $reloadUrl['path'] . $param . ($siteUrlParams[self::$yearKey]['value'] - 1) . "\" class=\"ui-datepicker-prev ui-corner-all\"><span class=\"ui-icon ui-icon-circle-triangle-w\">Prev</span></a></th><th><span class=\"thisYear\">" . $siteUrlParams[self::$yearKey]['value'] . "</span></th>";
             if ($siteUrlParams[self::$yearKey]['value'] < date('Y')) {
                 $r .= "<th><a id=\"year-control-next\" title=\"" . ($siteUrlParams[self::$yearKey]['value'] + 1) . "\" rel=\"nofollow\" href=\"" . $reloadUrl['path'] . $param . ($siteUrlParams[self::$yearKey]['value'] + 1) . "\" class=\"ui-datepicker-next ui-corner-all\"><span class=\"ui-icon ui-icon-circle-triangle-e\">Next</span></a></th>";
             } else {
                 $r .= '<th/>';
             }
             $options['year'] = $siteUrlParams[self::$yearKey]['value'];
             $options['date_start'] = $siteUrlParams[self::$yearKey]['value'] . '-Jan-01';
             $options['date_end'] = $siteUrlParams[self::$yearKey]['value'] . '-Dec-31';
             $options['downloadFilePrefix'] .= $siteUrlParams[self::$yearKey]['value'] . '_';
             return $r;
     }
 }
예제 #18
0
 private static function filter_toolbar($filters, $readAuth)
 {
     if (count($filters) === 0) {
         return '';
     }
     $reload = data_entry_helper::get_reload_link_parts();
     $r = "<form id=\"filters\" method=\"GET\" action=\"{$reload['path']}\">";
     foreach ($reload['params'] as $key => $value) {
         $value = urldecode($value);
         if ($key !== 'my_records') {
             $r .= "<input name=\"{$key}\" value=\"{$value}\" type=\"hidden\" />\n";
         }
     }
     foreach ($filters as $filter) {
         switch ($filter) {
             case 'my_records':
                 $checked = !empty($_GET['my_records']) ? ' checked="checked"' : '';
                 $r .= "<label>Show only my records?<input type=\"checkbox\" name=\"my_records\" value=\"1\"{$checked} /></label>";
                 break;
             case 'year':
                 $value = empty($_GET['year']) ? '' : $_GET['year'];
                 $r .= "<label>Limit to records from year:<input type=\"text\" name=\"year\" class=\"control-width-2\" value=\"{$value}\" /></label>";
                 break;
             case 'taxon_group_list':
                 $r .= "<label>Limit to records from species group:<select name=\"taxon_group_list\"><option value=\"\">&lt;" . lang::get('any group') . "&gt;</option>";
                 $groups = report_helper::get_report_data(array('dataSource' => '/library/taxon_groups/taxon_groups_used_in_checklist', 'readAuth' => $readAuth, 'extraParams' => array('taxon_list_id' => variable_get('iform_master_checklist_id', 0)), 'caching' => true, 'cachePerUser' => false, 'cachetimeout' => self::SLOW_CACHE_REFRESH));
                 $selectedId = empty($_GET['taxon_group_list']) ? '' : $_GET['taxon_group_list'];
                 foreach ($groups as $group) {
                     $selected = $group['id'] === $selectedId ? ' selected="selected"' : '';
                     $r .= "<option value=\"{$group['id']}\"{$selected}>{$group['title']}</option>";
                 }
                 $r .= "</select></label>";
                 break;
         }
     }
     $r .= '<input type="submit" value="Go"/>';
     $r .= '</form>';
     return $r;
 }
   /**
    * Construct a grid of existing records.
    * @param array $args iform parameters.
    * @param object $node node being shown.
    * @param array $auth authentication tokens for accessing the warehouse.
    * @return string HTML for grid.
    */
   protected static function getGrid($args, $node, $auth)
   {
       $r = '';
       $attributeOpts = array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']);
       if (isset($args['sample_method_id'])) {
           $attributeOpts['sample_method_id'] = $args['sample_method_id'];
       }
       $attributes = data_entry_helper::getAttributes($attributeOpts, false);
       $tabs = array('#sampleList' => lang::get('LANG_Main_Samples_Tab'));
       // Add in a tab for the allocation of locations if this option was selected
       if ($args['includeLocTools'] && function_exists('iform_loctools_checkaccess') && iform_loctools_checkaccess($node, 'admin')) {
           $tabs['#setLocations'] = lang::get('LANG_Allocate_Locations');
       }
       // An option for derived classes to add in extra tabs
       if (method_exists(self::$called_class, 'getExtraGridModeTabs')) {
           $extraTabs = call_user_func(array(self::$called_class, 'getExtraGridModeTabs'), false, $auth['read'], $args, $attributes);
           if (is_array($extraTabs)) {
               $tabs = $tabs + $extraTabs;
           }
       }
       // Only actually need to show tabs if there is more than one
       if (count($tabs) > 1) {
           $active = isset($_GET['page']) ? '#setLocations' : '#sampleList';
           $r .= "<div id=\"controls\">" . data_entry_helper::enable_tabs(array('divId' => 'controls', 'active' => $active)) . "<div id=\"temp\"></div>";
           $r .= data_entry_helper::tab_header(array('tabs' => $tabs));
       }
       // Here is where we get the table of samples
       $r .= "<div id=\"sampleList\">" . call_user_func(array(self::$called_class, 'getSampleListGrid'), $args, $node, $auth, $attributes) . "</div>";
       // Add content to the Allocate Locations tab if this option was selected
       if ($args['includeLocTools'] && function_exists('iform_loctools_checkaccess') && iform_loctools_checkaccess($node, 'admin')) {
           $r .= '<div id="setLocations">';
           $url = data_entry_helper::$base_url . '/index.php/services/data/location?mode=json&view=detail' . '&auth_token=' . $auth['read']['auth_token'] . '&nonce=' . $auth['read']["nonce"] . "&parent_id=NULL&orderby=name" . "&columns=id,name" . (isset($args['loctoolsLocTypeID']) && $args['loctoolsLocTypeID'] != '' ? '&location_type_id=' . $args['loctoolsLocTypeID'] : '');
           if (!isset($options['loctoolsPageSize'])) {
               $options['loctoolsPageSize'] = 20;
           }
           $page = empty($_REQUEST['page']) ? 1 : $_REQUEST['page'];
           // starts at 1.
           $session = curl_init($url);
           curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
           $entities = json_decode(curl_exec($session), true);
           $pages = ceil(count($entities) / $options['loctoolsPageSize']);
           // starts at 1
           $count = $page < $pages ? $options['loctoolsPageSize'] : (count($entities) - 1) % $options['loctoolsPageSize'] + 1;
           // number displayed on this page
           // build a jumper control:
           if ($pages > 1) {
               $reload = data_entry_helper::get_reload_link_parts();
               $r .= '<form method="GET" action="' . $reload['path'] . '">';
               if (count($reload['params'])) {
                   foreach ($reload['params'] as $param => $value) {
                       if ($param != "page") {
                           $r .= '<input type="hidden" name="' . $param . '" value="' . $value . '">';
                       }
                   }
               }
               $r .= '<label style="width:auto;" for="pageField">' . lang::get('Jump to page for location') . ':</label><select id="pageField" name="page"><option value="1">' . lang::get('Pick') . '</option>';
               foreach ($entities as $idx => $entity) {
                   $r .= '<option value="' . ceil(($idx + 1) / $options['loctoolsPageSize']) . '">' . $entity["name"] . '</option>';
               }
               $r .= "<input type=\"submit\" class=\"default-button\" value=\"" . lang::get('Go') . "\" /></form>\n";
               $r .= '<p>' . lang::get('You must save any changes made to data on this page before viewing any other page, otherwise those changes will be lost.') . "</p>\n";
           }
           $r .= '<form method="post"><input type="hidden" id="mnhnld1" name="mnhnld1" value="mnhnld1" /><input type="hidden" name="page" value="' . $page . '" />
 <div class="location-allocation-wrapper-outer" ><div class="location-allocation-wrapper-inner"><table border="1"></thead><tr><th class="freeze-first-col">' . lang::get('Location') . '</th>';
           // Main table body
           $userlist = iform_loctools_listusers($node);
           foreach ($userlist as $uid => $a_user) {
               $r .= '<th>' . $a_user->name . '</th>';
           }
           $r .= "</tr></thead><tbody>";
           if (!empty($entities)) {
               for ($i = 0; $i < $count; $i++) {
                   $entity = $entities[$i + ($page - 1) * $options['loctoolsPageSize']];
                   // only assign parent locations.
                   $r .= '<tr><td class="freeze-first-col">' . $entity["name"] . '</td>';
                   $defaultuserids = iform_loctools_getusers($node, $entity["id"]);
                   foreach ($userlist as $uid => $a_user) {
                       $r .= '<td><input type="hidden" name="location:' . $entity["id"] . ':' . $uid . '" value="0"><input type="checkbox" name="location:' . $entity["id"] . ':' . $uid . (in_array($uid, $defaultuserids) ? '" checked="checked"' : '"') . ' value="1"></td>';
                   }
                   $r .= "</tr>";
               }
           }
           $r .= "<tbody></table></div></div>\n";
           // build pager outside scrollable table.
           $numEachSide = 5;
           if ($pages > 1) {
               $path = iform_mnhnl_getReloadPath();
               $path .= (strpos($path, '?') === false ? '?' : '&') . 'page=';
               $r .= "<div class=\"pager ui-helper-clearfix\">";
               if ($page == 1) {
                   $r .= '<span class="ui-state-disabled pager-button">1</span>';
               } else {
                   $r .= '<a class="pager-button" href="' . $path . '1" rel="nofollow">1</a>';
               }
               if ($page - $numEachSide > 2) {
                   $r .= '...';
               }
               for ($i = max(2, $page - $numEachSide); $i <= min($pages - 1, $page + $numEachSide); $i++) {
                   if ($page == $i) {
                       $r .= ' <span class="ui-state-disabled pager-button">' . $i . '</span> ';
                   } else {
                       $r .= '<a class="pager-button" href="' . $path . $i . '" rel="nofollow">' . $i . '</a>';
                   }
               }
               if ($page + $numEachSide < $pages - 1) {
                   $r .= '...';
               }
               if ($page == $pages) {
                   $r .= '<span class="ui-state-disabled pager-button">' . $pages . '</span>';
               } else {
                   $r .= '<a class="pager-button" href="' . $path . $pages . '" rel="nofollow">' . $pages . '</a>';
               }
               $r .= "</div>";
           }
           $r .= '</table><input type="submit" class="default-button" value="' . lang::get('Save Location Allocations') . '" /></form></div>';
       }
       // Add content to extra tabs that derived classes may have added
       if (method_exists(self::$called_class, 'getExtraGridModeTabs')) {
           $r .= call_user_func(array(self::$called_class, 'getExtraGridModeTabs'), true, $auth['read'], $args, $attributes);
       }
       // Close tabs div if present
       if (count($tabs) > 1) {
           $r .= "</div>";
       }
       return $r;
   }
 protected static function getFirstTabAdditionalContent($args, $auth, &$attributes)
 {
     // Get authorisation tokens to update the Warehouse, plus any other hidden data.
     $r = $auth['write'] . "<input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n" . "<input type=\"hidden\" id=\"survey_id\" name=\"survey_id\" value=\"" . $args['survey_id'] . "\" />\n";
     if (!empty($args['sample_method_id'])) {
         $r .= '<input type="hidden" name="sample:sample_method_id" value="' . $args['sample_method_id'] . '"/>' . PHP_EOL;
     }
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         $r .= '<input type="hidden" id="sample:id" name="sample:id" value="' . data_entry_helper::$entity_to_load['sample:id'] . '" />' . PHP_EOL;
     }
     if (isset(data_entry_helper::$entity_to_load['occurrence:id'])) {
         $r .= '<input type="hidden" id="occurrence:id" name="occurrence:id" value="' . data_entry_helper::$entity_to_load['occurrence:id'] . '" />' . PHP_EOL;
     }
     if (!empty(data_entry_helper::$entity_to_load['sample:group_id'])) {
         $r .= "<input type=\"hidden\" id=\"group_id\" name=\"sample:group_id\" value=\"" . data_entry_helper::$entity_to_load['sample:group_id'] . "\" />\n";
         // If the group does not release it's records, set the release_status flag
         if (self::$group['private_records'] === 't') {
             $r .= "<input type=\"hidden\" id=\"occurrence:release_status\" name=\"occurrence:release_status\" value=\"U\" />\n";
         }
         if (empty(data_entry_helper::$entity_to_load['sample:group_title'])) {
             data_entry_helper::$entity_to_load['sample:group_title'] = self::$group['title'];
         }
         $msg = empty(self::$loadedSampleId) ? 'This form will be posted to the <strong>{1}</strong> group.' : 'This form was posted to the <strong>{1}</strong> group.';
         $r .= '<p>' . lang::get($msg, data_entry_helper::$entity_to_load['sample:group_title']) . '</p>';
     } elseif (self::$availableForGroups && !isset(data_entry_helper::$entity_to_load['sample:id'])) {
         // Group enabled form being used to add new records, but no group specified in URL path, so give
         // the user a chance to pick from their list of possible groups for this form.
         // Get the list of possible groups they might be posting into using this form. To do this we need the page
         // path without the initial leading /.
         $reload = data_entry_helper::get_reload_link_parts();
         // Slightly messy path handling. Ideally we'd call the same code as group_edit::get_path but we don't know the nid.
         $reload['path'] = preg_replace('/^\\//', '', $reload['path']);
         $dirname = preg_replace('/^\\//', '', dirname($_SERVER['SCRIPT_NAME'])) . '/';
         $reload['path'] = str_replace($dirname, '', $reload['path']);
         $possibleGroups = data_entry_helper::get_report_data(array('dataSource' => 'library/groups/groups_for_page', 'readAuth' => $auth['read'], 'extraParams' => array('currentUser' => hostsite_get_user_field('indicia_user_id'), 'path' => $reload['path'])));
         // Output a drop down so they can select the appropriate group.
         if (count($possibleGroups) > 1) {
             $options = array('' => lang::get('Ad-hoc non-group records'));
             foreach ($possibleGroups as $group) {
                 $options[$group['id']] = "{$group['group_type']}: {$group['title']}";
             }
             $r .= data_entry_helper::select(array('label' => lang::get('Record destination'), 'helpText' => lang::get('Choose whether to post your records into a group that you belong to.'), 'fieldname' => 'sample:group_id', 'lookupValues' => $options));
         } elseif (count($possibleGroups) === 1) {
             $r .= data_entry_helper::radio_group(array('label' => lang::get('Post to {1}', $possibleGroups[0]['title']), 'labelClass' => 'auto', 'helpText' => lang::get('Choose whether to post your records into {1}.', $possibleGroups[0]['title']), 'fieldname' => 'sample:group_id', 'lookupValues' => array('' => lang::get('No'), $possibleGroups[0]['id'] => lang::get('Yes'))));
         }
     }
     // Check if Record Status is included as a control. If not, then add it as a hidden.
     $arr = helper_base::explode_lines($args['structure']);
     if (!in_array('[record status]', $arr)) {
         $value = isset($args['defaults']['occurrence:record_status']) ? $args['defaults']['occurrence:record_status'] : 'C';
         $r .= '<input type="hidden" id="occurrence:record_status" name="occurrence:record_status" value="' . $value . '" />' . PHP_EOL;
     }
     if (!empty($args['defaults']['occurrence:release_status'])) {
         $r .= '<input type="hidden" id="occurrence:release_status" name="occurrence:release_status" value="' . $args['defaults']['occurrence:release_status'] . '" />' . PHP_EOL;
     }
     $r .= get_user_profile_hidden_inputs($attributes, $args, isset(data_entry_helper::$entity_to_load['sample:id']), $auth['read']);
     if ($args['multiple_occurrence_mode'] === 'multi') {
         $r .= '<input type="hidden" value="true" name="gridmode" />';
     }
     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;
 }
예제 #22
0
 protected static function getReloadPath()
 {
     $reload = data_entry_helper::get_reload_link_parts();
     unset($reload['params']['sample_id']);
     unset($reload['params']['occurrence_id']);
     unset($reload['params']['location_id']);
     unset($reload['params']['new']);
     unset($reload['params']['newLocation']);
     $reloadPath = $reload['path'];
     if (count($reload['params'])) {
         // decode params prior to encoding to prevent double encoding.
         foreach ($reload['params'] as $key => $param) {
             $reload['params'][$key] = urldecode($param);
         }
         $reloadPath .= '?' . http_build_query($reload['params']);
     }
     return $reloadPath;
 }
예제 #23
0
   /**
    * Return the generated form output.
    * @return Form HTML.
    */
   public static function get_form($args, $node)
   {
       define("MODE_GRID", 0);
       define("MODE_NEW_SAMPLE", 1);
       define("MODE_EXISTING", 2);
       self::parse_defaults($args);
       self::getArgDefaults($args);
       global $user;
       $logged_in = $user->uid > 0;
       $r = '';
       // Get authorisation tokens to update and read from the Warehouse.
       $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
       $svcUrl = data_entry_helper::$base_url . '/index.php/services';
       self::$auth = $auth;
       $mode = isset($args['no_grid']) && $args['no_grid'] ? MODE_NEW_SAMPLE : MODE_GRID;
       // default mode when no grid set to false - display grid of existing data
       // mode MODE_EXISTING: display existing sample
       $loadedSampleId = null;
       $loadedOccurrenceId = null;
       if ($_POST) {
           if (!array_key_exists('website_id', $_POST)) {
               // non Indicia POST, in this case must be the location allocations. add check to ensure we don't corrept the data by accident
               if (iform_loctools_checkaccess($node, 'admin') && array_key_exists('mnhnld1', $_POST)) {
                   iform_loctools_deletelocations($node);
                   foreach ($_POST as $key => $value) {
                       $parts = explode(':', $key);
                       iform_loctools_insertlocation($node, $parts[2], $parts[1]);
                   }
               }
           } else {
               if (!is_null(data_entry_helper::$entity_to_load)) {
                   $mode = MODE_EXISTING;
                   // errors with new sample, entity populated with post, so display this data.
               }
           }
           // else valid save, so go back to gridview: default mode 0
       }
       if (array_key_exists('sample_id', $_GET)) {
           $mode = MODE_EXISTING;
           $loadedSampleId = $_GET['sample_id'];
       }
       if (array_key_exists('occurrence_id', $_GET)) {
           $mode = MODE_EXISTING;
           $loadedOccurrenceId = $_GET['occurrence_id'];
       }
       if ($mode != MODE_EXISTING && array_key_exists('newSample', $_GET)) {
           $mode = MODE_NEW_SAMPLE;
           data_entry_helper::$entity_to_load = array();
       }
       // else default to mode MODE_GRID or MODE_NEW_SAMPLE depending on no_grid parameter
       self::$mode = $mode;
       // default mode  MODE_GRID : display grid of the samples to add a new one
       // or edit an existing one.
       if ($mode == MODE_GRID) {
           $attributes = data_entry_helper::getAttributes(array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']));
           $tabs = array('#sampleList' => lang::get('LANG_Main_Samples_Tab'));
           if ($args['includeLocTools'] && iform_loctools_checkaccess($node, 'admin')) {
               $tabs['#setLocations'] = lang::get('LANG_Allocate_Locations');
           }
           if (count($tabs) > 1) {
               $r .= "<div id=\"controls\">" . data_entry_helper::enable_tabs(array('divId' => 'controls', 'active' => '#sampleList')) . "<div id=\"temp\"></div>";
               $r .= data_entry_helper::tab_header(array('tabs' => $tabs));
           }
           $r .= "<div id=\"sampleList\">" . self::getSampleListGrid($args, $node, $auth, $attributes) . "</div>";
           if ($args['includeLocTools'] && iform_loctools_checkaccess($node, 'admin')) {
               $r .= '
 <div id="setLocations">
   <form method="post">
     <input type="hidden" id="mnhnld1" name="mnhnld1" value="mnhnld1" /><table border="1"><tr><td></td>';
               $url = $svcUrl . '/data/location?mode=json&view=detail&auth_token=' . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&parent_id=NULL&orderby=name";
               $session = curl_init($url);
               curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
               $entities = json_decode(curl_exec($session), true);
               $userlist = iform_loctools_listusers($node);
               foreach ($userlist as $uid => $a_user) {
                   $r .= '<td>' . $a_user->name . '</td>';
               }
               $r .= "</tr>";
               if (!empty($entities)) {
                   foreach ($entities as $entity) {
                       if (!$entity["parent_id"]) {
                           // only assign parent locations.
                           $r .= "<tr><td>" . $entity["name"] . "</td>";
                           $defaultuserids = iform_loctools_getusers($node, $entity["id"]);
                           foreach ($userlist as $uid => $a_user) {
                               $r .= '<td><input type="checkbox" name="location:' . $entity["id"] . ':' . $uid . (in_array($uid, $defaultuserids) ? '" checked="checked"' : '"') . '></td>';
                           }
                           $r .= "</tr>";
                       }
                   }
               }
               $r .= "</table>\n      <input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Save_Location_Allocations') . "\" />\n    </form>\n  </div>";
           }
           if (count($tabs) > 1) {
               // close tabs div if present
               $r .= "</div>";
           }
           return $r;
       }
       if ($mode == MODE_EXISTING) {
           data_entry_helper::$entity_to_load = array();
           // Displaying an existing sample. If we know the occurrence ID, and don't know the sample ID or are displaying just one occurrence
           // rather than a grid of occurrences then we must load the occurrence data.
           if ($loadedOccurrenceId && (!$loadedSampleId || !self::getGridMode($args))) {
               // The URL has provided us with an occurrence ID, but we need to know the sample ID as well.
               $url = $svcUrl . "/data/occurrence/{$loadedOccurrenceId}";
               $url .= "?mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"];
               $session = curl_init($url);
               curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
               $entity = json_decode(curl_exec($session), true);
               // Get the sample ID for the occurrence. This overwrites it if supply in GET but did not match the occurrence's sample
               $loadedSampleId = $entity[0]['sample_id'];
               if (!self::getGridMode($args)) {
                   // populate the entity to load with the single occurrence's data
                   foreach ($entity[0] as $key => $value) {
                       data_entry_helper::$entity_to_load['occurrence:' . $key] = $value;
                   }
               }
           }
           if ($loadedSampleId) {
               $url = $svcUrl . '/data/sample/' . $loadedSampleId;
               $url .= "?mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"];
               $session = curl_init($url);
               curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
               $entity = json_decode(curl_exec($session), true);
               // Build a list of the sample data.
               foreach ($entity[0] as $key => $value) {
                   data_entry_helper::$entity_to_load['sample:' . $key] = $value;
               }
               data_entry_helper::$entity_to_load['sample:geom'] = '';
               // value received from db is not WKT, which is assumed by all the code.
               data_entry_helper::$entity_to_load['sample:date'] = data_entry_helper::$entity_to_load['sample:date_start'];
               // bit of a bodge to get around vague dates.
           }
       }
       // atributes must be fetched after the entity to load is filled in - this is because the id gets filled in then!
       $attributes = data_entry_helper::getAttributes(array('id' => data_entry_helper::$entity_to_load['sample:id'], 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']));
       // Make sure the form action points back to this page
       $reload = data_entry_helper::get_reload_link_parts();
       $reloadPath = $reload['path'];
       $r = "<form method=\"post\" id=\"entry_form\" action=\"{$reloadPath}\">\n";
       // Get authorisation tokens to update the Warehouse, plus any other hidden data.
       $hiddens = $auth['write'] . "<input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n" . "<input type=\"hidden\" id=\"survey_id\" name=\"survey_id\" value=\"" . $args['survey_id'] . "\" />\n";
       if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
           $hiddens .= "<input type=\"hidden\" id=\"sample:id\" name=\"sample:id\" value=\"" . data_entry_helper::$entity_to_load['sample:id'] . "\" />\n";
       }
       if (isset(data_entry_helper::$entity_to_load['occurrence:id'])) {
           $hiddens .= "<input type=\"hidden\" id=\"occurrence:id\" name=\"occurrence:id\" value=\"" . data_entry_helper::$entity_to_load['occurrence:id'] . "\" />\n";
       }
       // Check if Record Status is included as a control. If not, then add it as a hidden.
       $arr = explode("\r\n", $args['structure']);
       if (!in_array('[record status]', $arr)) {
           $value = isset($args['defaults']['occurrence:record_status']) ? $args['defaults']['occurrence:record_status'] : 'C';
           $hiddens .= "<input type=\"hidden\" id=\"occurrence:record_status\" name=\"occurrence:record_status\" value=\"{$value}\" />\n";
       }
       // request automatic JS validation
       if (!isset($args['clientSideValidation']) || $args['clientSideValidation']) {
           data_entry_helper::enable_validation('entry_form');
       }
       // If logged in, output some hidden data about the user
       foreach ($attributes as &$attribute) {
           if (strcasecmp($attribute['caption'], 'cms user id') == 0) {
               if ($logged_in) {
                   $attribute['value'] = $user->uid;
               }
               $attribute['handled'] = true;
               // user id attribute is never displayed
           } elseif (strcasecmp($attribute['caption'], 'cms username') == 0) {
               if ($logged_in) {
                   $attribute['value'] = $user->name;
               }
               $attribute['handled'] = true;
               // username attribute is never displayed
           } elseif (strcasecmp($attribute['caption'], 'email') == 0) {
               if ($logged_in) {
                   if ($args['emailShow'] != true) {
                       // email attribute is not displayed
                       $attribute['value'] = $user->mail;
                       $attribute['handled'] = true;
                   } else {
                       $attribute['default'] = $user->mail;
                   }
               }
           } elseif ((strcasecmp($attribute['caption'], 'first name') == 0 || strcasecmp($attribute['caption'], 'last name') == 0 || strcasecmp($attribute['caption'], 'surname') == 0) && $logged_in) {
               if ($args['nameShow'] != true) {
                   // name attributes are not displayed
                   $attribute['handled'] = true;
               }
           }
           if (isset($attribute['value'])) {
               $hiddens .= '<input type="hidden" name="' . $attribute['fieldname'] . '" value="' . $attribute['value'] . '" />' . "\n";
           }
       }
       $customAttributeTabs = self::get_attribute_tabs($attributes);
       $tabs = self::get_all_tabs($args['structure'], $customAttributeTabs);
       $r .= "<div id=\"controls\">\n";
       // Build a list of the tabs that actually have content
       $tabHtml = self::get_tab_html($tabs, $auth, $args, $attributes, $hiddens);
       // Output the dynamic tab headers
       if ($args['interface'] != 'one_page') {
           $headerOptions = array('tabs' => array());
           foreach ($tabHtml as $tab => $tabContent) {
               $alias = preg_replace('/[^a-zA-Z0-9]/', '', strtolower($tab));
               $tabtitle = lang::get("LANG_Tab_{$alias}");
               if ($tabtitle == "LANG_Tab_{$alias}") {
                   // if no translation provided, we'll just use the standard heading
                   $tabtitle = $tab;
               }
               $headerOptions['tabs']['#' . $alias] = $tabtitle;
           }
           $r .= data_entry_helper::tab_header($headerOptions);
           data_entry_helper::enable_tabs(array('divId' => 'controls', 'style' => $args['interface'], 'progressBar' => isset($args['tabProgress']) && $args['tabProgress'] == true));
       }
       // Output the dynamic tab content
       $pageIdx = 0;
       foreach ($tabHtml as $tab => $tabContent) {
           // get a machine readable alias for the heading
           $tabalias = preg_replace('/[^a-zA-Z0-9]/', '', strtolower($tab));
           $r .= '<div id="' . $tabalias . '">' . "\n";
           // For wizard include the tab title as a header.
           if ($args['interface'] == 'wizard') {
               $r .= '<h1>' . $headerOptions['tabs']['#' . $tabalias] . '</h1>';
           }
           $r .= $tabContent;
           // Add any buttons required at the bottom of the tab
           if ($args['interface'] == 'wizard') {
               $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => $pageIdx === 0 ? 'first' : ($pageIdx == count($tabs) - 1 ? 'last' : 'middle')));
           } elseif ($pageIdx == count($tabs) - 1 && !($args['interface'] == 'tabs' && $args['save_button_below_all_pages'])) {
               // last part of a non wizard interface must insert a save button, unless it is tabbed interface with save button beneath all pages
               $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Save') . "\" />\n";
           }
           $pageIdx++;
           $r .= "</div>\n";
       }
       $r .= "</div>\n";
       if ($args['interface'] == 'tabs' && $args['save_button_below_all_pages']) {
           $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Save') . "\" />\n";
       }
       if (!empty(data_entry_helper::$validation_errors)) {
           $r .= data_entry_helper::dump_remaining_errors();
       }
       $r .= "</form>";
       // may need to keep following code for location change functionality
       // @todo Why is this not in the data entry helper, and is it really needed?
       if (self::$want_location_layer) {
           data_entry_helper::$onload_javascript .= "\n    \nlocationChange = function(obj){\n  locationLayer.destroyFeatures();\n  if(obj.value != ''){\n    jQuery.getJSON(\"" . $svcUrl . "\" + \"/data/location/\"+obj.value +\n      \"?mode=json&view=detail&auth_token=" . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "\" +\n      \"&callback=?\", function(data) {\n        if (data.length>0) {\n          var parser = new OpenLayers.Format.WKT();\n          for (var i=0;i<data.length;i++) {\n            if(data[i].centroid_geom){\n              feature = parser.read(data[i].centroid_geom);\n              centre = feature.geometry.getCentroid();\n              centrefeature = new OpenLayers.Feature.Vector(centre, {}, {label: data[i].name});\n              locationLayer.addFeatures([feature, centrefeature]); \n            }\n            if (data[i].boundary_geom){\n              feature = parser.read(data[i].boundary_geom);\n              feature.style = {strokeColor: \"Blue\",\n                  strokeWidth: 2,\n                  label: (data[i].centroid_geom ? \"\" : data[i].name)};\n                  locationLayer.addFeatures([feature]);\n            }\n          }\n          var extent=locationLayer.getDataExtent();\n          if (extent!==null) {\n            locationLayer.map.zoomToExtent(extent);\n          }\n        }\n\t\t  }\n    );\n  }\n};\njQuery('#imp-location').unbind('change');\njQuery('#imp-location').change(function(){\n\tlocationChange(this);\n});\n\nvar updatePlaceTabHandler = function(event, ui) { \n  if (ui.panel.id=='place') {\n    // upload location & sref initial values into map.\n    jQuery('#imp-location').change();\n    jQuery('#imp-sref').change();\n    jQuery('#controls').unbind('tabsshow', updatePlaceTabHandler);\n  }\n}\njQuery('#controls').bind('tabsshow', updatePlaceTabHandler);\n\n";
       }
       $r .= self::link_species_popups($args);
       return $r;
   }
예제 #24
0
    /**
     * Return the Indicia form code
     * @param array $args Input parameters.
     * @param array $node Drupal node object
     * @param array $response Response from Indicia services after posting a verification.
     * @return HTML string
     */
    public static function get_form($args, $node, $response)
    {
        global $user;
        $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
        $r = '';
        if ($_POST) {
            // dump out any errors that occurred on verification
            if (data_entry_helper::$validation_errors) {
                $r .= '<div class="page-notice ui-state-highlight ui-corner-all"><p>' . implode('</p></p>', array_values(data_entry_helper::$validation_errors)) . '</p></div>';
            } else {
                if (isset($_POST['email'])) {
                    // Send email. Depends upon settings in php.ini being correct
                    $success = mail($_POST['email_to'], $_POST['email_subject'], wordwrap($_POST['email_body'], 70), 'From: ' . $user->mail . PHP_EOL . 'Return-Path: ' . $user->mail);
                } else {
                    if (isset($_POST['occurrence:record_status']) && isset($response['success']) && $args['emails_enabled']) {
                        // Provide a send email form to allow the user to send a verification email
                        if ($_POST['occurrence:record_status'] == 'V') {
                            $action = 'verified';
                        } elseif ($_POST['occurrence:record_status'] == 'R') {
                            $action = 'rejected';
                        } else {
                            $action = '';
                        }
                        if ($action) {
                            $occ = data_entry_helper::get_population_data(array('table' => 'occurrence', 'extraParams' => $auth['read'] + array('id' => $response['outer_id'], 'view' => 'detail')));
                            $occ = $occ[0];
                            $email_attr = data_entry_helper::get_population_data(array('table' => 'sample_attribute_value', 'extraParams' => $auth['read'] + array('caption' => 'Email', 'sample_id' => $occ['sample_id'])));
                            $verified_taxa_taxon_list_id = $_POST['occAttr:' . $args['occ_attr_id']];
                            if ($action == 'verified' && $verified_taxa_taxon_list_id != $occ['taxa_taxon_list_id']) {
                                $action = 'misidentified';
                                $verified_taxon = data_entry_helper::get_population_data(array('table' => 'taxa_taxon_list', 'extraParams' => $auth['read'] + array('id' => $verified_taxa_taxon_list_id)));
                                $occ = array_merge($occ, array('verified_taxon' => $verified_taxon[0]['taxon']));
                            }
                            $subject = self::get_email_component('subject', $action, $occ, $args);
                            $body = self::get_email_component('body', $action, $occ, $args);
                            if (!empty($email_attr[0]['value'])) {
                                $r .= '
<form id="email" action="" method="post">
<fieldset>
<legend>Send a notification email to the recorder.</legend>
<label>To: <input type="text" name="email_to" size="80" value="' . $email_attr[0]['value'] . '"></label><br />
<label>Subject: <input type="text" name="email_subject" size="80" value="' . $subject . '"></label><br />
<label>Body: <textarea name="email_body" rows="5" cols="80">' . $body . '</textarea></label><br />
<input type="hidden" name="email" value="1">
<input type="button" value="Send Email" onclick="
    $(\'form#email\').attr(\'action\', submit_to());
    $(\'form#email\').submit();
">
</fieldset>
</form>
';
                            } else {
                                $r .= '<div class="page-notice ui-state-highlight ui-corner-all">The record has been ' . $action . '. The recorder did not leave an email address so cannot be notified.</div>';
                            }
                        }
                    }
                }
            }
        }
        //extract fixed parameters for report grid.
        $params = explode(",", $args['fixed_params']);
        foreach ($params as $param) {
            $keyvals = explode("=", $param);
            $key = trim($keyvals[0]);
            $val = trim($keyvals[1]);
            $extraParams[$key] = $val;
        }
        $columns = array(array('display' => 'Actions', 'actions' => array(array('caption' => 'Verify', 'javascript' => 'indicia_verify({occurrence_id}, true, ' . $user->uid . '); return false;'), array('caption' => 'Reject', 'javascript' => 'indicia_verify({occurrence_id}, false, ' . $user->uid . '); return false;'))));
        //create a list of species to choose from with a hidden field indicating which to preselect
        //with javascript
        $taxon_list = data_entry_helper::get_population_data(array('table' => 'taxa_taxon_list', 'extraParams' => $auth['read'] + array('taxon_list_id' => $args['taxon_list_id'], 'orderby' => 'taxon_id')));
        $species = '<select id="species-{occurrence_id}">';
        foreach ($taxon_list as $taxon) {
            $species .= '<option value="' . $taxon['id'] . '">' . $taxon['taxon'] . '</opton>';
        }
        $species .= '</select>';
        $species .= '<input type="hidden" value="{taxa_taxon_list_id}" />';
        $columns = array_merge($columns, array(array('display' => 'Taxon', 'template' => $species)));
        $r .= data_entry_helper::report_grid(array('id' => 'verification-grid', 'dataSource' => $args['report_name'], 'mode' => 'report', 'readAuth' => $auth['read'], 'columns' => $columns, 'itemsPerPage' => 10, 'autoParamsForm' => $args['auto_params_form'], 'extraParams' => $extraParams, 'callback' => 'indicia_verification_2_species_init'));
        $r .= '
<form id="verify" method="post" action="">
  ' . $auth['write'] . '
  <input type="hidden" id="occurrence:id" name="occurrence:id" value="" />
  <input type="hidden" id="occurrence:record_status" name="occurrence:record_status" value="" />
  <input type="hidden" id="website_id" name="website_id" value="' . $args['website_id'] . '" />
  <input type="hidden" id="occurrence:verified_by_id" name="occurrence:verified_by_id" value="" />
  <input type="hidden" id="occAttr:' . $args['occ_attr_id'] . '" name="occAttr:' . $args['occ_attr_id'] . '" value="" />
</form>
';
        drupal_add_js('
var verifiers_mapping = "' . $args['verifiers_mapping'] . '";
var url = ' . json_encode(data_entry_helper::get_reload_link_parts()) . ';
var verified_species = "occAttr:' . $args['occ_attr_id'] . '";', 'inline');
        return $r;
    }
예제 #25
0
 /**
  * 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;
 }
예제 #26
0
   /**
    * Return the generated form output.
    * @return Form HTML.
    */
   public static function get_form($args, $node)
   {
       define("MODE_GRID", 0);
       define("MODE_NEW_SAMPLE", 1);
       define("MODE_EXISTING", 2);
       self::parse_defaults($args);
       self::getArgDefaults($args);
       global $user;
       $logged_in = $user->uid > 0;
       self::$node = $node;
       // Get authorisation tokens to update and read from the Warehouse.
       $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
       $svcUrl = data_entry_helper::$base_url . '/index.php/services';
       self::$auth = $auth;
       $mode = isset($args['no_grid']) && $args['no_grid'] ? MODE_NEW_SAMPLE : MODE_GRID;
       // default mode when no grid set to false - display grid of existing data
       // mode MODE_EXISTING: display existing sample
       $loadedSampleId = null;
       $loadedOccurrenceId = null;
       if ($_POST) {
           if (!array_key_exists('website_id', $_POST)) {
               // non Indicia POST, in this case must be the location allocations. add check to ensure we don't corrept the data by accident
               if (function_exists('iform_loctools_checkaccess') && iform_loctools_checkaccess($node, 'admin') && array_key_exists('mnhnld1', $_POST)) {
                   iform_loctools_deletelocations($node);
                   foreach ($_POST as $key => $value) {
                       $parts = explode(':', $key);
                       iform_loctools_insertlocation($node, $parts[2], $parts[1]);
                   }
               }
           } else {
               if (!is_null(data_entry_helper::$entity_to_load)) {
                   $mode = MODE_EXISTING;
                   // errors with new sample, entity populated with post, so display this data.
               }
           }
           // else valid save, so go back to gridview: default mode 0
       }
       if (array_key_exists('sample_id', $_GET) && $_GET['sample_id'] != '{sample_id}') {
           $mode = MODE_EXISTING;
           $loadedSampleId = $_GET['sample_id'];
       }
       if (array_key_exists('occurrence_id', $_GET) && $_GET['occurrence_id'] != '{occurrence_id}') {
           $mode = MODE_EXISTING;
           $loadedOccurrenceId = $_GET['occurrence_id'];
           self::$occurrenceIds = array($loadedOccurrenceId);
       }
       if ($mode != MODE_EXISTING && array_key_exists('newSample', $_GET)) {
           $mode = MODE_NEW_SAMPLE;
           data_entry_helper::$entity_to_load = array();
       }
       // else default to mode MODE_GRID or MODE_NEW_SAMPLE depending on no_grid parameter
       self::$mode = $mode;
       // default mode  MODE_GRID : display grid of the samples to add a new one
       // or edit an existing one.
       if ($mode == MODE_GRID) {
           $r = '';
           $attributes = data_entry_helper::getAttributes(array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']), false);
           $tabs = array('#sampleList' => lang::get('LANG_Main_Samples_Tab'));
           if ($args['includeLocTools'] && function_exists('iform_loctools_checkaccess') && iform_loctools_checkaccess($node, 'admin')) {
               $tabs['#setLocations'] = lang::get('LANG_Allocate_Locations');
           }
           if (method_exists(get_called_class(), 'getExtraGridModeTabs')) {
               $extraTabs = call_user_func(array(get_called_class(), 'getExtraGridModeTabs'), false, $auth['read'], $args, $attributes);
               if (is_array($extraTabs)) {
                   $tabs = $tabs + $extraTabs;
               }
           }
           if (count($tabs) > 1) {
               $r .= "<div id=\"controls\">" . data_entry_helper::enable_tabs(array('divId' => 'controls', 'active' => '#sampleList')) . "<div id=\"temp\"></div>";
               $r .= data_entry_helper::tab_header(array('tabs' => $tabs));
           }
           $r .= "<div id=\"sampleList\">" . call_user_func(array(get_called_class(), 'getSampleListGrid'), $args, $node, $auth, $attributes) . "</div>";
           if ($args['includeLocTools'] && function_exists('iform_loctools_checkaccess') && iform_loctools_checkaccess($node, 'admin')) {
               $r .= '
 <div id="setLocations">
   <form method="post">
     <input type="hidden" id="mnhnld1" name="mnhnld1" value="mnhnld1" /><table border="1"><tr><td></td>';
               $url = $svcUrl . '/data/location?mode=json&view=detail&auth_token=' . $auth['read']['auth_token'] . "&nonce=" . $auth['read']["nonce"] . "&parent_id=NULL&orderby=name";
               $session = curl_init($url);
               curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
               $entities = json_decode(curl_exec($session), true);
               $userlist = iform_loctools_listusers($node);
               foreach ($userlist as $uid => $a_user) {
                   $r .= '<td>' . $a_user->name . '</td>';
               }
               $r .= "</tr>";
               if (!empty($entities)) {
                   foreach ($entities as $entity) {
                       if (!$entity["parent_id"]) {
                           // only assign parent locations.
                           $r .= "<tr><td>" . $entity["name"] . "</td>";
                           $defaultuserids = iform_loctools_getusers($node, $entity["id"]);
                           foreach ($userlist as $uid => $a_user) {
                               $r .= '<td><input type="checkbox" name="location:' . $entity["id"] . ':' . $uid . (in_array($uid, $defaultuserids) ? '" checked="checked"' : '"') . '></td>';
                           }
                           $r .= "</tr>";
                       }
                   }
               }
               $r .= "</table>\n      <input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Save_Location_Allocations') . "\" />\n    </form>\n  </div>";
           }
           if (method_exists(get_called_class(), 'getExtraGridModeTabs')) {
               $r .= call_user_func(array(get_called_class(), 'getExtraGridModeTabs'), true, $auth['read'], $args, $attributes);
           }
           if (count($tabs) > 1) {
               // close tabs div if present
               $r .= "</div>";
           }
           return $r;
       }
       if ($mode == MODE_EXISTING && is_null(data_entry_helper::$entity_to_load)) {
           // only load if not in error situation
           data_entry_helper::$entity_to_load = array();
           // Displaying an existing sample. If we know the occurrence ID, and don't know the sample ID or are displaying just one occurrence
           // rather than a grid of occurrences then we must load the occurrence data to get the sample id.
           if ($loadedOccurrenceId && (!$loadedSampleId || !self::getGridMode($args))) {
               data_entry_helper::load_existing_record($auth['read'], 'occurrence', $loadedOccurrenceId);
               // Get the sample ID for the occurrence. This overwrites it if supply in GET but did not match the occurrence's sample
               $loadedSampleId = data_entry_helper::$entity_to_load['occurrence:sample_id'];
               if (self::getGridMode($args)) {
                   // in grid mode, we only needed to load the occurrence to find out the sample id.
                   data_entry_helper::$entity_to_load = array();
               }
           }
           if ($loadedSampleId) {
               data_entry_helper::load_existing_record($auth['read'], 'sample', $loadedSampleId);
           }
       }
       // attributes must be fetched after the entity to load is filled in - this is because the id gets filled in then!
       $attrOpts = array('id' => data_entry_helper::$entity_to_load['sample:id'], 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']);
       // select only the custom attributes that are for this sample method or all sample methods, if this
       // form is for a specific sample method.
       if (!empty($args['sample_method_id'])) {
           $attrOpts['sample_method_id'] = $args['sample_method_id'];
       }
       $attributes = data_entry_helper::getAttributes($attrOpts, false);
       //// Make sure the form action points back to this page
       $reload = data_entry_helper::get_reload_link_parts();
       unset($reload['params']['sample_id']);
       unset($reload['params']['occurrence_id']);
       unset($reload['params']['newSample']);
       $reloadPath = $reload['path'];
       if (count($reload['params'])) {
           $reloadPath .= '?' . http_build_query($reload['params']);
       }
       $r = "<form method=\"post\" id=\"entry_form\" action=\"{$reloadPath}\">\n";
       // Get authorisation tokens to update the Warehouse, plus any other hidden data.
       $hiddens = $auth['write'] . "<input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n" . "<input type=\"hidden\" id=\"survey_id\" name=\"survey_id\" value=\"" . $args['survey_id'] . "\" />\n";
       if (!empty($args['sample_method_id'])) {
           $hiddens .= '<input type="hidden" name="sample:sample_method_id" value="' . $args['sample_method_id'] . '"/>';
       }
       if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
           $hiddens .= "<input type=\"hidden\" id=\"sample:id\" name=\"sample:id\" value=\"" . data_entry_helper::$entity_to_load['sample:id'] . "\" />\n";
       }
       if (isset(data_entry_helper::$entity_to_load['occurrence:id'])) {
           $hiddens .= "<input type=\"hidden\" id=\"occurrence:id\" name=\"occurrence:id\" value=\"" . data_entry_helper::$entity_to_load['occurrence:id'] . "\" />\n";
       }
       // Check if Record Status is included as a control. If not, then add it as a hidden.
       $arr = explode("\r\n", $args['structure']);
       if (!in_array('[record status]', $arr)) {
           $value = isset($args['defaults']['occurrence:record_status']) ? $args['defaults']['occurrence:record_status'] : 'C';
           $hiddens .= "<input type=\"hidden\" id=\"occurrence:record_status\" name=\"occurrence:record_status\" value=\"{$value}\" />\n";
       }
       // request automatic JS validation
       if (!isset($args['clientSideValidation']) || $args['clientSideValidation']) {
           data_entry_helper::enable_validation('entry_form');
       }
       // If logged in, output some hidden data about the user
       if (isset($args['copyFromProfile']) && $args['copyFromProfile'] == true) {
           self::profile_load_all_profile($user);
       }
       foreach ($attributes as &$attribute) {
           $attrPropName = 'profile_' . strtolower(str_replace(' ', '_', $attribute['caption']));
           if (isset($args['copyFromProfile']) && $args['copyFromProfile'] == true && isset($user->{$attrPropName})) {
               if ($args['nameShow'] == true) {
                   $attribute['default'] = $user->{$attrPropName};
               } else {
                   // profile attributes are not displayed as the user is logged in
                   $attribute['handled'] = true;
                   $attribute['value'] = $user->{$attrPropName};
               }
           } elseif (strcasecmp($attribute['caption'], 'cms user id') == 0) {
               if ($logged_in) {
                   $attribute['value'] = $user->uid;
               }
               $attribute['handled'] = true;
               // user id attribute is never displayed
           } elseif (strcasecmp($attribute['caption'], 'cms username') == 0) {
               if ($logged_in) {
                   $attribute['value'] = $user->name;
               }
               $attribute['handled'] = true;
               // username attribute is never displayed
           } elseif (strcasecmp($attribute['caption'], 'email') == 0) {
               if ($logged_in) {
                   if ($args['emailShow'] != true) {
                       // email attribute is not displayed
                       $attribute['value'] = $user->mail;
                       $attribute['handled'] = true;
                   } else {
                       $attribute['default'] = $user->mail;
                   }
               }
           } elseif ((strcasecmp($attribute['caption'], 'first name') == 0 || strcasecmp($attribute['caption'], 'last name') == 0 || strcasecmp($attribute['caption'], 'surname') == 0) && $logged_in) {
               if ($args['nameShow'] != true) {
                   // name attributes are not displayed because we have the users login
                   $attribute['handled'] = true;
               }
           }
           // If we have a value for one of the user login attributes then we need to output this value. BUT, for existing data
           // we must not overwrite the user who created the record.
           if (isset($attribute['value']) && $mode != MODE_EXISTING) {
               $hiddens .= '<input type="hidden" name="' . $attribute['fieldname'] . '" value="' . $attribute['value'] . '" />' . "\n";
           }
       }
       $customAttributeTabs = get_attribute_tabs($attributes);
       $tabs = self::get_all_tabs($args['structure'], $customAttributeTabs);
       $r .= "<div id=\"controls\">\n";
       // Build a list of the tabs that actually have content
       $tabHtml = self::get_tab_html($tabs, $auth, $args, $attributes, $hiddens);
       // Output the dynamic tab headers
       if ($args['interface'] != 'one_page') {
           $headerOptions = array('tabs' => array());
           foreach ($tabHtml as $tab => $tabContent) {
               $alias = preg_replace('/[^a-zA-Z0-9]/', '', strtolower($tab));
               $tabtitle = lang::get("LANG_Tab_{$alias}");
               if ($tabtitle == "LANG_Tab_{$alias}") {
                   // if no translation provided, we'll just use the standard heading
                   $tabtitle = $tab;
               }
               $headerOptions['tabs']['#' . $alias] = $tabtitle;
           }
           $r .= data_entry_helper::tab_header($headerOptions);
           data_entry_helper::enable_tabs(array('divId' => 'controls', 'style' => $args['interface'], 'progressBar' => isset($args['tabProgress']) && $args['tabProgress'] == true));
       }
       // Output the dynamic tab content
       $pageIdx = 0;
       foreach ($tabHtml as $tab => $tabContent) {
           // get a machine readable alias for the heading
           $tabalias = preg_replace('/[^a-zA-Z0-9]/', '', strtolower($tab));
           $r .= '<div id="' . $tabalias . '">' . "\n";
           // For wizard include the tab title as a header.
           if ($args['interface'] == 'wizard') {
               $r .= '<h1>' . $headerOptions['tabs']['#' . $tabalias] . '</h1>';
           }
           $r .= $tabContent;
           // Add any buttons required at the bottom of the tab
           if ($args['interface'] == 'wizard') {
               $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => $pageIdx === 0 ? 'first' : ($pageIdx == count($tabHtml) - 1 ? 'last' : 'middle')));
           } elseif ($pageIdx == count($tabHtml) - 1 && !($args['interface'] == 'tabs' && $args['save_button_below_all_pages'])) {
               // last part of a non wizard interface must insert a save button, unless it is tabbed interface with save button beneath all pages
               $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" id=\"save-button\" value=\"" . lang::get('LANG_Save') . "\" />\n";
           }
           $pageIdx++;
           $r .= "</div>\n";
       }
       $r .= "</div>\n";
       if ($args['interface'] == 'tabs' && $args['save_button_below_all_pages']) {
           $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" id=\"save-button\" value=\"" . lang::get('LANG_Save') . "\" />\n";
       }
       if (!empty(data_entry_helper::$validation_errors)) {
           $r .= data_entry_helper::dump_remaining_errors();
       }
       $r .= "</form>";
       $r .= self::link_species_popups($args);
       return $r;
   }
 private static function get_success_page($args, $auth, $sample_id)
 {
     $reload = data_entry_helper::get_reload_link_parts();
     if (isset($reload['params']['occurrence_id'])) {
         unset($reload['params']['occurrence_id']);
     }
     if (isset($reload['params']['sample_id'])) {
         unset($reload['params']['sample_id']);
     }
     $reload['params']['new'] = "1";
     $newPath = $reload['path'] . '?' . data_entry_helper::array_to_query_string($reload['params']);
     unset($reload['params']['new']);
     $reload['params']['sample_id'] = $sample_id;
     $reloadPath = $reload['path'] . '?' . data_entry_helper::array_to_query_string($reload['params']);
     $attributes = data_entry_helper::getAttributes(array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'] + array("untranslatedCaption" => "Shore Height"), 'survey_id' => $args['survey_id'], 'sample_method_id' => $args['transect_level_sample_method_id'], 'id' => $sample_id));
     $shore = '';
     foreach ($attributes as $attribute) {
         if ($attribute['untranslatedCaption'] == 'Shore Height') {
             $shore = ' (' . $attribute['displayValue'] . ' ' . $attribute['caption'] . ')';
         }
     }
     $r = '<h1>' . lang::get('Thank you!') . '</h1>' . '<h2>' . lang::get('Your survey data is a valuable contribution to the Capturing Our Coast programme.') . '</h2>' . '<p>' . str_replace(array('{name}', '{date}', '{shore}'), array(data_entry_helper::$entity_to_load['sample:location_name'], data_entry_helper::$entity_to_load['sample:date'], $shore), lang::get('You have completed entering your data for Transect &quot;{name}&quot; {shore} on {date}. ' . 'You can now choose to do one of several different things:')) . '</p><ul>' . '<li>' . str_replace('{newpath}', $newPath, lang::get('You can enter visit details for a new Transect by clicking <a href="{newpath}">here</a>.')) . '</li>' . '<li>' . str_replace('{reloadpath}', $reloadPath, lang::get('You can go back into the Transect you have just entered, to modify the data or upload photos, by clicking <a href="{reloadpath}">here</a>.')) . '</li>' . '<li>' . lang::get('Alternatively, you can choose one of the options in the main menu above, e.g. to explore your records.') . '</li>' . '</ul>';
     return $r;
 }
예제 #28
0
 private static function location_control($args, $readAuth, $node)
 {
     global $user;
     // loctools is not appropriate here as it is based on a node, for which this is a very simple one, invoking other nodes for the sample creation
     // need to scan param_presets for survey_id..
     $presets = get_options_array_with_user_data($args['param_presets']);
     if (!isset($presets['survey_id']) || $presets['survey_id'] == '') {
         return '<p>' . lang::get('The location selection control requires that survey_id is set in the presets in the form parameters.') . '</p>';
     }
     $attrArgs = array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $readAuth, 'survey_id' => $presets['survey_id']);
     if (isset($args['locationTypeFilter']) && $args['locationTypeFilter'] != "") {
         $attrArgs['location_type_id'] = $args['locationTypeFilter'];
     }
     $locationAttributes = data_entry_helper::getAttributes($attrArgs, false);
     $cmsAttr = extract_cms_user_attr($locationAttributes, false);
     if (!$cmsAttr) {
         return '<p>' . lang::get('The location selection control requires that CMS User ID location attribute is defined for locations in this survey. If restricting to a particular location type, this must be set in the parameters page for this form instance.') . '</p>';
     }
     $attrListArgs = array('nocache' => true, 'extraParams' => array_merge(array('view' => 'list', 'website_id' => $args['website_id'], 'location_attribute_id' => $cmsAttr['attributeId'], 'raw_value' => $user->uid), $readAuth), 'table' => 'location_attribute_value');
     $attrList = data_entry_helper::get_population_data($attrListArgs);
     if (isset($attrList['error'])) {
         return $attrList['error'];
     }
     $locationIDList = array();
     foreach ($attrList as $attr) {
         $locationIDList[] = $attr['location_id'];
     }
     $locationListArgs = array('nocache' => true, 'extraParams' => array_merge(array('view' => 'list', 'website_id' => $args['website_id'], 'id' => $locationIDList), $readAuth), 'table' => 'location');
     $locationList = data_entry_helper::get_population_data($locationListArgs);
     if (isset($locationList['error'])) {
         return $locationList['error'];
     }
     $ctrlid = 'calendar-location-select-' . $node->nid;
     $ctrl = '<label for="' . $ctrlid . '" class="location-select-label">' . lang::get('Filter by site') . ' :</label><select id="' . $ctrlid . '" class="location-select">' . '<option value="" class="location-select-option" ' . (self::$siteUrlParams[self::$locationKey]['value'] == null ? 'selected=\\"selected\\" ' : '') . '>' . lang::get('All sites') . '</option>';
     foreach ($locationList as $location) {
         $ctrl .= '<option value=' . $location['id'] . ' class="location-select-option" ' . (self::$siteUrlParams[self::$locationKey]['value'] == $location['id'] ? 'selected=\\"selected\\" ' : '') . '>' . $location['name'] . (isset($args['includeSrefInLocationFilter']) && $args['includeSrefInLocationFilter'] ? ' (' . $location['centroid_sref'] . ')' : '') . '</option>';
     }
     $ctrl .= '</select>';
     // get the url parameters. Don't use $_GET, because it contains any parameters that are not in the
     // URL when search friendly URLs are used (e.g. a Drupal path node/123 is mapped to index.php?q=node/123
     // using Apache mod_alias but we don't want to know about that)
     $reloadUrl = data_entry_helper::get_reload_link_parts();
     // find the names of the params we must not include
     foreach ($reloadUrl['params'] as $key => $value) {
         if (!array_key_exists($key, self::$siteUrlParams)) {
             $reloadUrl['path'] .= (strpos($reloadUrl['path'], '?') === false ? '?' : '&') . "{$key}={$value}";
         }
     }
     $param = (strpos($reloadUrl['path'], '?') === false ? '?' : '&') . self::$locationKey . '=';
     data_entry_helper::$javascript .= "\njQuery('#" . $ctrlid . "').change(function(){\n  window.location = '" . $reloadUrl['path'] . "' + (jQuery(this).val()=='' ? '' : '" . $param . "'+jQuery(this).val());\n});\n";
     return $ctrl;
 }