예제 #1
0
 /**
  * Converts the posted form values for a group into a warehouse submission.
  * @param array $values Form values
  * @param array $args Form configuration arguments
  * @return array Submission data
  */
 public static function get_submission($values, $args)
 {
     $struct = array('model' => 'group');
     if (!empty($values['filter:title'])) {
         $struct['superModels'] = array('filter' => array('fk' => 'filter_id'));
     }
     if (!empty($args['parent_group_relationship_type']) && !empty($_REQUEST['from_group_id'])) {
         // $from_group_id could be posted in the form if user selectable or provided in the URL if fixed.
         $from_group_id = empty($_GET['from_group_id']) ? $_POST['from_group_id'] : $_GET['from_group_id'];
         $struct['subModels'] = array('group_relation' => array('fk' => 'to_group_id'));
         $values['group_relation:from_group_id'] = $from_group_id;
         $values['group_relation:relationship_type_id'] = $args['parent_group_relationship_type'];
     }
     $s = submission_builder::build_submission($values, $struct);
     // scan the posted values for group pages. This search grabs the first column value keys.
     $pageKeys = preg_grep('/^group\\+:pages:\\d*:\\d+:0$/', array_keys($values));
     $pages = array();
     foreach ($pageKeys as $key) {
         // skip empty rows, unless they were rows loaded for an existing group_pages record
         if (!empty($values[$key]) || preg_match('/^group\\+:pages:(\\d+)/', $key)) {
             // get the key without the column index, so we can access any column we want
             $base = preg_replace('/0$/', '', $key);
             if (isset($values[$base . 'deleted']) && $values[$base . 'deleted'] === 't' || empty($values[$base . '0'])) {
                 $page = array('deleted' => 't');
             } else {
                 $tokens = explode(':', $values[$base . '0']);
                 $path = $tokens[0];
                 $caption = empty($values[$base . '1']) ? $tokens[1] : $values[$base . '1'];
                 $administrator = explode(':', $values[$base . '2']);
                 $administrator = empty($administrator) ? 'f' : $administrator[0];
                 $page = array('caption' => $caption, 'path' => $path, 'administrator' => $administrator);
             }
             // if existing group page, hook up to the id
             if (preg_match('/^group\\+:pages:(\\d+)/', $key, $matches)) {
                 $page['id'] = $matches[1];
             }
             $pages[] = $page;
         }
     }
     if (!empty($pages)) {
         if (!isset($s['subModels'])) {
             $s['subModels'] = array();
         }
         foreach ($pages as $page) {
             $s['subModels'][] = array('fkId' => 'group_id', 'model' => array('id' => 'group_page', 'fields' => $page));
         }
     }
     // need to manually build the submission for the admins sub_list, since we are hijacking what is
     // intended to be a custom attribute control
     if (self::extractUserInfoFromFormValues($s, $values, 'admin_user_id', 't') === 0 && empty($values['group:id'])) {
         // no admins created when setting up the group initially, so need to set the current user as an admin
         $s['subModels'][] = array('fkId' => 'group_id', 'model' => submission_builder::wrap(array('user_id' => hostsite_get_user_field('indicia_user_id'), 'administrator' => 't'), 'groups_user'));
     }
     self::extractUserInfoFromFormValues($s, $values, 'user_id', 'f');
     self::deleteExistingUsers($s, $values);
     return $s;
 }
 /**
  * Helper function to simplify building of a submission. Does simple submissions that do not involve
  * species checklist grids.
  * @param array $values List of the posted values to create the submission from.
  * @param array $structure Describes the structure of the submission. The form should be:
  * array(
  *     'model' => 'main model name',
  *     'subModels' => array('child model name' =>  array(
  *         'fieldPrefix'=>'Optional prefix for HTML form fields in the sub model. If not specified then the sub model name is used.',
  *         'fk' => 'foreign key name',
  *         'image_entity' => 'name of image entity if present'
  *     )),
  *     'superModels' => array('child model name' =>  array(
  *         'fieldPrefix'=>'Optional prefix for HTML form fields in the sub model. If not specified then the sub model name is used.',
  *         'fk' => 'foreign key name',
  *         'image_entity' => 'name of image entity if present'
  *     )),
  *     'metaFields' => array('fieldname1', 'fieldname2', ...)
  * )
  */
 public static function build_submission($values, $structure)
 {
     return submission_builder::build_submission($values, $structure);
 }
예제 #3
0
 /**
  * Handles the construction of a submission array from a set of form values.
  * @param array $values Associative array of form data values. 
  * @param array $args iform parameters. 
  * @return array Submission structure.
  */
 public static function get_submission($values, $args)
 {
     if (array_key_exists('newsample_parent_id', $_POST)) {
         // $mode = MODE_NEW_OCCURRENCE
         return null;
     }
     if (array_key_exists('sample:parent_id', $_POST)) {
         //  $mode = MODE_POST_OCCURRENCE;
         // Can't call getGridMode in this context as we might not have the $_GET value to indicate grid
         if (isset($values['gridmode'])) {
             return data_entry_helper::build_sample_occurrences_list_submission($values);
         } else {
             return data_entry_helper::build_sample_occurrence_submission($values);
         }
     } else {
         //  $mode = MODE_POST_SUPERSAMPLE;
         return submission_builder::build_submission($values, $structure = array('model' => 'sample'));
     }
 }
