/** * 生成文字水印 * @param string $source * @param string $toPath * @return string|false */ public static function water($source, $toPath = null) { $type = Options::getWaterMarkType(); if ($type !== DataOptions::WATER_MARK_TYPE_IMGDIR && $type !== DataOptions::WATER_MARK_TYPE_TEXT) { return false; } $position = Options::getWaterMarkPosition(); if ($position < 1 || $position > 9) { return false; } $offset = 1; if ($toPath === null) { $toPath = dirname($source) . DS . 'water_' . basename($source); } if ($type === DataOptions::WATER_MARK_TYPE_TEXT) { $text = Options::getWaterMarkText(); if ($text !== '') { $fontFile = Cfg::getApp('fontfile'); if (ImageManager::textWater($source, $text, $fontFile, $toPath, $position, $offset)) { return $toPath; } } } elseif ($type === DataOptions::WATER_MARK_TYPE_IMGDIR) { $water = Options::getWaterMarkImgdir(); if ($water !== '') { $pct = max(Options::getWaterMarkPct(), 0); if (ImageManager::imageWater($source, $water, $toPath, $position, $offset, $pct)) { return $toPath; } } } return false; }
/** * (non-PHPdoc) * @see \tfc\mvc\interfaces\Action::run() */ public function run() { $req = Ap::getRequest(); $cookie = new Cookie('cookie'); $appid = Cfg::getApp('appid', 'qq', 'extlogin'); $appkey = Cfg::getApp('appkey', 'qq', 'extlogin'); $callback = Options::getSiteUrl() . '/index.php?r=member/data/qqcallback'; if ($cookie->get('state') !== $req->getParam('state')) { exit('The state does not match. You may be a victim of CSRF.'); } $tokenUrl = 'https://graph.qq.com/oauth2.0/token?grant_type=authorization_code' . '&client_id=' . $appid . '&redirect_uri=' . urlencode($callback) . '&client_secret=' . $appkey . '&code=' . $req->getParam('code'); $response = file_get_contents($tokenUrl); if (strpos($response, 'callback') !== false) { $lpos = strpos($response, '('); $rpos = strrpos($response, ')'); $response = substr($response, $lpos + 1, $rpos - $lpos - 1); $msg = json_decode($response); if (isset($msg->error)) { echo '<h3>error:</h3>' . $msg->error; echo '<h3>msg :</h3>' . $msg->error_description; exit; } } $params = array(); parse_str($response, $params); $graphUrl = 'https://graph.qq.com/oauth2.0/me?access_token=' . $params['access_token']; $str = file_get_contents($graphUrl); if (strpos($str, 'callback') !== false) { $lpos = strpos($str, '('); $rpos = strrpos($str, ')'); $str = substr($str, $lpos + 1, $rpos - $lpos - 1); } $user = json_decode($str); if (isset($user->error)) { echo '<h3>error:</h3>' . $user->error; echo '<h3>msg :</h3>' . $user->error_description; exit; } $openid = $user->openid; $mod = Model::getInstance('Account', 'member'); $ret = $mod->extlogin(DataAccount::PARTNER_QQ, $openid); if ($ret['err_no'] === DataAccount::SUCCESS_LOGIN_NUM) { $httpReferer = HttpCookie::get('http_referer', 'index.php'); HttpCookie::remove('http_referer'); Ap::getResponse()->location($httpReferer); } else { Ap::getResponse()->location('index.php?r=member/show/login'); } }
/** * (non-PHPdoc) * @see \tfc\mvc\interfaces\Action::run() */ public function run() { $cookie = new Cookie('cookie'); $httpReferer = Ap::getRequest()->getTrim('http_referer'); if ($httpReferer === '') { $httpReferer = 'index.php'; } HttpCookie::add('http_referer', $httpReferer); $appid = Cfg::getApp('appid', 'qq', 'extlogin'); $callback = Options::getSiteUrl() . '/index.php?r=member/data/qqcallback'; $scope = 'get_user_info'; $state = md5(uniqid(rand(), TRUE)); //CSRF protection $cookie->add('state', $state); $loginUrl = 'https://graph.qq.com/oauth2.0/authorize?response_type=code' . '&client_id=' . $appid . '&redirect_uri=' . urlencode($callback) . '&state=' . $state . '&scope=' . $scope; Ap::getResponse()->location($loginUrl); }
/** * (non-PHPdoc) * @see \tfc\mvc\interfaces\Action::run() */ public function run() { $cookie = new Cookie('cookie'); $httpReferer = Ap::getRequest()->getTrim('http_referer'); if ($httpReferer === '') { $httpReferer = 'index.php'; } HttpCookie::add('http_referer', $httpReferer); $appid = Cfg::getApp('appid', 'wechat', 'extlogin'); $callback = Options::getSiteUrl() . '/index.php?r=member/data/wechatcallback'; $scope = 'snsapi_base'; $state = md5(uniqid(rand(), TRUE)); //CSRF protection $cookie->add('state', $state); $loginUrl = 'https://open.weixin.qq.com/connect/oauth2/authorize?response_type=code' . '&appid=' . $appid . '&redirect_uri=' . urlencode($callback) . '&state=' . $state . '&scope=' . $scope . '#wechat_redirect'; Ap::getResponse()->location($loginUrl); }
/** * (non-PHPdoc) * @see \tfc\mvc\Widget::run() */ public function run() { $output = ''; $html = $this->getHtml(); $config = Cfg::getApp('navbar'); foreach ($config as $menus) { $main = array_shift($menus); if (!is_array($main)) { continue; } // 主菜单 if (!$menus) { $output .= $html->tag('li', $this->getAttributes($main, false), $this->a($main)) . "\n"; continue; } // 主菜单外开始标签 $output .= $html->openTag('li', $this->getAttributes($main, true)) . "\n"; $output .= $this->a($main, true) . "\n"; // 下拉子菜单外开始标签 $output .= $html->openTag('ul', array('class' => 'dropdown-menu')) . "\n"; // 下拉子菜单列表 $total = count($menus); $curr = 0; foreach ($menus as $menu) { $output .= $html->tag('li', array(), $this->a($menu)) . "\n"; if (++$curr < $total) { $output .= $html->tag('li', array('class' => 'divider'), '') . "\n"; } } // 下拉子菜单外结束标签 $output .= $html->closeTag('ul') . "\n"; // 主菜单外结束标签 $output .= $html->closeTag('li') . "\n"; } $this->assign('is_login', Identity::isLogin()); $this->assign('user_id', Identity::getUserId()); $this->assign('login_name', Identity::getLoginName()); $this->assign('user_name', Identity::getNickname()); $this->assign('app_names', Identity::getAppNames()); $this->assign('menus', $output); $this->assign('logout', $this->getView()->CFG_SYSTEM_GLOBAL_LOGOUT); $this->display(); }
/** * 获取最后一次访问的列表页参数 * @param array $params * @return array */ public function getLLUParams(array $params = array()) { $attributes = isset($params['attributes']) ? (array) $params['attributes'] : array(); $order = isset($params['order']) ? trim($params['order']) : ''; $listRows = isset($params['limit']) ? (int) $params['limit'] : 0; $firstRow = isset($params['offset']) ? (int) $params['offset'] : 0; if ($order !== '') { $attributes['order'] = $order; } if ($listRows <= 0) { return $attributes; } if ($listRows !== (int) Cfg::getApp('list_rows', 'paginator')) { $attributes[PageHelper::getListRowsVar()] = $listRows; } $firstRow = max($firstRow, 0); $currPage = floor($firstRow / $listRows) + 1; if ($currPage > 0) { $attributes[PageHelper::getPageVar()] = $currPage; } return $attributes; }
/** * (non-PHPdoc) * @see \tfc\mvc\interfaces\Action::run() */ public function run() { $req = Ap::getRequest(); $cookie = new Cookie('cookie'); $appid = Cfg::getApp('appid', 'wechat', 'extlogin'); $appsecret = Cfg::getApp('appsecret', 'wechat', 'extlogin'); if ($cookie->get('state') !== $req->getParam('state')) { exit('The state does not match. You may be a victim of CSRF.'); } $tokenUrl = 'https://api.weixin.qq.com/sns/oauth2/access_token?grant_type=authorization_code' . '&appid=' . $appid . '&secret=' . $appsecret . '&code=' . $req->getParam('code'); $resource = curl_init(); curl_setopt($resource, CURLOPT_URL, $tokenUrl); curl_setopt($resource, CURLOPT_HEADER, 0); curl_setopt($resource, CURLOPT_RETURNTRANSFER, 1); curl_setopt($resource, CURLOPT_NOSIGNAL, 1); curl_setopt($resource, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); $result = curl_exec($resource); if ($result === false) { $errNo = curl_errno($resource); $errMsg = curl_error($resource); curl_close($resource); echo '<h3>error:</h3>' . $errNo; echo '<h3>msg :</h3>' . $errMsg; exit; } curl_close($resource); $user = json_decode($result); $openid = $user->openid; $mod = Model::getInstance('Account', 'member'); $ret = $mod->extlogin(DataAccount::PARTNER_WECHAT, $openid); if ($ret['err_no'] === DataAccount::SUCCESS_LOGIN_NUM) { $httpReferer = HttpCookie::get('http_referer', 'index.php'); HttpCookie::remove('http_referer'); Ap::getResponse()->location($httpReferer); } else { Ap::getResponse()->location('index.php?r=member/show/login'); } }
/** * 获取Cookie名 * @return string */ public function getCookieName() { static $cookieName = null; if ($cookieName === null) { $cookieName = Cfg::getApp('cookie_name', $this->getClusterName()); } return $cookieName; }
/** * 获取分页处理类 * @return \tfc\util\Paginator */ public function getPaginator() { // 总的记录数 <= 0,表示不需要分页 if (($totalRows = $this->getTotalRows()) <= 0) { return null; } $attributes = isset($this->_tplVars['attributes']) ? (array) $this->_tplVars['attributes'] : array(); $order = isset($this->_tplVars['order']) ? trim($this->_tplVars['order']) : ''; $listRows = isset($this->_tplVars['limit']) ? (int) $this->_tplVars['limit'] : 0; $firstRow = isset($this->_tplVars['offset']) ? (int) $this->_tplVars['offset'] : 0; // 每页展示的行数 <= 0,表示第一页展示所有数据 if ($listRows <= 0) { return null; } if ($order !== '') { $attributes['order'] = $order; } if ($listRows !== (int) Cfg::getApp('list_rows', 'paginator')) { $attributes[PageHelper::getListRowsVar()] = $listRows; } $firstRow = max($firstRow, 0); $currPage = floor($firstRow / $listRows) + 1; $url = $this->getUrlManager()->getUrl(Mvc::$action, Mvc::$controller, Mvc::$module, $attributes); $paginator = new Paginator($totalRows, $url, PageHelper::getPageVar()); $paginator->setListPages(PageHelper::getListPages()); $paginator->setListRows($listRows); $paginator->setCurrPage($currPage); return $paginator; }
/** * 获取从$_GET或$_POST中获取当前页的键名 * @return string */ public static function getPageVar() { try { $pageVar = Cfg::getApp('page_var', 'paginator'); } catch (ErrorException $e) { $pageVar = Paginator::DEFAULT_PAGE_VAR; } return $pageVar; }
/** * 从Cookie中获取用户身份信息并设置到用户身份管理类 * @return boolean */ public function initIdentity() { $clusterName = self::CLUSTER_NAME; $config = Cfg::getApp($clusterName); $expiry = isset($config['expiry']) ? (int) $config['expiry'] : 0; $cookieName = isset($config['cookie_name']) ? trim($config['cookie_name']) : ''; $cooksetPassword = isset($config['cookset_password']) ? (bool) $config['cookset_password'] : false; $cooksetRoleNames = isset($config['cookset_rolenames']) ? (bool) $config['cookset_rolenames'] : false; $cooksetAppNames = isset($config['cookset_appnames']) ? (bool) $config['cookset_appnames'] : false; if ($cookieName === '') { Log::warning(sprintf('Account cookie name must be string and not empty, cluster_name "%s"', $clusterName), 0, __METHOD__); return false; } $authentica = new Authentica($clusterName); $data = $authentica->getIdentity(); if (!$data || !is_array($data) || !isset($data['user_id'])) { Log::debug(sprintf('Account cookie data must be array and not empty, cluster_name "%s", cookie_name "%s"', $clusterName, $cookieName), 0, __METHOD__); return false; } $userId = isset($data['user_id']) ? (int) $data['user_id'] : 0; $loginName = isset($data['user_name']) ? trim($data['user_name']) : ''; $password = isset($data['password']) ? $data['password'] : ''; $ip = isset($data['ip']) ? (int) $data['ip'] : 0; $expiry = isset($data['expiry']) ? (int) $data['expiry'] : 0; $time = isset($data['time']) ? (int) $data['time'] : 0; $nickname = isset($data['nickname']) ? trim($data['nickname']) : ''; $roleNames = isset($data['role_names']) ? (array) $data['role_names'] : array(); $extends = isset($data['extends']) ? $data['extends'] : ''; if ($userId <= 0 || $loginName === '') { Log::warning(sprintf('Account cookie user_id and login_name must be not empty, cluster_name "%s", cookie_name "%s", user_id "%d", login_name "%s"', $clusterName, $cookieName, $userId, $loginName), 0, __METHOD__); return false; } $clientIp = ip2long(Ap::getRequest()->getClientIp()); if ($ip !== $clientIp) { Log::warning(sprintf('Account cookie ip "%s" is not equal to client ip "%s", cluster_name "%s", cookie_name "%s", user_id "%d", login_name "%s"', long2ip($ip), long2ip($clientIp), $clusterName, $cookieName, $userId, $loginName), 0, __METHOD__); return false; } if ($cooksetPassword) { if ($password === '') { Log::warning(sprintf('Account config cookset_password and cookie password must be not empty, cluster_name "%s", cookie_name "%s", user_id "%d", login_name "%s"', $clusterName, $cookieName, $userId, $loginName), 0, __METHOD__); return false; } $dbpwd = $this->_users->getPasswordByUserId($userId); if ($password !== $dbpwd) { Log::warning(sprintf('Account cookie password "%s" is not equal to db password "%s", cluster_name "%s", cookie_name "%s", user_id "%d", login_name "%s"', $clusterName, $cookieName, $userId, $loginName), 0, __METHOD__); return false; } } $groupIds = $roleNames; $appNames = explode(',', $extends); $authoriz = $this->getAuthoriz($roleNames); Identity::setAll($userId, $loginName, $nickname, $roleNames, $appNames, 0, 0, $authoriz); return true; }
/** * 获取数据库配置信息,如果配置信息中没有指定连接数据库失败尝试重连次数,则由MAX_RETRY_TIMES常量指定次数 * @param mixed $key * @return mixed * @throws ErrorException 如果配置信息中没有指定DSN、用户名、密码或编码格式,抛出异常 */ public function getConfig($key = null) { if ($this->_config === null) { $config = Cfg::getDb($this->getClusterName()); if (!isset($config['dsn']) || !isset($config['username']) || !isset($config['password']) || !isset($config['charset'])) { throw new ErrorException(sprintf('DbProxy no entry is registered for key: dsn|username|password|charset in db config "%s"', serialize($config))); } $config['retry'] = isset($config['retry']) ? (int) $config['retry'] : self::MAX_RETRY_TIMES; $this->_config = $config; } if ($key === null) { return $this->_config; } return isset($this->_config[$key]) ? $this->_config[$key] : null; }
/** * 获取密钥配置信息 * @param mixed $key * @return mixed * @throws ErrorException 如果配置信息中没有指定加密密钥、签名密钥、缺省的密文有效期或随机密钥长度,抛出异常 */ public function getConfig($key = null) { if ($this->_config === null) { $config = Cfg::getKey($this->getClusterName()); if (!isset($config['crypt'])) { throw new ErrorException('Keys no entry is registered for key: crypt in key config'); } if (!isset($config['sign'])) { throw new ErrorException('Keys no entry is registered for key: sign in key config'); } if (!isset($config['expiry'])) { throw new ErrorException('Keys no entry is registered for key: expiry in key config'); } if (!isset($config['rnd_len'])) { throw new ErrorException('Keys no entry is registered for key: rnd_len in key config'); } $this->_config = $config; } if ($key === null) { return $this->_config; } return isset($this->_config[$key]) ? $this->_config[$key] : null; }
/** * 获取Ral配置信息,如果配置信息中没有指定连接服务器失败尝试重连次数,则由MAX_RETRY_TIMES常量指定次数 * @param mixed $key * @return mixed * @throws ErrorException 如果没有指定服务器名称或IP地址、服务器端口号、连接超时、执行超时或获取数据后转码方式,抛出异常 */ public function getConfig($key = null) { if ($this->_config === null) { $config = Cfg::getRal($this->getClusterName()); if (!isset($config['server']) || !isset($config['port']) || !isset($config['connect_time_out_ms']) || !isset($config['time_out_ms']) || !isset($config['converter'])) { throw new ErrorException(sprintf('RalProxy no entry is registered for key: server|port|connect_time_out_ms|time_out_ms|converter in ral config "%s"', serialize($config))); } $config['retry'] = isset($config['retry']) ? (int) $config['retry'] : self::MAX_RETRY_TIMES; $this->_config = $config; } if ($key === null) { return $this->_config; } return isset($this->_config[$key]) ? $this->_config[$key] : null; }
/** * 通过文件名,获取访问该文件的URL * @param string $fileName * @return string */ public static function getUrl($fileName) { $req = Ap::getRequest(); $picServer = Cfg::getApp('picture_server'); $url = $picServer . str_replace('/webroot', '', $req->baseUrl) . str_replace(array(DIR_ROOT, '\\'), array('', '/'), $fileName); return $url; }
/** * 获取Cookie配置信息 * @param mixed $key * @return mixed */ public function getConfig($key = null) { if ($this->_config === null) { $config = Cfg::getApp($this->getClusterName()); $config['key_name'] = isset($config['key_name']) ? trim($config['key_name']) : ''; $config['path'] = isset($config['path']) ? trim($config['path']) : self::DEFAULT_PATH; $config['domain'] = isset($config['domain']) ? trim($config['domain']) : self::DEFAULT_DOMAIN; $config['secure'] = isset($config['secure']) ? (bool) $config['secure'] : self::DEFAULT_SECURE; $config['httponly'] = isset($config['httponly']) ? (bool) $config['httponly'] : self::DEFAULT_HTTPONLY; $this->_config = $config; } if ($key === null) { return $this->_config; } return isset($this->_config[$key]) ? $this->_config[$key] : null; }
/** * 初始化模板解析类 * * 配置 /cfg/app/appname/main.php: * <pre> * return array ( * 'view' => array ( * 'skin_name' => 'bootstrap', // 模板风格 * 'charset' => 'utf-8', // HTML编码 * 'tpl_extension' => '.php', // 模板后缀 * 'version' => '1.0', // Js、Css文件的版本号 * 'skin_version' => '3.0.3', // 模板风格文件的版本号 * ), * ); * </pre> * @return void */ protected function _initView() { $viw = Mvc::getView(); $viw->viewDirectory = DIR_APP_VIEWS; $viw->skinName = Cfg::getApp('skin_name', 'view'); $viw->tplExtension = Cfg::getApp('tpl_extension', 'view'); $viw->charset = Cfg::getApp('charset', 'view'); $viw->version = Cfg::getApp('version', 'view'); $viw->skinVersion = Cfg::getApp('skin_version', 'view'); }
/** * 初始化输出的语言种类 * @return void * @throws InvalidArgumentException 如果不是可支持的输出语种,抛出异常 */ protected function _initLanguageType() { // 验证配置中的当前输出语种是否合法 try { $languageType = trim(Cfg::getApp('language')); Ap::setLanguageType($languageType); } catch (ErrorException $e) { } if (!in_array(Ap::getLanguageType(), $this->_languageTypes)) { throw new InvalidArgumentException('BaseAction is unable to determine the language of the config.'); } // 从RGP中获取‘ol’的值(output language type),并验证是否合法 // 以RGP中指定的输出语种为主 $languageType = Ap::getRequest()->getTrim('ol'); if ($languageType !== '') { if (in_array($languageType, $this->_languageTypes)) { Ap::setLanguageType($languageType); } else { throw new InvalidArgumentException('BaseAction is unable to determine the language of the request.'); } } }
/** * 获取上传配置信息 * @param mixed $key * @return mixed */ public function getConfig($key = null) { if ($this->_config === null) { $config = Cfg::getApp($this->getClusterName(), self::CONFIG_NAME); $this->_config = $config; } if ($key === null) { return $this->_config; } return isset($this->_config[$key]) ? $this->_config[$key] : null; }
/** * 从Cookie中获取用户身份信息并设置到用户身份管理类 * @return boolean */ public function initIdentity() { $clusterName = self::CLUSTER_NAME; $config = Cfg::getApp($clusterName); $expiry = isset($config['expiry']) ? (int) $config['expiry'] : 0; $cookieName = isset($config['cookie_name']) ? trim($config['cookie_name']) : ''; $cooksetPassword = isset($config['cookset_password']) ? (bool) $config['cookset_password'] : false; if ($cookieName === '') { Log::warning(sprintf('Account cookie name must be string and not empty, cluster_name "%s"', $clusterName), 0, __METHOD__); return false; } $authentica = new Authentica($clusterName); $data = $authentica->getIdentity(); if (!$data || !is_array($data) || !isset($data['user_id'])) { Log::debug(sprintf('Account cookie data must be array and not empty, cluster_name "%s", cookie_name "%s"', $clusterName, $cookieName), 0, __METHOD__); return false; } $memberId = isset($data['user_id']) ? (int) $data['user_id'] : 0; $loginName = isset($data['user_name']) ? trim($data['user_name']) : ''; $password = isset($data['password']) ? $data['password'] : ''; $ip = isset($data['ip']) ? (int) $data['ip'] : 0; $expiry = isset($data['expiry']) ? (int) $data['expiry'] : 0; $time = isset($data['time']) ? (int) $data['time'] : 0; $nickname = isset($data['nickname']) ? trim($data['nickname']) : ''; $roleNames = isset($data['role_names']) ? (array) $data['role_names'] : array(); $extends = isset($data['extends']) ? $data['extends'] : ''; if ($memberId <= 0 || $loginName === '') { Log::warning(sprintf('Account cookie member_id and login_name must be not empty, cluster_name "%s", cookie_name "%s", member_id "%d", login_name "%s"', $clusterName, $cookieName, $memberId, $loginName), 0, __METHOD__); return false; } $clientIp = ip2long(Ap::getRequest()->getClientIp()); if ($ip !== $clientIp) { Log::warning(sprintf('Account cookie ip "%s" is not equal to client ip "%s", cluster_name "%s", cookie_name "%s", member_id "%d", login_name "%s"', long2ip($ip), long2ip($clientIp), $clusterName, $cookieName, $memberId, $loginName), 0, __METHOD__); return false; } if ($cooksetPassword) { if ($password === '') { Log::warning(sprintf('Account config cookset_password and cookie password must be not empty, cluster_name "%s", cookie_name "%s", member_id "%d", login_name "%s"', $clusterName, $cookieName, $memberId, $loginName), 0, __METHOD__); return false; } $dbpwd = $this->_portal->getPasswordByUserId($memberId); if ($password !== $dbpwd) { Log::warning(sprintf('Account cookie password "%s" is not equal to db password "%s", cluster_name "%s", cookie_name "%s", member_id "%d", login_name "%s"', $clusterName, $cookieName, $memberId, $loginName), 0, __METHOD__); return false; } } $typeId = $rankId = 0; foreach ($roleNames as $name) { $prev = substr($name, 0, 7); if ($prev === 'type_id') { $typeId = (int) substr($name, 8); continue; } if ($prev === 'rank_id') { $rankId = (int) substr($name, 8); continue; } } $appNames = array(); $authoriz = null; Identity::setAll($memberId, $loginName, $nickname, $roleNames, $appNames, $typeId, $rankId, $authoriz); return true; }