public function run() { $users = User::getUserArrayByExpire(); $notificationMail = Option::get('mail_stop_expire_notification'); $mailContentTemplate = Option::get('custom_mail_stop_expire_content'); if (!$notificationMail) { Option::set('mail_stop_expire_notification', 0); // 设置邮件提醒的系统参数 } $mailer = Mailer::getInstance(); $mailer->toQueue(true); foreach ($users as $user) { $user->stop(); Logger::getInstance()->info('user [' . $user->email . '] 未续费或流量超用已被暂停服务'); if ($notificationMail) { $mail = new Mail(); $mail->to = $user->email; $mail->subject = '[' . SITE_NAME . '] ' . "用户 {$user->nickname},您的账户由于未续费或流量超用已被暂停服务"; $params = ['nickname' => $user->nickname, 'email' => $user->email, 'useTraffic' => Utils::flowAutoShow($user->flow_up + $user->flow_down), 'transfer' => Utils::flowAutoShow($user->transfer), 'expireTime' => date('Y-m-d H:i:s', $user->expireTime)]; $mailContent = Utils::placeholderReplace($mailContentTemplate, $params); $mailContent .= "<p style=\"padding: 1.5em 1em 0; color: #999; font-size: 12px;\">—— 本邮件由 " . SITE_NAME . " (<a href=\"" . BASE_URL . "\">" . BASE_URL . "</a>) 账户管控系统发送</p>"; $mail->content = $mailContent; $mailer->send($mail); } } // 避免频繁更新 Option 单例对象,循环结束后再执行 if ($notificationMail) { Option::set('mail_queue', 1); } // 2016-04-26 15:00 - by @Sendya Fixed issue #62 // User::enableUsersByExpireTime(); // 启用已续费且流量未超过的用户 }
/** * 淘宝自动发货API * 创建卡号 * * @JSON */ public function createCard() { $CURR_KEY = $_SERVER['HTTP_AUTHORIZATION']; if (!$CURR_KEY) { header("HTTP/1.1 405 Method Not Allowed"); exit; } $KEY = Option::get('SYSTEM_API_KEY'); if ($KEY == null) { $KEY = password_hash(Utils::randomChar(12) . time(), PASSWORD_BCRYPT); Option::set('SYSTEM_API_KEY', $KEY); } $CURR_KEY = str_replace('Basic ', '', $CURR_KEY); $CURR_KEY = md5($CURR_KEY . ENCRYPT_KEY); $KEY = md5($KEY . ENCRYPT_KEY); if (strtoupper($KEY) == strtoupper($CURR_KEY)) { $card = new Card(); $card->card = substr(hash("sha256", time() . Utils::randomChar(10)) . time(), 1, 26); $card->add_time = time(); $card->type = intval(trim($_POST['type'])); $card->info = trim($_POST['info']); $card->status = 1; $card->save(); return array('error' => 0, 'message' => 'success', 'card' => $card); } else { return array('error' => 1, 'message' => 'Bad Request'); } }
public function __construct() { $className = Utils::getShortName($this); $this->isAvailable(); $config = Option::get('MAIL_' . $className); if (!$config) { throw new Error("邮件模块 " . $className . " 配置不完整,无法使用。"); } $this->config = json_decode($config, true); }
/** * @param \Throwable $instance Exception or Error instance * @throws Error */ public static function handleUncaughtException($instance) { @ob_end_clean(); if (Database::getInstance() && Database::getInstance()->inTransaction()) { Database::getInstance()->rollBack(); } if (!$instance instanceof Error) { $instance = new self($instance->getMessage(), intval($instance->getCode()), $instance, $instance->getTrace()); } elseif ($instance->getCode()) { \Helper\Utils::send_http_status($instance->getCode()); } Template::setView('Misc/Error'); Template::putContext('instance', $instance); Filter::preRender(); Template::render(); Filter::afterRender(); exit; }
public function __construct() { $className = Utils::getShortName($this); $this->isAvailable(); $config = Option::get('MAIL_' . $className); if (!$config) { throw new Error("邮件模块 " . $className . " 配置不完整,无法使用。"); } $this->config = json_decode($config, true); $this->setFrom($this->config['from']); //设置发件人 格式为( 发件人名称 <*****@*****.**> ) $this->setAddress($this->config['smtp_name']); // if ($this->config['smtp_ssl'] == 'ssl') { //ssl 模式 $this->setServer($this->config['server'], $this->config['smtp_name'], $this->config['smtp_pass'], 465, true); } else { // 非ssl $this->setServer($this->config['server'], $this->config['smtp_name'], $this->config['smtp_pass']); } }
/** * 激活(使用)卡号 * @JSON */ public function activation() { $user = User::getUserByUserId(User::getCurrent()->uid); $result = array('error' => 1, 'message' => '该卡已经被使用或不存在。'); if ($_POST['actCard'] != null) { $actCard = htmlspecialchars(trim($_POST['actCard'])); $card = Mcard::queryCard($actCard); if (!$card || !$card->status) { return $result; } $custom_transfer_level = json_decode(Option::get('custom_transfer_level'), true); $custom_transfer_repeat = json_decode(Option::get('custom_transfer_repeat'), true); /* 0-套餐卡 1-流量卡 2-测试卡 3-余额卡 */ if ($card->type == 0) { if ($user->plan == 'Z' && $user->transfer > $user->flow_up + $user->flow_down) { $result['message'] = '您的流量套餐尚未使用完毕。无法转换到 ' . Utils::planAutoShow($card->info) . ' 套餐'; return $result; } //判断账户卡号类型是否一致 一致则无视系统叠加开关进行 叠加时间 $user->payTime = time(); if ($user->flow_up + $user->flow_down < $user->transfer) { $user->enable = 1; } else { $user->enable = 0; } $cardDay = 31; if (is_numeric($card->expireTime)) { $cardDay = intval($card->expireTime); } $expireTime = 0; if ($user->plan == $card->info) { // 卡片与账户类型相等 if ($user->expireTime > time()) { $expireTime = $user->expireTime + 3600 * 24 * $cardDay; // 到期时间 = 当前账户到期时间+卡片时间 } else { $expireTime = time() + 3600 * 24 * $cardDay; // 到期时间 = 当前系统续费时间+卡片时间 } } else { if ($user->expireTime < time() || !$custom_transfer_repeat) { $expireTime = time() + 3600 * 24 * $cardDay; // 到期时间 = 不叠加原时间 (当前系统续费时间+卡片时间) } else { $expireTime = $user->expireTime + 3600 * 24 * $cardDay; // 到期时间 = 当前账户到期时间+卡片时间 } } $user->expireTime = $expireTime; $user->plan = $card->info; $user->transfer = Utils::GB * intval($custom_transfer_level[$user->plan]); $result['message'] = '您的账户已升级到 ' . Utils::planAutoShow($user->plan) . ' ,共有流量 ' . Utils::flowAutoShow($user->transfer) . ', 已用 ' . Utils::flowAutoShow($user->flow_down + $user->flow_up) . ', 到期时间:' . date('Y-m-d H:i:s', $user->expireTime); } elseif ($card->type == 1) { if ($user->plan == 'Z') { $user->transfer += intval($card->info) * Utils::GB; // 如果之前是 流量 套餐,则递增 } else { $user->transfer = intval($card->info) * Utils::GB; // 如果之前是 普通套餐,则清空总流量并设定新流量 $user->flow_up = 0; $user->flow_down = 0; } if ($user->flow_up + $user->flow_down < $user->transfer) { $user->enable = 1; } else { $user->enable = 0; } $user->plan = 'Z'; // 强制设定为Z $user->expireTime = strtotime("+1 year"); // 账户可用时间增加一年 $result['message'] = '您的账户已经激活固定流量套餐,共有流量' . Utils::flowAutoShow($user->transfer) . ' ,该流量到期时间 ' . date('Y-m-d H:i:s', $user->expireTime) . ', 感谢您的使用(注意:流量使用完毕前无法通过套餐卡转换为套餐包月用户)'; } elseif ($card->type == 2) { $user_test_day = Option::get('user_test_day') ?: 7; if ($user->plan != 'A') { return array('error' => 1, 'message' => '喂喂,你不是测试账户诶? 没办法帮你续命。'); } $user->plan = 'A'; $user->payTime = time(); if ($user->expireTime < time()) { $user->expireTime = time() + 3600 * 24 * intval($user_test_day); // 到期时间 } else { $user->expireTime = $user->expireTime + 3600 * 24 * intval($user_test_day); // 到期时间 } $user->transfer = Utils::GB * intval($custom_transfer_level[$user->plan]); $user->flow_down = 0; $user->flow_up = 0; $user->enable = 1; $result['message'] = '您的账户已经激活测试套餐,共有流量' . Utils::flowAutoShow($user->transfer) . ' ,到期时间 ' . date('Y-m-d H:i:s', $user->expireTime) . ', 感谢您的使用'; } elseif ($card->type == 3) { // 余额卡 $user->money += intval($card->info); $user->save(); $result['message'] = '余额充值成功,您当前余额为 ' . $user->money . ' 元'; } $card->destroy(); // 将此卡片禁止 $user->save(); $_SESSION['currentUser'] = $user; // 将用户信息更新到 session 中. } return $result; }
public function getPlan() { return Utils::planAutoShow($this->plan); }
/** * 签到 * * @JSON */ public function checkIn() { $user = User::getCurrent(); $result = array('error' => 1, 'message' => '签到失败或已签到。'); if ($user->lastCheckinTime <= strtotime(date('Y-m-d 00:00:00', time()))) { $user = User::getUserByUserId($user->uid); $user->lastCheckinTime = time(); $checkinTransfer = rand(intval(Option::get('check_transfer_min')), intval(Option::get('check_transfer_max'))) * Utils::MB; $user->transfer = $user->transfer + $checkinTransfer; $_SESSION['currentUser'] = $user; $user->save(); $result['time'] = date("m-d H:i:s", $user->lastCheckinTime); $result['message'] = '签到成功, 获得' . Utils::flowAutoShow($checkinTransfer) . ' 流量'; $result['error'] = 0; } else { $result['message'] = '你已经在 ' . date('Y-m-d H:i:s', $user->lastCheckinTime) . " 时签到过."; } return $result; }
/** * 修改用户信息 * @JSON */ public function update() { $result = array("error" => 1, "message" => "Request failed"); if ($_POST['user_uid'] != null) { $us = UserModel::getUserByUserId(trim($_POST['user_uid'])); if ($us) { if ($_POST['user_email'] != null) { $us->email = $_POST['user_email']; } if ($_POST['user_nickname'] != null) { $us->nickname = $_POST['user_nickname']; } if ($_POST['user_port'] != null) { $us->port = $_POST['user_port']; } if ($_POST['user_sspwd'] != null) { $us->sspwd = $_POST['user_sspwd']; } if ($_POST['user_plan'] != null) { $us->plan = $_POST['user_plan']; } if ($_POST['user_invite_num'] != null) { $us->invite_num = $_POST['user_invite_num']; } if ($_POST['user_transfer'] != null) { $us->transfer = floatval($_POST['user_transfer']) * Utils::GB; } if ($_POST['user_flow_down'] != null) { $us->flow_down = floatval($_POST['user_flow_down']) * Utils::GB; $us->flow_up = 0; } if ($_POST['user_enable'] != null) { $us->enable = intval($_POST['user_enable']); } // 是否启用该用户。该字段会强制用户无法链接到所有服务器! if ($_POST['user_payTime'] != null) { $us->payTime = strtotime($_POST['user_payTime']); } if ($_POST['user_expireTime'] != null) { $us->expireTime = strtotime($_POST['user_expireTime']); } if ($us->enable != 0 && $us->enable != 1) { $us->enable = 0; } if ($us->port != null && $us->port != 0) { $rs = UserModel::checkUserPortIsAvailable($us->port, $us->uid); if ($rs) { $result = array("error" => 1, "message" => "端口{$rs->port}已被占用,请更换"); return $result; } } if ($_POST['user_password'] != null && $_POST['user_password'] != '') { // change password $us->setPassword(trim($_POST['user_password'])); } $us->save(); if ($_POST['user_isAdmin'] != null) { // 如果选中了管理员,设置管理员的值 $us->setAdmin($_POST['user_isAdmin']); } $result['error'] = 0; $result['message'] = '更新信息成功'; $us->plan = Utils::planAutoShow($us->plan); $us->transfer = Utils::flowAutoShow($us->transfer); $us->flow_down = ($us->flow_up + $us->flow_down) / Utils::GB; $us->payTime = date('Y-m-d H:i:s', $us->payTime); $us->expireTime = date('Y-m-d H:i:s', $us->expireTime); $result['user'] = $us; } } return $result; }
/** * 修改 和 新增 卡号 * * @JSON */ public function update() { $result = array('error' => 1, 'message' => '请求错误'); $user = User::getCurrent(); if ($_POST['card_no'] != null && $_POST['card'] != null) { // 修改 $cardId = intval(trim($_POST['card'])); $card = MCard::queryCardById($cardId); if (!$card) { return $result; } $card->type = intval(trim($_POST['card_type'])); $card->info = htmlspecialchars(trim($_POST['card_info'])); $card->status = intval(trim($_POST['card_status'])); $card->expireTime = intval(trim($_POST['card_exp'])); $card->save(); $card->add_time = date("Y-m-d H:i:s", $card->add_time); if ($card->type == 0) { $card->type = "套餐卡"; } elseif ($card->type == 1) { $card->type = "流量卡"; } elseif ($card->type == 2) { $card->type = "试用延期卡"; } elseif ($card->type == 3) { $card->type = "余额卡"; } $card->status = $card->status == 1 ? "未用" : "已用"; $result['error'] = 0; $result['message'] = "修改卡号成功。"; $result['card'] = $card; return $result; } else { // 新增 $number = 1; if ($_POST['card_num'] != null) { $number = intval(trim($_POST['card_num'])); } $cardList = array(); for ($i = 0; $i < $number; ++$i) { $cardStr = substr(hash("sha256", $user->uid . Utils::randomChar(10)) . time(), 1, 26); $card = new MCard(); $card->add_time = time(); $card->card = $cardStr; $card->type = intval(trim($_POST['card_type'])); $card->info = htmlspecialchars(trim($_POST['card_info'])); $card->expireTime = intval(trim($_POST['card_exp'])); $card->status = 1; $card->save(); $card->add_time = date("Y-m-d H:i:s", $card->add_time); if ($card->type == 0) { $card->type = "套餐卡"; } elseif ($card->type == 1) { $card->type = "流量卡"; } elseif ($card->type == 2) { $card->type = "试用延期卡"; } elseif ($card->type == 3) { $card->type = "余额卡"; } $card->status = $card->status == 1 ? "未用" : "已用"; $cardList[] = $card; } $result['error'] = 0; $result['message'] = "新增卡号成功,共 {$number} 个。"; $result['card'] = $cardList; return $result; } }
/** * 对邮件占位符进行替换 * 支持: * <pre> * {SITE_NAME} : 站点名称 * {nickname} : 当前用户名称 * {email} : 用户电子邮件 * {code} : 验证码 * {newPassword}: 新密码 * {useTraffic}: 已用流量 * {transfer} : 总流量 * {expireTime}: 到期时间 * {avatar}: 用户头像 (必须与 {email} 同时使用) * {REGISTER_URL}: 注册校验链接 * </pre> * @param $content * @param $params array * @return string */ public static function placeholderReplace($content, $params) { if ($params['REGISTER_URL'] != null) { $url = BASE_URL . 'auth/verification?verification=' . urlencode($params['REGISTER_URL']); $params['REGISTER_URL'] = "<a href=\"{$url}\" target=\"_blank\" title=\"点击校验您的账户并完成注册!\">{$url}</a>"; } if ($params['avatar'] === true) { $params['avatar'] = Utils::gravatar($params['email']); } // 替换 $content = str_replace(['{SITE_NAME}', '{nickname}', '{email}', '{code}', '{newPassword}', '{useTraffic}', '{transfer}', '{expireTime}', '{REGISTER_URL}', '{avatar}'], [SITE_NAME, $params['nickname'], $params['email'], $params['code'], $params['newPassword'], $params['useTraffic'], $params['transfer'], $params['expireTime'], $params['REGISTER_URL'], $params['avatar']], $content); return $content; }
/** * @JSON * @return array * @throws \Core\Error */ public function postAll() { $subject = $_POST['mailer_subject']; $content = htmlspecialchars($_POST['mailer_content']); $content .= "<p style=\"padding: 1.5em 1em 0; color: #999; font-size: 12px;\">—— 本邮件由 " . SITE_NAME . " (<a href=\"" . BASE_URL . "\">" . BASE_URL . "</a>) 管理员发送</p>"; if ($subject == null || $subject == '' || $content == null || $content == '') { return array('error' => 1, 'message' => '请求错误,您提交的参数不对。'); } $users = User::getUserList(); $mailer = Mailer1::getInstance(); $mailer->toQueue(true); foreach ($users as $user) { $mail = new Mail(); $params = ['nickname' => $user->nickname, 'email' => $user->email, 'useTraffic' => Utils::flowAutoShow($user->flow_up + $user->flow_down), 'transfer' => Utils::flowAutoShow($user->transfer), 'expireTime' => date('Y-m-d H:i:s', $user->expireTime), 'avatar' => true]; $mail->subject = $subject; $mail->content = Utils::placeholderReplace($content, $params); $mail->to = $user->email; $mailer->send($mail); } return array('error' => 0, 'message' => '邮件列队正在工作,将在稍后开始发送..'); }
/** * 查询 * @JSON */ public function query() { $result = array('error' => 1, 'message' => 'Request failed'); $result['message_id'] = $_GET['message_id']; if ($_GET['message_id'] != null) { $rs = MessageModel::getMessageById(trim($_GET['message_id'])); $rs->pushTime = date('Y-m-d H:i:s', $rs->pushTime); $rs->pushEndTime = date('Y-m-d H:i:s', $rs->pushEndTime); $rs->content = Utils::br2nl($rs->content); if ($rs) { $result = array('error' => 0, 'message' => 'success', 'modal' => $rs); } } return $result; }
/** * 导出邀请码 */ public function export() { $invites = InviteModel::getInviteArray(0); $file_name = '邀请码列表_' . time() . '.csv'; $data = 'id,邀请码,邀请码等级,创建时间,状态' . "\n"; foreach ($invites as $invite) { $data .= $invite->id . ',' . $invite->invite . ',' . Utils::planAutoShow($invite->plan) . '(' . $invite->plan . '),' . date('Y-m-d H:i:s', $invite->dateLine) . ',' . '可用' . "\n"; } header("Content-type:text/csv;charset=utf-8"); header("Content-Disposition:attachment;filename=" . $file_name); header('Cache-Control:must-revalidate,post-check=0,pre-check=0'); header('Expires:0'); header('Pragma:public'); $data = iconv('utf-8', 'gb2312', $data); echo $data; exit; }
/** * Add a invite * @param $uid * @param string $plan * @param bool $isTransfer * @return bool */ public static function addInvite($uid, $plan = 'A', $isTransfer = false) { $inviteStr = substr(hash("sha256", $uid . Utils::randomChar(10)), 0, 26) . $uid; $obj = new self(); $obj->inviteIp = Utils::getUserIP(); $obj->invite = $inviteStr; $obj->plan = $plan; $obj->uid = $uid; if ($isTransfer) { $user = User::getUserByUserId($uid); $user->transfer = $user->transfer - Utils::GB * 10; $user->invite_num = $user->invite_num - 1; $user->save(); } $result = $obj->save(); return $obj; }
/** * @JSON * @throws \Core\Error */ public function forgePwd() { $result = array('error' => 1, 'message' => '请求找回密码失败,请刷新页面重试。'); $siteName = SITE_NAME; if (isset($_POST['email']) && $_POST['email'] != '') { $user = User::getUserByEmail(htmlspecialchars(trim($_POST['email']))); if (!$user) { return $result; } if ($user->enable == 0) { $verify_code = json_decode($user->forgePwdCode, true)['verification']; if ($verify_code != null) { $result['message'] = '您的账户还未进行邮箱校验,请校验完毕后再试!'; return $result; } } $user->lastFindPasswdTime = time(); if ($user->lastFindPasswdCount != 0 && $user->lastFindPasswdCount > 2) { $result['message'] = '找回密码重试次数已达上限!'; return $result; } $code = Utils::randomChar(10); $forgePwdCode['code'] = $code; $forgePwdCode['time'] = time(); $user->forgePwdCode = json_encode($forgePwdCode); $content = Option::get('custom_mail_forgePassword_content'); $params = ['code' => $code, 'nickname' => $user->nickname, 'email' => $user->email, 'useTraffic' => Utils::flowAutoShow($user->flow_up + $user->flow_down), 'transfer' => Utils::flowAutoShow($user->transfer), 'expireTime' => date('Y-m-d H:i:s', $user->expireTime)]; $content = Utils::placeholderReplace($content, $params); $mailer = Mailer::getInstance(); $mail = new \Model\Mail(); $mail->to = $user->email; $mail->subject = "[" . SITE_NAME . "] Password Recovery"; $mail->content = $content; $mailer->toQueue(true); // 添加到邮件列队 $isOk = $mailer->send($mail); $user->save(); $result['uid'] = $user->uid; if ($isOk) { $result['message'] = '验证代码已经发送到该注册邮件地址,请注意查收!<br/>请勿关闭本页面,您还需要验证码来验证您的账户所有权才可重置密码!!'; $result['error'] = 0; } else { $result['message'] = '邮件发送失败, 请联系管理员检查邮件系统设置!'; $result['error'] = 1; } return $result; } else { if ($_POST['code'] != '' && $_POST['uid'] != '') { $uid = $_POST['uid']; $code = trim($_POST['code']); $user = User::GetUserByUserId(trim($uid)); $forgePwdCode = json_decode($user->forgePwdCode, true); // forgePwdCode.length > 1 且 验证码一样 且 时间不超过600秒(10分钟) if (count($forgePwdCode) > 1 && $forgePwdCode['code'] == $code && time() - intval($forgePwdCode['time']) < 600) { $newPassword = Utils::randomChar(10); $user->setPassword($newPassword); $user->lastFindPasswdCount = 0; $user->lastFindPasswdTime = 0; $user->save(); $content = Option::get('custom_mail_forgePassword_content_2'); $params = ['code' => $code, 'newPassword' => $newPassword, 'nickname' => $user->nickname, 'email' => $user->email, 'useTraffic' => Utils::flowAutoShow($user->flow_up + $user->flow_down), 'transfer' => Utils::flowAutoShow($user->transfer), 'expireTime' => date('Y-m-d H:i:s', $user->expireTime)]; $content = Utils::placeholderReplace($content, $params); $mailer = Mailer::getInstance(); $mail = new \Model\Mail(); $mail->to = $user->email; $mail->subject = "[" . SITE_NAME . "] Your new Password"; $mail->content = $content; $mailer->toQueue(true); // 添加到邮件列队 $isOk = $mailer->send($mail); if ($isOk) { $result['message'] = '新密码已经发送到该账户邮件地址,请注意查收!<br/> 并且请在登录后修改密码!'; $result['error'] = 0; } else { $result['message'] = '邮件发送失败, 请联系管理员检查邮件系统设置!'; $result['error'] = 1; } } else { $result['message'] = '验证码已经超时或者 验证码填写不正确。请再次确认'; $result['error'] = -1; } return $result; } else { Template::putContext('user', User::getCurrent()); Template::setView('panel/forgePwd'); } } return $result; }