예제 #4
0
 /**
  * Wraps a standard $_POST type array into a save array suitable for use in saving
  * records.
  *
  * @param array $array Array to wrap
  * @param bool $fkLink=false Link foreign keys?
  * @return array Wrapped array
  */
 protected function wrap($array, $fkLink = false)
 {
     // share the wrapping library with the client helpers
     require_once DOCROOT . 'client_helpers/submission_builder.php';
     $r = submission_builder::build_submission($array, $this->get_submission_structure());
     // Map fk_* fields to the looked up id
     if ($fkLink) {
         $r = $this->getFkFields($r, $array);
     }
     if (array_key_exists('superModels', $r)) {
         $idx = 0;
         foreach ($r['superModels'] as $super) {
             $r['superModels'][$idx]['model'] = $this->getFkFields($super['model'], $array);
             $idx++;
         }
     }
     return $r;
 }
 /**
  * Handles the construction of a submission array from a set of form values.
  * @param array $values Associative array of form data values.
  * @param array $args iform parameters.
  * @return array Submission structure.
  */
 public static function get_submission($values, $args)
 {
     $values['sample:location_name'] = $values['sample:entered_sref'];
     $submission = submission_builder::build_submission($values, array('model' => 'sample'));
     return $submission;
 }
 /**
  * Handles the construction of a submission array from a set of form values.
  * For example, the following represents a submission structure for a simple
  * sample and 1 occurrence submission
  * return data_entry_helper::build_sample_occurrence_submission($values);
  * @param array $values Associative array of form data values. 
  * @param array $args iform parameters. 
  * @return array Submission structure.
  * @todo: Implement this method
  */
 public static function get_submission($values, $args)
 {
     if (!isset($values['page']) || $values['page'] != 'grid') {
         // submitting the first page, with top level sample details
         if (!isset($values['sample:entered_sref'])) {
             // the sample does not have sref data, as the user has just picked a transect site at this point. Copy the
             // site's centroid across to the sample.
             $read = array('nonce' => $values['read_nonce'], 'auth_token' => $values['read_auth_token']);
             $site = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $read + array('view' => 'detail', 'id' => $values['sample:location_id'], 'deleted' => 'f')));
             $site = $site[0];
             $values['sample:entered_sref'] = $site['centroid_sref'];
             $values['sample:entered_sref_system'] = $site['centroid_sref_system'];
         }
     }
     $submission = submission_builder::build_submission($values, array('model' => 'sample'));
     return $submission;
 }
예제 #7
0
 public static function create_submission($values, $args)
 {
     $structure = array('model' => 'location');
     // Either an uploadable file, or a link to a Flickr external detail means include the submodel
     // (Copied from data_entry_helper::build_sample_occurrence_submission. If file_box control is used
     // then build_submission calls wrap_with_images instead)
     if (array_key_exists('location:image', $values) && $values['location:image'] || array_key_exists('location_image:external_details', $values) && $values['location_image:external_details']) {
         $structure['submodel'] = array('model' => 'location_image', 'fk' => 'location_id');
     }
     $s = submission_builder::build_submission($values, $structure);
     // On first save of a new location, link it to the website.
     // Be careful not to over-write other subModels (e.g. images)
     if (empty($values['location:id'])) {
         $s['subModels'][] = array('fkId' => 'location_id', 'model' => array('id' => 'locations_website', 'fields' => array('website_id' => $args['website_id'])));
     }
     return $s;
 }
 /**
  * Builds a submission for identifiers_subject_observation join data 
  * from the form values. Also adds identifier if it doesn't exist.
  * @param array $values Associative array of form data values. 
  * @param array $matches Associative array of stored identifiers which match submitted values. 
  * @param array $so The subject_observation submission we are adding to
  * @return array subject_observation Submission structure with identifier data added.
  */
 private static function build_identifier_observation_submission($values, $matches, $so)
 {
     // work out what to do, insert?, update? delete?
     $set = $values['identifier:checkbox'] == 1;
     $code = $values['identifier:coded_value'];
     $old_id = (int) $values['identifier:id'];
     $new_id = 0;
     $identifier_status = 'U';
     foreach ($matches as $match) {
         if ($match['coded_value'] === $code) {
             $new_id = (int) $match['id'];
             $identifier_status = $match['status'];
         }
     }
     // see if we have any updates on the isoAttr
     $isoAttrUpdated = count(preg_grep('/^isoAttr:[0-9]+$/', array_keys($values))) > 0;
     if (!$isoAttrUpdated) {
         $keys = preg_grep('/^isoAttr:[0-9]+:[0-9]+$/', array_keys($values));
         foreach ($keys as $key) {
             if ($values[$key] === '') {
                 $isoAttrUpdated = true;
                 break;
             }
         }
     }
     // this identifier exists but its identity has been changed
     if ($old_id > 0 && $old_id !== $new_id) {
         // unlink the old identifier
         $values['identifiers_subject_observation:deleted'] = 't';
         $iso = submission_builder::build_submission($values, array('model' => 'identifiers_subject_observation'));
         $so['subModels'][] = array('fkId' => 'subject_observation_id', 'model' => $iso);
     }
     // identifier submitted, has been edited and matches an existing identifier
     if ($set && $new_id > 0 && $old_id !== $new_id) {
         // create link to the new matching identifier
         unset($values['identifiers_subject_observation:id']);
         $values['identifiers_subject_observation:identifier_id'] = $new_id;
         $values['identifiers_subject_observation:matched'] = $identifier_status !== 'U' ? 't' : 'f';
         unset($values['identifiers_subject_observation:verified_status']);
         unset($values['identifiers_subject_observation:verified_by_id']);
         unset($values['identifiers_subject_observation:verified_on']);
         unset($values['identifiers_subject_observation:created_on']);
         unset($values['identifiers_subject_observation:created_by_id']);
         unset($values['identifiers_subject_observation:updated_on']);
         unset($values['identifiers_subject_observation:updated_by_id']);
         unset($values['identifiers_subject_observation:deleted']);
         $iso = submission_builder::build_submission($values, array('model' => 'identifiers_subject_observation'));
         $so['subModels'][] = array('fkId' => 'subject_observation_id', 'model' => $iso);
     }
     // identifier submitted and doesn't match an existing identifier
     if ($set && $new_id === 0) {
         // create new link to a new identifier which we also create here
         unset($values['identifiers_subject_observation:id']);
         unset($values['identifiers_subject_observation:identifier_id']);
         $values['identifiers_subject_observation:matched'] = 'f';
         unset($values['identifiers_subject_observation:verified_status']);
         unset($values['identifiers_subject_observation:verified_by_id']);
         unset($values['identifiers_subject_observation:verified_on']);
         unset($values['identifiers_subject_observation:created_on']);
         unset($values['identifiers_subject_observation:created_by_id']);
         unset($values['identifiers_subject_observation:updated_on']);
         unset($values['identifiers_subject_observation:updated_by_id']);
         unset($values['identifiers_subject_observation:deleted']);
         $iso = submission_builder::build_submission($values, array('model' => 'identifiers_subject_observation'));
         // now add the identifier
         unset($values['identifier:id']);
         unset($values['identifier:issue_authority_id']);
         unset($values['identifier:issue_scheme_id']);
         unset($values['identifier:issue_date']);
         unset($values['identifier:first_use_date']);
         unset($values['identifier:last_observed_date']);
         unset($values['identifier:final_date']);
         unset($values['identifier:summary']);
         unset($values['identifier:status']);
         unset($values['identifier:verified_by_id']);
         unset($values['identifier:verified_on']);
         unset($values['identifier:known_subject_id']);
         unset($values['identifier:created_on']);
         unset($values['identifier:created_by_id']);
         unset($values['identifier:updated_on']);
         unset($values['identifier:updated_by_id']);
         unset($values['identifier:deleted']);
         $i = submission_builder::build_submission($values, array('model' => 'identifier'));
         $iso['superModels'] = array(array('fkId' => 'identifier_id', 'model' => $i));
         $so['subModels'][] = array('fkId' => 'subject_observation_id', 'model' => $iso);
     }
     // identifier exists and is unchanged but has iso attributes which have changed
     if ($old_id > 0 && $old_id === $new_id && $isoAttrUpdated) {
         // update link to trigger update to isoAttr
         $iso = submission_builder::build_submission($values, array('model' => 'identifiers_subject_observation'));
         $so['subModels'][] = array('fkId' => 'subject_observation_id', 'model' => $iso);
     }
     return $so;
 }
