function register($invite_md5 = '') { //check if user logged in //session_start(); // this can't do, or the original session will b lost $log_info = 'in register, ip:' . $this->request->clientIp(); $reg_refer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : 'not set'; $log_info .= ', refer:' . $reg_refer; CakeLog::write('info', $log_info); $log_info = ''; if ($this->Session->read('uid')) { $this->redirect(array("controller" => "users", "action" => "ucenter")); } $money = $this->Session->read('money'); if ($money) { $this->set('remindInfo', '注册成功后¥' . $money . '将存入您的账户'); } $inviting_user = array(); if ($invite_md5 != '') { // user visit from shared inviting page // this code block writes log and insert db record, // avoid attack !!! do { // check if invite_md5 correct $conditions = array('uniq_md5' => $invite_md5); $inviting_user = $this->User->find('first', array('conditions' => $conditions)); // not exists if (empty($inviting_user)) { $log_str = sprintf('ip[%s] invite_md5[%s] find ' . 'no inviting user', $this->request->clientIp(), $invite_md5); Cakelog::write('warning', $log_str); // reset invite_md5 to avoid following process $invite_md5 = ''; break; } // if the distinct ip much more less than visit count, // we regard it as an attack. // i.e. visit_count / ip_count > threshold in a day, // disable insert $time_start = date('Y-m-d 00:00:00', time()); $select_cond = array('invite_md5' => $invite_md5, 'created >=' => $time_start); $this->loadModel('Ivisit'); $visited_total = $this->Ivisit->find('count', array('conditions' => $select_cond)); $distinct_ip_total = $this->Ivisit->find('count', array('fields' => 'distinct req_ip', 'conditions' => $select_cond)); if ($distinct_ip_total > 0) { $ratio = $visited_total / $distinct_ip_total; $log_str = sprintf('daily visited/disctinct [%s], threshold[%s]', $ratio, $this->VISIT_RATIO_THRESHOLD); CakeLog::write('debug', $log_str); if ($ratio >= $this->VISIT_RATIO_THRESHOLD) { break; } } // record this visit $data_row = array('req_ip' => $this->request->clientIp(), 'invite_md5' => $invite_md5); $save_res = $this->Ivisit->save($data_row); $money = Configure::read('register_user_money') / 100; $this->Session->write('invite_md5', $invite_md5); $this->set('invite_info', '注册成功后¥' . $money . '将存入您的账户'); $log_str = sprintf('ip[%s] invite_md5[%s] save to ivisit res[%s].', $this->request->clientIp(), $data_row['invite_md5'], $save_res['Ivisit']['id']); CakeLog::write('debug', $log_str); } while (0); } $this->set('title_for_layout', "User::register|倚天剑shadow - 提供shadowsocks科学上(翻)网(墙)账号!倚天剑shadow|shadowsocks账号|免费shadowsocks账号"); //var_dump($this->request->data); $err = 0; // no error $msg = ""; $isPost = $this->request->is('post'); //var_dump(CakeSession::read('vcode')); //var_dump($_SESSION['vcode']); if ($isPost) { $rdata = $this->request->data; //verify check code if (empty($rdata['checkcode']) || 0 != strcasecmp($rdata['checkcode'], $this->Session->read('vcode'))) { $err = 4; $msg = '验证码错误!'; } CakeSession::write('vcode', ''); if ($rdata['password'] != $rdata['password2']) { $err = 1; $msg = "密码输入不一致!"; } //$pattern = "/^([0-9A-Za-z\\-_\\.]+)@([0-9a-z]+\\.[a-z]{2,3}(\\.[a-z]{2})?)$/i"; $pattern = "/^([0-9A-Za-z\\-_\\.]+)@([0-9a-z]+\\.[a-z]{2,7}(\\.[a-z]{2})?)\$/i"; // allow user register with both email and telephone $tel_pattern = '#1[\\d]{10}#'; if (!preg_match($pattern, $rdata['email']) && !preg_match($tel_pattern, $rdata['email'])) { $err = 2; $msg = "邮箱格式或电话号码错误 !"; } if ($err == 0) { $existEmail = $this->User->find('first', array('conditions' => array('email' => $rdata['email']))); //var_dump($existEmail); //var_dump($existEmail['User']['uid']); $datetime = date("Y-m-d H:i:s", time()); //var_dump($datetime); if (count($existEmail) > 0) { $err = 3; $msg = "用户已注册!"; } } } if ($isPost && $err == 0) { //data validated ok //insert into db, get user loged in $datetime = date("Y-m-d H:i:s", time()); $data_row = array('email' => $rdata['email'], 'password' => md5($rdata['password'])); if (Configure::read('open_invite') > 0) { $md5_field = sprintf('%d,%s,%s', rand(1000, 9999), $this->request->clientIp(), $rdata['email']); $data_row['uniq_md5'] = md5($md5_field); $data_row['reg_ip'] = $this->request->clientIp(); } //save_res is the whole data_row $save_res = $this->User->save($data_row); //var_dump($save_res); //var_dump($data_row); if ($save_res) { //after save, cake return the id of the recored //table 'uid' while cake uses 'id' for prod env $uid = $save_res['User']['id']; if (empty($uid)) { //Mac dev enviroment use uid CakeLog::write('warning', 'get uid from save_res empty'); $uid = $save_res['User']['uid']; } //var_dump($uid); //null //var_dump($save_res['User']['uid']); //userid $this->Session->write('uid', $uid); $this->Session->write('username', $rdata['email']); //unset vcode to avoid attack $this->Session->write('vcode', ''); //var_dump($this->Session->read('uid')); //var_dump($save_res); $this->log('register success,email=' . $rdata['email'], 'info'); // register ok. process inviting related logic // 1. add a voucher to registered user // 2. add invite_num to inviting user in cake_users $invite_md5 = $this->Session->read('invite_md5'); if (Configure::read('open_invite') > 0 && $invite_md5 != '') { $this->loadModel('Voucher'); $conditions = array('uniq_md5' => $invite_md5); $inviting_user = $this->User->find('first', array('conditions' => $conditions)); $inviting_uid = $inviting_user['User']['uid']; $date_time_now = date('Y-m-d H:i:s', time()); $md5_source = sprintf('%d-%s-%s-%s', $uid, $rdata['email'], $date_time_now, $this->request->clientIp()); // for registering user $expire_after_k_days = 7; $expire_datetime = date('Y-m-d H:i:s', strtotime("+{$expire_after_k_days} day")); $data_row = array('md5str' => md5($md5_source), 'uid' => $uid, 'from_uid' => $inviting_uid, 'get_from' => $this->VOUCHER_VIA_REGISTER, 'expire' => $expire_datetime, 'amount' => Configure::read('register_user_money'), 'is_valid' => $this->VOUCHER_VALID); $save_res = $this->Voucher->save($data_row); if (empty($save_res)) { $log_str = sprintf('save voucher failed, user[%d]', $uid); CakeLog::write('warning', $log_str); } // increase invite_num field. // the following code block doesn't work on 2t-vps[ubuntu] // while works on Mac dev env // $this->User->id = $inviting_user['User']['uid']; // $invite_num = $inviting_user['User']['invite_num'] + 1; // $this->User->saveField('invite_num', $invite_num); $update_fields = array('invite_num' => $inviting_user['User']['invite_num'] + 1); $update_cond = array('uid' => $inviting_user['User']['uid']); $up_res = $this->User->updateAll($update_fields, $update_cond); $log_str = sprintf('invite success, new user[%d]' . ' update invite_num result[%s]', $uid, $up_res); CakeLog::write('debug', $log_str); } $this->assign_money2user(); return $this->redirect(array("controller" => "users", "action" => "ucenter")); } else { $err = 5; $msg = "系统忙,注册失败!"; } // return $this->redirect( // array("controller" => "users", "action" => "ucenter") // ); } if ($err > 0) { $this->set('isError', $err); $this->set('errMsg', $msg); $this->log('in register, err:' . $err . ', msg:' . $msg, 'warn'); } }
/** * Wrapper of CakeEmail object creation and submission. * @param $emailData * @param string $templateName * @param string $to * @param string $subjectBlockName * @param string $tag * @param string $locale * @param bool $debug * @param array $emailOptions * @return string * @throws Exception */ public static function sendEmail($emailData, $templateName = '', $to = '', $subjectBlockName = '', $tag = '', $locale = 'en-US', $debug = false, $emailOptions = array()) { if (empty($templateName) || empty($to) || empty($subjectBlockName)) { CakeLog::error('CRITICAL EXEPTION: In email library.'); CakeLog::error('Empty argument passed to email sender.'); throw new BadMethodCallException('Empty argument passed to email sender.', 1); return false; } // Since getting the data from Drupal happens in-line we need to check // for errors by seeing if we only get log_info back and nothing else. if (!empty($tag)) { $drupalData = array(); DruniqueAPIUtil::getData(['api_url' => 'email_text.json', 'params' => ['tag' => $tag], 'locale' => $locale], $drupalData); if (sizeof($drupalData) <= 1) { CakeLog::error('CRITICAL EXEPTION: In email library.'); CakeLog::error('Unable to get view variables from CMS.'); throw new Exception('Unable to get view variables from CMS.', 1); return false; } $emailData['email_text'] = $drupalData; } $email = new CakeEmail('default'); $subject = DruniqueAPIUtil::content($subjectBlockName, $emailData['email_text']); $subject = preg_replace('/[\\pZ\\pC]/u', ' ', $subject); if ($debug) { $email->transport('Debug'); } // Make sure format is set correctly based on existence of templates. $format = 'both'; $htmlTemplateExists = is_readable(APP . "View/Emails/html/{$templateName}.ctp"); $textTemplateExists = is_readable(APP . "View/Emails/text/{$templateName}.ctp"); if (!$htmlTemplateExists && !$textTemplateExists) { CakeLog::error('CRITICAL ERROR: In email library.'); CakeLog::error("Unable to find email template named {$templateName}.ctp"); return false; } elseif (!$htmlTemplateExists && $textTemplateExists) { $format = 'text'; } elseif ($htmlTemplateExists && !$textTemplateExists) { $format = 'html'; } $email->template($templateName, 'default')->emailFormat($format)->to($to)->subject(html_entity_decode($subject, ENT_QUOTES))->viewVars($emailData); if (isset($emailOptions['bcc'])) { $email->bcc($emailOptions['bcc']); } if (isset($emailOptions['cc'])) { $email->cc($emailOptions['cc']); } try { $response = $email->send(); if ($debug) { return $response; } if ($response) { $result = 'Email was sent successfully'; } else { $result = 'Email failed to send without exceptions'; CakeLog::error('CRITICAL ERROR: Email library failed to send an email without exception.'); Cakelog::error(print_r($email, true)); } } catch (Exception $e) { $result = 'Email failed with exception: ' . print_r($e->getMessage(), true); CakeLog::error('CRITICAL ERROR: In email library.'); CakeLog::error($e->getMessage()); } return $result; }