Пример #1
0
 /**
  * Return the generated form output.
  * @return Form HTML.
  */
 public static function get_form($args, $node)
 {
     data_entry_helper::$website_id = $args['website_id'];
     if (!empty($args['high_volume']) && $args['high_volume']) {
         // node level caching for most page hits
         $cached = data_entry_helper::cache_get(array('node' => $node->nid), HIGH_VOLUME_CACHE_TIMEOUT);
         if ($cached !== false) {
             $cached = explode('|!|', $cached);
             data_entry_helper::$javascript = $cached[1];
             data_entry_helper::$late_javascript = $cached[2];
             data_entry_helper::$onload_javascript = $cached[3];
             data_entry_helper::$required_resources = json_decode($cached[4], true);
             return $cached[0];
         }
     }
     self::$node = $node;
     self::$called_class = 'iform_' . $node->iform;
     // Convert parameter, defaults, into structured array
     self::parse_defaults($args);
     // Supply parameters that may be missing after form upgrade
     if (method_exists(self::$called_class, 'getArgDefaults')) {
         $args = call_user_func(array(self::$called_class, 'getArgDefaults'), $args);
     }
     // Get authorisation tokens to update and read from the Warehouse. We allow child classes to generate this first if subclassed.
     if (self::$auth) {
         $auth = self::$auth;
     } else {
         $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
         self::$auth = $auth;
     }
     // Determine how the form was requested and therefore what to output
     $mode = method_exists(self::$called_class, 'getMode') ? call_user_func(array(self::$called_class, 'getMode'), $args, $node) : '';
     self::$mode = $mode;
     if ($mode === self::MODE_GRID) {
         // Output a grid of existing records
         $r = call_user_func(array(self::$called_class, 'getGrid'), $args, $node, $auth);
     } else {
         if (($mode === self::MODE_EXISTING || $mode === self::MODE_EXISTING_RO || $mode === self::MODE_CLONE) && is_null(data_entry_helper::$entity_to_load)) {
             // only load if not in error situation.
             call_user_func_array(array(self::$called_class, 'getEntity'), array(&$args, $auth));
         }
         // attributes must be fetched after the entity to load is filled in - this is because the id gets filled in then!
         $attributes = method_exists(self::$called_class, 'getAttributes') ? call_user_func(array(self::$called_class, 'getAttributes'), $args, $auth) : array();
         $r = call_user_func(array(self::$called_class, 'get_form_html'), $args, $auth, $attributes);
     }
     if (!empty($args['high_volume']) && $args['high_volume']) {
         $c = $r . '|!|' . data_entry_helper::$javascript . '|!|' . data_entry_helper::$late_javascript . '|!|' . data_entry_helper::$onload_javascript . '|!|' . json_encode(data_entry_helper::$required_resources);
         data_entry_helper::cache_set(array('node' => $node->nid), $c, HIGH_VOLUME_CACHE_TIMEOUT);
     }
     return $r;
 }
 public static function mapping_for_volunteers_guests($auth, $args, $tabalias, $options, $path)
 {
     iform_load_helpers(array('data_entry_helper'));
     data_entry_helper::$javascript = "\n    if (\$('#dynamic-my_own_locality').is(':checked')) {\n      \$('#tab-records').show();\n    } else {\n      \$('#tab-records').hide();\n    }\n    ";
 }
 private static function get_control_speciesidentifier($auth, $args, $tabalias, $options)
 {
     static $taxIdx = 0;
     // we need to control which items are lockable if locking requested
     if (!empty($options['lockable']) && $options['lockable'] == true) {
         $options['identifiers_lockable'] = $options['lockable'];
     } else {
         $options['identifiers_lockable'] = '';
     }
     unset($options['lockable']);
     // get the identifier type data
     $filter = array('termlist_external_key' => 'indicia:assoc:identifier_type');
     $dataOpts = array('table' => 'termlists_term', 'extraParams' => $auth['read'] + $filter);
     $options['identifierTypes'] = data_entry_helper::get_population_data($dataOpts);
     // get the identifier attribute type data
     $dataOpts = array('table' => 'identifier_attribute', 'extraParams' => $auth['read']);
     $options['idnAttributeTypes'] = data_entry_helper::get_population_data($dataOpts);
     // set up the known system types for identifier attributes
     $options['baseColourId'] = -1;
     $options['textColourId'] = -1;
     $options['sequenceId'] = -1;
     $options['positionId'] = -1;
     foreach ($options['idnAttributeTypes'] as $idnAttributeType) {
         if (!empty($idnAttributeType['system_function'])) {
             switch ($idnAttributeType['system_function']) {
                 case 'base_colour':
                     $options['baseColourId'] = $idnAttributeType['id'];
                     break;
                 case 'text_colour':
                     $options['textColourId'] = $idnAttributeType['id'];
                     break;
                 case 'sequence':
                     $options['sequenceId'] = $idnAttributeType['id'];
                     break;
                 case 'position':
                     $options['positionId'] = $idnAttributeType['id'];
                     break;
             }
         }
     }
     // get the subject observation attribute type data
     $dataOpts = array('table' => 'subject_observation_attribute', 'extraParams' => $auth['read']);
     $options['sjoAttributeTypes'] = data_entry_helper::get_population_data($dataOpts);
     // set up the known system types for subject_observation attributes
     $options['attachmentId'] = -1;
     $options['genderId'] = -1;
     $options['stageId'] = -1;
     $options['lifeStatusId'] = -1;
     foreach ($options['sjoAttributeTypes'] as $sjoAttributeType) {
         if (!empty($sjoAttributeType['system_function'])) {
             switch ($sjoAttributeType['system_function']) {
                 case 'attachment':
                     $options['attachmentId'] = $sjoAttributeType['id'];
                     break;
                 case 'gender':
                     $options['genderId'] = $sjoAttributeType['id'];
                     break;
                 case 'stage':
                     $options['stageId'] = $sjoAttributeType['id'];
                     break;
                 case 'life_status':
                     $options['lifeStatusId'] = $sjoAttributeType['id'];
                     break;
             }
         }
     }
     // get the identifiers subject observation attribute type data
     $dataOpts = array('table' => 'identifiers_subject_observation_attribute', 'extraParams' => $auth['read']);
     $options['isoAttributeTypes'] = data_entry_helper::get_population_data($dataOpts);
     // set up the known system types for subject_observation attributes
     $options['conditionsId'] = -1;
     foreach ($options['isoAttributeTypes'] as $isoAttributeType) {
         if (!empty($isoAttributeType['system_function'])) {
             switch ($isoAttributeType['system_function']) {
                 case 'identifier_condition':
                     $options['conditionsId'] = $isoAttributeType['id'];
                     break;
             }
         }
     }
     // throw an exception if any of the required custom attributes is missing
     $errorMessages = array();
     foreach (array('baseColourId', 'textColourId', 'sequenceId', 'positionId', 'attachmentId', 'genderId', 'stageId', 'lifeStatusId', 'conditionsId') as $attrId) {
         if ($options[$attrId] === -1) {
             $errorMessages[] = lang::get('Required custom attribute for ' . $attrId . ' has not been found. ' . 'Please check this has been created on the warehouse and is associated with the correct system function.');
         }
     }
     if (count($errorMessages) > 0) {
         $errorMessage = implode('<br />', $errorMessages);
         throw new exception($errorMessage);
     }
     // configure the identifiers javascript
     // write it late so it happens after any locked values are applied
     if (!$options['inNewIndividual']) {
         data_entry_helper::$late_javascript .= "indicia.wwt.initForm (\n        '" . $options['baseColourId'] . "',\n        '" . $options['textColourId'] . "',\n        '" . $options['sequenceId'] . "',\n        '" . $options['positionId'] . "',\n        '" . $args['default_leg_vertical'] . "',\n        '" . (!empty($args['neck_collar_regex']) ? $args['neck_collar_regex'] : '') . "',\n        '" . (!empty($args['enscribed_colour_ring_regex']) ? $args['enscribed_colour_ring_regex'] : '') . "',\n        '" . (!empty($args['metal_ring_regex']) ? $args['metal_ring_regex'] : '') . "',\n        '" . ($args['clientSideValidation'] ? 'true' : 'false') . "',\n        '" . ($args['subjectAccordion'] ? 'true' : 'false') . "'\n" . ");\n";
     }
     $r = '';
     $options['fieldprefix'] = 'idn:' . $taxIdx . ':';
     if (!$options['inNewIndividual']) {
         $r .= '<div id="idn:subject:accordion" class="idn-subject-accordion">';
     }
     if ($args['subjectAccordion']) {
         $r .= '<h3 id="' . $options['fieldprefix'] . 'individual:header" class="individual_header"><a href="" data-heading="' . lang::get('Colour-marked Individual') . ' ' . ($taxIdx + 1) . '">' . lang::get('Colour-marked Individual') . ' ' . ($taxIdx + 1) . '</a></h3>';
     } else {
         $r .= '<h3 id="' . $options['fieldprefix'] . 'individual:header" class="individual_header" data-heading="' . lang::get('Colour-marked Individual') . ' ' . ($taxIdx + 1) . '">' . lang::get('Colour-marked Individual') . ' ' . ($taxIdx + 1) . '</h3>';
     }
     $r .= '<div id="' . $options['fieldprefix'] . 'individual:panel" class="individual_panel ui-corner-all">';
     $r .= '<div class="ui-helper-clearfix">';
     $r .= '<fieldset id="' . $options['fieldprefix'] . 'individual:fieldset" class="taxon_individual ui-corner-all">';
     $r .= '<legend id="' . $options['fieldprefix'] . 'individual:legend">Individual details</legend>';
     // output the hiddens
     if (isset(data_entry_helper::$entity_to_load[$options['fieldprefix'] . 'subject_observation:id'])) {
         $r .= '<input type="hidden" id="' . $options['fieldprefix'] . 'subject_observation:id" name="' . $options['fieldprefix'] . 'subject_observation:id" ' . 'value="' . data_entry_helper::$entity_to_load[$options['fieldprefix'] . 'subject_observation:id'] . '" />' . "\n";
     }
     if (isset(data_entry_helper::$entity_to_load[$options['fieldprefix'] . 'occurrences_subject_observation:id'])) {
         $r .= '<input type="hidden" id="' . $options['fieldprefix'] . 'occurrences_subject_observation:id" name="' . $options['fieldprefix'] . 'occurrences_subject_observation:id" ' . 'value="' . data_entry_helper::$entity_to_load[$options['fieldprefix'] . 'occurrences_subject_observation:id'] . '" />' . "\n";
     }
     if (isset(data_entry_helper::$entity_to_load[$options['fieldprefix'] . 'occurrence:id'])) {
         $r .= '<input type="hidden" id="' . $options['fieldprefix'] . 'occurrence:id" name="' . $options['fieldprefix'] . 'occurrence:id" ' . 'value="' . data_entry_helper::$entity_to_load[$options['fieldprefix'] . 'occurrence:id'] . '" />' . "\n";
     }
     // 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)) {
         if (isset(data_entry_helper::$entity_to_load[$options['fieldprefix'] . 'occurrence:record_status'])) {
             $value = data_entry_helper::$entity_to_load[$options['fieldprefix'] . 'occurrence:record_status'];
         } else {
             $value = isset($args['defaults']['occurrence:record_status']) ? $args['defaults']['occurrence:record_status'] : 'C';
         }
         $r .= '<input type="hidden" id="' . $options['fieldprefix'] . 'occurrence:record_status" ' . 'name="' . $options['fieldprefix'] . 'occurrence:record_status" value="' . $value . '" />' . "\n";
     }
     // add subject type and count as a hidden
     $value = '';
     if (isset(data_entry_helper::$entity_to_load[$options['fieldprefix'] . 'subject_observation:subject_type_id'])) {
         $value = data_entry_helper::$entity_to_load[$options['fieldprefix'] . 'subject_observation:subject_type_id'];
     } else {
         if (isset($args['subject_type_id'])) {
             $value = $args['subject_type_id'];
         }
     }
     if ($value !== '') {
         $r .= '<input type="hidden" id="' . $options['fieldprefix'] . 'subject_observation:subject_type_id" ' . 'name="' . $options['fieldprefix'] . 'subject_observation:subject_type_id" value="' . $value . '" />' . "\n";
     }
     if (isset(data_entry_helper::$entity_to_load[$options['fieldprefix'] . 'subject_observation:count'])) {
         $value = data_entry_helper::$entity_to_load[$options['fieldprefix'] . 'subject_observation:count'];
     } else {
         $value = '1';
     }
     if ($value !== '') {
         $r .= '<input type="hidden" id="' . $options['fieldprefix'] . 'subject_observation:count" ' . 'name="' . $options['fieldprefix'] . 'subject_observation:count" value="' . $value . '" />' . "\n";
     }
     // output the species selection control
     $options['blankText'] = '<Please select>';
     $options['lockable'] = $options['identifiers_lockable'];
     if ($args['species_ctrl'] == 'autocomplete') {
         $temp = data_entry_helper::$javascript;
     }
     $r .= self::get_control_species($auth, $args, $tabalias, $options + array('validation' => array('required'), 'class' => 'select_taxon'));
     if ($args['species_ctrl'] == 'autocomplete') {
         if (!$options['inNewIndividual']) {
             $autoJavascript = substr(data_entry_helper::$javascript, strlen($temp));
         } else {
             data_entry_helper::$javascript = $temp;
         }
         unset($temp);
     } else {
         $autoJavascript = '';
     }
     unset($options['lockable']);
     // gender
     if ($options['genderId'] > 0 && !empty($args['request_gender_values']) && count($args['request_gender_values']) > 0) {
         // filter the genders available
         $query = array('in' => array('id', $args['request_gender_values']));
         $filter = array('query' => json_encode($query), 'orderby' => 'sort_order');
         $extraParams = array_merge($filter, $auth['read']);
         $options['lockable'] = $options['identifiers_lockable'];
         $fieldname = $options['fieldprefix'] . 'sjoAttr:' . $options['genderId'];
         $idname = $fieldname;
         // if this attribute exists on DB, we need to append id to fieldname
         if (is_array(data_entry_helper::$entity_to_load)) {
             $stored_keys = preg_grep('/^' . $fieldname . ':[0-9]+$/', array_keys(data_entry_helper::$entity_to_load));
             if (count($stored_keys) === 1) {
                 foreach ($stored_keys as $stored_key) {
                     $fieldname = $stored_key;
                 }
             }
         }
         $r .= data_entry_helper::select(array_merge(array('label' => lang::get('Sex of the bird'), 'fieldname' => $fieldname, 'id' => $idname, 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'id', 'default' => $args['default_gender'], 'extraParams' => $extraParams), $options));
         unset($options['lockable']);
     }
     // age
     if ($options['stageId'] > 0 && !empty($args['request_stage_values']) && count($args['request_stage_values']) > 0) {
         // filter the stages available
         $query = array('in' => array('id', $args['request_stage_values']));
         $filter = array('query' => json_encode($query), 'orderby' => 'sort_order');
         $extraParams = array_merge($filter, $auth['read']);
         $options['lockable'] = $options['identifiers_lockable'];
         $fieldname = $options['fieldprefix'] . 'sjoAttr:' . $options['stageId'];
         $idname = $fieldname;
         // if this attribute exists on DB, we need to append id to fieldname
         if (is_array(data_entry_helper::$entity_to_load)) {
             $stored_keys = preg_grep('/^' . $fieldname . ':[0-9]+$/', array_keys(data_entry_helper::$entity_to_load));
             if (count($stored_keys) === 1) {
                 foreach ($stored_keys as $stored_key) {
                     $fieldname = $stored_key;
                 }
             }
         }
         $r .= data_entry_helper::select(array_merge(array('label' => lang::get('Age of the bird'), 'fieldname' => $fieldname, 'id' => $idname, 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'id', 'default' => $args['default_stage'], 'extraParams' => $extraParams), $options));
         unset($options['lockable']);
     }
     // subject status
     if ($options['lifeStatusId'] > 0 && !empty($args['request_life_status_values']) && count($args['request_life_status_values']) > 0) {
         // filter the life status's available
         $query = array('in' => array('id', $args['request_life_status_values']));
         $filter = array('query' => json_encode($query), 'orderby' => 'sort_order');
         $extraParams = array_merge($filter, $auth['read']);
         $options['lockable'] = $options['identifiers_lockable'];
         $fieldname = $options['fieldprefix'] . 'sjoAttr:' . $options['lifeStatusId'];
         $idname = $fieldname;
         // if this attribute exists on DB, we need to append id to fieldname
         if (is_array(data_entry_helper::$entity_to_load)) {
             $stored_keys = preg_grep('/^' . $fieldname . ':[0-9]+$/', array_keys(data_entry_helper::$entity_to_load));
             if (count($stored_keys) === 1) {
                 foreach ($stored_keys as $stored_key) {
                     $fieldname = $stored_key;
                 }
             }
         }
         $r .= data_entry_helper::select(array_merge(array('label' => lang::get('This bird was'), 'fieldname' => $fieldname, 'id' => $idname, 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'id', 'default' => $args['default_life_status'], 'extraParams' => $extraParams), $options));
         unset($options['lockable']);
     }
     // output each required identifier
     $r .= '<div id="' . $options['fieldprefix'] . 'accordion" class="idn-accordion">';
     // setup and call function for neck collar
     $options['identifierName'] = '';
     $options['identifierTypeId'] = '';
     foreach ($options['identifierTypes'] as $identifier_type) {
         if ($identifier_type['id'] == $args['neck_collar_type']) {
             $options['identifierName'] = $identifier_type['term'];
             $options['identifierTypeId'] = $identifier_type['id'];
             break;
         }
     }
     $options['attrList'] = array(array('attrType' => 'idn', 'typeId' => $options['baseColourId'], 'lockable' => true, 'hidden' => false), array('attrType' => 'idn', 'typeId' => $options['textColourId'], 'lockable' => true, 'hidden' => false), array('attrType' => 'idn', 'typeId' => $options['sequenceId'], 'lockable' => false, 'hidden' => false), array('attrType' => 'idn', 'typeId' => $options['positionId'], 'lockable' => false, 'hidden' => true, 'hiddenValue' => $args['neck_collar_position']), array('attrType' => 'iso', 'typeId' => $options['conditionsId'], 'lockable' => false, 'hidden' => false));
     $options['fieldprefix'] = 'idn:' . $taxIdx . ':neck-collar:';
     $options['classprefix'] = 'idn-neck-collar-';
     $options['seq_maxlength'] = !empty($args['neck_collar_max_length']) ? $args['neck_collar_max_length'] : '';
     if (!empty($args['neck_collar_regex'])) {
         $options['seq_format_class'] = 'collarFormat';
     }
     $r .= self::get_control_identifier($auth, $args, $tabalias, $options);
     if (!empty($args['neck_collar_regex'])) {
         unset($options['seq_format_class']);
     }
     // setup and call function for left enscribed colour ring
     $options['identifierName'] = '';
     $options['identifierTypeId'] = '';
     foreach ($options['identifierTypes'] as $identifier_type) {
         if ($identifier_type['id'] == $args['enscribed_colour_ring_type']) {
             $options['identifierName'] = $identifier_type['term'] . lang::get(' (Left leg)');
             $options['identifierTypeId'] = $identifier_type['id'];
             break;
         }
     }
     $options['attrList'] = array(array('attrType' => 'idn', 'typeId' => $options['baseColourId'], 'lockable' => true, 'hidden' => false), array('attrType' => 'idn', 'typeId' => $options['textColourId'], 'lockable' => true, 'hidden' => false), array('attrType' => 'idn', 'typeId' => $options['sequenceId'], 'lockable' => false, 'hidden' => false), array('attrType' => 'idn', 'typeId' => $options['positionId'], 'lockable' => false, 'hidden' => true, 'hiddenValue' => $args['left_enscribed_colour_ring_position']), array('attrType' => 'iso', 'typeId' => $options['conditionsId'], 'lockable' => false, 'hidden' => false));
     $options['fieldprefix'] = 'idn:' . $taxIdx . ':colour-left:';
     $options['classprefix'] = 'idn-colour-left-';
     $options['seq_maxlength'] = !empty($args['enscribed_colour_ring_max_length']) ? $args['enscribed_colour_ring_max_length'] : '';
     if (!empty($args['enscribed_colour_ring_regex'])) {
         $options['seq_format_class'] = 'colourRingFormat';
     }
     $r .= self::get_control_identifier($auth, $args, $tabalias, $options);
     if (!empty($args['enscribed_colour_ring_regex'])) {
         unset($options['seq_format_class']);
     }
     // setup and call function for right enscribed colour ring
     $options['identifierName'] = '';
     $options['identifierTypeId'] = '';
     foreach ($options['identifierTypes'] as $identifier_type) {
         if ($identifier_type['id'] == $args['enscribed_colour_ring_type']) {
             $options['identifierName'] = $identifier_type['term'] . lang::get(' (Right leg)');
             $options['identifierTypeId'] = $identifier_type['id'];
             break;
         }
     }
     $options['attrList'] = array(array('attrType' => 'idn', 'typeId' => $options['baseColourId'], 'lockable' => true, 'hidden' => false), array('attrType' => 'idn', 'typeId' => $options['textColourId'], 'lockable' => true, 'hidden' => false), array('attrType' => 'idn', 'typeId' => $options['sequenceId'], 'lockable' => false, 'hidden' => false), array('attrType' => 'idn', 'typeId' => $options['positionId'], 'lockable' => false, 'hidden' => true, 'hiddenValue' => $args['right_enscribed_colour_ring_position']), array('attrType' => 'iso', 'typeId' => $options['conditionsId'], 'lockable' => false, 'hidden' => false));
     $options['fieldprefix'] = 'idn:' . $taxIdx . ':colour-right:';
     $options['classprefix'] = 'idn-colour-right-';
     $options['seq_maxlength'] = !empty($args['enscribed_colour_ring_max_length']) ? $args['enscribed_colour_ring_max_length'] : '';
     if (!empty($args['enscribed_colour_ring_regex'])) {
         $options['seq_format_class'] = 'colourRingFormat';
     }
     $r .= self::get_control_identifier($auth, $args, $tabalias, $options);
     if (!empty($args['enscribed_colour_ring_regex'])) {
         unset($options['seq_format_class']);
     }
     // setup and call function for metal ring
     $options['identifierName'] = '';
     $options['identifierTypeId'] = '';
     foreach ($options['identifierTypes'] as $identifier_type) {
         if ($identifier_type['id'] == $args['metal_ring_type']) {
             $options['identifierName'] = $identifier_type['term'];
             $options['identifierTypeId'] = $identifier_type['id'];
             break;
         }
     }
     $options['attrList'] = array(array('attrType' => 'idn', 'typeId' => $options['positionId'], 'lockable' => true, 'hidden' => false), array('attrType' => 'idn', 'typeId' => $options['sequenceId'], 'lockable' => false, 'hidden' => false), array('attrType' => 'iso', 'typeId' => $options['conditionsId'], 'lockable' => false, 'hidden' => false));
     $options['fieldprefix'] = 'idn:' . $taxIdx . ':metal:';
     $options['classprefix'] = 'idn-metal-';
     $options['seq_maxlength'] = !empty($args['metal_ring_max_length']) ? $args['metal_ring_max_length'] : '';
     $options['seq_maxlength'] = !empty($args['metal_ring_max_length']) ? $args['metal_ring_max_length'] : '';
     if (!empty($args['metal_ring_regex'])) {
         $options['seq_format_class'] = 'metalRingFormat';
     }
     $r .= self::get_control_identifier($auth, $args, $tabalias, $options);
     if (!empty($args['metal_ring_regex'])) {
         unset($options['seq_format_class']);
     }
     unset($options['seq_maxlength']);
     $r .= '</div>';
     // end of identifier accordion
     // other devices (trackers etc.)
     if ($options['attachmentId'] > 0 && !empty($args['other_devices']) && count($args['other_devices']) > 0) {
         // reset prefix
         $options['fieldprefix'] = 'idn:' . $taxIdx . ':';
         // filter the devices available
         $query = array('in' => array('id', $args['other_devices']));
         $filter = array('query' => json_encode($query), 'orderby' => 'sort_order');
         $extraParams = array_merge($filter, $auth['read']);
         $fieldname = $options['fieldprefix'] . 'sjoAttr:' . $options['attachmentId'];
         $default = array();
         // if this attribute exists on DB, we need to write a hidden with id appended to fieldname and set defaults for checkboxes
         if (is_array(data_entry_helper::$entity_to_load)) {
             $stored_keys = preg_grep('/^' . $fieldname . ':[0-9]+$/', array_keys(data_entry_helper::$entity_to_load));
             foreach ($stored_keys as $stored_key) {
                 $r .= '<input type="hidden" name="' . $stored_key . '" value="" />';
                 $default[] = array('fieldname' => $stored_key, 'default' => data_entry_helper::$entity_to_load[$stored_key]);
                 unset(data_entry_helper::$entity_to_load[$stored_key]);
             }
         }
         $r .= data_entry_helper::checkbox_group(array_merge(array('label' => lang::get('What other devices did you see on the bird'), 'fieldname' => $fieldname, 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'id', 'default' => $default, 'extraParams' => $extraParams), $options));
     }
     // subject_observation comment
     if ($args['observation_comment']) {
         $r .= self::get_control_observationcomment($auth, $args, $tabalias, $options);
     }
     $r .= '</fieldset>';
     // output identifier visualisations
     $r .= '<div id="idn:' . $taxIdx . ':neck-collar:colourbox" class="neck-collar-indentifier-colourbox ui-corner-all">&nbsp;</div>';
     $r .= '<div id="idn:' . $taxIdx . ':colour-left:colourbox" class="colour-left-indentifier-colourbox ui-corner-all">&nbsp;</div>';
     $r .= '<div id="idn:' . $taxIdx . ':colour-right:colourbox" class="colour-right-indentifier-colourbox ui-corner-all">&nbsp;</div>';
     $r .= '</div>';
     // close clearfix div
     // occurrence images
     $opts = array('table' => 'idn:' . $taxIdx . ':' . 'occurrence_image', 'label' => lang::get('Upload your photos'));
     if ($args['interface'] !== 'one_page') {
         $opts['tabDiv'] = $tabalias;
     }
     $opts['resizeWidth'] = isset($options['resizeWidth']) ? $options['resizeWidth'] : 1600;
     $opts['resizeHeight'] = isset($options['resizeHeight']) ? $options['resizeHeight'] : 1600;
     $opts['caption'] = lang::get('Photos');
     $opts['readAuth'] = $auth['read'];
     $opts['imageWidth'] = '168';
     // $opts['id'] = 'idn:0';
     if ($options['inNewIndividual']) {
         $opts['codeGenerated'] = 'php';
     }
     $r .= data_entry_helper::file_box($opts);
     // remove bird button - don't show if bird is being edited or only bird on the form
     $r .= '<input type="button" id="idn:0:remove-individual" class="idn-remove-individual" value="' . lang::get('Remove This Bird') . '" />';
     $r .= '</div>';
     // recursive call to get a template for the 'individual panel' markup for a new observation so we can add another bird
     if (!$options['inNewIndividual']) {
         $r .= '</div>';
         $temp = data_entry_helper::$entity_to_load;
         data_entry_helper::$entity_to_load = null;
         $options['inNewIndividual'] = true;
         $options['lockable'] = $options['identifiers_lockable'];
         $new_individual = self::get_control_speciesidentifier($auth, $args, $tabalias, $options);
         unset($options['lockable']);
         $opts['codeGenerated'] = 'js';
         $photoJavascript = data_entry_helper::file_box($opts);
         data_entry_helper::$entity_to_load = $temp;
         unset($options['inNewIndividual']);
         data_entry_helper::$javascript .= "window.indicia.wwt.newIndividual = '" . str_replace(array('\'', "\n"), array('\\\'', ' '), $new_individual) . "';\n";
         // save the javascript needed for an additional colour-marked individual
         // process it to sanitise the string and remove comments (works now but not 100% reliable)
         data_entry_helper::$javascript .= "window.indicia.wwt.newJavascript = '" . str_replace(array('\'', "\n"), array('\\\'', ' '), str_replace('\\', '\\\\', preg_replace('#^\\s*//.+$#m', '', $photoJavascript))) . str_replace(array('\'', "\n", "\r"), array('\\\'', ' ', ' '), str_replace('\\', '\\\\', preg_replace('#^\\s*//.+$#m', '', $autoJavascript))) . "';\n";
         $r .= '<input type="button" id="idn:add-another" class="ui-state-default ui-corner-all" ' . 'value="' . lang::get('Add Another Bird at the Same Date and Location') . '" /><br />';
     }
     return $r;
 }
 /**
  * Outputs a file upload control suitable for linking images to records.
  * The control allows selection of multiple files, and depending on the browser functionality it gives progress feedback.
  * The control uses Silverlight, Flash or HTML5 to enhance the functionality where available. The output of the control 
  * can be configured by changing the content of the templates called file_box, file_box_initial_file_info, 
  * file_box_uploaded_image and button.
  *
  * @param array $options Options array with the following possibilities:<ul>
  * <li><b>table</b><br/>
  * Name of the image table to upload images into, e.g. occurrence_medium, location_medium, sample_medium or taxon_medium.
  * Defaults to occurrence_medium.
  * </li>
  * <li><b>loadExistingRecordKey</b><br/>
  * Optional prefix for the information in the data_entry_helper::$entity_to_load to use for loading any existing images. 
  * Defaults to use the table option.
  * </li>
  * <li><b>id</b><br/>
  * Optional. Provide a unique identifier for this image uploader control if more than one are required on the page.
  * </li>
  * <li><b>SubType</b><br/>
  * Optional. The name of the image sub-type to limit the file box to e.g. Image:Local:Sketch
  * </li>
  * <li><b>caption</b><br/>
  * Caption to display at the top of the uploader box. Defaults to the translated string for "Files".
  * </li>
  * <li><b>uploadSelectBtnCaption</b><br/>
  * Set this to override the caption for the button for selecting files to upload.
  * </li>
  * <li><b>uploadStartBtnCaption</b><br/>
  * Set this to override the caption for the start upload button, which is only visible if autoUpload is false.
  * </li>
  * <li><b>useFancybox</b><br/>
  * Defaults to true. If true, then image previews use the Fancybox plugin to display a "lightbox" effect when clicked on.
  * </li>
  * <li><b>imageWidth</b><br/>
  * Defaults to 200. Number of pixels wide the image previews should be.
  * </li>
  * <li><b>resizeWidth</b><br/>
  * If set, then the file will be resized before upload using this as the maximum pixels width.
  * </li>
  * <li><b>resizeHeight</b><br/>
  * If set, then the file will be resized before upload using this as the maximum pixels height.
  * </li>
  * <li><b>resizeQuality</b><br/>
  * Defines the quality of the resize operation (from 1 to 100). Has no effect unless either resizeWidth or resizeHeight are non-zero.
  * </li>
  * <li><b>upload</b><br/>
  * Boolean, defaults to true. 
  * </li>
  * <li><b>maxFileCount</b><br/>
  * Maximum number of files to allow upload for. Defaults to 4. Set to false to allow unlimited files.
  * </li>
  * <li><b>maxUploadSize</b><br/>
  * Maximum file size to allow in bytes. This limits file selection. PHP settings on 
  * server may limit upload. 
  * </li>
  * <li><b>autoupload</b><br/>
  * Defaults to true. If false, then a button is displayed which the user must click to initiate upload of the files
  * currently in the queue.
  * </li>
  * <li><b>msgUploadError</b><br/>
  * Use this to override the message displayed for a generic file upload error.
  * </li>
  * <li><b>msgFileTooBig</b><br/>
  * Use this to override the message displayed when the file is larger than the size limit allowed on the Warehouse.
  * </li>
  * <li><b>msgTooManyFiles</b><br/>
  * Use this to override the message displayed when attempting to upload more files than the maxFileCount allows. Use a
  * replacement string [0] to specify the maxFileCount value.
  * </li>
  * <li><b>uploadScript</b><br/>
  * Specify the script used to handle image uploads on the server (relative to the client_helpers folder). You should not
  * normally need to change this. Defaults to upload.php.
  * </li>
  * <li><b>runtimes</b><br/>
  * Array of runtimes that the file upload component will use in order of priority. Defaults to
  * array('html5','flash','silverlight','html4'), though flash is removed for Internet Explorer 6. You 
  * should not normally need to change this.
  * </li>
  * <li><b>destinationFolder</b><br/>
  * Override the destination folder for uploaded files. You should not normally need to change this.
  * </li>
  * <li><b>codeGenerated</b>
  * If set to all (default), then this returns the HTML required and also inserts JavaScript in the document onload event. However, if you
  * need to delay the loading of the control until a certain event, e.g. when a radio button is checked, then this can be set
  * to php to return just the php and ignore the JavaScript, or js to return the JavaScript instead of inserting it into
  * document onload, in which case the php is ignored. this allows you to attach the JavaScript to any event you need to.
  * </li>
  * <li><b>tabDiv</b><br/>
  * If loading this control onto a set of tabs, specify the tab control's div ID here. This allows the control to
  * automatically generate code which only generates the uploader when the tab is shown, reducing problems in certain
  * runtimes. This has no effect if codeGenerated is not left to the default state of all.
  * </li>
  * </ul>
  * The output of this control can be configured using the following templates: 
  * <ul>
  * <li><b>file_box</b></br>
  * Outputs the HTML container which will contain the upload button and images.
  * </li>
  * <li><b>file_box_initial_file_info</b></br>
  * HTML which provides the outer container for each displayed image, including the header and
  * remove file button. Has an element with class set to media-wrapper into which images 
  * themselves will be inserted.
  * </li>
  * <li><b>file_box_uploaded_image</b></br>
  * Template for the HTML for each uploaded image, including the image, caption input
  * and hidden inputs to define the link to the database. Will be inserted into the
  * file_box_initial_file_info template's media-wrapper element.
  * </li>
  * <li><b>button</b></br>
  * Template for the buttons used.
  * </li>
  * <li><b>readAuth</b><br/>
  * Optional. Read authentication tokens for the Indicia warehouse if using the 
  * add_link_popup.</li>
  * </ul>
  *
  * @todo select file button pointer overriden by the flash shim
  * @todo if using a normal file input, after validation, the input needs to show that the file upload has worked.
  * @todo Cleanup uploaded files that never got submitted because of validation failure elsewhere.
  */
 public static function file_box($options)
 {
     global $indicia_templates;
     // Upload directory defaults to client_helpers/upload, but can be overriden.
     $interim_image_folder = isset(parent::$interim_image_folder) ? parent::$interim_image_folder : 'upload/';
     $relpath = self::getRootFolder() . self::client_helper_path();
     //If a subType option is supplied, it means we only want to load a particular media type, not just any old media associated with the sample
     if (!empty($options['subType'])) {
         self::$upload_file_types[$options['subType']] = self::$upload_file_types['image'];
     }
     // Allow options to be defaulted and overridden
     $defaults = array('id' => 'default', 'upload' => true, 'maxFileCount' => 4, 'autoupload' => false, 'msgUploadError' => lang::get('upload error'), 'msgFileTooBig' => lang::get('file too big for warehouse'), 'runtimes' => array('html5', 'flash', 'silverlight', 'html4'), 'autoupload' => true, 'imageWidth' => 200, 'uploadScript' => $relpath . 'upload.php', 'destinationFolder' => $relpath . $interim_image_folder, 'finalImageFolder' => self::get_uploaded_image_folder(), 'jsPath' => self::$js_path, 'buttonTemplate' => $indicia_templates['button'], 'table' => 'occurrence_medium', 'maxUploadSize' => self::convert_to_bytes(isset(parent::$maxUploadSize) ? parent::$maxUploadSize : '4M'), 'codeGenerated' => 'all', 'mediaTypes' => !empty($options['subType']) ? array($options['subType']) : array('Image:Local'), 'fileTypes' => (object) self::$upload_file_types, 'imgPath' => empty(self::$images_path) ? self::relative_client_helper_path() . "../media/images/" : self::$images_path, 'addBtnCaption' => lang::get('Add {1}'), 'msgPhoto' => lang::get('photo'), 'msgFile' => lang::get('file'), 'msgLink' => lang::get('link'), 'msgNewImage' => lang::get('New {1}'), 'msgDelete' => lang::get('Delete this item'), 'msgUseAddFileBtn' => lang::get('Use the Add file button to select a file from your local disk. Files of type {1} are allowed.'), 'msgUseAddLinkBtn' => lang::get('Use the Add link button to add a link to information stored elsewhere on the internet. You can enter links from {1}.'));
     $defaults['caption'] = !isset($options['mediaTypes']) || $options['mediaTypes'] === array('Image:Local') ? lang::get('Photos') : lang::get('Media files');
     if (isset(self::$final_image_folder_thumbs)) {
         $defaults['finalImageFolderThumbs'] = $relpath . self::$final_image_folder_thumbs;
     }
     $browser = self::get_browser_info();
     // Flash doesn't seem to work on IE6.
     if ($browser['name'] == 'msie' && $browser['version'] < 7) {
         $defaults['runtimes'] = array_diff($defaults['runtimes'], array('flash'));
     }
     if ($indicia_templates['file_box'] != '') {
         $defaults['file_boxTemplate'] = $indicia_templates['file_box'];
     }
     if ($indicia_templates['file_box_initial_file_info'] != '') {
         $defaults['file_box_initial_file_infoTemplate'] = $indicia_templates['file_box_initial_file_info'];
     }
     if ($indicia_templates['file_box_uploaded_image'] != '') {
         $defaults['file_box_uploaded_imageTemplate'] = $indicia_templates['file_box_uploaded_image'];
     }
     $options = array_merge($defaults, $options);
     $options['id'] = $options['table'] . '-' . $options['id'];
     $containerId = 'container-' . $options['id'];
     if ($options['codeGenerated'] != 'php') {
         // build the JavaScript including the required file links
         self::add_resource('plupload');
         foreach ($options['runtimes'] as $runtime) {
             self::add_resource("plupload_{$runtime}");
         }
         // convert runtimes list to plupload format
         $options['runtimes'] = implode(',', $options['runtimes']);
         $javascript = "\n\$('#" . str_replace(':', '\\\\:', $containerId) . "').uploader({";
         // Just pass the options array through
         $idx = 0;
         foreach ($options as $option => $value) {
             if (is_array($value) || is_object($value)) {
                 $value = json_encode($value);
             } else {
                 // not an array, so wrap as string
                 $value = "'{$value}'";
             }
             $javascript .= "\n  {$option} : {$value}";
             // comma separated, except last entry
             if ($idx < count($options) - 1) {
                 $javascript .= ',';
             }
             $idx++;
         }
         //If the subType is specified, then this option is supplied as text by the user. So go and look up the ID to use in code.
         if (!empty($options['subType'])) {
             $typeTermData = self::get_population_data(array('table' => 'termlists_term', 'extraParams' => $options['readAuth'] + array('term' => $options['subType'], 'columns' => 'id')));
             $mediaTypeIdLimiter = $typeTermData[0]['id'];
         }
         // add in any reloaded items, when editing or after validation failure
         if (self::$entity_to_load) {
             //If we only want to display media of a particular type, then supply this as a parameter when extracting the media.
             if (!empty($mediaTypeIdLimiter)) {
                 $images = self::extract_media_data(self::$entity_to_load, isset($options['loadExistingRecordKey']) ? $options['loadExistingRecordKey'] : $options['table'], false, false, $mediaTypeIdLimiter);
             } else {
                 $images = self::extract_media_data(self::$entity_to_load, isset($options['loadExistingRecordKey']) ? $options['loadExistingRecordKey'] : $options['table']);
             }
             $javascript .= ",\n  existingFiles : " . json_encode($images);
         }
         $javascript .= "\n});\n";
     }
     if ($options['codeGenerated'] == 'js') {
         // we only want to return the JavaScript, so go no further.
         return $javascript;
     } elseif ($options['codeGenerated'] == 'all') {
         if (isset($options['tabDiv'])) {
             // The file box is displayed on a tab, so we must only generate it when the tab is displayed.
             $javascript = "var uploaderTabHandler = function(event, ui) { \n" . "  panel = typeof ui.newPanel==='undefined' ? ui.panel : ui.newPanel[0];\n" . "  if (\$(panel).attr('id')==='" . $options['tabDiv'] . "') {\n    " . $javascript . "    indiciaFns.unbindTabsActivate(\$(\$('#" . $options['tabDiv'] . "').parent()), uploaderTabHandler);\n" . "  }\n};\n" . "indiciaFns.bindTabsActivate(\$(\$('#" . $options['tabDiv'] . "').parent()), uploaderTabHandler);\n";
             // Insert this script at the beginning, because it must be done before the tabs are initialised or the
             // first tab cannot fire the event
             self::$javascript = $javascript . self::$javascript;
         } else {
             self::$onload_javascript .= $javascript;
         }
     }
     // Output a placeholder div for the jQuery plugin. Also output a normal file input for the noscripts
     // version.
     $r = '<div class="file-box" id="' . $containerId . '"></div><noscript>' . self::image_upload(array('label' => $options['caption'], 'id' => $options['id'], 'fieldname' => str_replace('_', ':', $options['table']))) . '</noscript>';
     $r .= self::add_link_popup($options);
     return $r;
 }