예제 #9
0
 /**
  * Handles the construction of a submission array from a set of form values.
  * @param array $values Associative array of form data values. 
  * @param array $args iform parameters. 
  * @return array Submission structure.
  */
 public static function get_submission($values, $args)
 {
     $structure = array('model' => 'person');
     $s = submission_builder::build_submission($values, $structure);
     return $s;
 }
 /**
  * Handles the construction of a submission array from a set of form values.
  * @param array $values Associative array of form data values.
  * @param array $args iform parameters.
  * @return array Submission structure.
  * @todo: Implement this method
  */
 public static function get_submission($values, $args)
 {
     $subsampleModels = array();
     if (isset($values['page']) && $values['page'] == 'speciesmap') {
         $submission = data_entry_helper::build_sample_subsamples_occurrences_submission($values);
     } else {
         if (!isset($values['page']) || $values['page'] == 'mainSample') {
             // submitting the first page, with top level sample details
             $read = array('nonce' => $values['read_nonce'], 'auth_token' => $values['read_auth_token']);
             if (!isset($values['sample:entered_sref'])) {
                 // the sample does not have sref data, as the user has just picked a transect site at this point. Copy the
                 // site's centroid across to the sample. Should this be cached?
                 $site = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $read + array('view' => 'detail', 'id' => $values['sample:location_id'], 'deleted' => 'f')));
                 $site = $site[0];
                 $values['sample:entered_sref'] = $site['centroid_sref'];
                 $values['sample:entered_sref_system'] = $site['centroid_sref_system'];
             }
             // Build the subsamples
             $sections = data_entry_helper::get_population_data(array('table' => 'location', 'extraParams' => $read + array('view' => 'detail', 'parent_id' => $values['sample:location_id'], 'deleted' => 'f'), 'nocache' => true));
             if (isset($values['sample:id'])) {
                 $existingSubSamples = data_entry_helper::get_population_data(array('table' => 'sample', 'extraParams' => $read + array('view' => 'detail', 'parent_id' => $values['sample:id'], 'deleted' => 'f'), 'nocache' => true));
             } else {
                 $existingSubSamples = array();
             }
             $sampleMethods = helper_base::get_termlist_terms(array('read' => $read), 'indicia:sample_methods', array('Transect Section'));
             $attributes = data_entry_helper::getAttributes(array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $read, 'survey_id' => $values['sample:survey_id'], 'sample_method_id' => $sampleMethods[0]['id'], 'multiValue' => false));
             $smpDate = self::parseSingleDate($values['sample:date']);
             foreach ($sections as $section) {
                 $smp = false;
                 $exists = false;
                 foreach ($existingSubSamples as $existingSubSample) {
                     if ($existingSubSample['location_id'] == $section['id']) {
                         $exists = $existingSubSample;
                         break;
                     }
                 }
                 if (!$exists) {
                     $smp = array('fkId' => 'parent_id', 'model' => array('id' => 'sample', 'fields' => array('survey_id' => array('value' => $values['sample:survey_id']), 'website_id' => array('value' => $values['website_id']), 'date' => array('value' => $values['sample:date']), 'location_id' => array('value' => $section['id']), 'entered_sref' => array('value' => $section['centroid_sref']), 'entered_sref_system' => array('value' => $section['centroid_sref_system']), 'sample_method_id' => array('value' => $sampleMethods[0]['id']))), 'copyFields' => array('date_start' => 'date_start', 'date_end' => 'date_end', 'date_type' => 'date_type'));
                     foreach ($attributes as $attr) {
                         foreach ($values as $key => $value) {
                             $parts = explode(':', $key);
                             if (count($parts) > 1 && $parts[0] == 'smpAttr' && $parts[1] == $attr['attributeId']) {
                                 $smp['model']['fields']['smpAttr:' . $attr['attributeId']] = array('value' => $value);
                             }
                         }
                     }
                 } else {
                     // need to ensure any date change is propagated: only do if date has changed for performance reasons.
                     $subSmpDate = self::parseSingleDate($exists['date_start']);
                     if (strcmp($smpDate, $subSmpDate)) {
                         $smp = array('fkId' => 'parent_id', 'model' => array('id' => 'sample', 'fields' => array('survey_id' => array('value' => $values['sample:survey_id']), 'website_id' => array('value' => $values['website_id']), 'id' => array('value' => $exists['id']), 'date' => array('value' => $values['sample:date']), 'location_id' => array('value' => $exists['location_id']))), 'copyFields' => array('date_start' => 'date_start', 'date_end' => 'date_end', 'date_type' => 'date_type'));
                     }
                 }
                 if ($smp) {
                     $subsampleModels[] = $smp;
                 }
             }
         }
         $submission = submission_builder::build_submission($values, array('model' => 'sample'));
         if (count($subsampleModels) > 0) {
             $submission['subModels'] = $subsampleModels;
         }
     }
     return $submission;
 }
