function reset_password($tagdata, $ret, $error_handling, $is_ajax_request = 'no')
 {
     $TMPL_cache = $this->EE->TMPL;
     $errors = array();
     $vars = array();
     $vars[0] = array('email' => '', 'error:password' => '');
     if (isset($_POST['visitor_action']) && $_POST['visitor_action'] == 'reset_password') {
         $result = $this->process_reset_password();
         if (array_key_exists("success", $result)) {
             if ($ret != '') {
                 if ($this->EE->TMPL->fetch_param('secure_return') == 'yes') {
                     $ret = preg_replace('/^http:/', 'https:', $ret);
                 }
                 $this->EE->functions->redirect($ret);
             }
             if ($is_ajax_request == 'yes') {
                 $return = array('success' => 1, 'errors' => array());
                 $this->EE->output->send_ajax_response($return);
             }
             $tagdata = $this->EE->functions->prep_conditionals($tagdata, array('password_reset' => TRUE));
         } else {
             if ($is_ajax_request == 'yes') {
                 $return = array('success' => 0, 'errors' => $result);
                 $this->EE->output->send_ajax_response($return);
             }
             if ($error_handling != 'inline') {
                 $this->EE->output->show_user_error(FALSE, $result['password']);
             } else {
                 $result['password'] = prep_errors($this->EE, array($result['password']));
                 $vars[0] = array('password' => $_POST['password'], 'error:password' => implode('<br/>', $result['password']));
             }
             $tagdata = $this->EE->functions->prep_conditionals($tagdata, array('password_reset' => FALSE));
         }
     } else {
         $tagdata = $this->EE->functions->prep_conditionals($tagdata, array('password_reset' => FALSE));
     }
     // if the use is logged in, then send them away
     if (ee()->session->userdata('member_id') !== 0) {
         return ee()->functions->redirect(ee()->functions->fetch_site_index());
     }
     // If the user is banned, send them away.
     if (ee()->session->userdata('is_banned') === TRUE) {
         return ee()->output->show_user_error('general', array(lang('not_authorized')));
     }
     // They didn't include their token.  Give em an error.
     if (!($resetcode = ee()->input->get_post('id'))) {
         return ee()->output->show_user_error('submission', array(lang('mbr_no_reset_id')));
     }
     $data = array();
     $data['action'] = $this->EE->TMPL->fetch_param('action', $this->EE->functions->create_url($this->EE->uri->uri_string)) . '?&id=' . $resetcode;
     $data['id'] = $this->EE->TMPL->fetch_param('id', $this->EE->TMPL->fetch_param('form_id', ''));
     $data['class'] = $this->EE->TMPL->fetch_param('class', $this->EE->TMPL->fetch_param('form_class', ''));
     // Check to see whether we're in the forum or not.
     $in_forum = isset($_GET['r']) && $_GET['r'] == 'f';
     $data['hidden_fields']['from'] = $in_forum == TRUE ? 'forum' : '';
     $data['hidden_fields']['visitor_action'] = 'reset_password';
     $data['hidden_fields']['RET'] = $ret;
     $data['hidden_fields']['resetcode'] = $resetcode;
     $form_declared = $this->EE->functions->form_declaration($data);
     $tagdata = $this->EE->TMPL->parse_variables($tagdata, $vars);
     if ($this->EE->TMPL->fetch_param('secure_action') == 'yes') {
         $form_declared = preg_replace('/(<form.*?action=")http:/', '\\1https:', $form_declared);
     }
     return $form_declared . $tagdata . '</form>';
 }
 function hook_safecracker_submit_entry_end(&$obj)
 {
     $member_id = 0;
     // ===========================
     // = Get stored field errors =
     // ===========================
     $obj->field_errors = array_merge($obj->field_errors, $this->EE->session->cache['zoo_visitor_field_errors']);
     $this->EE->session->cache['zoo_visitor_field_errors'] = array();
     /** ----------------------------------------
     		/**  Zoo visitor action is set to register
     		/** ----------------------------------------*/
     //$this->EE->lang->loadfile('zoo_visitor');
     if (isset($_POST['zoo_visitor_action'])) {
         // =========================
         // = create native profile =
         // =========================
         if ($_POST['zoo_visitor_action'] == 'register') {
             // -------------------------------------------
             // 'zoo_visitor_register_validation_start' hook.
             //  - Additional processing when a member is being validated through the registration form tag
             //
             $field_errors = $this->EE->extensions->call('zoo_visitor_register_validation_start', $obj->field_errors);
             if ($field_errors) {
                 $obj->field_errors = $field_errors;
             }
             if ($this->EE->extensions->end_script === TRUE) {
                 return;
             }
             //wrap errors if there is an error delimiter
             $obj->field_errors = prep_errors($this->EE, $obj->field_errors);
             if (is_array($obj->errors) && count($obj->errors) > 0 || is_array($obj->field_errors) && count($obj->field_errors) > 0) {
                 $this->EE->db->where('entry_id', $obj->entry('entry_id'));
                 $this->EE->db->delete('channel_titles');
                 $this->EE->db->where('entry_id', $obj->entry('entry_id'));
                 $this->EE->db->delete('channel_data');
                 //do nothing. let safecracker handle the error reporting
             } else {
                 // -------------------------------------------
                 // 'zoo_visitor_register_start' hook.
                 //  - Additional processing before a member is registered
                 //
                 $edata = $this->EE->extensions->call('zoo_visitor_register_start', $_POST);
                 if ($this->EE->extensions->end_script === TRUE) {
                     return;
                 }
                 /** ----------------------------------------
                 				/** No Safecracker errors, register EE member
                 				/** ----------------------------------------*/
                 $reg_result = $this->EE->zoo_visitor_lib->register_member($this);
                 //EE member registration is complete, check result
                 if (isset($reg_result['result']) && $reg_result['result'] == "registration_complete") {
                     $member_id = $reg_result['member_data']['member_id'];
                     //registration successfull, set author_id in channel entry
                     $this->EE->db->update('channel_titles', array('author_id' => $member_id), 'entry_id = ' . $obj->entry('entry_id'));
                     //sync the screen_name based on the provided override fields
                     if ($this->zoo_settings['use_screen_name'] == "no" && $this->zoo_settings['screen_name_override'] != '') {
                         $this->EE->zoo_visitor_lib->update_screen_name($member_id);
                     }
                     if (!isset($_POST['use_dynamic_title'])) {
                         $this->EE->zoo_visitor_lib->update_entry_title($obj->entry('entry_id'));
                     }
                     //set membergroup status
                     $this->EE->zoo_visitor_cp->id = $member_id;
                     $this->EE->zoo_visitor_cp->entry_id = $obj->entry('entry_id');
                     $this->EE->zoo_visitor_cp->update_member_status($reg_result['member_data']['group_id']);
                     //update native mmemberfield (url, location, signature...) and custom native memberfields
                     $this->EE->zoo_visitor_lib->update_native_member_fields($member_id, $obj->entry('entry_id'));
                 } else {
                     /** ----------------------------------------
                     				/** EE member registration failed
                     				/** ----------------------------------------*/
                     $this->EE->extensions->end_script = TRUE;
                     //EE registration failed, remove member channel entry
                     $this->EE->db->where('entry_id', $obj->entry('entry_id'));
                     $this->EE->db->delete('channel_titles');
                     $this->EE->db->where('entry_id', $obj->entry('entry_id'));
                     $this->EE->db->delete('channel_data');
                     $errors = array();
                     foreach ($reg_result[1] as $key => $value) {
                         if (count($value) > 0) {
                             if (is_array($value)) {
                                 $errors[$key] = implode('<br/>', $value);
                             } else {
                                 $errors[$key] = $value;
                             }
                         }
                     }
                     $this->EE->output->show_user_error($reg_result[0], $errors);
                 }
             }
         }
         // =========================
         // = Native profile update =
         // =========================
         if ($_POST['zoo_visitor_action'] == 'update_profile' || $_POST['zoo_visitor_action'] == 'update') {
             $member_id = $this->EE->input->post('author_id');
             $obj->field_errors = prep_errors($this->EE, $obj->field_errors);
             //check for safecracker errors
             if (is_array($obj->errors) && count($obj->errors) > 0 || is_array($obj->field_errors) && count($obj->field_errors) > 0) {
                 //do nothing. let safecracker handle the error reporting
             } else {
                 // -------------------------------------------
                 // 'zoo_visitor_update_start' hook.
                 //  - Additional processing before a member is updated through the update form tag
                 //
                 $edata = $this->EE->extensions->call('zoo_visitor_update_start', $_POST);
                 if ($this->EE->extensions->end_script === TRUE) {
                     return;
                 }
                 //do update
                 $this->EE->zoo_visitor_lib->update(TRUE);
                 //update native mmemberfield (url, location, signature...) and custom native memberfields
                 $this->EE->zoo_visitor_lib->update_native_member_fields($member_id);
             }
         }
         //sync the screen_name based on the provided override fields
         if ($this->zoo_settings['use_screen_name'] == "no" && $this->zoo_settings['screen_name_override'] != '') {
             $this->EE->zoo_visitor_lib->update_screen_name($member_id);
         }
         if (!isset($_POST['use_dynamic_title'])) {
             $this->EE->zoo_visitor_lib->update_entry_title($obj->entry('entry_id'));
         }
         //set membergroup status
         $this->EE->zoo_visitor_cp->sync_member_status($member_id);
         // ===================
         // = Post processing =
         // ===================
         if (isset($reg_result['result']) && $reg_result['result'] == "registration_complete") {
             // -------------------------------------------
             // 'zoo_visitor_register' hook.
             //  - Additional processing when a member is created through the registration form tag
             //  Still present for backward compatibility with other add-ons using the old register hook
             //
             $edata = $this->EE->extensions->call('zoo_visitor_register', array_merge($reg_result['member_data'], $_POST), $reg_result['member_data']['member_id']);
             if ($this->EE->extensions->end_script === TRUE) {
                 return;
             }
             // -------------------------------------------
             // 'zoo_visitor_register_end' hook.
             //  - Additional processing when a member is created through the registration form tag
             //
             $edata = $this->EE->extensions->call('zoo_visitor_register_end', array_merge($reg_result['member_data'], $_POST), $reg_result['member_data']['member_id']);
             if ($this->EE->extensions->end_script === TRUE) {
                 return;
             }
             //check activation method, if none, auto-login
             if ($this->EE->config->item('req_mbr_activation') == 'none') {
                 if (isset($_POST['autologin']) && $_POST['autologin'] == 'no') {
                 } else {
                     $this->autologin($reg_result['member_data'], $member_id);
                 }
                 //is redirect set?
                 if ($this->zoo_settings['redirect_after_activation'] == "yes") {
                     $this->EE->extensions->end_script = TRUE;
                     //sync the screen_name based on the provided override fields before the redirect
                     if ($this->zoo_settings['use_screen_name'] == "no" && $this->zoo_settings['screen_name_override'] != '') {
                         $this->EE->zoo_visitor_lib->update_screen_name($member_id);
                     }
                     //$this->redirect();
                 }
             }
             // ==============================================
             // = Send JSON RESPONSE WITH MEMBER ID INCLUDED =
             // ==============================================
             if ($obj->json) {
                 if (is_array($obj->errors)) {
                     //add the field name to custom_field_empty errors
                     foreach ($obj->errors as $field_name => $error) {
                         if ($error == $this->EE->lang->line('custom_field_empty')) {
                             $obj->errors[$field_name] = $error . ' ' . $field_name;
                         }
                     }
                 }
                 return $obj->send_ajax_response(array('success' => empty($obj->errors) && empty($obj->field_errors) ? 1 : 0, 'errors' => empty($obj->errors) ? array() : $obj->errors, 'field_errors' => empty($obj->field_errors) ? array() : $obj->field_errors, 'entry_id' => $obj->entry('entry_id'), 'member_id' => $member_id, 'url_title' => $obj->entry('url_title'), 'channel_id' => $obj->entry('channel_id')));
             }
         }
         if ($_POST['zoo_visitor_action'] == 'update_profile' || $_POST['zoo_visitor_action'] == 'update') {
             // -------------------------------------------
             // 'zoo_visitor_update_end' hook.
             //  - Additional processing when a member is update through the update form tag
             //
             $edata = $this->EE->extensions->call('zoo_visitor_update_end', $_POST, $member_id);
             if ($this->EE->extensions->end_script === TRUE) {
                 return;
             }
         }
     }
 }