Пример #5
0
 /**
  * Helper function to collect javascript code in a single location. Should be called at the end of each HTML
  * page which uses the data entry helper so output all JavaScript required by previous calls.
  *
  * @return string JavaScript to insert into the page for all the controls added to the page so far.
  *
  * @link http://code.google.com/p/indicia/wiki/TutorialBuildingBasicPage#Build_a_data_entry_page
  */
 public static function dump_javascript()
 {
     // Add the default stylesheet to the end of the list, so it has highest CSS priority
     if (self::$default_styles) {
         self::add_resource('defaultStylesheet');
     }
     self::setup_jquery_validation_js();
     $dump = self::internal_dump_javascript(self::$javascript, self::$late_javascript, self::$onload_javascript, self::$required_resources);
     // ensure scripted JS does not output again if recalled.
     self::$javascript = "";
     self::$late_javascript = "";
     self::$onload_javascript = "";
     return $dump;
 }
Пример #6
0
 /**
  * Helper function to collect javascript code in a single location. Should be called at the end of each HTML
  * page which uses the data entry helper so output all JavaScript required by previous calls.
  *
  * @return string JavaScript to insert into the page for all the controls added to the page so far.
  *
  * @link http://code.google.com/p/indicia/wiki/TutorialBuildingBasicPage#Build_a_data_entry_page
  */
 public static function dump_javascript()
 {
     global $indicia_resources, $indicia_templates;
     // Add the default stylesheet to the end of the list, so it has highest CSS priority
     if (self::$default_styles) {
         self::add_resource('defaultStylesheet');
     }
     // If required, setup jQuery validation. We can't prep this JavaScript earlier since we would
     // not know all the control messages.
     // In the following block, we set the validation plugin's error class to our template.
     // We also define the error label to be wrapped in a <p> if it is on a newline.
     if (self::$validated_form_id) {
         self::$javascript .= "\$('#" . self::$validated_form_id . "').validate({\n        errorClass: \"" . $indicia_templates['error_class'] . "\",\n        " . (in_array('inline', self::$validation_mode) ? "\n      " : "errorElement: 'p',\n      ") . "highlight: function(element, errorClass) {\n           // Don't highlight the actual control, as it could be hidden anyway\n        },\n        messages: " . json_encode(self::$validation_messages) . "\n      });\n";
     }
     $dump = self::internal_dump_javascript(self::$javascript, self::$late_javascript, self::$onload_javascript, $indicia_resources);
     // ensure scripted JS does not output again if recalled.
     self::$javascript = "";
     self::$late_javascript = "";
     self::$onload_javascript = "";
     return $dump;
 }