예제 #11
0
 /**
  * Converts the posted form values for a group into a warehouse submission.
  * @param array $values Form values
  * @param array $args Form configuration arguments
  * @return array Submission data
  */
 public static function get_submission($values, $args)
 {
     $struct = array('model' => 'group');
     if (!empty($values['filter:title'])) {
         $struct['superModels'] = array('filter' => array('fk' => 'filter_id'));
     }
     if (!empty($args['parent_group_relationship_type']) && !empty($_GET['from_group_id'])) {
         $struct['subModels'] = array('group_relation' => array('fk' => 'to_group_id'));
         $values['group_relation:from_group_id'] = $_GET['from_group_id'];
         $values['group_relation:relationship_type_id'] = $args['parent_group_relationship_type'];
     }
     $s = submission_builder::build_submission($values, $struct);
     // need to manually build the submission for the admins sub_list, since we are hijacking what is
     // intended to be a custom attribute control
     self::extractUserInfoFromFormValues($s, $values, 'admin_user_id', 't');
     self::extractUserInfoFromFormValues($s, $values, 'user_id', 'f');
     return $s;
 }
예제 #12
0
 public function testCreateUser()
 {
     $array = array('person:first_name' => 'Test', 'person:surname' => 'Person', 'person:email_address' => '*****@*****.**');
     $s = submission_builder::build_submission($array, array('model' => 'person'));
     $r = data_entry_helper::forward_post_to('person', $s, $this->auth['write_tokens']);
     $this->assertTrue(isset($r['success']), 'Submitting a new person did not work');
     $personId = $r['success'];
     $array = array('user:person_id' => $personId, 'user:email_visible' => 'f', 'user:core_role_id' => 1, 'user:username' => 'testUser');
     $s = submission_builder::build_submission($array, array('model' => 'user'));
     $r = data_entry_helper::forward_post_to('user', $s, $this->auth['write_tokens']);
     $this->assertTrue(isset($r['success']), 'Submitting a new user did not work');
     $userId = $r['success'];
     ORM::Factory('user', $userId)->delete();
     ORM::Factory('person', $personId)->delete();
 }
 /**
  * Construct a submission for the location.
  * @param array $values Associative array of form data values. 
  * @param array $args iform parameters. 
  * @return array Submission structure.
  */
 public static function get_submission($values, $args)
 {
     $s = submission_builder::build_submission($values, array('model' => 'location'));
     if (empty($values['location:id'])) {
         $s['subModels'] = array(array('fkId' => 'location_id', 'model' => array('id' => 'locations_website', 'fields' => array('website_id' => $args['website_id']))));
     }
     return $s;
 }
예제 #14
0
 /**
  * Converts the posted form values for a group into a warehouse submission.
  * @param array $values Form values
  * @param array $args Form configuration arguments
  * @return array Submission data
  */
 public static function get_submission($values, $args)
 {
     $struct = array('model' => 'user_trust');
     return submission_builder::build_submission($values, $struct);
 }
예제 #15
0
 /**
  * Handles the construction of a submission array from a set of form values. 
  * @param array $values Associative array of form data values. 
  * @param array $args iform parameters. 
  * @return array Submission structure.
  */
 public static function get_submission($values, $args)
 {
     iform_load_helpers(array('submission_builder'));
     return submission_builder::build_submission($values, array('model' => 'termlists_term', 'superModels' => array('meaning' => array('fk' => 'meaning_id'), 'term' => array('fk' => 'term_id'))));
 }
예제 #16
0
 /**
  * Handles the construction of a submission array from a set of form values.
  * @param array $values Associative array of form data values. 
  * @param array $args iform parameters. 
  * @return array Submission structure.
  */
 public static function get_submission($values, $args)
 {
     //If the location_type_id is supplied in the url, then use this
     if (!empty($_GET['location_type_id'])) {
         $values['location:location_type_id'] = $_GET['location_type_id'];
     }
     $structure = array('model' => 'location');
     // Either an uploadable file, or a link to a Flickr external detail means include the submodel
     // (Copied from data_entry_helper::build_sample_occurrence_submission. If file_box control is used
     // then build_submission calls wrap_with_images instead)
     if (array_key_exists('location:medium', $values) && $values['location:medium'] || array_key_exists('location_medium:external_details', $values) && $values['location_medium:external_details']) {
         $structure['submodel'] = array('model' => 'location_medium', 'fk' => 'location_id');
     }
     $s = submission_builder::build_submission($values, $structure);
     // On first save of a new location, link it to the website.
     // Be careful not to over-write other subModels (e.g. images)
     if (empty($values['location:id'])) {
         $s['subModels'][] = array('fkId' => 'location_id', 'model' => array('id' => 'locations_website', 'fields' => array('website_id' => $args['website_id'])));
         // also, on first save we might be linking to a group
         if (!empty($values['group_id'])) {
             $s['subModels'][] = array('fkId' => 'location_id', 'model' => array('id' => 'groups_location', 'fields' => array('group_id' => $values['group_id'])));
         }
     }
     return $s;
 }
