function update_native_member_fields($member_id = '', $entry_id = NULL)
 {
     $author_id = $member_id;
     $entry_id = $entry_id != NULL ? $entry_id : $this->EE->input->post('entry_id');
     // ===============================
     // = Custom member fields =
     // ===============================
     $custom_member_data = array();
     $sql = 'SELECT mf.m_field_id member_field_id, mf.m_field_name, cf.field_id channel_field_id, cf.field_name FROM exp_member_fields mf, exp_channel_fields cf WHERE cf.field_name = CONCAT("member_", mf.m_field_name) ';
     $query = $this->EE->db->query($sql);
     //get data from channel entry instead from post array
     $data_sql = 'SELECT * from exp_channel_data WHERE entry_id = "' . $entry_id . '"';
     $data_query = $this->EE->db->query($data_sql);
     $entry_channel_data = $data_query->first_row('array');
     if ($query->num_rows() > 0) {
         foreach ($query->result() as $row) {
             $custom_member_data['m_field_id_' . $row->member_field_id] = $entry_channel_data['field_id_' . $row->channel_field_id];
         }
     }
     if (count($custom_member_data) > 0) {
         $this->EE->member_model->update_member_data($author_id, $custom_member_data);
     }
     // ==========================
     // = Standard member fields =
     // ==========================
     //deprecated method for saving native fields based on name m_field_id_x
     $native_member_fields_data = contains_native_member_fields();
     if ($native_member_fields_data !== FALSE) {
         $this->EE->db->where('member_id', $author_id);
         $this->EE->db->update('member_data', $native_member_fields_data);
     }
     //new method for saving native fields
     $data = array();
     $fields = array('bday_y', 'bday_m', 'bday_d', 'birthday', 'url', 'location', 'occupation', 'interests', 'aol_im', 'icq', 'yahoo_im', 'msn_im', 'bio', 'signature', 'avatar', 'photo', 'timezone', 'time_format', 'language');
     if (APP_VER < '2.6.0') {
         $fields[] = 'daylight_savings';
     }
     //get the channel field ids based on the name of the member fields
     $member_fields = array();
     foreach ($fields as $field) {
         $member_fields[] = 'member_' . $field;
     }
     $member_fields_str = implode('","', $member_fields);
     $sql = 'SELECT field_name, field_id FROM exp_channel_fields WHERE field_name IN ("' . $member_fields_str . '")';
     $query = $this->EE->db->query($sql);
     //place the fields in an array field_name => field_id, we need this because fields are in post array based on field_id
     $field_map = array();
     if ($query->num_rows() > 0) {
         foreach ($query->result() as $row) {
             $field_map[str_replace('member_', '', $row->field_name)] = $row->field_id;
         }
         foreach ($fields as $val) {
             if (isset($field_map[$val])) {
                 if (isset($entry_channel_data['field_id_' . $field_map[$val]])) {
                     $field_value = $entry_channel_data['field_id_' . $field_map[$val]];
                     if (strpos($field_value, '}')) {
                         $field_value = substr($field_value, strpos($field_value, '}') + 1);
                     }
                     $data[$val] = $field_value;
                 }
             }
         }
         if (isset($data['birthday'])) {
             //dropdate passes date as an array
             if (is_array($data['birthday'])) {
                 $data['bday_d'] = $data['birthday'][0];
                 $data['bday_m'] = $data['birthday'][1];
                 $data['bday_y'] = $data['birthday'][2];
             } else {
                 $data['bday_d'] = date('j', strtotime($data['birthday']));
                 $data['bday_m'] = date('n', strtotime($data['birthday']));
                 $data['bday_y'] = date('Y', strtotime($data['birthday']));
             }
             unset($data['birthday']);
         }
         if (isset($data['bday_d']) && isset($data['bday_m']) && is_numeric($data['bday_d']) and is_numeric($data['bday_m'])) {
             $year = isset($data['bday_y']) && $data['bday_y'] != '' ? $data['bday_y'] : date('Y');
             if (version_compare(APP_VER, '2.6.0', '<')) {
                 $mdays = $this->EE->localize->fetch_days_in_month($data['bday_m'], $year);
             } else {
                 $this->EE->load->helper('date');
                 $mdays = days_in_month($data['bday_m'], $year);
             }
             if ($data['bday_d'] > $mdays) {
                 $data['bday_d'] = $mdays;
             }
         }
     }
     // ============================================
     // = Check if there is a membergroup selected =
     // ============================================
     $this->check_membergroup_change($data);
     if (isset($data['avatar'])) {
         $data['avatar_filename'] = 'uploads/' . $data['avatar'];
         unset($data['avatar']);
     }
     if (isset($data['photo'])) {
         $data['photo_filename'] = $data['photo'];
         unset($data['photo']);
     }
     if (count($data) > 0) {
         $this->EE->member_model->update_member($author_id, $data);
     }
 }
 function hook_safecracker_submit_entry_start(&$obj)
 {
     $this->EE->session->cache['zoo_visitor_field_errors'] = array();
     //zoo visitor action is set to register
     if (isset($_POST['zoo_visitor_action']) && ($_POST['zoo_visitor_action'] == 'register' || $_POST['zoo_visitor_action'] == 'update')) {
         $profile_fields = array("username", "screen_name", "password", "email", "new_password");
         //Check if there are any native member fields
         $native_member_fields_data = contains_native_member_fields();
         // ==============================================================
         // = is password required to update the regular channel fields? =
         // ==============================================================
         if (isset($_POST['zoo_visitor_require_password']) && $_POST['zoo_visitor_require_password'] == 'yes') {
             $current_password = isset($_POST['current_password']) ? $_POST['current_password'] : '';
             $member_id = $this->EE->zoo_visitor_lib->get_member_id($_POST['entry_id']);
             $member_id = $member_id ? $member_id->member_id : $this->EE->session->userdata('member_id');
             $current_password_errors = $this->EE->zoo_visitor_lib->_validate_current_password($current_password, $member_id);
             if ($current_password_errors != 'valid') {
                 $obj->field_errors['current_password'] = $current_password_errors;
                 $this->EE->session->cache['zoo_visitor_field_errors']['current_password'] = $current_password_errors;
             }
         }
         if (!isset($_POST['username']) && !isset($_POST['screen_name']) && !isset($_POST['password']) && !isset($_POST['email']) && !isset($_POST['new_password']) && $native_member_fields_data == FALSE && !isset($_POST['group_id'])) {
             //This is no member profile update request
         } else {
             if (isset($_POST)) {
                 foreach ($profile_fields as $name) {
                     if (isset($_POST[$name]) && $_POST[$name] == "") {
                         unset($_POST[$name]);
                     }
                 }
             }
             //this is a member profile update or registration
             $_POST['zoo_visitor_action'] = $_POST['zoo_visitor_action'] == 'register' ? 'register' : 'update_profile';
             $title = '';
             if (isset($_POST['email'])) {
                 $_POST['email'] = trim($_POST['email']);
             }
             //set the channel entry title, because this field is required
             if ($this->zoo_settings['email_is_username'] == 'yes' && isset($_POST['email'])) {
                 $_POST['username'] = $_POST['email'];
             }
             if ($this->zoo_settings['email_is_username'] == 'yes' && isset($_POST['username'])) {
                 $_POST['email'] = $_POST['username'];
             }
             if ($this->zoo_settings['use_screen_name'] == "no" && isset($_POST['username'])) {
                 $_POST['screen_name'] = $_POST['username'];
             }
             if ($this->zoo_settings['password_confirmation'] == "no" && isset($_POST['password'])) {
                 $_POST['password_confirm'] = $_POST['password'];
             }
             if ($this->zoo_settings['email_confirmation'] == "no" && isset($_POST['email'])) {
                 $_POST['email_confirm'] = $_POST['email'];
             }
             //the title will be synced when entry is submitted
             if (!isset($_POST['use_dynamic_title'])) {
                 $_POST['title'] = isset($_POST['EE_title']) ? $_POST['EE_title'] : 'no_title';
                 $_POST['title'] = isset($_POST['username']) ? $_POST['username'] : $_POST['title'];
                 $_POST['title'] = $_POST['title'] == '' ? 'no_title' : $_POST['title'];
             }
             // =============================================
             // = CHECK FOR ERRORS AND PASS TO THE END HOOK =
             // =============================================
             // ==========================
             // = grab the update errors =
             // ==========================
             if ($_POST['zoo_visitor_action'] == 'update_profile') {
                 //Validate update
                 $validate_errors = $this->EE->zoo_visitor_lib->update(FALSE);
                 if (count($validate_errors) > 0) {
                     foreach ($validate_errors as $key => $value) {
                         if (count($value) > 0) {
                             $obj->field_errors[$key] = implode('<br/>', $value);
                             $this->EE->session->cache['zoo_visitor_field_errors'][$key] = implode('<br/>', $value);
                         }
                     }
                 }
             }
             // ================================
             // = grab the registration errors =
             // ================================
             if ($_POST['zoo_visitor_action'] == 'register') {
                 $reg_result = $this->EE->zoo_visitor_lib->register_member($this, FALSE);
                 if ($reg_result[0] == "submission" && count($reg_result[1]) > 0) {
                     foreach ($reg_result[1] as $key => $value) {
                         if (count($value) > 0) {
                             $obj->field_errors[$key] = implode('<br/>', $value);
                             $this->EE->session->cache['zoo_visitor_field_errors'][$key] = implode('<br/>', $value);
                         }
                     }
                 }
             }
         }
         // ==================================================================================
         // = extra merging of categories, can be used to split up categories for validation =
         // ==================================================================================
         if (isset($_POST['category_to_be_merged']) && !empty($_POST['category_to_be_merged'])) {
             $category = isset($_POST['category']) ? $_POST['category'] : array();
             foreach ($_POST['category_to_be_merged'] as $key => $value) {
                 $category = array_merge($category, $value);
             }
             $_POST['category'] = $category;
         }
     }
     //Validation rules based on the "rules" parameter
     $additional_rule_fields = array('screen_name', 'username', 'email', 'password', 'current_password', 'new_password', 'new_password_confirm');
     $rules = $this->EE->input->post('rules');
     if ($rules) {
         foreach ($additional_rule_fields as $additional_rule) {
             if (array_key_exists($additional_rule, $rules)) {
                 $this->EE->form_validation->set_rules($additional_rule, $this->EE->lang->line($additional_rule), $obj->decrypt_input($rules[$additional_rule]));
             }
         }
     }
     return $obj;
 }