Пример #7
0
 /**
  * Outputs a file upload control suitable for linking images to records.
  * The control allows selection of multiple files, and depending on the browser functionality it gives progress feedback.
  * The control uses Silverlight, Flash or HTML5 to enhance the functionality where available. The output of the control 
  * can be configured by changing the content of the templates called file_box, file_box_initial_file_info, 
  * file_box_uploaded_image and button.
  *
  * @param array $options Options array with the following possibilities:<ul>
  * <li><b>table</b><br/>
  * Name of the image table to upload images into, e.g. occurrence_medium, location_medium, sample_medium or taxon_medium.
  * Defaults to occurrence_medium.
  * </li>
  * <li><b>loadExistingRecordKey</b><br/>
  * Optional prefix for the information in the data_entry_helper::$entity_to_load to use for loading any existing images. 
  * Defaults to use the table option.
  * </li>
  * <li><b>id</b><br/>
  * Optional. Provide a unique identifier for this image uploader control if more than one are required on the page.
  * </li>
  * <li><b>caption</b><br/>
  * Caption to display at the top of the uploader box. Defaults to the translated string for "Files".
  * </li>
  * <li><b>uploadSelectBtnCaption</b><br/>
  * Set this to override the caption for the button for selecting files to upload.
  * </li>
  * <li><b>uploadStartBtnCaption</b><br/>
  * Set this to override the caption for the start upload button, which is only visible if autoUpload is false.
  * </li>
  * <li><b>useFancybox</b><br/>
  * Defaults to true. If true, then image previews use the Fancybox plugin to display a "lightbox" effect when clicked on.
  * </li>
  * <li><b>imageWidth</b><br/>
  * Defaults to 200. Number of pixels wide the image previews should be.
  * </li>
  * <li><b>resizeWidth</b><br/>
  * If set, then the file will be resized before upload using this as the maximum pixels width.
  * </li>
  * <li><b>resizeHeight</b><br/>
  * If set, then the file will be resized before upload using this as the maximum pixels height.
  * </li>
  * <li><b>resizeQuality</b><br/>
  * Defines the quality of the resize operation (from 1 to 100). Has no effect unless either resizeWidth or resizeHeight are non-zero.
  * </li>
  * <li><b>upload</b><br/>
  * Boolean, defaults to true. 
  * </li>
  * <li><b>maxFileCount</b><br/>
  * Maximum number of files to allow upload for. Defaults to 4. Set to false to allow unlimited files.
  * </li>
  * <li><b>autoupload</b><br/>
  * Defaults to true. If false, then a button is displayed which the user must click to initiate upload of the files
  * currently in the queue.
  * </li>
  * <li><b>msgUploadError</b><br/>
  * Use this to override the message displayed for a generic file upload error.
  * </li>
  * <li><b>msgFileTooBig</b><br/>
  * Use this to override the message displayed when the file is larger than the size limit allowed on the Warehouse.
  * </li>
  * <li><b>msgTooManyFiles</b><br/>
  * Use this to override the message displayed when attempting to upload more files than the maxFileCount allows. Use a
  * replacement string [0] to specify the maxFileCount value.
  * </li>
  * <li><b>uploadScript</b><br/>
  * Specify the script used to handle image uploads on the server (relative to the client_helpers folder). You should not
  * normally need to change this. Defaults to upload.php.
  * </li>
  * <li><b>runtimes</b><br/>
  * Array of runtimes that the file upload component will use in order of priority. Defaults to
  * array('html5','flash','silverlight','html4'), though flash is removed for Internet Explorer 6. You 
  * should not normally need to change this.
  * </li>
  * <li><b>destinationFolder</b><br/>
  * Override the destination folder for uploaded files. You should not normally need to change this.
  * </li>
  * <li><b>codeGenerated</b>
  * If set to all (default), then this returns the HTML required and also inserts JavaScript in the document onload event. However, if you
  * need to delay the loading of the control until a certain event, e.g. when a radio button is checked, then this can be set
  * to php to return just the php and ignore the JavaScript, or js to return the JavaScript instead of inserting it into
  * document onload, in which case the php is ignored. this allows you to attach the JavaScript to any event you need to.
  * </li>
  * <li><b>tabDiv</b><br/>
  * If loading this control onto a set of tabs, specify the tab control's div ID here. This allows the control to
  * automatically generate code which only generates the uploader when the tab is shown, reducing problems in certain
  * runtimes. This has no effect if codeGenerated is not left to the default state of all.
  * </li>
  * </ul>
  * The output of this control can be configured using the following templates: 
  * <ul>
  * <li><b>file_box</b></br>
  * Outputs the HTML container which will contain the upload button and images.
  * </li>
  * <li><b>file_box_initial_file_info</b></br>
  * HTML which provides the outer container for each displayed image, including the header and
  * remove file button. Has an element with class set to media-wrapper into which images 
  * themselves will be inserted.
  * </li>
  * <li><b>file_box_uploaded_image</b></br>
  * Template for the HTML for each uploaded image, including the image, caption input
  * and hidden inputs to define the link to the database. Will be inserted into the
  * file_box_initial_file_info template's media-wrapper element.
  * </li>
  * <li><b>button</b></br>
  * Template for the buttons used.
  * </li>
  * </ul>
  *
  * @todo select file button pointer overriden by the flash shim
  * @todo if using a normal file input, after validation, the input needs to show that the file upload has worked.
  * @todo Cleanup uploaded files that never got submitted because of validation failure elsewhere.
  */
 public static function file_box($options)
 {
     global $indicia_templates;
     // Upload directory defaults to client_helpers/upload, but can be overriden.
     $interim_image_folder = isset(parent::$interim_image_folder) ? parent::$interim_image_folder : 'upload/';
     $relpath = self::getRootFolder() . self::client_helper_path();
     // Allow options to be defaulted and overridden
     $defaults = array('caption' => lang::get('Files'), 'id' => 'default', 'upload' => true, 'maxFileCount' => 4, 'autoupload' => false, 'msgUploadError' => lang::get('upload error'), 'msgFileTooBig' => lang::get('file too big for warehouse'), 'runtimes' => array('html5', 'flash', 'silverlight', 'html4'), 'autoupload' => true, 'imageWidth' => 200, 'uploadScript' => $relpath . 'upload.php', 'destinationFolder' => $relpath . $interim_image_folder, 'finalImageFolder' => self::get_uploaded_image_folder(), 'jsPath' => self::$js_path, 'buttonTemplate' => $indicia_templates['button'], 'table' => 'occurrence_medium', 'maxUploadSize' => self::convert_to_bytes(isset(parent::$maxUploadSize) ? parent::$maxUploadSize : '4M'), 'codeGenerated' => 'all', 'mediaTypes' => array('Image:Local'), 'imgPath' => empty(self::$images_path) ? self::relative_client_helper_path() . "../media/images/" : self::$images_path);
     if (isset(self::$final_image_folder_thumbs)) {
         $defaults['finalImageFolderThumbs'] = $relpath . self::$final_image_folder_thumbs;
     }
     $browser = self::get_browser_info();
     // Flash doesn't seem to work on IE6.
     if ($browser['name'] == 'msie' && $browser['version'] < 7) {
         $defaults['runtimes'] = array_diff($defaults['runtimes'], array('flash'));
     }
     if ($indicia_templates['file_box'] != '') {
         $defaults['file_boxTemplate'] = $indicia_templates['file_box'];
     }
     if ($indicia_templates['file_box_initial_file_info'] != '') {
         $defaults['file_box_initial_file_infoTemplate'] = $indicia_templates['file_box_initial_file_info'];
     }
     if ($indicia_templates['file_box_uploaded_image'] != '') {
         $defaults['file_box_uploaded_imageTemplate'] = $indicia_templates['file_box_uploaded_image'];
     }
     $options = array_merge($defaults, $options);
     $options['id'] = $options['table'] . '-' . $options['id'];
     $containerId = 'container-' . $options['id'];
     if ($options['codeGenerated'] != 'php') {
         // build the JavaScript including the required file links
         self::add_resource('plupload');
         foreach ($options['runtimes'] as $runtime) {
             self::add_resource("plupload_{$runtime}");
         }
         // convert runtimes list to plupload format
         $options['runtimes'] = implode(',', $options['runtimes']);
         $javascript = "\n\$('#" . str_replace(':', '\\\\:', $containerId) . "').uploader({";
         // Just pass the options array through
         $idx = 0;
         foreach ($options as $option => $value) {
             if (is_array($value)) {
                 $value = json_encode($value);
             } else {
                 // not an array, so wrap as string
                 $value = "'{$value}'";
             }
             $javascript .= "\n  {$option} : {$value}";
             // comma separated, except last entry
             if ($idx < count($options) - 1) {
                 $javascript .= ',';
             }
             $idx++;
         }
         // add in any reloaded items, when editing or after validation failure
         if (self::$entity_to_load) {
             $images = self::extract_media_data(self::$entity_to_load, isset($options['loadExistingRecordKey']) ? $options['loadExistingRecordKey'] : $options['table']);
             $javascript .= ",\n  existingFiles : " . json_encode($images);
         }
         $javascript .= "\n});\n";
     }
     if ($options['codeGenerated'] == 'js') {
         // we only want to return the JavaScript, so go no further.
         return $javascript;
     } elseif ($options['codeGenerated'] == 'all') {
         if (isset($options['tabDiv'])) {
             // The file box is displayed on a tab, so we must only generate it when the tab is displayed.
             $javascript = "var uploaderTabHandler = function(event, ui) { \n" . "  if (ui.panel.id=='" . $options['tabDiv'] . "') {\n    " . $javascript . "    jQuery(jQuery('#" . $options['tabDiv'] . "').parent()).unbind('tabsshow', uploaderTabHandler);\n" . "  }\n};\n" . "jQuery(jQuery('#" . $options['tabDiv'] . "').parent()).bind('tabsshow', uploaderTabHandler);\n";
             // Insert this script at the beginning, because it must be done before the tabs are initialised or the
             // first tab cannot fire the event
             self::$javascript = $javascript . self::$javascript;
         } else {
             self::$onload_javascript .= $javascript;
         }
     }
     // Output a placeholder div for the jQuery plugin. Also output a normal file input for the noscripts
     // version.
     $r = '<div class="file-box" id="' . $containerId . '"></div><noscript>' . self::image_upload(array('label' => $options['caption'], 'id' => $options['id'], 'fieldname' => str_replace('_', ':', $options['table']))) . '</noscript>';
     $r .= self::add_link_popup($options);
     return $r;
 }