예제 #17
0
 /**
  * Handles the construction of a submission array from a set of form values.
  * @param array $values Associative array of form data values.
  * @param array $args iform parameters.
  * @return array Submission structure.
  */
 public static function get_submission($values, $args)
 {
     $subsampleModels = array();
     $read = array('nonce' => $values['read_nonce'], 'auth_token' => $values['read_auth_token']);
     if (!isset($values['page']) || $values['page'] == 'site') {
         // submitting the first page, with top level sample details
         // keep the first count date on a subsample for use later.
         // only create if a new sample: if existing, then this will already exist.
         if (isset($values['C1:sample:date']) && !isset($values['sample:id'])) {
             $sampleMethods = helper_base::get_termlist_terms(array('read' => $read), 'indicia:sample_methods', array('Timed Count Count'));
             $smp = array('fkId' => 'parent_id', 'model' => array('id' => 'sample', 'fields' => array('survey_id' => array('value' => $values['sample:survey_id']), 'website_id' => array('value' => $values['website_id']), 'date' => array('value' => $values['C1:sample:date']), 'sample_method_id' => array('value' => $sampleMethods[0]['id']))), 'copyFields' => array('entered_sref' => 'entered_sref', 'entered_sref_system' => 'entered_sref_system'));
             //                   'copyFields' => array('date_start'=>'date_start','date_end'=>'date_end','date_type'=>'date_type'));
             $subsampleModels[] = $smp;
         }
     } else {
         if ($values['page'] == 'occurrences') {
             // at this point there is a parent supersample.
             // loop from 1 to numberOfCounts, or number of existing subsamples, whichever is bigger.
             $subSamples = data_entry_helper::get_population_data(array('table' => 'sample', 'extraParams' => $read + array('parent_id' => $values['sample:id']), 'nocache' => true));
             for ($i = 1; $i <= max(count($subSamples), $args['numberOfCounts']); $i++) {
                 if (isset($values['C' . $i . ':sample:id']) || isset($values['C' . $i . ':sample:date']) && $values['C' . $i . ':sample:date'] != '') {
                     $subSample = array('website_id' => $values['website_id'], 'survey_id' => $values['sample:survey_id']);
                     $occurrences = array();
                     $occModels = array();
                     foreach ($values as $field => $value) {
                         $parts = explode(':', $field, 2);
                         if ($parts[0] == 'C' . $i) {
                             $subSample[$parts[1]] = $value;
                         }
                         if ($parts[0] == 'O' . $i) {
                             $occurrences[$parts[1]] = $value;
                         }
                     }
                     ksort($occurrences);
                     foreach ($occurrences as $field => $value) {
                         // have take off O<i> do is now <j>:<ttlid>:<occid>:<attrid>:<attrvalid> - sorted in <j> order
                         $parts = explode(':', $field);
                         $occurrence = array('website_id' => $values['website_id']);
                         if ($parts[1] != '--ttlid--') {
                             $occurrence['taxa_taxon_list_id'] = $parts[1];
                         }
                         if ($parts[2] != '--occid--') {
                             $occurrence['id'] = $parts[2];
                         }
                         if ($value == '') {
                             $occurrence['deleted'] = 't';
                         } else {
                             if ($parts[4] == '--valid--') {
                                 $occurrence['occAttr:' . $parts[3]] = $value;
                             } else {
                                 $occurrence['occAttr:' . $parts[3] . ':' . $parts[4]] = $value;
                             }
                         }
                         if (array_key_exists('occurrence:determiner_id', $values)) {
                             $occurrence['determiner_id'] = $values['occurrence:determiner_id'];
                         }
                         if (array_key_exists('occurrence:record_status', $values)) {
                             $occurrence['record_status'] = $values['occurrence:record_status'];
                         }
                         if (isset($occurrence['id']) || !isset($occurrence['deleted'])) {
                             $occ = data_entry_helper::wrap($occurrence, 'occurrence');
                             $occModels[] = array('fkId' => 'sample_id', 'model' => $occ);
                         }
                     }
                     $smp = array('fkId' => 'parent_id', 'model' => data_entry_helper::wrap($subSample, 'sample'), 'copyFields' => array('entered_sref' => 'entered_sref', 'entered_sref_system' => 'entered_sref_system'));
                     // from parent->to child
                     if (!isset($subSample['sample:deleted']) && count($occModels) > 0) {
                         $smp['model']['subModels'] = $occModels;
                     }
                     $subsampleModels[] = $smp;
                 }
             }
         }
     }
     $sampleMod = submission_builder::build_submission($values, array('model' => 'sample'));
     if (count($subsampleModels) > 0) {
         $sampleMod['subModels'] = $subsampleModels;
     }
     return $sampleMod;
 }
 /**
  * Construct a submission for the location.
  * @param array $values Associative array of form data values. 
  * @param array $args iform parameters. 
  * @return array Submission structure.
  */
 public static function get_submission($values, $args)
 {
     $s = submission_builder::build_submission($values, array('model' => 'location'));
     // on first save of a new transect, link it to the website.
     if (empty($values['location:id'])) {
         $s['subModels'] = array(array('fkId' => 'location_id', 'model' => array('id' => 'locations_website', 'fields' => array('website_id' => $args['website_id']))));
     }
     return $s;
 }
 /**
  * Handles the construction of a submission array from a set of form values.
  * @param array $values Associative array of form data values. 
  * @param array $args iform parameters. 
  * @return array Submission structure.
  */
 public static function get_submission($values, $args)
 {
     return submission_builder::build_submission($values, array('model' => 'occurrence'));
 }
 /**
  * Given a reject response, delete the invite, and redirect to the groups home page.
  * @param array $args Form config arguments
  * @param array $invite Invitation record
  */
 private static function reject($args, $invite, $auth)
 {
     $values = array('id' => $invite['id'], 'deleted' => 't');
     $s = submission_builder::build_submission($values, array('model' => 'group_invitation'));
     $r = data_entry_helper::forward_post_to('group_invitation', $s, $auth['write_tokens']);
     hostsite_show_message(lang::get("OK, thanks anyway. We've removed your invitation to join this group."));
     hostsite_goto_page($args['groups_page_path']);
 }
예제 #21
0
 /**
  * Performs the sending of invitation emails.
  * @param array $args Form configuration arguments
  * @param array $auth Authorisation tokens
  * @todo Integrate with notifications for logged in users.
  */
 private static function sendInvites($args, $auth)
 {
     $emails = helper_base::explode_lines($_POST['invitee_emails']);
     // first task is to populate the groups_invitations table
     $base = uniqid();
     $success = true;
     $failedRecipients = array();
     foreach ($emails as $idx => $email) {
         $values = array('group_invitation:group_id' => $_GET['group_id'], 'group_invitation:email' => $email, 'group_invitation:token' => $base . $idx, 'website_id' => $args['website_id']);
         $s = submission_builder::build_submission($values, array('model' => 'group_invitation'));
         $r = data_entry_helper::forward_post_to('group_invitation', $s, $auth['write_tokens']);
         $pathParam = function_exists('variable_get') && variable_get('clean_url', 0) == '0' ? 'q' : '';
         $rootFolder = data_entry_helper::getRootFolder() . (empty($pathParam) ? '' : "?{$pathParam}=");
         $protocol = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' || $_SERVER['SERVER_PORT'] == 443 ? "https://" : "http://";
         $acceptUrl = $protocol . $_SERVER['HTTP_HOST'] . $rootFolder . $args['accept_invite_path'] . (empty($pathParam) ? '?' : '&') . 'token=' . $base . $idx;
         $body = $_POST['invite_message'] . "<br/><br/>" . '<a href="' . $acceptUrl . '">' . lang::get('Accept this invitation') . '</a>';
         $message = array('id' => 'iform_group_invite', 'to' => implode(',', $emails), 'subject' => 'Invitation to join a recording group', 'body' => $body, 'headers' => array('MIME-Version' => '1.0', 'Content-type' => 'text/html; charset=iso-8859-1'));
         $mimeheaders = array();
         foreach ($message['headers'] as $name => $value) {
             $mimeheaders[] = $name . ': ' . mime_header_encode($value);
         }
         $thismailsuccess = mail($message['to'], mime_header_encode($message['subject']), str_replace("\r", '', $message['body']), join("\n", $mimeheaders));
         if (!$thismailsuccess) {
             $failedRecipients[$message['to']] = $acceptUrl;
         }
         $success = $success && $thismailsuccess;
     }
     if ($success) {
         drupal_set_message(lang::get('Invitation emails sent'));
     } else {
         drupal_set_message(lang::get('The emails could not be sent due to a server configuration issue. Please contact the site admin. ' . 'The list below gives the emails and the links you need to send to each invitee which they need to click on in order to join the group.'), 'warning');
         $list = array();
         foreach ($failedRecipients as $email => $link) {
             $list[] = lang::get("Send link {1} to {2}.", $link, $email);
         }
         drupal_set_message(implode('<br/>', $list), 'warning');
     }
     drupal_goto($args['redirect_on_success']);
 }
 /**
  * Handles the construction of a submission array from a set of form values.
  * @param array $values Associative array of form data values.
  * @param array $args iform parameters.
  * @return array Submission structure.
  */
 public static function get_submission($values, $args)
 {
     global $user;
     $subsampleModels = array();
     $submission = submission_builder::build_submission($values, array('model' => 'sample'));
     // this handles the photos as well.
     // deal with any species grid options.
     foreach ($values as $key => $value) {
         $parts = explode(':', $key, 5);
         if ($parts[0] == 'Grid') {
             $details = explode(':', $parts[4], 3);
             if (!isset($subsampleModels[$parts[1]])) {
                 $smp = array('fkId' => 'parent_id', 'model' => array('id' => 'sample', 'fields' => array('sample_method_id' => array('value' => $args['quadrat_level_sample_method_id']))), 'data' => $parts[2] != '', 'copyFields' => array('survey_id' => 'survey_id', 'date_start' => 'date_start', 'date_end' => 'date_end', 'date_type' => 'date_type', 'entered_sref_system' => 'entered_sref_system', 'entered_sref' => 'entered_sref', 'location_name' => 'location_name'));
                 // from parent->to child
                 if ($parts[2] != '') {
                     // set any existing subsample id
                     $smp['model']['fields']['id'] = array('value' => $parts[2]);
                 }
                 $subsampleModels[$parts[1]] = $smp;
             }
             if ($parts[3] == 'smpAttr') {
                 $subsampleModels[$parts[1]]['model']['fields']['smpAttr:' . $parts[4]] = array('value' => $value);
                 if ($details[0] != $args['sample_attribute_id_1'] && (!isset($args['sample_attribute_id_2']) || $args['sample_attribute_id_2'] == '' || $details[0] != $args['sample_attribute_id_2'])) {
                     $subsampleModels[$parts[1]]['data'] = $subsampleModels[$parts[1]]['data'] || $value != '';
                 }
             } else {
                 if ($parts[3] == 'occ') {
                     $occ = array('fkId' => 'sample_id', 'model' => array('id' => 'occurrence', 'fields' => array('taxa_taxon_list_id' => array('value' => $details[0]), 'website_id' => array('value' => $values['website_id']), 'record_status' => array('value' => $values['occurrence:record_status']), 'zero_abundance' => array('value' => $value != '0' ? 'f' : 't'), $details[2] => array('value' => $value))));
                     if ($details[1] != '') {
                         $occ['model']['fields']['id'] = array('value' => $details[1]);
                     }
                     if ($value != '' || $details[1] != '') {
                         if (!isset($subsampleModels[$parts[1]]['model']['subModels'])) {
                             $subsampleModels[$parts[1]]['model']['subModels'] = array($occ);
                         } else {
                             $subsampleModels[$parts[1]]['model']['subModels'][] = $occ;
                         }
                         $subsampleModels[$parts[1]]['data'] = true;
                     }
                 }
             }
         }
     }
     foreach ($subsampleModels as $row => $data) {
         if (!$subsampleModels[$row]['data']) {
             unset($subsampleModels[$row]);
         }
     }
     if (count($subsampleModels) > 0) {
         $submission['subModels'] = array_merge(isset($submission['subModels']) && is_array($submission['subModels']) ? $submission['subModels'] : array(), array_values($subsampleModels));
         //if($user->uid == 1)
         //	drupal_set_message(print_r($submission,true), 'warning');
     }
     return $submission;
 }