Пример #8
0
 private static function get_site_tab($auth, $args, $settings)
 {
     $r = '<div id="site-details" class="ui-helper-clearfix">';
     $r .= '<form method="post" id="input-form">';
     $r .= $auth['write'];
     $r .= '<fieldset><legend>' . lang::get('Site Details') . '</legend>';
     $r .= "<input type=\"hidden\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" name=\"survey_id\" value=\"" . $args['survey_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" name=\"location:location_type_id\" value=\"" . $settings['SiteLocationType'][0]['id'] . "\" />\n";
     if ($settings['locationId']) {
         $r .= '<input type="hidden" name="location:id" id="location:id" value="' . $settings['locationId'] . "\" />\n";
     }
     $r .= data_entry_helper::text_input(array('fieldname' => 'location:name', 'label' => lang::get('Site Name'), 'class' => 'control-width-4 required'));
     $r .= data_entry_helper::sref_and_system(array('fieldname' => 'location:centroid_sref', 'geomFieldname' => 'location:centroid_geom', 'label' => 'Site Central Grid Ref', 'systems' => array('4326' => '4326'), 'class' => 'required', 'disabled' => ' readonly="readonly" ', 'helpText' => lang::get('The following field is filled in automatically when the site is drawn on the map.')));
     $r .= '<input type="hidden" name="location:boundary_geom" id="imp-boundary-geom" value="' . data_entry_helper::$entity_to_load['location:boundary_geom'] . '"/>';
     // setup the map options
     $options = iform_map_get_map_options($args, $auth['read']);
     $r .= get_attribute_html($settings['attributes'], $args, array('extraParams' => $auth['read']));
     $r .= '</fieldset>';
     if (!$settings['locationId']) {
         $help = lang::get('Use the search box to find a nearby town or village, then drag the map to pan and zoom in or out to find your site.');
         $r .= '<p class="ui-state-highlight page-notice ui-corner-all">' . $help . '</p>';
         $r .= data_entry_helper::georeference_lookup(array('label' => lang::get('Search for place'), 'driver' => $args['georefDriver'], 'georefPreferredArea' => $args['georefPreferredArea'], 'georefCountry' => $args['georefCountry'], 'georefLang' => $args['language'], 'readAuth' => $auth['read']));
     }
     $help = '<p>' . lang::get('Draw your site by selecting the appropriate tool in the top right of the map') . ':</p>' . '<ol><li>' . lang::get('Navigation Tool. This allows you to navigate around the map by dragging.') . '</li>' . '<li>' . lang::get('Draw Site Tool. This tool allows you to draw your site on the map. Click on the map to start drawing, and click each time you wish to fix a point on the outline of your site.  <b>Double click the last fixed point to finish drawing</b>. Double clicking will replace any previously drawn site outline.') . '</li>' . '<li>' . lang::get('Modify Site Tool. This tool allows you to change the shape of a previously drawn site. Click on the existing site outline to add grab points (circles) along it. You can then click and drag these points to change the shape of the site. To remove a fixed point, hover your mouse over the point and press the "Delete" button on your keyboard.') . '</li></ol>';
     if ($args['allow_user_assignment']) {
         if ($settings['canAllocUser']) {
             $help .= '<p>' . lang::get('You, as a scheme administrator, have the option of changing who the site is assigned to, using control under the map. If you so wish, the site may be assigned to more than one person at a time.') . '</p>';
         }
     }
     $r .= '<div class="page-notice ui-state-highlight ui-corner-all">' . $help . '</div>';
     if (isset($args['maxPrecision']) && $args['maxPrecision'] != '') {
         $options['clickedSrefPrecisionMax'] = $args['maxPrecision'];
     }
     if (isset($args['minPrecision']) && $args['minPrecision'] != '') {
         $options['clickedSrefPrecisionMin'] = $args['minPrecision'];
     }
     $olOptions = iform_map_get_ol_options($args);
     $options['clickForSpatialRef'] = false;
     $options['allowPolygonRecording'] = true;
     $options['latLongFormat'] = 'DMS';
     $options['autoFillInCentroid'] = true;
     $options['initialFeatureWkt'] = false;
     $options['initialBoundaryWkt'] = data_entry_helper::$entity_to_load['location:boundary_geom'];
     $options['hintModifyFeature'] = lang::get('Modify Site Tool.');
     $options['hintDrawPolygonHint'] = lang::get('Draw Site Tool.');
     $options['hintNavigation'] = lang::get('Navigation Tool.');
     $options['searchDisplaysPoint'] = false;
     // with multiple maps can't use built in method on tabshow, so do here...
     $divId = preg_replace('/[^a-zA-Z0-9]/', '', 'site-details');
     $javascript = "var mapTabHandler = function(event, ui) { \n";
     $javascript .= "  panel = typeof ui.newPanel==='undefined' ? ui.panel : ui.newPanel[0];\n  if (panel.id=='site-details' && typeof indiciaData.mapdiv !== 'undefined') {\n    var map = jQuery('#map')[0].map;\n    map.updateSize();\n    var layerBounds = map.editLayer.getDataExtent().clone(); // use a clone\n    map.zoomToExtent(layerBounds);\n  }\n};\nindiciaFns.bindTabsActivate(jQuery(jQuery('#site-details').parent()), mapTabHandler);\n";
     // Insert this script at the beginning, because it must be done before the tabs are initialised or the
     // first tab cannot fire the event
     data_entry_helper::$javascript = $javascript . data_entry_helper::$javascript;
     $r .= map_helper::map_panel($options, $olOptions);
     if ($args['allow_user_assignment']) {
         if ($settings['canAllocUser']) {
             $r .= self::get_user_assignment_control($auth['read'], $settings['cmsUserAttr'], $args);
         } else {
             if (!$settings['locationId']) {
                 // for a new record, we need to link the current user to the location if they are not admin.
                 global $user;
                 self::get_user_assignment_control($auth['read'], $settings['cmsUserAttr'], $args);
                 // this will populate the recorder list.
                 $r .= '<input type="hidden" name="locAttr:' . self::$cmsUserAttrId . '" value="' . $user->uid . '">';
             }
         }
     }
     $r .= '<button type="submit" class="indicia-button right">' . lang::get('Save') . '</button>';
     if ($settings['locationId']) {
         $r .= '<button type="button" class="indicia-button right" id="delete-site">' . lang::get('Delete') . '</button>';
     }
     $r .= '</form>';
     $r .= '</div>';
     // site-details
     if ($settings['locationId']) {
         $treeIDs = array();
         foreach ($settings['trees'] as $id => $tree) {
             $treeIDs[] = $tree['id'];
         }
         data_entry_helper::$javascript .= "\ndeleteSite = function(){\n  if(confirm(\"" . lang::get('Are you sure you wish to delete this location?') . "\")){\n    deleteTrees([" . implode(',', $treeIDs) . "]);\n    \$('#delete-site').html('Deleting Site');\n    deleteLocation(" . $settings['locationId'] . ");\n    \$('#delete-site').html('Done');\n    window.location='" . url($args['sites_list_path']) . "';\n  };\n};\n\$('#delete-site').click(deleteSite);\n";
     }
     return $r;
 }