예제 #23
0
 /**
  * Controller action that performs the import of data in an uploaded CSV file.
  * Allows $_GET parameters to specify the filepos, offset and limit when uploading just a chunk at a time.
  * This method is called to perform the entire upload when JavaScript is not enabled, or can 
  * be called to perform part of an AJAX csv upload where only a part of the data is imported
  * on each call.
  * Requires a $_GET parameter for uploaded_csv - the uploaded file name.
  */
 public function upload()
 {
     $csvTempFile = DOCROOT . "upload/" . $_GET['uploaded_csv'];
     $metadata = $this->_get_metadata($_GET['uploaded_csv']);
     if (!empty($metadata['user_id'])) {
         global $remoteUserId;
         $remoteUserId = $metadata['user_id'];
     }
     // Check if details of the last supermodel (e.g. sample for an occurrence) are in the cache from a previous iteration of
     // this bulk operation
     $cache = Cache::instance();
     $this->getPreviousRowSupermodel($cache);
     // enable caching of things like language lookups
     ORM::$cacheFkLookups = true;
     // make sure the file still exists
     if (file_exists($csvTempFile)) {
         // Following helps for files from Macs
         ini_set('auto_detect_line_endings', 1);
         // create the file pointer, plus one for errors
         $handle = fopen($csvTempFile, "r");
         $this->checkIfUtf8($metadata, $handle);
         $errorHandle = $this->_get_error_file_handle($csvTempFile, $handle);
         $count = 0;
         $limit = isset($_GET['limit']) ? $_GET['limit'] : false;
         $filepos = isset($_GET['filepos']) ? $_GET['filepos'] : 0;
         $offset = isset($_GET['offset']) ? $_GET['offset'] : 0;
         if ($filepos == 0) {
             // first row, so skip the header
             fseek($handle, 0);
             fgetcsv($handle, 1000, ",");
             // also clear the lookup cache
             $cache->delete_tag('lookup');
         } else {
             // skip rows to allow for the last file position
             fseek($handle, $filepos);
         }
         $model = ORM::Factory($_GET['model']);
         $this->submissionStruct = $model->get_submission_structure();
         // special date processing.
         $index = 0;
         $dayColumn = false;
         $monthColumn = false;
         $yearColumn = false;
         foreach ($metadata['mappings'] as $col => $attr) {
             // skip cols to do with remembered mappings
             if ($col !== 'RememberAll' && substr($col, -9) !== '_Remember') {
                 switch ($attr) {
                     case 'sample:date:day':
                         $dayColumn = $index;
                     case 'sample:date:month':
                         $monthColumn = $index;
                     case 'sample:date:year':
                         $yearColumn = $index;
                 }
                 $index++;
             }
         }
         $processDate = $dayColumn !== false && $monthColumn !== false && $yearColumn !== false;
         // initially has to have all 3 fields: TODO vaguer dates?
         while (($data = fgetcsv($handle, 1000, ",")) !== FALSE && ($limit === false || $count < $limit)) {
             if (!array_filter($data)) {
                 // skip empty rows
                 continue;
             }
             $count++;
             $index = 0;
             $saveArray = $model->getDefaults();
             // Note, the mappings will always be in the same order as the columns of the CSV file
             foreach ($metadata['mappings'] as $col => $attr) {
                 // skip cols to do with remembered mappings
                 if ($col !== 'RememberAll' && substr($col, -9) !== '_Remember') {
                     if (isset($data[$index])) {
                         // '<Please select>' is a value fixed in import_helper::model_field_options
                         if ($attr != '<Please select>' && $data[$index] !== '') {
                             // Add the data to the record save array. Utf8 encode if file does not have UTF8 BOM.
                             $saveArray[$attr] = $metadata['isUtf8'] ? $data[$index] : utf8_encode($data[$index]);
                         }
                     } else {
                         // This is one of our static fields at the end
                         $saveArray[$col] = $attr;
                     }
                     $index++;
                 }
             }
             if ((!isset($saveArray['sample:date']) || $saveArray['sample:date'] == '') && $processDate) {
                 $saveArray['sample:date'] = $data[$yearColumn] . '-' . sprintf('%02d', $data[$monthColumn]) . '-' . sprintf('%02d', $data[$dayColumn]);
                 // initially has to have all 3 fields: TODO vaguer dates?
                 unset($saveArray['sample:date:day']);
                 unset($saveArray['sample:date:month']);
                 unset($saveArray['sample:date:year']);
             }
             // copy across the fixed values, including the website id, into the data to save.
             if ($metadata['settings']) {
                 $saveArray = array_merge($metadata['settings'], $saveArray);
             }
             if (!empty($saveArray['website_id'])) {
                 // automatically join to the website if relevant
                 if (isset($this->submissionStruct['joinsTo']) && in_array('websites', $this->submissionStruct['joinsTo'])) {
                     $saveArray['joinsTo:website:' . $saveArray['website_id']] = 1;
                 }
             }
             // Check if in an association situation
             $associationExists = false;
             if (self::_check_module_active($this->submissionStruct['model'] . '_associations')) {
                 // assume model has attributes.
                 $attrDetails = $model->get_attr_details();
                 $associatedSuffix = '_2';
                 $associatedRecordSubmissionStructure = $this->submissionStruct;
                 $originalRecordPrefix = $this->submissionStruct['model'];
                 $originalAttributePrefix = $attrDetails['attrs_field_prefix'];
                 $originalMediaPrefix = $originalRecordPrefix . '_media';
                 $associatedRecordPrefix = $originalRecordPrefix . $associatedSuffix;
                 $associatedAttributePrefix = $originalAttributePrefix . $associatedSuffix;
                 $associatedMediaPrefix = $originalMediaPrefix . $associatedSuffix;
                 $associationRecordPrefix = $originalRecordPrefix . '_association';
                 // find out if association or associated records exist
                 foreach ($saveArray as $assocField => $assocValue) {
                     $associationExists = $associationExists || substr($assocField, 0, strlen($associationRecordPrefix)) == $associationRecordPrefix || substr($assocField, 0, strlen($associatedRecordPrefix)) == $associatedRecordPrefix;
                 }
             }
             // If posting a supermodel, are the details of the supermodel the same as for the previous CSV row? If so, we can link to that
             // record rather than create a new supermodel record.
             $updatedPreviousCsvSupermodelDetails = $this->checkForSameSupermodel($saveArray, $model, $associationExists);
             // Clear the model, so nothing else from the previous row carries over.
             $model->clear();
             // Save the record
             $model->set_submission_data($saveArray, true);
             /* At this point, if model has associations (i.e. a module is active called <modelSingular>_associations)
                we flip the submission so the model becomes the subModel. This way we can bolt any second associated
                record in, into the submodel array. */
             // GvB TODO alter automatic mappings to set up secondary occurrences correctly.
             if ($associationExists && isset($model->submission['superModels']) && is_array($model->submission['superModels']) && count($model->submission['superModels']) === 1) {
                 // We are assuming only one superModel, which must exist at this point.
                 // Use key 'record1' into the subModel array so association record knows which is which.
                 unset($associatedRecordSubmissionStructure['superModels']);
                 // we are using the previously wrapped superModel
                 // flip then bolt in as second submodel to the supermodel using key 'record2',
                 $submissionData = $model->submission;
                 $superModelSubmission = $submissionData['superModels'][0]['model'];
                 $superModelFK = $submissionData['superModels'][0]['fkId'];
                 $superModel = ORM::Factory($superModelSubmission['id']);
                 $superModel->clear();
                 unset($submissionData['superModels']);
                 // try to wrap second record of original model.
                 // as the submission builder needs a 1-1 match between field prefix and model name, we need to generate an altered saveArray.
                 $associatedArray = array();
                 foreach ($saveArray as $fieldname => $value) {
                     $parts = explode(':', $fieldname);
                     // filter out original model feilds, any of its attributes and media records.
                     if ($parts[0] != $originalRecordPrefix && $parts[0] != $originalAttributePrefix && $parts[0] != $originalMediaPrefix) {
                         if ($parts[0] == $associatedRecordPrefix) {
                             $parts[0] = $originalRecordPrefix;
                         } else {
                             if ($parts[0] == $associatedAttributePrefix) {
                                 $parts[0] = $originalAttributePrefix;
                             } else {
                                 if ($parts[0] == $associatedMediaPrefix) {
                                     $parts[0] = $originalMediaPrefix;
                                 }
                             }
                         }
                         $associatedArray[implode(':', $parts)] = $value;
                     }
                 }
                 $associatedSubmission = submission_builder::build_submission($associatedArray, $associatedRecordSubmissionStructure);
                 // func already loaded for previous wrap
                 // Map fk_* fields to the looked up id
                 $associatedSubmission = $model->getFkFields($associatedSubmission, $associatedArray);
                 // wrap the association and bolt in as a submodel of original model, using '||record2||' pointer.
                 $association = ORM::Factory($associationRecordPrefix);
                 $association->set_submission_data($saveArray, true);
                 $association->submission['fields']['to_' . $associatedRecordSubmissionStructure['model'] . '_id'] = array('value' => '||record2||');
                 $submissionData['subModels'] = array(array('fkId' => 'from_' . $associatedRecordSubmissionStructure['model'] . '_id', 'model' => $association->submission));
                 $superModelSubmission['subModels'] = array('record1' => array('fkId' => $superModelFK, 'model' => $submissionData), 'record2' => array('fkId' => $superModelFK, 'model' => $associatedSubmission));
                 $superModel->submission = $superModelSubmission;
                 $model = $superModel;
             } else {
                 $associationExists = false;
             }
             if (($id = $model->submit()) == null) {
                 // Record has errors - now embedded in model, so dump them into the error file
                 $errors = array();
                 foreach ($model->getAllErrors() as $field => $msg) {
                     $fldTitle = array_search($field, $metadata['mappings']);
                     $fldTitle = $fldTitle ? $fldTitle : $field;
                     $errors[] = "{$fldTitle}: {$msg}";
                 }
                 $errors = implode("\n", array_unique($errors));
                 $data[] = $errors;
                 $data[] = $count + $offset + 1;
                 // 1 for header
                 fputcsv($errorHandle, $data);
                 kohana::log('debug', 'Failed to import CSV row: ' . $errors);
                 $metadata['errorCount'] = $metadata['errorCount'] + 1;
             } else {
                 // now the record has successfully posted, we need to store the details of any new supermodels and their Ids,
                 // in case they are duplicated in the next csv row.
                 $this->previousCsvSupermodel['details'] = array_merge($this->previousCsvSupermodel['details'], $updatedPreviousCsvSupermodelDetails);
                 $this->captureSupermodelIds($model, $associationExists);
             }
             // get file position here otherwise the fgetcsv in the while loop will move it one record too far.
             $filepos = ftell($handle);
         }
         // Get percentage progress
         $progress = $filepos * 100 / filesize($csvTempFile);
         $r = "{\"uploaded\":{$count},\"progress\":{$progress},\"filepos\":{$filepos}}";
         // allow for a JSONP cross-site request
         if (array_key_exists('callback', $_GET)) {
             $r = $_GET['callback'] . "(" . $r . ")";
         }
         echo $r;
         fclose($handle);
         fclose($errorHandle);
         self::internal_cache_upload_metadata($metadata);
         // An AJAX upload request will just receive the number of records uploaded and progress
         $this->auto_render = false;
         $cache->set(basename($csvTempFile) . 'previousSupermodels', $this->previousCsvSupermodel);
     }
 }